File size: 2,016 Bytes
4513a96
220a682
 
 
 
 
 
 
 
 
4513a96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220a682
4513a96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220a682
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import React, { useState, useMemo } from "react";

interface ResultBlockProps {
  error?: string;
  result?: unknown;
}

const ResultBlock: React.FC<ResultBlockProps> = ({
  error,
  result,
}) => {
  const [isExpanded, setIsExpanded] = useState(false);
  const MAX_LENGTH = 10000; // Characters to show before truncating

  const formattedResult = useMemo(() => {
    if (result === undefined || result === null) {
      return "No result";
    }

    if (typeof result !== "object") {
      return String(result);
    }

    try {
      const fullString = JSON.stringify(result, null, 2);

      // If the result is very large, provide truncation
      if (fullString.length > MAX_LENGTH && !isExpanded) {
        return fullString.substring(0, MAX_LENGTH);
      }

      return fullString;
    } catch (err) {
      // Handle circular references or other JSON.stringify errors
      return String(result);
    }
  }, [result, isExpanded]);

  const isTruncated = useMemo(() => {
    if (typeof result !== "object" || result === null) return false;
    try {
      return JSON.stringify(result, null, 2).length > MAX_LENGTH;
    } catch {
      return false;
    }
  }, [result]);

  return (
    <div
      className={
        error
          ? "bg-red-900 border border-red-600 rounded p-3"
          : "bg-gray-700 border border-gray-600 rounded p-3"
      }
    >
      {error ? <p className="text-red-300 text-sm">Error: {error}</p> : null}
      <pre className="text-sm text-gray-300 whitespace-pre-wrap overflow-auto mt-2 max-h-96">
        {formattedResult}
        {isTruncated && !isExpanded && (
          <span className="text-yellow-400">... (truncated)</span>
        )}
      </pre>
      {isTruncated && (
        <button
          onClick={() => setIsExpanded(!isExpanded)}
          className="mt-2 text-xs text-blue-400 hover:text-blue-300 underline"
        >
          {isExpanded ? "Show less" : "Show full result"}
        </button>
      )}
    </div>
  );
};

export default ResultBlock;