update: moved input control buttons JSON Data area.

This commit is contained in:
2026-01-31 09:10:55 +01:00
parent b7df3e731f
commit 452e6e74cb

View File

@@ -12,6 +12,7 @@ function MainPage({
const [result, setResult] = useState(""); const [result, setResult] = useState("");
const [error, setError] = useState(""); const [error, setError] = useState("");
const [jsonError, setJsonError] = useState(""); const [jsonError, setJsonError] = useState("");
const [copySuccess, setCopySuccess] = useState(false);
const evaluateExpression = () => { const evaluateExpression = () => {
try { try {
@@ -77,6 +78,26 @@ function MainPage({
setJsonError(""); setJsonError("");
}; };
const copyToClipboard = async () => {
try {
await navigator.clipboard.writeText(result);
setCopySuccess(true);
setTimeout(() => setCopySuccess(false), 2000);
} catch (err) {
console.error("Failed to copy!", err);
}
};
const downloadResult = () => {
const blob = new Blob([result], { type: "application/json" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "result.json";
a.click();
URL.revokeObjectURL(url);
};
const loadSample = () => { const loadSample = () => {
const sampleData = { const sampleData = {
users: [ users: [
@@ -155,11 +176,54 @@ function MainPage({
<div className="row mb-2"> <div className="row mb-2">
<div className="col-12"> <div className="col-12">
<div className="card"> <div className="card">
<div className="card-header d-flex justify-content-between align-items-center py-2"> <div className="card-header py-2">
<h6 className="mb-0"> <h6 className="mb-0">
<i className="bi bi-search me-2"></i> <i className="bi bi-search me-2"></i>
JMESPath Expression JMESPath Expression
</h6> </h6>
</div>
<div className="card-body">
<input
type="text"
className={`form-control jmespath-input ${error ? "error" : "success"}`}
value={jmespathExpression}
onChange={handleJmespathChange}
placeholder="Enter JMESPath expression (e.g., people[*].name)"
/>
<div
className={`alert mt-2 mb-0 d-flex justify-content-between align-items-center ${error ? "alert-danger" : "alert-success"}`}
>
<small className="mb-0">
{error || "Expression is correct"}
</small>
{showReloadButton && (
<button
className="btn btn-light btn-sm ms-2 border"
onClick={() => {
onReloadSampleData();
}}
title="New sample data is available"
>
<i className="bi bi-arrow-clockwise me-1"></i>
Reload Sample Data
</button>
)}
</div>
</div>
</div>
</div>
</div>
{/* Lower Middle Section: Input and Output Areas */}
<div className="row flex-grow-1" style={{ minHeight: 0 }}>
{/* Left Panel: JSON Data Input */}
<div className="col-md-6">
<div className="card h-100 d-flex flex-column">
<div className="card-header d-flex justify-content-between align-items-center py-2">
<h6 className="mb-0">
<i className="bi bi-file-earmark-code me-2"></i>
JSON Data
</h6>
<div> <div>
<button <button
className="btn btn-outline-success btn-sm me-2" className="btn btn-outline-success btn-sm me-2"
@@ -198,49 +262,6 @@ function MainPage({
</button> </button>
</div> </div>
</div> </div>
<div className="card-body">
<input
type="text"
className={`form-control jmespath-input ${error ? "error" : "success"}`}
value={jmespathExpression}
onChange={handleJmespathChange}
placeholder="Enter JMESPath expression (e.g., people[*].name)"
/>
<div
className={`alert mt-2 mb-0 d-flex justify-content-between align-items-center ${error ? "alert-danger" : "alert-success"}`}
>
<small className="mb-0">
{error || "Expression is correct"}
</small>
{showReloadButton && (
<button
className="btn btn-light btn-sm ms-2 border"
onClick={() => {
onReloadSampleData();
}}
title="New sample data is available"
>
<i className="bi bi-arrow-clockwise me-1"></i>
Reload Sample Data
</button>
)}
</div>
</div>
</div>
</div>
</div>
{/* Lower Middle Section: Input and Output Areas */}
<div className="row flex-grow-1" style={{ minHeight: 0 }}>
{/* Left Panel: JSON Data Input */}
<div className="col-md-6">
<div className="card h-100 d-flex flex-column">
<div className="card-header py-2">
<h6 className="mb-0">
<i className="bi bi-file-earmark-code me-2"></i>
JSON Data
</h6>
</div>
<div <div
className="card-body flex-grow-1 d-flex flex-column" className="card-body flex-grow-1 d-flex flex-column"
style={{ minHeight: 0 }} style={{ minHeight: 0 }}
@@ -264,11 +285,31 @@ function MainPage({
{/* Right Panel: Results */} {/* Right Panel: Results */}
<div className="col-md-6"> <div className="col-md-6">
<div className="card h-100 d-flex flex-column"> <div className="card h-100 d-flex flex-column">
<div className="card-header py-2"> <div className="card-header py-2 d-flex justify-content-between align-items-center">
<h6 className="mb-0"> <h6 className="mb-0">
<i className="bi bi-output me-2"></i> <i className="bi bi-output me-2"></i>
Results Results
</h6> </h6>
<div>
<button
className={`btn btn-sm me-2 ${copySuccess ? "btn-success" : "btn-outline-secondary"}`}
onClick={copyToClipboard}
disabled={!result || result === "null"}
title="Copy result to clipboard"
>
<i className={`bi ${copySuccess ? "bi-check-lg" : "bi-clipboard"} me-1`}></i>
{copySuccess ? "Copied!" : "Copy"}
</button>
<button
className="btn btn-outline-secondary btn-sm"
onClick={downloadResult}
disabled={!result || result === "null"}
title="Download result as JSON file"
>
<i className="bi bi-download me-1"></i>
Download
</button>
</div>
</div> </div>
<div <div
className="card-body flex-grow-1 d-flex flex-column" className="card-body flex-grow-1 d-flex flex-column"