Enhanced Object Editor with fetch data & mobile improvements

🚀 New Features:
- Fetch Data functionality with URL input and error handling
- Auto-protocol detection (adds https:// if missing)
- Smart content-type handling for various JSON APIs
- Perfect for Telegram Bot API, GitHub API, JSONPlaceholder, etc.

📱 Mobile Responsiveness:
- Desktop: Clean tab interface for view modes
- Mobile: Native select dropdown with emoji icons
- StructuredEditor: Horizontal scroll for wide JSON structures
- Input data field auto-hides on successful fetch

🐛 Critical Fixes:
- Fixed StructuredEditor reinitialization loop issue
- Fixed deep nested property/array item deletion
- Proper array splicing and object property removal
- Internal vs external data change tracking

🎨 UX Improvements:
- Loading states during fetch operations
- Better error messages and validation
- Responsive button layouts and spacing
- Enhanced usage tips with fetch examples
This commit is contained in:
dwindown
2025-09-21 17:08:20 +07:00
parent e1c74e4a4e
commit f2163c9814
2 changed files with 161 additions and 19 deletions

View File

@@ -1,13 +1,20 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import { Plus, Minus, ChevronDown, ChevronRight, Type, Hash, ToggleLeft, List, Braces } from 'lucide-react';
const StructuredEditor = ({ onDataChange, initialData = {} }) => {
const [data, setData] = useState(initialData);
const [expandedNodes, setExpandedNodes] = useState(new Set(['root']));
const isInternalUpdate = useRef(false);
// Update internal data when initialData prop changes
// Update internal data when initialData prop changes (but not from internal updates)
useEffect(() => {
console.log('📥 INITIAL DATA CHANGED:', {
// Skip update if this change came from internal editor actions
if (isInternalUpdate.current) {
isInternalUpdate.current = false;
return;
}
console.log('📥 EXTERNAL DATA CHANGED:', {
keys: Object.keys(initialData),
hasData: Object.keys(initialData).length > 0,
data: initialData
@@ -20,7 +27,8 @@ const StructuredEditor = ({ onDataChange, initialData = {} }) => {
}, [initialData]);
const updateData = (newData) => {
console.log('📊 DATA UPDATE:', { keys: Object.keys(newData), totalProps: JSON.stringify(newData).length });
console.log('📊 INTERNAL DATA UPDATE:', { keys: Object.keys(newData), totalProps: JSON.stringify(newData).length });
isInternalUpdate.current = true; // Mark as internal update
setData(newData);
onDataChange(newData);
};
@@ -78,22 +86,31 @@ const StructuredEditor = ({ onDataChange, initialData = {} }) => {
};
const removeProperty = (key, parentPath) => {
console.log('🗑️ REMOVE PROPERTY:', { key, parentPath });
const pathParts = parentPath.split('.');
const newData = { ...data };
let current = newData;
// Navigate to the parent object/array
for (let i = 1; i < pathParts.length; i++) {
if (i === pathParts.length - 1) {
delete current[key];
} else {
current = current[pathParts[i]];
}
current = current[pathParts[i]];
}
if (pathParts.length === 1) {
delete newData[key];
// Delete the property/item from the parent
if (Array.isArray(current)) {
// For arrays, remove by index and reindex
current.splice(parseInt(key), 1);
} else {
// For objects, delete the property
delete current[key];
}
console.log('🗑️ REMOVE PROPERTY - After:', {
parentPath,
remainingKeys: Array.isArray(current) ? current.length : Object.keys(current)
});
updateData(newData);
};