Compare commits

..

No commits in common. "bf355dd40e3f6c80b58ce2e3462ce3330e478741" and "270407a187c469791aacf49db9b291a828b08c04" have entirely different histories.

3 changed files with 25 additions and 247 deletions

View File

@ -43,7 +43,6 @@ const AddTableModal = ({
onAddTable,
schemas = [],
existingTables = [],
position = 'center', // 'center' | 'bottom-right'
tableTypes = [
{ value: 'fact', label: 'Fact Table' },
{ value: 'dimension', label: 'Dimension Table' },
@ -79,14 +78,6 @@ const AddTableModal = ({
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({});
const [isSubmitting, setIsSubmitting] = useState(false);
@ -99,91 +90,9 @@ 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: '',
@ -194,10 +103,6 @@ const AddTableModal = ({
setColumns([]);
setKeys([]);
setRelations([]);
setKeyTypes([]);
setLoadingKeyTypes(false);
setColumnTypesFromAPI([]);
setLoadingColumnTypes(false);
setErrors({});
setIsSubmitting(false);
setKeysViewMode('keys');
@ -221,11 +126,10 @@ const AddTableModal = ({
// Column management
const addColumn = () => {
const defaultColumnType = columnTypesFromAPI.length > 0 ? columnTypesFromAPI[0].name : 'VARCHAR';
const newColumn = {
id: Date.now(),
name: '',
type: defaultColumnType,
type: 'VARCHAR(255)',
isPrimaryKey: false,
isForeignKey: false,
isNullable: true
@ -273,12 +177,11 @@ 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: defaultKeyType, // Use first available key type from API
keyType: 'PRIMARY', // PRIMARY, FOREIGN, UNIQUE
keyColumns: [] // Array of {columnId, sequence} objects
};
setKeys(prev => [...prev, newKey]);
@ -503,16 +406,12 @@ const AddTableModal = ({
columns: columns.map(col => ({
name: col.name.trim(),
data_type: col.type,
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_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_nullable: col.isNullable
})),
keys: keys.flatMap(key =>
@ -545,44 +444,14 @@ 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 (
<Dialog
open={open}
onClose={onClose}
maxWidth={position === 'bottom-right' ? false : 'lg'}
fullWidth={position !== 'bottom-right'}
sx={getDialogStyles()}
maxWidth="lg"
fullWidth
PaperProps={{
sx: position === 'bottom-right' ? {} : {
sx: {
minHeight: '80vh',
maxHeight: '90vh'
}
@ -598,7 +467,7 @@ const AddTableModal = ({
</IconButton>
</DialogTitle>
<DialogContent dividers sx={{ p: position === 'bottom-right' ? 2 : 3 }}>
<DialogContent dividers sx={{ p: 3 }}>
{errors.submit && (
<Alert severity="error" sx={{ mb: 3 }}>
{errors.submit}
@ -606,7 +475,7 @@ const AddTableModal = ({
)}
{/* Basic Table Information */}
<Paper elevation={1} sx={{ p: position === 'bottom-right' ? 2 : 3, mb: position === 'bottom-right' ? 2 : 3 }}>
<Paper elevation={1} sx={{ p: 3, mb: 3 }}>
<Typography variant="h6" gutterBottom color="primary">
Table Information
</Typography>
@ -673,7 +542,7 @@ const AddTableModal = ({
</Paper>
{/* Columns Section */}
<Paper elevation={1} sx={{ p: position === 'bottom-right' ? 2 : 3, mb: position === 'bottom-right' ? 2 : 3 }}>
<Paper elevation={1} sx={{ p: 3, mb: 3 }}>
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>
<Typography variant="h6" color="primary">
Columns
@ -718,30 +587,12 @@ const AddTableModal = ({
value={column.type}
onChange={(e) => updateColumn(column.id, 'type', e.target.value)}
label="Data Type"
disabled={loadingColumnTypes}
>
{loadingColumnTypes ? (
<MenuItem value="">Loading...</MenuItem>
) : columnTypesFromAPI.length > 0 ? (
columnTypesFromAPI.map(type => (
<MenuItem key={type.cltp} value={type.name} title={type.description}>
<Box>
<Typography variant="body2" component="div">
{type.name}
</Typography>
<Typography variant="caption" color="text.secondary" component="div">
{type.description}
</Typography>
</Box>
</MenuItem>
))
) : (
columnTypes.map(type => (
{columnTypes.map(type => (
<MenuItem key={type} value={type}>
{type}
</MenuItem>
))
)}
))}
</Select>
</FormControl>
</Grid>
@ -773,7 +624,7 @@ const AddTableModal = ({
</Paper>
{/* Keys Section */}
<Paper elevation={1} sx={{ p: position === 'bottom-right' ? 2 : 3, mb: position === 'bottom-right' ? 2 : 3 }}>
<Paper elevation={1} sx={{ p: 3, mb: 3 }}>
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>
<Typography variant="h6" color="primary">
<KeyIcon style={{ marginRight: '8px', verticalAlign: 'middle' }} />
@ -860,17 +711,10 @@ const AddTableModal = ({
updateKey(key.id, 'keyType', e.target.value);
}}
onClick={(e) => e.stopPropagation()}
disabled={loadingKeyTypes}
>
{loadingKeyTypes ? (
<MenuItem value="">Loading...</MenuItem>
) : (
keyTypes.map((keyType) => (
<MenuItem key={keyType.kytp} value={keyType.kytp}>
{keyType.name} Key
</MenuItem>
))
)}
<MenuItem value="PRIMARY">Primary Key</MenuItem>
<MenuItem value="FOREIGN">Foreign Key</MenuItem>
<MenuItem value="UNIQUE">Unique Key</MenuItem>
</Select>
</FormControl>
</TableCell>
@ -1010,7 +854,7 @@ const AddTableModal = ({
</Paper>
{/* Relations Section */}
<Paper elevation={1} sx={{ p: position === 'bottom-right' ? 2 : 3 }}>
<Paper elevation={1} sx={{ p: 3 }}>
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 2 }}>
<Typography variant="h6" color="primary">
<LinkIcon style={{ marginRight: '8px', verticalAlign: 'middle' }} />
@ -1121,7 +965,7 @@ const AddTableModal = ({
</Paper>
</DialogContent>
<DialogActions sx={{ p: position === 'bottom-right' ? 2 : 3, gap: 1 }}>
<DialogActions sx={{ p: 3, gap: 1 }}>
<Button onClick={onClose} variant="outlined">
Cancel
</Button>

View File

@ -1755,7 +1755,6 @@ const ERDiagramCanvasContent = () => {
onAddTable={handleAddTable}
schemas={availableSchemas}
existingTables={existingTables}
position="bottom-right"
/>
</div>

View File

@ -1,65 +0,0 @@
// 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();