Skip to content

Commit 620570a

Browse files
feat(editor): per-script activity in the inspector
Selecting a script entity now shows its traffic inline under the editor: the events it received and the commands it emitted, filtered from the same journal the console log streams, scoped to that entity by id. Each row is tagged command or event and hovers to its full detail, so you can watch one script react without reading the whole global log.
1 parent 55cb7a9 commit 620570a

2 files changed

Lines changed: 128 additions & 1 deletion

File tree

apps/editor/public/styles.css

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,79 @@ input[type="range"] {
655655
color: var(--text);
656656
}
657657

658+
.script-activity-title {
659+
font-size: 10.5px;
660+
text-transform: uppercase;
661+
letter-spacing: 0.04em;
662+
opacity: 0.55;
663+
margin: 10px 0 4px;
664+
}
665+
666+
.script-activity {
667+
display: flex;
668+
flex-direction: column;
669+
gap: 1px;
670+
max-height: 200px;
671+
overflow-y: auto;
672+
font-family: ui-monospace, "Cascadia Code", Menlo, monospace;
673+
font-size: 11px;
674+
}
675+
676+
.script-activity-empty {
677+
opacity: 0.45;
678+
font-size: 11px;
679+
padding: 6px 2px;
680+
}
681+
682+
.script-activity-row {
683+
display: grid;
684+
grid-template-columns: 28px auto 1fr auto;
685+
align-items: baseline;
686+
gap: 7px;
687+
padding: 2px 6px;
688+
border-radius: 5px;
689+
border-left: 2px solid transparent;
690+
}
691+
692+
.script-activity-command {
693+
border-left-color: #60a5fa;
694+
}
695+
696+
.script-activity-event {
697+
border-left-color: var(--accent);
698+
}
699+
700+
.script-activity-tag {
701+
font-size: 9px;
702+
font-weight: 700;
703+
text-transform: uppercase;
704+
}
705+
706+
.script-activity-command .script-activity-tag {
707+
color: #60a5fa;
708+
}
709+
710+
.script-activity-event .script-activity-tag {
711+
color: var(--accent);
712+
}
713+
714+
.script-activity-label {
715+
font-weight: 600;
716+
white-space: nowrap;
717+
}
718+
719+
.script-activity-detail {
720+
opacity: 0.6;
721+
overflow: hidden;
722+
text-overflow: ellipsis;
723+
white-space: nowrap;
724+
}
725+
726+
.script-activity-count {
727+
font-size: 9.5px;
728+
opacity: 0.6;
729+
}
730+
658731
.scripts-section {
659732
border-top: 1px solid var(--border, #2a3340);
660733
padding: 6px 8px 10px;

apps/editor/src/components/inspector.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ fn EntitySections(
417417
let script = detail
418418
.script
419419
.clone()
420-
.map(|source| view! { <ScriptSection bridge id source /> });
420+
.map(|source| view! { <ScriptSection bridge state id source /> });
421421
let render_layer = detail.render_layer.map(|layer| {
422422
view! {
423423
<div class="section">
@@ -2028,6 +2028,7 @@ fn TextSection(
20282028
#[component]
20292029
fn ScriptSection(
20302030
bridge: StoredValue<Option<Bridge>, LocalStorage>,
2031+
state: EditorState,
20312032
id: u32,
20322033
source: String,
20332034
) -> impl IntoView {
@@ -2059,6 +2060,59 @@ fn ScriptSection(
20592060
send_component(bridge, id, ComponentPatch::Script(value), true);
20602061
})
20612062
/>
2063+
<div class="script-activity-title">"Activity"</div>
2064+
<div class="script-activity">
2065+
{move || {
2066+
let mut rows: Vec<_> = state
2067+
.command_log
2068+
.get()
2069+
.into_iter()
2070+
.filter(|(entry, _)| entry.entities.contains(&id))
2071+
.collect();
2072+
if rows.is_empty() {
2073+
return view! {
2074+
<div class="script-activity-empty">
2075+
"No events or commands for this entity yet. Run scripts to see its traffic."
2076+
</div>
2077+
}
2078+
.into_any();
2079+
}
2080+
rows.reverse();
2081+
rows.truncate(24);
2082+
rows.into_iter()
2083+
.map(|(entry, count)| {
2084+
let is_command = entry.kind
2085+
== nightshade_api::editor::protocol::CommandLogKind::Command;
2086+
let detail = entry.detail.clone();
2087+
view! {
2088+
<div
2089+
class=if is_command {
2090+
"script-activity-row script-activity-command"
2091+
} else {
2092+
"script-activity-row script-activity-event"
2093+
}
2094+
title=detail
2095+
>
2096+
<span class="script-activity-tag">
2097+
{if is_command { "cmd" } else { "evt" }}
2098+
</span>
2099+
<span class="script-activity-label">{entry.label}</span>
2100+
<span class="script-activity-detail">{entry.detail}</span>
2101+
{(count > 1)
2102+
.then(|| {
2103+
view! {
2104+
<span class="script-activity-count">
2105+
{format!("x{count}")}
2106+
</span>
2107+
}
2108+
})}
2109+
</div>
2110+
}
2111+
})
2112+
.collect_view()
2113+
.into_any()
2114+
}}
2115+
</div>
20622116
</div>
20632117
}
20642118
}

0 commit comments

Comments
 (0)