/** * ParamSchemaDisplay - Read-only display component for parameters * Shows parameter values in a human-friendly format based on their schema. * Expects StackStorm-style flat parameter format with inline required/secret. */ import type { ParamSchema } from "./ParamSchemaForm"; export type { ParamSchema }; import { extractProperties } from "./ParamSchemaForm"; /** A JSON-compatible value that can appear in display data */ // eslint-disable-next-line @typescript-eslint/no-explicit-any type JsonValue = any; interface ParamSchemaDisplayProps { schema: ParamSchema; values: Record; className?: string; emptyMessage?: string; } /** * Read-only component that displays parameter values based on a schema */ export default function ParamSchemaDisplay({ schema, values, className = "", emptyMessage = "No parameters configured", }: ParamSchemaDisplayProps) { const properties = extractProperties(schema); const paramEntries = Object.entries(properties); // Filter to only show parameters that have values const populatedParams = paramEntries.filter(([key]) => { const value = values[key]; return value !== undefined && value !== null && value !== ""; }); if (populatedParams.length === 0) { return (
{emptyMessage}
); } /** * Check if a field is required */ const isRequired = (key: string): boolean => { return !!properties[key]?.required; }; /** * Format value for display based on its type * Returns both the formatted value and whether it should be displayed inline */ const formatValue = ( value: JsonValue, type?: string, ): { element: React.JSX.Element; isInline: boolean } => { if (value === undefined || value === null) { return { element: ( Not set ), isInline: true, }; } switch (type) { case "boolean": return { element: ( {value ? "✓ Enabled" : "✗ Disabled"} ), isInline: true, }; case "array": if (Array.isArray(value)) { if (value.length === 0) { return { element: ( Empty array ), isInline: true, }; } return { element: (
{value.map((item, idx) => (
{JSON.stringify(item)}
))}
), isInline: false, }; } // Fallback for non-array values return { element: (
              {JSON.stringify(value, null, 2)}
            
), isInline: false, }; case "object": if (typeof value === "object" && !Array.isArray(value)) { const entries = Object.entries(value); if (entries.length === 0) { return { element: ( Empty object ), isInline: true, }; } return { element: (
{entries.map(([k, v]) => (
{k}: {JSON.stringify(v)}
))}
), isInline: false, }; } // Fallback for non-object values return { element: (
              {JSON.stringify(value, null, 2)}
            
), isInline: false, }; case "number": case "integer": return { element: ( {value} ), isInline: true, }; default: // String or unknown type if (typeof value === "string") { // Check if it looks like a template/expression if (value.includes("{{") || value.includes("${")) { return { element: ( {value} ), isInline: true, }; } // Regular string - check length for inline vs block const isShort = value.length < 60; return { element: ( {value} ), isInline: isShort, }; } // Fallback for complex types return { element: (
              {JSON.stringify(value, null, 2)}
            
), isInline: false, }; } }; return (
{populatedParams.map(([key, param]) => { const value = values[key]; const type = param?.type || "string"; const { element: valueElement, isInline } = formatValue(value, type); return (
{isInline ? ( // Inline layout for small values
{key} {type} {isRequired(key) && ( Required )} {param?.secret && ( Secret )}
{param?.description && (

{param.description}

)}
{valueElement}
) : ( // Block layout for large values
{key} {type} {isRequired(key) && ( Required )} {param?.secret && ( Secret )}
{param?.description && (

{param.description}

)}
{valueElement}
)}
); })}
); } /** * Compact variant for smaller displays - just shows key-value pairs */ export function ParamSchemaDisplayCompact({ schema, values, className = "", }: ParamSchemaDisplayProps) { const properties = extractProperties(schema); const paramEntries = Object.entries(properties); const populatedParams = paramEntries.filter(([key]) => { const value = values[key]; return value !== undefined && value !== null && value !== ""; }); if (populatedParams.length === 0) { return (
No parameters set
); } return (
{populatedParams.map(([key, param]) => { const value = values[key]; const type = param?.type || "string"; let displayValue: string; if (type === "boolean") { displayValue = value ? "Yes" : "No"; } else if (type === "array" || type === "object") { displayValue = JSON.stringify(value); } else if (param?.secret && value) { displayValue = "••••••••"; } else { displayValue = String(value); } return (
{key}:
{displayValue}
); })}
); }