Split file loading into two separate buttons
- Add 'Load an Object' button for standard JSON files (.json) - Add 'Load a Log File' button for JSON Lines files (.log) - Each button has specific file type filter and handling logic - Improved user experience with clear separation of functionality - Add styling for the new info button (log files) - Update documentation to reflect the two-button approach
This commit is contained in:
8
.github/copilot-instructions.md
vendored
8
.github/copilot-instructions.md
vendored
@@ -9,9 +9,11 @@ The tool in this repository is designed to help users validate and test JMESPath
|
|||||||
The application is single page. The page is divided into three sections:
|
The application is single page. The page is divided into three sections:
|
||||||
|
|
||||||
- Top section: Title and description of the tool.
|
- Top section: Title and description of the tool.
|
||||||
- Middle section: Input area for JMESPath expressions
|
- Middle section:
|
||||||
- Bottom left section: Input area for JSON data
|
- Input area for JMESPath expressions
|
||||||
- Bottom right section: Output are for JMESPath query results
|
- Lower Middle left section: Input area for JSON data
|
||||||
|
- Lower Middle right section: Output are for JMESPath query results
|
||||||
|
- Boottom section: Footer with author and license information
|
||||||
|
|
||||||
The Middle section also contains a toolbar with buttons to load data from disk, load sample data, format JSON input, and clear all inputs.
|
The Middle section also contains a toolbar with buttons to load data from disk, load sample data, format JSON input, and clear all inputs.
|
||||||
|
|
||||||
|
|||||||
@@ -75,14 +75,14 @@ npm run docker:run
|
|||||||
|
|
||||||
1. **Enter a JMESPath expression** in the top input field (e.g., `people[*].name`)
|
1. **Enter a JMESPath expression** in the top input field (e.g., `people[*].name`)
|
||||||
2. **Add JSON data** using one of these methods:
|
2. **Add JSON data** using one of these methods:
|
||||||
- **Load from disk**: Click "📁 Load from Disk" to upload files
|
- **Load an Object**: Click "📄 Load an Object" to upload standard JSON files (.json)
|
||||||
- `.json` files: Standard JSON format
|
- **Load a Log File**: Click "📋 Load a Log File" to upload JSON Lines files (.log) - each line converted to array
|
||||||
- `.log` files: JSON Lines format (each line is a JSON object, automatically converted to array)
|
|
||||||
- **Paste or type**: Enter JSON data directly in the bottom-left textarea
|
- **Paste or type**: Enter JSON data directly in the bottom-left textarea
|
||||||
- **Load sample**: Use the "Load Sample" button for quick testing
|
- **Load sample**: Use the "Load Sample" button for quick testing
|
||||||
3. **View the results** in the bottom-right output area
|
3. **View the results** in the bottom-right output area
|
||||||
4. **Use the toolbar buttons** to:
|
4. **Use the toolbar buttons** to:
|
||||||
- Load JSON data from local files
|
- Load JSON objects from standard .json files
|
||||||
|
- Load log files from JSON Lines .log files (auto-converted to arrays)
|
||||||
- Load sample data for testing
|
- Load sample data for testing
|
||||||
- Format JSON for better readability
|
- Format JSON for better readability
|
||||||
- Clear all inputs
|
- Clear all inputs
|
||||||
|
|||||||
70
src/App.js
70
src/App.js
@@ -119,7 +119,7 @@ function App() {
|
|||||||
const loadFromDisk = () => {
|
const loadFromDisk = () => {
|
||||||
const fileInput = document.createElement('input');
|
const fileInput = document.createElement('input');
|
||||||
fileInput.type = 'file';
|
fileInput.type = 'file';
|
||||||
fileInput.accept = '.json,.log';
|
fileInput.accept = '.json';
|
||||||
fileInput.onchange = (event) => {
|
fileInput.onchange = (event) => {
|
||||||
const file = event.target.files[0];
|
const file = event.target.files[0];
|
||||||
if (file) {
|
if (file) {
|
||||||
@@ -127,35 +127,50 @@ function App() {
|
|||||||
reader.onload = (e) => {
|
reader.onload = (e) => {
|
||||||
try {
|
try {
|
||||||
const content = e.target.result;
|
const content = e.target.result;
|
||||||
let jsonContent;
|
// Handle .json files as regular JSON
|
||||||
|
JSON.parse(content); // Validate JSON
|
||||||
|
setJsonData(content);
|
||||||
|
setJsonError('');
|
||||||
|
} catch (err) {
|
||||||
|
setJsonError(`Invalid JSON file: ${err.message}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.readAsText(file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fileInput.click();
|
||||||
|
};
|
||||||
|
|
||||||
// Handle .log files as sequences of JSON objects (JSON Lines format)
|
const loadLogFile = () => {
|
||||||
if (file.name.toLowerCase().endsWith('.log')) {
|
const fileInput = document.createElement('input');
|
||||||
const lines = content.split('\n')
|
fileInput.type = 'file';
|
||||||
.map(line => line.trim())
|
fileInput.accept = '.log';
|
||||||
.filter(line => line.length > 0);
|
fileInput.onchange = (event) => {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
try {
|
||||||
|
const content = e.target.result;
|
||||||
|
const lines = content.split('\n')
|
||||||
|
.map(line => line.trim())
|
||||||
|
.filter(line => line.length > 0);
|
||||||
|
|
||||||
const jsonObjects = [];
|
const jsonObjects = [];
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
try {
|
try {
|
||||||
const obj = JSON.parse(line);
|
const obj = JSON.parse(line);
|
||||||
jsonObjects.push(obj);
|
jsonObjects.push(obj);
|
||||||
} catch (lineError) {
|
} catch (lineError) {
|
||||||
throw new Error(`Invalid JSON on line: "${line.substring(0, 50)}..." - ${lineError.message}`);
|
throw new Error(`Invalid JSON on line: "${line.substring(0, 50)}..." - ${lineError.message}`);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonContent = JSON.stringify(jsonObjects, null, 2);
|
|
||||||
} else {
|
|
||||||
// Handle .json files as regular JSON
|
|
||||||
JSON.parse(content); // Validate JSON
|
|
||||||
jsonContent = content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const jsonContent = JSON.stringify(jsonObjects, null, 2);
|
||||||
setJsonData(jsonContent);
|
setJsonData(jsonContent);
|
||||||
setJsonError('');
|
setJsonError('');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setJsonError(`Invalid file content: ${err.message}`);
|
setJsonError(`Invalid log file: ${err.message}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
@@ -195,9 +210,16 @@ function App() {
|
|||||||
<button
|
<button
|
||||||
className="btn btn-outline-success btn-sm me-2"
|
className="btn btn-outline-success btn-sm me-2"
|
||||||
onClick={loadFromDisk}
|
onClick={loadFromDisk}
|
||||||
title="Load JSON from disk"
|
title="Load JSON object from file"
|
||||||
>
|
>
|
||||||
📁 Load from Disk
|
📄 Load an Object
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="btn btn-outline-info btn-sm me-2"
|
||||||
|
onClick={loadLogFile}
|
||||||
|
title="Load JSON Lines log file"
|
||||||
|
>
|
||||||
|
📋 Load a Log File
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="btn btn-outline-primary btn-sm me-2"
|
className="btn btn-outline-primary btn-sm me-2"
|
||||||
|
|||||||
@@ -65,6 +65,12 @@ code {
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-outline-info:hover {
|
||||||
|
background-color: #17a2b8;
|
||||||
|
border-color: #17a2b8;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.header-section {
|
.header-section {
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
color: white;
|
color: white;
|
||||||
|
|||||||
Reference in New Issue
Block a user