|
|
@@ -26,7 +26,8 @@ export default function JsonViewer() {
|
|
|
|
|
|
|
|
|
|
|
|
const [jsonInput, setJsonInput] = useState<string>(JSON.stringify(initialData, null, 2))
|
|
|
|
const [jsonInput, setJsonInput] = useState<string>(JSON.stringify(initialData, null, 2))
|
|
|
|
const [query, setQuery] = useState<string>("$.staff_members[*].name")
|
|
|
|
const [query, setQuery] = useState<string>("$.staff_members[*].name")
|
|
|
|
const [copied, setCopied] = useState(false)
|
|
|
|
const [copiedCsv, setCopiedCsv] = useState(false)
|
|
|
|
|
|
|
|
const [copiedRawJson, setCopiedRawJson] = useState(false)
|
|
|
|
|
|
|
|
|
|
|
|
const isPlainObject = (value: unknown): value is Record<string, unknown> => {
|
|
|
|
const isPlainObject = (value: unknown): value is Record<string, unknown> => {
|
|
|
|
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
|
|
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
|
@@ -85,11 +86,23 @@ export default function JsonViewer() {
|
|
|
|
})()
|
|
|
|
})()
|
|
|
|
|
|
|
|
|
|
|
|
navigator.clipboard.writeText(csv).then(() => {
|
|
|
|
navigator.clipboard.writeText(csv).then(() => {
|
|
|
|
setCopied(true)
|
|
|
|
setCopiedCsv(true)
|
|
|
|
setTimeout(() => setCopied(false), 2000)
|
|
|
|
setTimeout(() => setCopiedCsv(false), 2000)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}, [query, result.matchedValues])
|
|
|
|
}, [query, result.matchedValues])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const copySelectedRawJson = useCallback(() => {
|
|
|
|
|
|
|
|
if (result.matchedValues.length === 0) return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const payload = result.matchedValues.length === 1 ? result.matchedValues[0] : result.matchedValues
|
|
|
|
|
|
|
|
const json = JSON.stringify(payload, null, 2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
navigator.clipboard.writeText(json).then(() => {
|
|
|
|
|
|
|
|
setCopiedRawJson(true)
|
|
|
|
|
|
|
|
setTimeout(() => setCopiedRawJson(false), 2000)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}, [result.matchedValues])
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div className="h-full flex gap-4 overflow-hidden">
|
|
|
|
<div className="h-full flex gap-4 overflow-hidden">
|
|
|
|
<Seo
|
|
|
|
<Seo
|
|
|
@@ -141,12 +154,19 @@ export default function JsonViewer() {
|
|
|
|
<span className="text-xs font-medium px-2 py-0.5 bg-indigo-100 text-indigo-700 rounded-full">
|
|
|
|
<span className="text-xs font-medium px-2 py-0.5 bg-indigo-100 text-indigo-700 rounded-full">
|
|
|
|
{result.matchedPaths.length} {t("jsonViewer.matches")}
|
|
|
|
{result.matchedPaths.length} {t("jsonViewer.matches")}
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
|
|
|
onClick={copySelectedRawJson}
|
|
|
|
|
|
|
|
disabled={result.matchedValues.length === 0 || !!result.error}
|
|
|
|
|
|
|
|
className="text-xs font-medium px-3 py-1 bg-indigo-500 text-white rounded-lg hover:bg-indigo-600 disabled:bg-slate-300 disabled:cursor-not-allowed transition-colours"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{copiedRawJson ? t("jsonViewer.copied") : t("jsonViewer.copyRawJson")}
|
|
|
|
|
|
|
|
</button>
|
|
|
|
<button
|
|
|
|
<button
|
|
|
|
onClick={copyAsCsv}
|
|
|
|
onClick={copyAsCsv}
|
|
|
|
disabled={result.matchedValues.length === 0 || !!result.error}
|
|
|
|
disabled={result.matchedValues.length === 0 || !!result.error}
|
|
|
|
className="text-xs font-medium px-3 py-1 bg-emerald-500 text-white rounded-lg hover:bg-emerald-600 disabled:bg-slate-300 disabled:cursor-not-allowed transition-colours"
|
|
|
|
className="text-xs font-medium px-3 py-1 bg-emerald-500 text-white rounded-lg hover:bg-emerald-600 disabled:bg-slate-300 disabled:cursor-not-allowed transition-colours"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
{copied ? t("jsonViewer.copied") : t("jsonViewer.copyAsCsv")}
|
|
|
|
{copiedCsv ? t("jsonViewer.copied") : t("jsonViewer.copyAsCsv")}
|
|
|
|
</button>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|