mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
fix(ui): move the policy flow builder onto theme tokens (#37654)
* fix(ui): move the policy flow builder onto theme tokens The flow builder carried its own private palette: 126 raw literals across a 1644-line file, hardcoded into React inline style objects and SVG presentation attributes. Inline styles beat every class, so the whole page, its version sidebar, its step cards and its test panel stayed light no matter what the theme said. Each literal now resolves through the token it was already imitating. The greys map onto card, muted, border, muted-foreground and foreground; the indigo and blue accents onto info; the pass, fail and API-failure accents onto success, destructive and warning; and the pale status washes become a color-mix of the same token so they track it in both themes. Six icons carried their colour as an SVG presentation attribute, where custom properties do not substitute, so those switch to currentColor with the token set alongside. Light mode is not byte-identical, and that is the point: the file stops keeping a second palette. Of the mappings, card, muted and border land on the exact same rgb they had, covering most of the file. The rest snap to the dashboard's canonical shade, which mostly means slightly darker text and deeper status colours: the gray-400 labels pick up real contrast, the soft red on the fail icon becomes the destructive red every other failure indicator uses, and the indigo accent becomes the blue that info resolves to. Verified in a browser on both themes. In dark mode nothing on the page paints a light background any more; the six that still do are shadcn's inverted primary buttons and badges, which are meant to. * fix(ui): token the flow builder test textarea fill The quick-chat textarea is the one bare form control left in the file, so the @tailwindcss/forms base layer still paints it `background-color: #fff`. The inline style overrode the plugin's border but not its fill, which left a white box inside the now-dark test panel, and its text inherits the near-white foreground, so the typed message was invisible in dark mode. Pin both halves of the pair on the element the plugin styles: the card token it sits on, and the foreground token it was already inheriting.
This commit is contained in:
parent
5cd6347c2c
commit
0e7e640062
1 changed files with 245 additions and 129 deletions
|
|
@ -113,7 +113,7 @@ const GuardrailIcon: React.FC = () => (
|
|||
width: 28,
|
||||
height: 28,
|
||||
borderRadius: "50%",
|
||||
backgroundColor: "#eef2ff",
|
||||
backgroundColor: "color-mix(in oklab, var(--color-info) 10%, transparent)",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
|
|
@ -125,8 +125,9 @@ const GuardrailIcon: React.FC = () => (
|
|||
height="14"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="#6366f1"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
style={{ color: "var(--color-info)" }}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
|
|
@ -142,14 +143,21 @@ const PlayIcon: React.FC = () => (
|
|||
width: 28,
|
||||
height: 28,
|
||||
borderRadius: "50%",
|
||||
backgroundColor: "#f3f4f6",
|
||||
backgroundColor: "var(--color-muted)",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="#6b7280" stroke="none">
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
stroke="none"
|
||||
style={{ color: "var(--color-muted-foreground)" }}
|
||||
>
|
||||
<polygon points="6,3 20,12 6,21" />
|
||||
</svg>
|
||||
</div>
|
||||
|
|
@ -161,11 +169,11 @@ const PassIcon: React.FC = () => (
|
|||
height="14"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="#22c55e"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
style={{ flexShrink: 0 }}
|
||||
style={{ flexShrink: 0, color: "var(--color-success)" }}
|
||||
>
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<path d="M9 12l2 2 4-4" />
|
||||
|
|
@ -178,11 +186,11 @@ const FailIcon: React.FC = () => (
|
|||
height="14"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="#f87171"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
style={{ flexShrink: 0 }}
|
||||
style={{ flexShrink: 0, color: "var(--color-destructive)" }}
|
||||
>
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
</svg>
|
||||
|
|
@ -194,11 +202,11 @@ const ApiFailureIcon: React.FC = () => (
|
|||
height="14"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="#d97706"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
style={{ flexShrink: 0 }}
|
||||
style={{ flexShrink: 0, color: "var(--color-warning)" }}
|
||||
>
|
||||
<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" />
|
||||
<line x1="12" y1="9" x2="12" y2="13" />
|
||||
|
|
@ -216,7 +224,7 @@ interface ConnectorProps {
|
|||
|
||||
const Connector: React.FC<ConnectorProps> = ({ onInsert }) => (
|
||||
<div className="flex flex-col items-center" style={{ height: 56 }}>
|
||||
<div style={{ width: 1, flex: 1, backgroundColor: "#d1d5db" }} />
|
||||
<div style={{ width: 1, flex: 1, backgroundColor: "var(--color-border)" }} />
|
||||
<button
|
||||
onClick={onInsert}
|
||||
className="flex items-center justify-center"
|
||||
|
|
@ -224,25 +232,25 @@ const Connector: React.FC<ConnectorProps> = ({ onInsert }) => (
|
|||
width: 24,
|
||||
height: 24,
|
||||
borderRadius: "50%",
|
||||
border: "1px solid #d1d5db",
|
||||
backgroundColor: "#fff",
|
||||
border: "1px solid var(--color-border)",
|
||||
backgroundColor: "var(--color-card)",
|
||||
cursor: "pointer",
|
||||
zIndex: 1,
|
||||
transition: "all 0.15s ease",
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
e.currentTarget.style.borderColor = "#6366f1";
|
||||
e.currentTarget.style.backgroundColor = "#eef2ff";
|
||||
e.currentTarget.style.borderColor = "var(--color-info)";
|
||||
e.currentTarget.style.backgroundColor = "color-mix(in oklab, var(--color-info) 10%, transparent)";
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.borderColor = "#d1d5db";
|
||||
e.currentTarget.style.backgroundColor = "#fff";
|
||||
e.currentTarget.style.borderColor = "var(--color-border)";
|
||||
e.currentTarget.style.backgroundColor = "var(--color-card)";
|
||||
}}
|
||||
title="Insert step"
|
||||
>
|
||||
<Plus style={{ width: 12, height: 12, color: "#9ca3af" }} />
|
||||
<Plus style={{ width: 12, height: 12, color: "var(--color-muted-foreground)" }} />
|
||||
</button>
|
||||
<div style={{ width: 1, flex: 1, backgroundColor: "#d1d5db" }} />
|
||||
<div style={{ width: 1, flex: 1, backgroundColor: "var(--color-border)" }} />
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
@ -275,9 +283,9 @@ const StepCard: React.FC<StepCardProps> = ({
|
|||
return (
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid #e5e7eb",
|
||||
border: "1px solid var(--color-border)",
|
||||
borderRadius: 10,
|
||||
backgroundColor: "#fff",
|
||||
backgroundColor: "var(--color-card)",
|
||||
maxWidth: 720,
|
||||
width: "100%",
|
||||
overflow: "hidden",
|
||||
|
|
@ -292,7 +300,7 @@ const StepCard: React.FC<StepCardProps> = ({
|
|||
fontSize: 11,
|
||||
fontWeight: 700,
|
||||
textTransform: "uppercase",
|
||||
color: "#6366f1",
|
||||
color: "var(--color-info)",
|
||||
letterSpacing: "0.06em",
|
||||
}}
|
||||
>
|
||||
|
|
@ -300,7 +308,7 @@ const StepCard: React.FC<StepCardProps> = ({
|
|||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span style={{ fontSize: 13, color: "#9ca3af" }}>Step {stepIndex + 1}</span>
|
||||
<span style={{ fontSize: 13, color: "var(--color-muted-foreground)" }}>Step {stepIndex + 1}</span>
|
||||
<button
|
||||
onClick={onDelete}
|
||||
disabled={totalSteps <= 1}
|
||||
|
|
@ -315,14 +323,22 @@ const StepCard: React.FC<StepCardProps> = ({
|
|||
}}
|
||||
title="Delete step"
|
||||
>
|
||||
<MoreVertical style={{ width: 16, height: 16, color: "#9ca3af" }} />
|
||||
<MoreVertical style={{ width: 16, height: 16, color: "var(--color-muted-foreground)" }} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Guardrail selector */}
|
||||
<div style={{ padding: "12px 20px 16px 20px" }}>
|
||||
<label style={{ fontSize: 12, fontWeight: 500, color: "#6b7280", display: "block", marginBottom: 6 }}>
|
||||
<label
|
||||
style={{
|
||||
fontSize: 12,
|
||||
fontWeight: 500,
|
||||
color: "var(--color-muted-foreground)",
|
||||
display: "block",
|
||||
marginBottom: 6,
|
||||
}}
|
||||
>
|
||||
Guardrail
|
||||
</label>
|
||||
<SearchSelect
|
||||
|
|
@ -335,12 +351,20 @@ const StepCard: React.FC<StepCardProps> = ({
|
|||
</div>
|
||||
|
||||
{/* ON PASS section */}
|
||||
<div style={{ borderTop: "1px solid #f0f0f0", padding: "14px 20px" }}>
|
||||
<div style={{ borderTop: "1px solid var(--color-border)", padding: "14px 20px" }}>
|
||||
<div className="flex items-center gap-2" style={{ marginBottom: 8 }}>
|
||||
<PassIcon />
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: "#374151" }}>ON PASS</span>
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: "var(--color-foreground)" }}>ON PASS</span>
|
||||
</div>
|
||||
<label style={{ fontSize: 12, fontWeight: 500, color: "#6b7280", display: "block", marginBottom: 6 }}>
|
||||
<label
|
||||
style={{
|
||||
fontSize: 12,
|
||||
fontWeight: 500,
|
||||
color: "var(--color-muted-foreground)",
|
||||
display: "block",
|
||||
marginBottom: 6,
|
||||
}}
|
||||
>
|
||||
Action
|
||||
</label>
|
||||
<Select value={step.on_pass} onValueChange={(value) => onChange({ on_pass: value as PipelineStep["on_pass"] })}>
|
||||
|
|
@ -357,7 +381,15 @@ const StepCard: React.FC<StepCardProps> = ({
|
|||
</Select>
|
||||
{step.on_pass === "modify_response" && (
|
||||
<div style={{ marginTop: 8 }}>
|
||||
<label style={{ fontSize: 12, fontWeight: 500, color: "#6b7280", display: "block", marginBottom: 6 }}>
|
||||
<label
|
||||
style={{
|
||||
fontSize: 12,
|
||||
fontWeight: 500,
|
||||
color: "var(--color-muted-foreground)",
|
||||
display: "block",
|
||||
marginBottom: 6,
|
||||
}}
|
||||
>
|
||||
Custom Response Message
|
||||
</label>
|
||||
<Input
|
||||
|
|
@ -370,12 +402,20 @@ const StepCard: React.FC<StepCardProps> = ({
|
|||
</div>
|
||||
|
||||
{/* ON FAIL section */}
|
||||
<div style={{ borderTop: "1px solid #f0f0f0", padding: "14px 20px" }}>
|
||||
<div style={{ borderTop: "1px solid var(--color-border)", padding: "14px 20px" }}>
|
||||
<div className="flex items-center gap-2" style={{ marginBottom: 8 }}>
|
||||
<FailIcon />
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: "#374151" }}>ON FAIL</span>
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: "var(--color-foreground)" }}>ON FAIL</span>
|
||||
</div>
|
||||
<label style={{ fontSize: 12, fontWeight: 500, color: "#6b7280", display: "block", marginBottom: 6 }}>
|
||||
<label
|
||||
style={{
|
||||
fontSize: 12,
|
||||
fontWeight: 500,
|
||||
color: "var(--color-muted-foreground)",
|
||||
display: "block",
|
||||
marginBottom: 6,
|
||||
}}
|
||||
>
|
||||
Action
|
||||
</label>
|
||||
<Select value={step.on_fail} onValueChange={(value) => onChange({ on_fail: value as PipelineStep["on_fail"] })}>
|
||||
|
|
@ -392,7 +432,15 @@ const StepCard: React.FC<StepCardProps> = ({
|
|||
</Select>
|
||||
{step.on_fail === "modify_response" && (
|
||||
<div style={{ marginTop: 8 }}>
|
||||
<label style={{ fontSize: 12, fontWeight: 500, color: "#6b7280", display: "block", marginBottom: 6 }}>
|
||||
<label
|
||||
style={{
|
||||
fontSize: 12,
|
||||
fontWeight: 500,
|
||||
color: "var(--color-muted-foreground)",
|
||||
display: "block",
|
||||
marginBottom: 6,
|
||||
}}
|
||||
>
|
||||
Custom Response Message
|
||||
</label>
|
||||
<Input
|
||||
|
|
@ -405,12 +453,20 @@ const StepCard: React.FC<StepCardProps> = ({
|
|||
</div>
|
||||
|
||||
{/* ON API FAILURE (technical / provider outage) — optional; defaults to ON FAIL */}
|
||||
<div style={{ borderTop: "1px solid #f0f0f0", padding: "14px 20px" }}>
|
||||
<div style={{ borderTop: "1px solid var(--color-border)", padding: "14px 20px" }}>
|
||||
<div className="flex items-center gap-2" style={{ marginBottom: 8 }}>
|
||||
<ApiFailureIcon />
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: "#374151" }}>ON API FAILURE</span>
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: "var(--color-foreground)" }}>ON API FAILURE</span>
|
||||
</div>
|
||||
<label style={{ fontSize: 12, fontWeight: 500, color: "#6b7280", display: "block", marginBottom: 6 }}>
|
||||
<label
|
||||
style={{
|
||||
fontSize: 12,
|
||||
fontWeight: 500,
|
||||
color: "var(--color-muted-foreground)",
|
||||
display: "block",
|
||||
marginBottom: 6,
|
||||
}}
|
||||
>
|
||||
Action
|
||||
</label>
|
||||
<Select
|
||||
|
|
@ -435,7 +491,15 @@ const StepCard: React.FC<StepCardProps> = ({
|
|||
</Select>
|
||||
{step.on_error === "modify_response" && step.on_fail !== "modify_response" && (
|
||||
<div style={{ marginTop: 8 }}>
|
||||
<label style={{ fontSize: 12, fontWeight: 500, color: "#6b7280", display: "block", marginBottom: 6 }}>
|
||||
<label
|
||||
style={{
|
||||
fontSize: 12,
|
||||
fontWeight: 500,
|
||||
color: "var(--color-muted-foreground)",
|
||||
display: "block",
|
||||
marginBottom: 6,
|
||||
}}
|
||||
>
|
||||
Custom Response Message
|
||||
</label>
|
||||
<Input
|
||||
|
|
@ -481,10 +545,10 @@ const PipelineFlowBuilder: React.FC<PipelineFlowBuilderProps> = ({ pipeline, onC
|
|||
{/* Trigger Card */}
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid #e5e7eb",
|
||||
border: "1px solid var(--color-border)",
|
||||
borderRadius: 10,
|
||||
padding: "16px 20px",
|
||||
backgroundColor: "#fff",
|
||||
backgroundColor: "var(--color-card)",
|
||||
maxWidth: 720,
|
||||
width: "100%",
|
||||
}}
|
||||
|
|
@ -497,7 +561,7 @@ const PipelineFlowBuilder: React.FC<PipelineFlowBuilderProps> = ({ pipeline, onC
|
|||
fontSize: 11,
|
||||
fontWeight: 700,
|
||||
textTransform: "uppercase",
|
||||
color: "#6b7280",
|
||||
color: "var(--color-muted-foreground)",
|
||||
letterSpacing: "0.06em",
|
||||
display: "block",
|
||||
marginBottom: 2,
|
||||
|
|
@ -505,10 +569,12 @@ const PipelineFlowBuilder: React.FC<PipelineFlowBuilderProps> = ({ pipeline, onC
|
|||
>
|
||||
TRIGGER
|
||||
</span>
|
||||
<span style={{ fontSize: 14, fontWeight: 600, color: "#111827", display: "block" }}>
|
||||
<span style={{ fontSize: 14, fontWeight: 600, color: "var(--color-foreground)", display: "block" }}>
|
||||
Incoming LLM Request
|
||||
</span>
|
||||
<span style={{ fontSize: 13, color: "#9ca3af" }}>This flow runs when a request matches this policy</span>
|
||||
<span style={{ fontSize: 13, color: "var(--color-muted-foreground)" }}>
|
||||
This flow runs when a request matches this policy
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -534,10 +600,10 @@ const PipelineFlowBuilder: React.FC<PipelineFlowBuilderProps> = ({ pipeline, onC
|
|||
{/* End card */}
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid #e5e7eb",
|
||||
border: "1px solid var(--color-border)",
|
||||
borderRadius: 10,
|
||||
padding: "14px 20px",
|
||||
backgroundColor: "#fff",
|
||||
backgroundColor: "var(--color-card)",
|
||||
maxWidth: 720,
|
||||
width: "100%",
|
||||
}}
|
||||
|
|
@ -548,7 +614,7 @@ const PipelineFlowBuilder: React.FC<PipelineFlowBuilderProps> = ({ pipeline, onC
|
|||
width: 28,
|
||||
height: 28,
|
||||
borderRadius: "50%",
|
||||
backgroundColor: "#f3f4f6",
|
||||
backgroundColor: "var(--color-muted)",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
|
|
@ -560,10 +626,11 @@ const PipelineFlowBuilder: React.FC<PipelineFlowBuilderProps> = ({ pipeline, onC
|
|||
height="12"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="#6b7280"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
style={{ color: "var(--color-muted-foreground)" }}
|
||||
>
|
||||
<rect x="3" y="3" width="18" height="18" rx="2" />
|
||||
<line x1="8" y1="12" x2="16" y2="12" />
|
||||
|
|
@ -575,7 +642,7 @@ const PipelineFlowBuilder: React.FC<PipelineFlowBuilderProps> = ({ pipeline, onC
|
|||
fontSize: 11,
|
||||
fontWeight: 700,
|
||||
textTransform: "uppercase",
|
||||
color: "#6b7280",
|
||||
color: "var(--color-muted-foreground)",
|
||||
letterSpacing: "0.06em",
|
||||
display: "block",
|
||||
marginBottom: 2,
|
||||
|
|
@ -583,8 +650,10 @@ const PipelineFlowBuilder: React.FC<PipelineFlowBuilderProps> = ({ pipeline, onC
|
|||
>
|
||||
END
|
||||
</span>
|
||||
<span style={{ fontSize: 14, fontWeight: 600, color: "#111827", display: "block" }}>Continue to LLM</span>
|
||||
<span style={{ fontSize: 13, color: "#9ca3af" }}>Request proceeds to the model</span>
|
||||
<span style={{ fontSize: 14, fontWeight: 600, color: "var(--color-foreground)", display: "block" }}>
|
||||
Continue to LLM
|
||||
</span>
|
||||
<span style={{ fontSize: 13, color: "var(--color-muted-foreground)" }}>Request proceeds to the model</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -605,10 +674,10 @@ export const PipelineInfoDisplay: React.FC<PipelineInfoDisplayProps> = ({ pipeli
|
|||
{/* Trigger */}
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid #e5e7eb",
|
||||
border: "1px solid var(--color-border)",
|
||||
borderRadius: 10,
|
||||
padding: "14px 20px",
|
||||
backgroundColor: "#fff",
|
||||
backgroundColor: "var(--color-card)",
|
||||
maxWidth: 720,
|
||||
width: "100%",
|
||||
}}
|
||||
|
|
@ -621,7 +690,7 @@ export const PipelineInfoDisplay: React.FC<PipelineInfoDisplayProps> = ({ pipeli
|
|||
fontSize: 11,
|
||||
fontWeight: 700,
|
||||
textTransform: "uppercase",
|
||||
color: "#6b7280",
|
||||
color: "var(--color-muted-foreground)",
|
||||
letterSpacing: "0.06em",
|
||||
display: "block",
|
||||
marginBottom: 2,
|
||||
|
|
@ -629,7 +698,7 @@ export const PipelineInfoDisplay: React.FC<PipelineInfoDisplayProps> = ({ pipeli
|
|||
>
|
||||
TRIGGER
|
||||
</span>
|
||||
<span style={{ fontSize: 14, fontWeight: 600, color: "#111827" }}>Incoming LLM Request</span>
|
||||
<span style={{ fontSize: 14, fontWeight: 600, color: "var(--color-foreground)" }}>Incoming LLM Request</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -638,15 +707,15 @@ export const PipelineInfoDisplay: React.FC<PipelineInfoDisplayProps> = ({ pipeli
|
|||
{pipeline.steps.map((step, index) => (
|
||||
<React.Fragment key={index}>
|
||||
{/* Connector */}
|
||||
<div style={{ width: 1, height: 32, backgroundColor: "#d1d5db" }} />
|
||||
<div style={{ width: 1, height: 32, backgroundColor: "var(--color-border)" }} />
|
||||
|
||||
{/* Step card */}
|
||||
<div
|
||||
style={{
|
||||
border: "1px solid #e5e7eb",
|
||||
border: "1px solid var(--color-border)",
|
||||
borderRadius: 10,
|
||||
padding: "14px 20px",
|
||||
backgroundColor: "#fff",
|
||||
backgroundColor: "var(--color-card)",
|
||||
maxWidth: 720,
|
||||
width: "100%",
|
||||
}}
|
||||
|
|
@ -660,24 +729,26 @@ export const PipelineInfoDisplay: React.FC<PipelineInfoDisplayProps> = ({ pipeli
|
|||
fontSize: 11,
|
||||
fontWeight: 700,
|
||||
textTransform: "uppercase",
|
||||
color: "#6366f1",
|
||||
color: "var(--color-info)",
|
||||
letterSpacing: "0.06em",
|
||||
}}
|
||||
>
|
||||
GUARDRAIL
|
||||
</span>
|
||||
</div>
|
||||
<span style={{ fontSize: 13, color: "#9ca3af" }}>Step {index + 1}</span>
|
||||
<span style={{ fontSize: 13, color: "var(--color-muted-foreground)" }}>Step {index + 1}</span>
|
||||
</div>
|
||||
|
||||
{/* Name */}
|
||||
<div style={{ fontSize: 15, fontWeight: 600, color: "#111827", marginBottom: 8 }}>{step.guardrail}</div>
|
||||
<div style={{ fontSize: 15, fontWeight: 600, color: "var(--color-foreground)", marginBottom: 8 }}>
|
||||
{step.guardrail}
|
||||
</div>
|
||||
|
||||
{/* Divider */}
|
||||
<div style={{ borderTop: "1px solid #f3f4f6", marginBottom: 10 }} />
|
||||
<div style={{ borderTop: "1px solid var(--color-muted)", marginBottom: 10 }} />
|
||||
|
||||
{/* Pass / Fail / API failure */}
|
||||
<div className="flex flex-col gap-2" style={{ fontSize: 13, color: "#374151" }}>
|
||||
<div className="flex flex-col gap-2" style={{ fontSize: 13, color: "var(--color-foreground)" }}>
|
||||
<span className="flex items-center gap-1.5">
|
||||
<PassIcon /> Pass → {ACTION_LABELS[step.on_pass] || step.on_pass}
|
||||
</span>
|
||||
|
|
@ -708,15 +779,27 @@ interface PipelineTestPanelProps {
|
|||
}
|
||||
|
||||
const OUTCOME_STYLES: Record<string, { bg: string; color: string; label: string }> = {
|
||||
pass: { bg: "#f0fdf4", color: "#16a34a", label: "PASS" },
|
||||
fail: { bg: "#fef2f2", color: "#dc2626", label: "FAIL" },
|
||||
error: { bg: "#fffbeb", color: "#d97706", label: "ERROR" },
|
||||
pass: {
|
||||
bg: "color-mix(in oklab, var(--color-success) 10%, transparent)",
|
||||
color: "var(--color-success)",
|
||||
label: "PASS",
|
||||
},
|
||||
fail: {
|
||||
bg: "color-mix(in oklab, var(--color-destructive) 10%, transparent)",
|
||||
color: "var(--color-destructive)",
|
||||
label: "FAIL",
|
||||
},
|
||||
error: {
|
||||
bg: "color-mix(in oklab, var(--color-warning) 10%, transparent)",
|
||||
color: "var(--color-warning)",
|
||||
label: "ERROR",
|
||||
},
|
||||
};
|
||||
|
||||
const TERMINAL_STYLES: Record<string, { bg: string; color: string }> = {
|
||||
allow: { bg: "#f0fdf4", color: "#16a34a" },
|
||||
block: { bg: "#fef2f2", color: "#dc2626" },
|
||||
modify_response: { bg: "#eff6ff", color: "#2563eb" },
|
||||
allow: { bg: "color-mix(in oklab, var(--color-success) 10%, transparent)", color: "var(--color-success)" },
|
||||
block: { bg: "color-mix(in oklab, var(--color-destructive) 10%, transparent)", color: "var(--color-destructive)" },
|
||||
modify_response: { bg: "color-mix(in oklab, var(--color-info) 10%, transparent)", color: "var(--color-info)" },
|
||||
};
|
||||
|
||||
interface ComplianceRunEntry {
|
||||
|
|
@ -801,8 +884,8 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
<div
|
||||
style={{
|
||||
width: 400,
|
||||
borderLeft: "1px solid #e5e7eb",
|
||||
backgroundColor: "#fff",
|
||||
borderLeft: "1px solid var(--color-border)",
|
||||
backgroundColor: "var(--color-card)",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
flexShrink: 0,
|
||||
|
|
@ -813,13 +896,13 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
<div
|
||||
style={{
|
||||
padding: "12px 16px",
|
||||
borderBottom: "1px solid #e5e7eb",
|
||||
borderBottom: "1px solid var(--color-border)",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: 14, fontWeight: 600, color: "#111827" }}>Test Pipeline</span>
|
||||
<span style={{ fontSize: 14, fontWeight: 600, color: "var(--color-foreground)" }}>Test Pipeline</span>
|
||||
<button
|
||||
onClick={onClose}
|
||||
style={{
|
||||
|
|
@ -827,7 +910,7 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
border: "none",
|
||||
cursor: "pointer",
|
||||
fontSize: 18,
|
||||
color: "#9ca3af",
|
||||
color: "var(--color-muted-foreground)",
|
||||
padding: "0 4px",
|
||||
}}
|
||||
>
|
||||
|
|
@ -836,8 +919,16 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
</div>
|
||||
|
||||
{/* Input section */}
|
||||
<div style={{ padding: 16, borderBottom: "1px solid #e5e7eb" }}>
|
||||
<label style={{ fontSize: 12, fontWeight: 500, color: "#6b7280", display: "block", marginBottom: 6 }}>
|
||||
<div style={{ padding: 16, borderBottom: "1px solid var(--color-border)" }}>
|
||||
<label
|
||||
style={{
|
||||
fontSize: 12,
|
||||
fontWeight: 500,
|
||||
color: "var(--color-muted-foreground)",
|
||||
display: "block",
|
||||
marginBottom: 6,
|
||||
}}
|
||||
>
|
||||
Test with
|
||||
</label>
|
||||
<Select value={testSource} onValueChange={(value) => value !== null && setTestSource(value)}>
|
||||
|
|
@ -856,7 +947,15 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
</Select>
|
||||
{isQuickChat && (
|
||||
<>
|
||||
<label style={{ fontSize: 12, fontWeight: 500, color: "#6b7280", display: "block", marginBottom: 6 }}>
|
||||
<label
|
||||
style={{
|
||||
fontSize: 12,
|
||||
fontWeight: 500,
|
||||
color: "var(--color-muted-foreground)",
|
||||
display: "block",
|
||||
marginBottom: 6,
|
||||
}}
|
||||
>
|
||||
Message
|
||||
</label>
|
||||
<textarea
|
||||
|
|
@ -866,12 +965,14 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
rows={3}
|
||||
style={{
|
||||
width: "100%",
|
||||
border: "1px solid #d1d5db",
|
||||
border: "1px solid var(--color-border)",
|
||||
borderRadius: 6,
|
||||
padding: "8px 10px",
|
||||
fontSize: 13,
|
||||
resize: "vertical",
|
||||
fontFamily: "inherit",
|
||||
backgroundColor: "var(--color-card)",
|
||||
color: "var(--color-foreground)",
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
|
@ -880,9 +981,9 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
<div
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: "#6b7280",
|
||||
color: "var(--color-muted-foreground)",
|
||||
padding: "8px 10px",
|
||||
backgroundColor: "#f9fafb",
|
||||
backgroundColor: "var(--color-muted)",
|
||||
borderRadius: 6,
|
||||
marginBottom: 8,
|
||||
}}
|
||||
|
|
@ -903,11 +1004,11 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
<div
|
||||
style={{
|
||||
padding: "10px 12px",
|
||||
backgroundColor: "#fef2f2",
|
||||
border: "1px solid #fecaca",
|
||||
backgroundColor: "color-mix(in oklab, var(--color-destructive) 10%, transparent)",
|
||||
border: "1px solid color-mix(in oklab, var(--color-destructive) 30%, transparent)",
|
||||
borderRadius: 6,
|
||||
fontSize: 13,
|
||||
color: "#dc2626",
|
||||
color: "var(--color-destructive)",
|
||||
marginBottom: 12,
|
||||
}}
|
||||
>
|
||||
|
|
@ -924,14 +1025,14 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
<div
|
||||
key={i}
|
||||
style={{
|
||||
border: "1px solid #e5e7eb",
|
||||
border: "1px solid var(--color-border)",
|
||||
borderRadius: 8,
|
||||
padding: "10px 12px",
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center justify-between" style={{ marginBottom: 4 }}>
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: "#111827" }}>
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: "var(--color-foreground)" }}>
|
||||
Step {i + 1}: {step.guardrail_name}
|
||||
</span>
|
||||
<span
|
||||
|
|
@ -947,14 +1048,16 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
{style.label}
|
||||
</span>
|
||||
</div>
|
||||
<div style={{ fontSize: 12, color: "#6b7280" }}>
|
||||
<div style={{ fontSize: 12, color: "var(--color-muted-foreground)" }}>
|
||||
Action: {ACTION_LABELS[step.action_taken] || step.action_taken}
|
||||
{step.duration_seconds != null && (
|
||||
<span style={{ marginLeft: 8 }}>({(step.duration_seconds * 1000).toFixed(0)}ms)</span>
|
||||
)}
|
||||
</div>
|
||||
{step.error_detail && (
|
||||
<div style={{ fontSize: 12, color: "#dc2626", marginTop: 4 }}>{step.error_detail}</div>
|
||||
<div style={{ fontSize: 12, color: "var(--color-destructive)", marginTop: 4 }}>
|
||||
{step.error_detail}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
@ -963,13 +1066,13 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
{/* Terminal result */}
|
||||
<div
|
||||
style={{
|
||||
borderTop: "1px solid #e5e7eb",
|
||||
borderTop: "1px solid var(--color-border)",
|
||||
paddingTop: 12,
|
||||
marginTop: 4,
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: "#111827" }}>Result</span>
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: "var(--color-foreground)" }}>Result</span>
|
||||
{(() => {
|
||||
const ts = TERMINAL_STYLES[result.terminal_action] || TERMINAL_STYLES.block;
|
||||
return (
|
||||
|
|
@ -990,10 +1093,12 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
})()}
|
||||
</div>
|
||||
{result.error_message && (
|
||||
<div style={{ fontSize: 12, color: "#dc2626", marginTop: 6 }}>{result.error_message}</div>
|
||||
<div style={{ fontSize: 12, color: "var(--color-destructive)", marginTop: 6 }}>
|
||||
{result.error_message}
|
||||
</div>
|
||||
)}
|
||||
{result.modify_response_message && (
|
||||
<div style={{ fontSize: 12, color: "#2563eb", marginTop: 6 }}>
|
||||
<div style={{ fontSize: 12, color: "var(--color-info)", marginTop: 6 }}>
|
||||
Response: {result.modify_response_message}
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -1007,7 +1112,7 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
style={{
|
||||
fontSize: 13,
|
||||
fontWeight: 600,
|
||||
color: "#111827",
|
||||
color: "var(--color-foreground)",
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
|
|
@ -1016,7 +1121,7 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
<div
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: "#6b7280",
|
||||
color: "var(--color-muted-foreground)",
|
||||
marginBottom: 10,
|
||||
}}
|
||||
>
|
||||
|
|
@ -1026,27 +1131,30 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
style={{
|
||||
maxHeight: 320,
|
||||
overflowY: "auto",
|
||||
border: "1px solid #e5e7eb",
|
||||
border: "1px solid var(--color-border)",
|
||||
borderRadius: 8,
|
||||
}}
|
||||
>
|
||||
{complianceResults.map((entry, i) => {
|
||||
const actual = entry.result?.terminal_action ?? (entry.error ? "error" : "—");
|
||||
const matchStyle = entry.matched
|
||||
? { bg: "#f0fdf4", color: "#16a34a" }
|
||||
: { bg: "#fef2f2", color: "#dc2626" };
|
||||
? { bg: "color-mix(in oklab, var(--color-success) 10%, transparent)", color: "var(--color-success)" }
|
||||
: {
|
||||
bg: "color-mix(in oklab, var(--color-destructive) 10%, transparent)",
|
||||
color: "var(--color-destructive)",
|
||||
};
|
||||
return (
|
||||
<div
|
||||
key={entry.prompt.id ?? i}
|
||||
style={{
|
||||
padding: "8px 10px",
|
||||
borderBottom: i < complianceResults.length - 1 ? "1px solid #e5e7eb" : "none",
|
||||
borderBottom: i < complianceResults.length - 1 ? "1px solid var(--color-border)" : "none",
|
||||
fontSize: 12,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
color: "#374151",
|
||||
color: "var(--color-foreground)",
|
||||
marginBottom: 4,
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
|
|
@ -1064,9 +1172,11 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
flexWrap: "wrap",
|
||||
}}
|
||||
>
|
||||
<span style={{ color: "#6b7280" }}>expected: {entry.prompt.expectedResult}</span>
|
||||
<span style={{ color: "#9ca3af" }}>→</span>
|
||||
<span style={{ color: "#6b7280" }}>actual: {actual}</span>
|
||||
<span style={{ color: "var(--color-muted-foreground)" }}>
|
||||
expected: {entry.prompt.expectedResult}
|
||||
</span>
|
||||
<span style={{ color: "var(--color-muted-foreground)" }}>→</span>
|
||||
<span style={{ color: "var(--color-muted-foreground)" }}>actual: {actual}</span>
|
||||
<span
|
||||
style={{
|
||||
backgroundColor: matchStyle.bg,
|
||||
|
|
@ -1079,7 +1189,9 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
{entry.matched ? "✓" : "✗"}
|
||||
</span>
|
||||
</div>
|
||||
{entry.error && <div style={{ color: "#dc2626", marginTop: 4 }}>{entry.error}</div>}
|
||||
{entry.error && (
|
||||
<div style={{ color: "var(--color-destructive)", marginTop: 4 }}>{entry.error}</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
|
@ -1088,7 +1200,7 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
)}
|
||||
|
||||
{!result && !error && complianceResults.length === 0 && (
|
||||
<div style={{ textAlign: "center", color: "#9ca3af", fontSize: 13, marginTop: 24 }}>
|
||||
<div style={{ textAlign: "center", color: "var(--color-muted-foreground)", fontSize: 13, marginTop: 24 }}>
|
||||
Choose a test source above (quick chat or a compliance dataset) and click "Run Test"
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -1102,9 +1214,9 @@ const PipelineTestPanel: React.FC<PipelineTestPanelProps> = ({ pipeline, accessT
|
|||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
const VERSION_STATUS_STYLES: Record<string, { bg: string; color: string }> = {
|
||||
draft: { bg: "#f3f4f6", color: "#6b7280" },
|
||||
published: { bg: "#eff6ff", color: "#2563eb" },
|
||||
production: { bg: "#f0fdf4", color: "#16a34a" },
|
||||
draft: { bg: "var(--color-muted)", color: "var(--color-muted-foreground)" },
|
||||
published: { bg: "color-mix(in oklab, var(--color-info) 10%, transparent)", color: "var(--color-info)" },
|
||||
production: { bg: "color-mix(in oklab, var(--color-success) 10%, transparent)", color: "var(--color-success)" },
|
||||
};
|
||||
|
||||
interface PolicyVersionsSidebarProps {
|
||||
|
|
@ -1144,8 +1256,8 @@ const PolicyVersionsSidebar: React.FC<PolicyVersionsSidebarProps> = ({
|
|||
style={{
|
||||
width: 260,
|
||||
flexShrink: 0,
|
||||
backgroundColor: "#fff",
|
||||
borderRight: "1px solid #e5e7eb",
|
||||
backgroundColor: "var(--color-card)",
|
||||
borderRight: "1px solid var(--color-border)",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
overflow: "hidden",
|
||||
|
|
@ -1159,7 +1271,7 @@ const PolicyVersionsSidebar: React.FC<PolicyVersionsSidebarProps> = ({
|
|||
fontSize: 11,
|
||||
fontWeight: 700,
|
||||
textTransform: "uppercase",
|
||||
color: "#6b7280",
|
||||
color: "var(--color-muted-foreground)",
|
||||
letterSpacing: "0.06em",
|
||||
display: "block",
|
||||
marginBottom: 4,
|
||||
|
|
@ -1170,7 +1282,7 @@ const PolicyVersionsSidebar: React.FC<PolicyVersionsSidebarProps> = ({
|
|||
<span
|
||||
style={{
|
||||
fontSize: 11,
|
||||
color: "#6b7280",
|
||||
color: "var(--color-muted-foreground)",
|
||||
lineHeight: 1.4,
|
||||
display: "block",
|
||||
marginBottom: 12,
|
||||
|
|
@ -1190,7 +1302,7 @@ const PolicyVersionsSidebar: React.FC<PolicyVersionsSidebarProps> = ({
|
|||
<UiLoadingSpinner className="size-4" />
|
||||
</div>
|
||||
) : versions.length === 0 ? (
|
||||
<span style={{ fontSize: 13, color: "#9ca3af" }}>No versions found</span>
|
||||
<span style={{ fontSize: 13, color: "var(--color-muted-foreground)" }}>No versions found</span>
|
||||
) : (
|
||||
<div className="flex flex-col gap-1">
|
||||
{versions.map((v) => {
|
||||
|
|
@ -1206,13 +1318,17 @@ const PolicyVersionsSidebar: React.FC<PolicyVersionsSidebarProps> = ({
|
|||
textAlign: "left",
|
||||
padding: "10px 12px",
|
||||
borderRadius: 8,
|
||||
border: isActive ? "1px solid #6366f1" : "1px solid #e5e7eb",
|
||||
backgroundColor: isActive ? "#eef2ff" : "#fff",
|
||||
border: isActive ? "1px solid var(--color-info)" : "1px solid var(--color-border)",
|
||||
backgroundColor: isActive
|
||||
? "color-mix(in oklab, var(--color-info) 10%, transparent)"
|
||||
: "var(--color-card)",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center justify-between" style={{ marginBottom: 4 }}>
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: "#111827" }}>v{v.version_number ?? 1}</span>
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: "var(--color-foreground)" }}>
|
||||
v{v.version_number ?? 1}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
fontSize: 10,
|
||||
|
|
@ -1235,7 +1351,7 @@ const PolicyVersionsSidebar: React.FC<PolicyVersionsSidebarProps> = ({
|
|||
|
||||
{/* Publish / Promote to production for selected version */}
|
||||
{(canPublish || canPromote) && (
|
||||
<div style={{ marginTop: 12, paddingTop: 12, borderTop: "1px solid #e5e7eb" }}>
|
||||
<div style={{ marginTop: 12, paddingTop: 12, borderTop: "1px solid var(--color-border)" }}>
|
||||
{canPublish && (
|
||||
<>
|
||||
<Button
|
||||
|
|
@ -1249,7 +1365,7 @@ const PolicyVersionsSidebar: React.FC<PolicyVersionsSidebarProps> = ({
|
|||
<span
|
||||
style={{
|
||||
fontSize: 11,
|
||||
color: "#6b7280",
|
||||
color: "var(--color-muted-foreground)",
|
||||
lineHeight: 1.4,
|
||||
display: "block",
|
||||
marginBottom: canPromote ? 8 : 0,
|
||||
|
|
@ -1271,7 +1387,7 @@ const PolicyVersionsSidebar: React.FC<PolicyVersionsSidebarProps> = ({
|
|||
<span
|
||||
style={{
|
||||
fontSize: 11,
|
||||
color: "#6b7280",
|
||||
color: "var(--color-muted-foreground)",
|
||||
lineHeight: 1.4,
|
||||
display: "block",
|
||||
}}
|
||||
|
|
@ -1292,7 +1408,7 @@ const PolicyVersionsSidebar: React.FC<PolicyVersionsSidebarProps> = ({
|
|||
fontSize: 11,
|
||||
fontWeight: 700,
|
||||
textTransform: "uppercase",
|
||||
color: "#6b7280",
|
||||
color: "var(--color-muted-foreground)",
|
||||
letterSpacing: "0.06em",
|
||||
}}
|
||||
>
|
||||
|
|
@ -1302,8 +1418,8 @@ const PolicyVersionsSidebar: React.FC<PolicyVersionsSidebarProps> = ({
|
|||
style={{
|
||||
fontSize: 10,
|
||||
fontWeight: 600,
|
||||
backgroundColor: "#eef2ff",
|
||||
color: "#6366f1",
|
||||
backgroundColor: "color-mix(in oklab, var(--color-info) 10%, transparent)",
|
||||
color: "var(--color-info)",
|
||||
padding: "2px 6px",
|
||||
borderRadius: 4,
|
||||
}}
|
||||
|
|
@ -1314,7 +1430,7 @@ const PolicyVersionsSidebar: React.FC<PolicyVersionsSidebarProps> = ({
|
|||
<span
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: "#6b7280",
|
||||
color: "var(--color-muted-foreground)",
|
||||
lineHeight: 1.5,
|
||||
display: "block",
|
||||
}}
|
||||
|
|
@ -1514,7 +1630,7 @@ export const FlowBuilderPage: React.FC<FlowBuilderPageProps> = ({
|
|||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
backgroundColor: "#f9fafb",
|
||||
backgroundColor: "var(--color-muted)",
|
||||
zIndex: 1000,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
|
|
@ -1524,8 +1640,8 @@ export const FlowBuilderPage: React.FC<FlowBuilderPageProps> = ({
|
|||
{/* Header bar */}
|
||||
<div
|
||||
style={{
|
||||
borderBottom: "1px solid #e5e7eb",
|
||||
backgroundColor: "#fff",
|
||||
borderBottom: "1px solid var(--color-border)",
|
||||
backgroundColor: "var(--color-card)",
|
||||
padding: "10px 24px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
|
|
@ -1545,10 +1661,10 @@ export const FlowBuilderPage: React.FC<FlowBuilderPageProps> = ({
|
|||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<ArrowLeft style={{ width: 18, height: 18, color: "#6b7280" }} />
|
||||
<ArrowLeft style={{ width: 18, height: 18, color: "var(--color-muted-foreground)" }} />
|
||||
</button>
|
||||
<span style={{ fontSize: 14, color: "#6b7280" }}>Policies</span>
|
||||
<span style={{ fontSize: 14, color: "#d1d5db" }}>/</span>
|
||||
<span style={{ fontSize: 14, color: "var(--color-muted-foreground)" }}>Policies</span>
|
||||
<span style={{ fontSize: 14, color: "var(--color-border)" }}>/</span>
|
||||
<Input
|
||||
placeholder="Policy name..."
|
||||
value={policyName}
|
||||
|
|
@ -1560,8 +1676,8 @@ export const FlowBuilderPage: React.FC<FlowBuilderPageProps> = ({
|
|||
style={{
|
||||
fontSize: 11,
|
||||
fontWeight: 600,
|
||||
backgroundColor: "#eef2ff",
|
||||
color: "#6366f1",
|
||||
backgroundColor: "color-mix(in oklab, var(--color-info) 10%, transparent)",
|
||||
color: "var(--color-info)",
|
||||
padding: "3px 8px",
|
||||
borderRadius: 4,
|
||||
letterSpacing: "0.02em",
|
||||
|
|
@ -1587,8 +1703,8 @@ export const FlowBuilderPage: React.FC<FlowBuilderPageProps> = ({
|
|||
<div
|
||||
style={{
|
||||
padding: "8px 24px",
|
||||
backgroundColor: "#fff",
|
||||
borderBottom: "1px solid #e5e7eb",
|
||||
backgroundColor: "var(--color-card)",
|
||||
borderBottom: "1px solid var(--color-border)",
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue