Release v1.3.1: Added PowerShell support and fixed theme issues
This commit is contained in:
@@ -1,6 +1,36 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
function ApiKeyPage({ apiKey, onRegenerateApiKey }) {
|
||||
function CodeBlock({ code }) {
|
||||
const [copySuccess, setCopySuccess] = useState(false);
|
||||
|
||||
const handleCopy = async () => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(code);
|
||||
setCopySuccess(true);
|
||||
setTimeout(() => setCopySuccess(false), 2000);
|
||||
} catch (err) {
|
||||
console.error('Failed to copy to clipboard:', err);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="position-relative">
|
||||
<pre className="bg-light p-3 pe-5 rounded border shadow-sm">
|
||||
<code className="d-block" style={{ whiteSpace: 'pre-wrap' }}>{code}</code>
|
||||
</pre>
|
||||
<button
|
||||
className={`btn btn-sm ${copySuccess ? 'btn-success' : 'btn-outline-secondary'} position-absolute top-0 end-0 m-2`}
|
||||
onClick={handleCopy}
|
||||
title="Copy code to clipboard"
|
||||
style={{ opacity: 0.8 }}
|
||||
>
|
||||
{copySuccess ? '✓' : '📋'}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ApiKeyPage({ apiKey, onRegenerateApiKey, shellType, onShellTypeChange }) {
|
||||
const [copySuccess, setCopySuccess] = useState(false);
|
||||
|
||||
const handleCopyToClipboard = async () => {
|
||||
@@ -60,28 +90,50 @@ function ApiKeyPage({ apiKey, onRegenerateApiKey }) {
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<h6>📡 Remote Data Upload API</h6>
|
||||
<div className="d-flex justify-content-between align-items-center mb-2">
|
||||
<h6 className="mb-0">📡 Remote Data Upload API</h6>
|
||||
<div className="btn-group btn-group-sm" role="group" aria-label="Shell type selector">
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
name="shellType"
|
||||
id="shellBash"
|
||||
autoComplete="off"
|
||||
checked={shellType === 'bash'}
|
||||
onChange={() => onShellTypeChange('bash')}
|
||||
/>
|
||||
<label className="btn btn-outline-secondary" htmlFor="shellBash">UNIX (Bash)</label>
|
||||
<input
|
||||
type="radio"
|
||||
className="btn-check"
|
||||
name="shellType"
|
||||
id="shellPowerShell"
|
||||
autoComplete="off"
|
||||
checked={shellType === 'powershell'}
|
||||
onChange={() => onShellTypeChange('powershell')}
|
||||
/>
|
||||
<label className="btn btn-outline-secondary" htmlFor="shellPowerShell">Windows (PowerShell)</label>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-muted">
|
||||
External tools can upload sample data remotely using the REST API.
|
||||
The API key is required for authentication. Define two
|
||||
environment variables in your <code>.bashrc</code>.
|
||||
environment variables in your {shellType === 'bash' ? <code>.bashrc</code> : <code>PowerShell profile</code>}.
|
||||
</p>
|
||||
<pre className="bg-light p-3 rounded border">
|
||||
<code>export JMESPATH_PLAYGROUND_API_URL={window.location.origin}<br/>export JMESPATH_PLAYGROUND_API_KEY={apiKey}</code>
|
||||
</pre>
|
||||
<p className="text-muted">Then, use the following <code>curl</code> command to upload your data:</p>
|
||||
<pre className="bg-light p-3 rounded border">
|
||||
<code>{`curl -s -X POST \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-H "Accept: application/json" \\
|
||||
-H "X-API-Key: $JMESPATH_PLAYGROUND_API_KEY" \\
|
||||
--data @__JSON_FILE_NAME__ \\
|
||||
"$\{JMESPATH_PLAYGROUND_API_URL}/api/v1/upload"`}</code>
|
||||
</pre>
|
||||
<CodeBlock
|
||||
code={shellType === 'bash'
|
||||
? `export JMESPATH_PLAYGROUND_API_URL=${window.location.origin}\nexport JMESPATH_PLAYGROUND_API_KEY=${apiKey}`
|
||||
: `$env:JMESPATH_PLAYGROUND_API_URL = "${window.location.origin}"\n$env:JMESPATH_PLAYGROUND_API_KEY = "${apiKey}"`}
|
||||
/>
|
||||
<p className="text-muted">Then, use the following {shellType === 'bash' ? <code>curl</code> : <code>PowerShell</code>} command to upload your data:</p>
|
||||
<CodeBlock
|
||||
code={shellType === 'bash'
|
||||
? `curl -s -X POST \\\n -H "Content-Type: application/json" \\\n -H "Accept: application/json" \\\n -H "X-API-Key: $JMESPATH_PLAYGROUND_API_KEY" \\\n --data @__JSON_FILE_NAME__ \\\n "$JMESPATH_PLAYGROUND_API_URL/api/v1/upload"`
|
||||
: `Invoke-RestMethod -Uri "$env:JMESPATH_PLAYGROUND_API_URL/api/v1/upload" \\\n -Method Post \\\n -ContentType "application/json" \\\n -Headers @{\n "X-API-Key" = $env:JMESPATH_PLAYGROUND_API_KEY\n "Accept" = "application/json"\n } \\\n -InFile __JSON_FILE_NAME__`}
|
||||
/>
|
||||
<div className="form-text">
|
||||
Replace <code>{"__JSON_FILE_NAME__"}</code> with the path to your
|
||||
JSON file containing the sample data. or use <code>-</code> to
|
||||
read from standard input.
|
||||
JSON file containing the sample data. {shellType === 'bash' && <span>or use <code>-</code> to read from standard input.</span>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,19 +2,19 @@ import React from 'react';
|
||||
|
||||
function Header({ theme, onThemeChange, currentPage, onPageChange }) {
|
||||
return (
|
||||
<div className="header-section py-2">
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="header-section">
|
||||
<div className="container-fluid px-4">
|
||||
<div className="row align-items-center">
|
||||
<div className="col-12 text-center position-relative">
|
||||
<h2 className="mb-1">JMESPath Testing Tool</h2>
|
||||
{/* Right side controls - better positioning */}
|
||||
<div className="position-absolute top-0 end-0 d-flex align-items-center gap-2">
|
||||
<div className="position-absolute top-50 end-0 translate-middle-y d-flex align-items-center gap-2 me-4">
|
||||
{/* API Key Management Button - more prominent */}
|
||||
<button
|
||||
type="button"
|
||||
className={`btn btn-sm ${
|
||||
currentPage === 'apikey'
|
||||
? 'btn-warning fw-bold'
|
||||
? 'btn-warning fw-bold text-dark'
|
||||
: 'btn-outline-warning'
|
||||
}`}
|
||||
onClick={() => onPageChange(currentPage === 'main' ? 'apikey' : 'main')}
|
||||
@@ -28,8 +28,8 @@ function Header({ theme, onThemeChange, currentPage, onPageChange }) {
|
||||
type="button"
|
||||
className={`btn ${
|
||||
theme === 'auto'
|
||||
? 'btn-primary'
|
||||
: 'btn-outline-secondary'
|
||||
? 'btn-light active'
|
||||
: 'btn-outline-light'
|
||||
}`}
|
||||
onClick={() => onThemeChange('auto')}
|
||||
title="Auto (follow system)"
|
||||
@@ -40,8 +40,8 @@ function Header({ theme, onThemeChange, currentPage, onPageChange }) {
|
||||
type="button"
|
||||
className={`btn ${
|
||||
theme === 'light'
|
||||
? 'btn-primary'
|
||||
: 'btn-outline-secondary'
|
||||
? 'btn-light active'
|
||||
: 'btn-outline-light'
|
||||
}`}
|
||||
onClick={() => onThemeChange('light')}
|
||||
title="Light theme"
|
||||
@@ -52,8 +52,8 @@ function Header({ theme, onThemeChange, currentPage, onPageChange }) {
|
||||
type="button"
|
||||
className={`btn ${
|
||||
theme === 'dark'
|
||||
? 'btn-primary'
|
||||
: 'btn-outline-secondary'
|
||||
? 'btn-light active'
|
||||
: 'btn-outline-light'
|
||||
}`}
|
||||
onClick={() => onThemeChange('dark')}
|
||||
title="Dark theme"
|
||||
|
||||
Reference in New Issue
Block a user