diff --git a/src/components/AddTableModal.jsx b/src/components/AddTableModal.jsx index 095f747..26a3225 100644 --- a/src/components/AddTableModal.jsx +++ b/src/components/AddTableModal.jsx @@ -43,6 +43,7 @@ const AddTableModal = ({ onAddTable, schemas = [], existingTables = [], + position = 'center', // 'center' | 'bottom-right' tableTypes = [ { value: 'fact', label: 'Fact Table' }, { value: 'dimension', label: 'Dimension Table' }, @@ -77,6 +78,14 @@ const AddTableModal = ({ const [columns, setColumns] = useState([]); const [keys, setKeys] = useState([]); const [relations, setRelations] = useState([]); + + // Key types from API + const [keyTypes, setKeyTypes] = useState([]); + const [loadingKeyTypes, setLoadingKeyTypes] = useState(false); + + // Column types from API + const [columnTypesFromAPI, setColumnTypesFromAPI] = useState([]); + const [loadingColumnTypes, setLoadingColumnTypes] = useState(false); // Validation and UI state const [errors, setErrors] = useState({}); @@ -90,9 +99,91 @@ const AddTableModal = ({ useEffect(() => { if (open) { resetForm(); + fetchKeyTypes(); + fetchColumnTypes(); } }, [open]); + // Fetch key types from API + const fetchKeyTypes = async () => { + setLoadingKeyTypes(true); + try { + const response = await fetch('https://sandbox.kezel.io/api/qbt_table_key_type_list_get', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + token: "abdhsg", + org: "sN05Pjv11qvH" + }) + }); + const data = await response.json(); + + if (data.status === 200 && data.items) { + setKeyTypes(data.items); + } else { + console.error('Failed to fetch key types:', data.message); + } + } catch (error) { + console.error('Error fetching key types:', error); + // Fallback to default key types + setKeyTypes([ + { kytp: 'PRIMARY', name: 'Primary' }, + { kytp: 'FOREIGN', name: 'Foreign' }, + { kytp: 'UNIQUE', name: 'Unique' } + ]); + } finally { + setLoadingKeyTypes(false); + } + }; + + // Fetch column types from API + const fetchColumnTypes = async () => { + setLoadingColumnTypes(true); + try { + const response = await fetch('https://sandbox.kezel.io/api/qbt_column_type_list_get', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + token: "abdhsg", + org: "sN05Pjv11qvH" + }) + }); + const data = await response.json(); + + if (data.status === 200 && data.items) { + setColumnTypesFromAPI(data.items); + } else { + console.error('Failed to fetch column types:', data.message); + // Fallback to default column types + setColumnTypesFromAPI([ + { cltp: 'VARCHAR', name: 'VARCHAR', description: 'Variable-length character string' }, + { cltp: 'INT', name: 'INT', description: 'Standard integer value' }, + { cltp: 'TEXT', name: 'TEXT', description: 'Variable-length character string for long text' }, + { cltp: 'DATE', name: 'DATE', description: 'Date value' }, + { cltp: 'TIMESTAMP', name: 'TIMESTAMP', description: 'Timestamp value' }, + { cltp: 'BOOLEAN', name: 'BOOLEAN', description: 'Logical boolean value' } + ]); + } + } catch (error) { + console.error('Error fetching column types:', error); + // Fallback to default column types + setColumnTypesFromAPI([ + { cltp: 'VARCHAR', name: 'VARCHAR', description: 'Variable-length character string' }, + { cltp: 'INT', name: 'INT', description: 'Standard integer value' }, + { cltp: 'TEXT', name: 'TEXT', description: 'Variable-length character string for long text' }, + { cltp: 'DATE', name: 'DATE', description: 'Date value' }, + { cltp: 'TIMESTAMP', name: 'TIMESTAMP', description: 'Timestamp value' }, + { cltp: 'BOOLEAN', name: 'BOOLEAN', description: 'Logical boolean value' } + ]); + } finally { + setLoadingColumnTypes(false); + } + }; + const resetForm = () => { setFormData({ name: '', @@ -103,6 +194,10 @@ const AddTableModal = ({ setColumns([]); setKeys([]); setRelations([]); + setKeyTypes([]); + setLoadingKeyTypes(false); + setColumnTypesFromAPI([]); + setLoadingColumnTypes(false); setErrors({}); setIsSubmitting(false); setKeysViewMode('keys'); @@ -126,10 +221,11 @@ const AddTableModal = ({ // Column management const addColumn = () => { + const defaultColumnType = columnTypesFromAPI.length > 0 ? columnTypesFromAPI[0].name : 'VARCHAR'; const newColumn = { id: Date.now(), name: '', - type: 'VARCHAR(255)', + type: defaultColumnType, isPrimaryKey: false, isForeignKey: false, isNullable: true @@ -177,11 +273,12 @@ const AddTableModal = ({ // Key management const addKey = () => { + const defaultKeyType = keyTypes.length > 0 ? keyTypes[0].kytp : 'PRIMARY'; const newKey = { id: Date.now(), name: '', columnIds: [], // Changed to array for multi-select - keyType: 'PRIMARY', // PRIMARY, FOREIGN, UNIQUE + keyType: defaultKeyType, // Use first available key type from API keyColumns: [] // Array of {columnId, sequence} objects }; setKeys(prev => [...prev, newKey]); @@ -406,12 +503,16 @@ const AddTableModal = ({ columns: columns.map(col => ({ name: col.name.trim(), data_type: col.type, - is_primary_key: keys.some(key => - key.keyColumns?.some(kc => kc.columnId === col.id) && key.keyType === 'PRIMARY' - ), - is_foreign_key: keys.some(key => - key.keyColumns?.some(kc => kc.columnId === col.id) && key.keyType === 'FOREIGN' - ), + is_primary_key: keys.some(key => { + const keyTypeObj = keyTypes.find(kt => kt.kytp === key.keyType); + return key.keyColumns?.some(kc => kc.columnId === col.id) && + keyTypeObj?.name?.toLowerCase() === 'primary'; + }), + is_foreign_key: keys.some(key => { + const keyTypeObj = keyTypes.find(kt => kt.kytp === key.keyType); + return key.keyColumns?.some(kc => kc.columnId === col.id) && + keyTypeObj?.name?.toLowerCase() === 'foreign'; + }), is_nullable: col.isNullable })), keys: keys.flatMap(key => @@ -444,14 +545,44 @@ const AddTableModal = ({ } }; + // Define positioning styles based on position prop + const getDialogStyles = () => { + if (position === 'bottom-right') { + return { + '& .MuiDialog-container': { + justifyContent: 'flex-end', + alignItems: 'flex-end', + padding: '20px', + }, + '& .MuiDialog-paper': { + margin: 0, + maxWidth: '780px', // Increased by 30% from 600px + width: '780px', // Increased by 30% from 600px + maxHeight: '80vh', + minHeight: '60vh', + borderRadius: '12px', + boxShadow: '0 8px 32px rgba(0, 0, 0, 0.3)', + } + }; + } + return { + '& .MuiDialog-paper': { + minHeight: '80vh', + maxHeight: '90vh', + maxWidth: '1170px', // Increased by 30% from 900px (lg breakpoint) + } + }; + }; + return ( - + {errors.submit && ( {errors.submit} @@ -475,7 +606,7 @@ const AddTableModal = ({ )} {/* Basic Table Information */} - + Table Information @@ -542,7 +673,7 @@ const AddTableModal = ({ {/* Columns Section */} - + Columns @@ -587,12 +718,30 @@ const AddTableModal = ({ value={column.type} onChange={(e) => updateColumn(column.id, 'type', e.target.value)} label="Data Type" + disabled={loadingColumnTypes} > - {columnTypes.map(type => ( - - {type} - - ))} + {loadingColumnTypes ? ( + Loading... + ) : columnTypesFromAPI.length > 0 ? ( + columnTypesFromAPI.map(type => ( + + + + {type.name} + + + {type.description} + + + + )) + ) : ( + columnTypes.map(type => ( + + {type} + + )) + )} @@ -624,7 +773,7 @@ const AddTableModal = ({ {/* Keys Section */} - + @@ -711,10 +860,17 @@ const AddTableModal = ({ updateKey(key.id, 'keyType', e.target.value); }} onClick={(e) => e.stopPropagation()} + disabled={loadingKeyTypes} > - Primary Key - Foreign Key - Unique Key + {loadingKeyTypes ? ( + Loading... + ) : ( + keyTypes.map((keyType) => ( + + {keyType.name} Key + + )) + )} @@ -854,7 +1010,7 @@ const AddTableModal = ({ {/* Relations Section */} - + @@ -965,7 +1121,7 @@ const AddTableModal = ({ - + diff --git a/src/components/ERDiagramCanvas.jsx b/src/components/ERDiagramCanvas.jsx index 4f6c09f..f9b0625 100644 --- a/src/components/ERDiagramCanvas.jsx +++ b/src/components/ERDiagramCanvas.jsx @@ -1755,6 +1755,7 @@ const ERDiagramCanvasContent = () => { onAddTable={handleAddTable} schemas={availableSchemas} existingTables={existingTables} + position="bottom-right" /> diff --git a/test_api.js b/test_api.js new file mode 100644 index 0000000..8aa5e93 --- /dev/null +++ b/test_api.js @@ -0,0 +1,65 @@ +// Test script to verify both API calls +async function testKeyTypesAPI() { + console.log('šŸ” Testing Key Types API...'); + try { + const response = await fetch('https://sandbox.kezel.io/api/qbt_table_key_type_list_get', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + token: "abdhsg", + org: "sN05Pjv11qvH" + }) + }); + const data = await response.json(); + + if (data.status === 200 && data.items) { + console.log('āœ… Key Types API call successful'); + console.log('Key types found:', data.items.length); + data.items.forEach(item => { + console.log(`- ${item.name} (ID: ${item.kytp})`); + }); + } else { + console.log('āŒ Key Types API call failed:', data.message); + } + } catch (error) { + console.error('āŒ Error calling Key Types API:', error); + } +} + +async function testColumnTypesAPI() { + console.log('\nšŸ” Testing Column Types API...'); + try { + const response = await fetch('https://sandbox.kezel.io/api/qbt_column_type_list_get', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + token: "abdhsg", + org: "sN05Pjv11qvH" + }) + }); + const data = await response.json(); + + if (data.status === 200 && data.items) { + console.log('āœ… Column Types API call successful'); + console.log('Column types found:', data.items.length); + data.items.forEach(item => { + console.log(`- ${item.name} (ID: ${item.cltp}) - ${item.description}`); + }); + } else { + console.log('āŒ Column Types API call failed:', data.message); + } + } catch (error) { + console.error('āŒ Error calling Column Types API:', error); + } +} + +async function runTests() { + await testKeyTypesAPI(); + await testColumnTypesAPI(); +} + +runTests(); \ No newline at end of file