Skip to content

Commit b1e36f1

Browse files
authored
Merge pull request #13 from pipecat-ai/aleix/use-and-cleanup-css
use and cleanup css, also apply PUSH/PROCESS filter to frame path
2 parents a22022b + ac70133 commit b1e36f1

6 files changed

Lines changed: 270 additions & 223 deletions

File tree

ui/src/App.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ export default function App() {
3131
<div className="graph">
3232
<Pipeline />
3333
</div>
34-
<div className="footer-note" style={{ marginTop: 8 }}>
34+
<div className="footer-note mt-md">
3535
Tip: Click a processor node to inspect frames.
3636
</div>
3737
</div>
3838
<div className="card">
39-
<div className="card" style={{ flex: 2 }}>
39+
<div className="card flex-2">
4040
<h3>
4141
Frames{" "}
4242
{selectedProcessor
@@ -45,13 +45,13 @@ export default function App() {
4545
</h3>
4646
<FrameInspector />
4747
</div>
48-
<div className="card" style={{ flex: 1, marginTop: "1rem" }}>
48+
<div className="card flex-1 mt-lg">
4949
<h3>
5050
Frame path {selectedFrame ? `(frame: ${selectedFrame.name})` : ""}
5151
</h3>
5252
<FramePath />
5353
</div>
54-
<div className="footer-note" style={{ marginTop: 8 }}>
54+
<div className="footer-note mt-md">
5555
Tip: Click a frame in the path and press{" "}
5656
<span className="kbd">Up</span> or <span className="kbd">Down</span>{" "}
5757
to move between processors.

ui/src/components/FrameInspector.tsx

Lines changed: 29 additions & 200 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,19 @@ import { useEffect, useMemo, useRef, useState } from "react";
88
import { useStore } from "../state.store";
99
import { FrameMessage } from "../types";
1010
import { useWhisker } from "../hooks.useWhisker";
11+
import cls from "classnames";
1112

1213
export function FrameInspector() {
1314
const [selectedTypes, setSelectedTypes] = useState<Set<string>>(new Set());
1415
const [isFilterOpen, setIsFilterOpen] = useState(false);
1516
const [typeSearch, setTypeSearch] = useState("");
16-
const [showPush, setShowPush] = useState(true);
17-
const [showProcess, setShowProcess] = useState(true);
1817
const [showUpstream, setShowUpstream] = useState(true);
1918
const [showDownstream, setShowDownstream] = useState(true);
2019
const frames = useStore((s) => s.frames);
20+
const showPush = useStore((s) => s.showPush);
21+
const showProcess = useStore((s) => s.showProcess);
22+
const setShowPush = useStore((s) => s.setShowPush);
23+
const setShowProcess = useStore((s) => s.setShowProcess);
2124
const selected = useStore((s) => s.selectedProcessor);
2225
const selectedFrame = useStore((s) => s.selectedFrame);
2326
const setSelectedFrame = useStore((s) => s.setSelectedFrame);
@@ -93,25 +96,11 @@ export function FrameInspector() {
9396

9497
return (
9598
<div className="split">
96-
<div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
97-
<div style={{ position: "relative", flex: 1 }}>
99+
<div className="filter-row">
100+
<div className="filter-dropdown">
98101
<button
102+
className="filter-button"
99103
onClick={() => setIsFilterOpen(!isFilterOpen)}
100-
style={{
101-
width: "100%",
102-
padding: "8px 10px",
103-
fontSize: "14px",
104-
borderRadius: "8px",
105-
border: "1px solid var(--border)",
106-
margin: "4px 0 4px 0",
107-
background: "var(--bg)",
108-
color: "var(--text)",
109-
cursor: "pointer",
110-
textAlign: "left",
111-
display: "flex",
112-
justifyContent: "space-between",
113-
alignItems: "center",
114-
}}
115104
>
116105
<span>
117106
{selectedTypes.size === 0
@@ -121,223 +110,79 @@ export function FrameInspector() {
121110
<span>{isFilterOpen ? "▲" : "▼"}</span>
122111
</button>
123112
{isFilterOpen && (
124-
<div
125-
style={{
126-
position: "absolute",
127-
top: "100%",
128-
left: 0,
129-
right: 0,
130-
background: "var(--bg)",
131-
border: "1px solid var(--border)",
132-
borderRadius: "8px",
133-
zIndex: 100,
134-
maxHeight: "300px",
135-
overflowY: "auto",
136-
boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
137-
}}
138-
>
139-
<div
140-
style={{
141-
display: "flex",
142-
gap: "8px",
143-
padding: "8px",
144-
borderBottom: "1px solid var(--border)",
145-
}}
146-
>
147-
<button
148-
onClick={selectAll}
149-
style={{
150-
flex: 1,
151-
padding: "6px 8px",
152-
fontSize: "14px",
153-
borderRadius: "4px",
154-
border: "none",
155-
background: "var(--border)",
156-
color: "var(--text)",
157-
cursor: "pointer",
158-
fontWeight: 500,
159-
}}
160-
>
113+
<div className="filter-menu">
114+
<div className="filter-menu-header">
115+
<button className="btn-sm" onClick={selectAll}>
161116
Select All
162117
</button>
163-
<button
164-
onClick={clearAll}
165-
style={{
166-
flex: 1,
167-
padding: "6px 8px",
168-
fontSize: "14px",
169-
borderRadius: "4px",
170-
border: "none",
171-
background: "var(--border)",
172-
color: "var(--text)",
173-
cursor: "pointer",
174-
fontWeight: 500,
175-
}}
176-
>
118+
<button className="btn-sm" onClick={clearAll}>
177119
Clear All
178120
</button>
179121
</div>
180-
<div
181-
style={{
182-
padding: "8px",
183-
borderBottom: "1px solid var(--border)",
184-
}}
185-
>
122+
<div className="filter-menu-search">
186123
<input
187124
type="text"
125+
className="filter-input"
188126
placeholder="Search frames..."
189127
value={typeSearch}
190128
onChange={(e) => setTypeSearch(e.target.value)}
191-
style={{
192-
width: "100%",
193-
padding: "6px 8px",
194-
fontSize: "14px",
195-
borderRadius: "4px",
196-
border: "1px solid var(--border)",
197-
background: "var(--bg)",
198-
color: "var(--text)",
199-
boxSizing: "border-box",
200-
}}
201129
/>
202130
</div>
203131
{filteredTypes.length === 0 ? (
204-
<div
205-
style={{
206-
padding: "12px",
207-
color: "var(--text)",
208-
opacity: 0.6,
209-
}}
210-
>
211-
No frames available
212-
</div>
132+
<div className="filter-menu-empty">No frames available</div>
213133
) : (
214134
filteredTypes.map((type) => (
215-
<label
216-
key={type}
217-
style={{
218-
display: "flex",
219-
alignItems: "center",
220-
gap: "8px",
221-
padding: "8px 12px",
222-
cursor: "pointer",
223-
borderBottom: "1px solid var(--border)",
224-
fontSize: "14px",
225-
}}
226-
>
135+
<label key={type} className="filter-menu-item">
227136
<input
228137
type="checkbox"
229138
checked={selectedTypes.has(type)}
230139
onChange={() => toggleType(type)}
231-
style={{ cursor: "pointer" }}
232140
/>
233-
<span style={{ color: "var(--text)" }}>{type}</span>
141+
<span>{type}</span>
234142
</label>
235143
))
236144
)}
237145
</div>
238146
)}
239147
</div>
240-
<div
241-
style={{
242-
display: "flex",
243-
gap: "8px",
244-
padding: "6px 10px",
245-
border: "1px solid var(--border)",
246-
borderRadius: "8px",
247-
}}
248-
>
249-
<label
250-
style={{
251-
display: "flex",
252-
alignItems: "center",
253-
gap: "4px",
254-
cursor: "pointer",
255-
fontSize: "14px",
256-
color: "var(--text)",
257-
}}
258-
>
148+
<div className="checkbox-group">
149+
<label className="checkbox-label">
259150
<input
260151
type="checkbox"
261152
checked={showPush}
262153
onChange={(e) => setShowPush(e.target.checked)}
263-
style={{ cursor: "pointer" }}
264154
/>
265155
PUSH
266156
</label>
267-
<label
268-
style={{
269-
display: "flex",
270-
alignItems: "center",
271-
gap: "4px",
272-
cursor: "pointer",
273-
fontSize: "14px",
274-
color: "var(--text)",
275-
}}
276-
>
157+
<label className="checkbox-label">
277158
<input
278159
type="checkbox"
279160
checked={showProcess}
280161
onChange={(e) => setShowProcess(e.target.checked)}
281-
style={{ cursor: "pointer" }}
282162
/>
283163
PROCESS
284164
</label>
285165
</div>
286-
<div
287-
style={{
288-
display: "flex",
289-
gap: "8px",
290-
padding: "6px 10px",
291-
border: "1px solid var(--border)",
292-
borderRadius: "8px",
293-
}}
294-
>
295-
<label
296-
style={{
297-
display: "flex",
298-
alignItems: "center",
299-
gap: "4px",
300-
cursor: "pointer",
301-
fontSize: "14px",
302-
color: "var(--text)",
303-
}}
304-
>
166+
<div className="checkbox-group">
167+
<label className="checkbox-label">
305168
<input
306169
type="checkbox"
307170
checked={showUpstream}
308171
onChange={(e) => setShowUpstream(e.target.checked)}
309-
style={{ cursor: "pointer" }}
310172
/>
311173
UPSTREAM
312174
</label>
313-
<label
314-
style={{
315-
display: "flex",
316-
alignItems: "center",
317-
gap: "4px",
318-
cursor: "pointer",
319-
fontSize: "14px",
320-
color: "var(--text)",
321-
}}
322-
>
175+
<label className="checkbox-label">
323176
<input
324177
type="checkbox"
325178
checked={showDownstream}
326179
onChange={(e) => setShowDownstream(e.target.checked)}
327-
style={{ cursor: "pointer" }}
328180
/>
329181
DOWNSTREAM
330182
</label>
331183
</div>
332184
</div>
333-
<span
334-
style={{
335-
fontSize: "14px",
336-
color: "var(--text)",
337-
opacity: 0.7,
338-
margin: "4px 0",
339-
}}
340-
>
185+
<span className="frame-count">
341186
Showing {sortedFrames.length} frames out of {allFrames.length}
342187
</span>
343188
<div className="pane">
@@ -390,23 +235,10 @@ function FrameItem({
390235
<div
391236
key={`frame-${frame.id}-${idx}`}
392237
ref={ref}
393-
className="list-item"
394-
style={{
395-
background: frameBackground(frame),
396-
display: "flex",
397-
flexDirection: "column",
398-
border: isSelected ? "2px solid black" : "1px solid transparent",
399-
}}
238+
className={cls("list-item", "frame-item", { selected: isSelected })}
239+
style={{ background: frameBackground(frame) }}
400240
>
401-
<div
402-
style={{
403-
display: "flex",
404-
alignItems: "center",
405-
gap: 6,
406-
cursor: "pointer",
407-
}}
408-
onClick={onClick}
409-
>
241+
<div className="frame-header" onClick={onClick}>
410242
<span>{frame.direction === "upstream" ? "⬆️️" : "⬇️️"}</span>
411243
<span>
412244
<b>{frame.event === "process" ? "PROCESS ⚙️️" : "PUSH 🚀"}</b>
@@ -415,13 +247,10 @@ function FrameItem({
415247
<span className="footer-note">
416248
{new Date(frame.timestamp).toISOString()}
417249
</span>
418-
<span style={{ marginLeft: "auto" }}>{isSelected ? "▼" : "▶"}</span>
250+
<span className="ml-auto">{isSelected ? "▼" : "▶"}</span>
419251
</div>
420252
{isSelected && (
421-
<div
422-
className="footer-note"
423-
style={{ whiteSpace: "pre-wrap", marginTop: 4, userSelect: "text" }}
424-
>
253+
<div className="footer-note frame-details">
425254
{JSON.stringify(frame.payload, null, 2)}
426255
</div>
427256
)}

0 commit comments

Comments
 (0)