|
|
|
|
@ -563,167 +563,61 @@ const ERDiagramCanvasContent = () => {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Mock database data representing ONE database with multiple schemas (fallback only)
|
|
|
|
|
// const mockDatabaseData = {
|
|
|
|
|
// id: 1,
|
|
|
|
|
// name: "Sample Database",
|
|
|
|
|
// slug: "sample_database",
|
|
|
|
|
// description: "Sample Database Structure (Mock Data)",
|
|
|
|
|
// service: selectedService?.name || "Unknown Service",
|
|
|
|
|
// dataSource: selectedDataSource?.name || "Unknown DataSource",
|
|
|
|
|
// schemas: [
|
|
|
|
|
// {
|
|
|
|
|
// sch: "FINANCE_MART",
|
|
|
|
|
// tables: [
|
|
|
|
|
// {
|
|
|
|
|
// id: 1,
|
|
|
|
|
// name: "accounts",
|
|
|
|
|
// table_type: "dimension",
|
|
|
|
|
// columns: [
|
|
|
|
|
// { name: "account_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
// { name: "account_number", data_type: "VARCHAR(20)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "account_name", data_type: "VARCHAR(100)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "account_type", data_type: "VARCHAR(50)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "balance", data_type: "DECIMAL(15,2)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "created_date", data_type: "TIMESTAMP", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
// ]
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 2,
|
|
|
|
|
// name: "transactions",
|
|
|
|
|
// table_type: "fact",
|
|
|
|
|
// columns: [
|
|
|
|
|
// { name: "transaction_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
// { name: "account_id", data_type: "INTEGER", is_primary_key: false, is_foreign_key: true },
|
|
|
|
|
// { name: "transaction_date", data_type: "DATE", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "amount", data_type: "DECIMAL(12,2)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "transaction_type", data_type: "VARCHAR(20)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "description", data_type: "VARCHAR(255)", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
// ]
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 3,
|
|
|
|
|
// name: "customers",
|
|
|
|
|
// table_type: "dimension",
|
|
|
|
|
// columns: [
|
|
|
|
|
// { name: "customer_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
// { name: "first_name", data_type: "VARCHAR(50)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "last_name", data_type: "VARCHAR(50)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "email", data_type: "VARCHAR(100)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "phone", data_type: "VARCHAR(20)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "registration_date", data_type: "TIMESTAMP", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
// ]
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 4,
|
|
|
|
|
// name: "financial_reports",
|
|
|
|
|
// table_type: "fact",
|
|
|
|
|
// columns: [
|
|
|
|
|
// { name: "report_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
// { name: "account_id", data_type: "INTEGER", is_primary_key: false, is_foreign_key: true },
|
|
|
|
|
// { name: "report_date", data_type: "DATE", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "balance_amount", data_type: "DECIMAL(15,2)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "profit_loss", data_type: "DECIMAL(12,2)", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
// ]
|
|
|
|
|
// }
|
|
|
|
|
// ]
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// sch: "Schema100",
|
|
|
|
|
// tables: [
|
|
|
|
|
// {
|
|
|
|
|
// id: 5,
|
|
|
|
|
// name: "products",
|
|
|
|
|
// table_type: "dimension",
|
|
|
|
|
// columns: [
|
|
|
|
|
// { name: "product_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
// { name: "product_name", data_type: "VARCHAR(100)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "category", data_type: "VARCHAR(50)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "price", data_type: "DECIMAL(10,2)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "stock_quantity", data_type: "INTEGER", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
// ]
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 6,
|
|
|
|
|
// name: "orders",
|
|
|
|
|
// table_type: "fact",
|
|
|
|
|
// columns: [
|
|
|
|
|
// { name: "order_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
// { name: "customer_id", data_type: "INTEGER", is_primary_key: false, is_foreign_key: true },
|
|
|
|
|
// { name: "product_id", data_type: "INTEGER", is_primary_key: false, is_foreign_key: true },
|
|
|
|
|
// { name: "order_date", data_type: "DATE", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "quantity", data_type: "INTEGER", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "total_amount", data_type: "DECIMAL(12,2)", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
// ]
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 7,
|
|
|
|
|
// name: "inventory",
|
|
|
|
|
// table_type: "stage",
|
|
|
|
|
// columns: [
|
|
|
|
|
// { name: "inventory_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
// { name: "product_id", data_type: "INTEGER", is_primary_key: false, is_foreign_key: true },
|
|
|
|
|
// { name: "warehouse_location", data_type: "VARCHAR(100)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "stock_level", data_type: "INTEGER", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "last_updated", data_type: "TIMESTAMP", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
// ]
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 8,
|
|
|
|
|
// name: "suppliers",
|
|
|
|
|
// table_type: "dimension",
|
|
|
|
|
// columns: [
|
|
|
|
|
// { name: "supplier_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
// { name: "supplier_name", data_type: "VARCHAR(100)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "contact_email", data_type: "VARCHAR(100)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "phone_number", data_type: "VARCHAR(20)", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
// ]
|
|
|
|
|
// }
|
|
|
|
|
// ]
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// sch: "New_sch",
|
|
|
|
|
// tables: [
|
|
|
|
|
// {
|
|
|
|
|
// id: 9,
|
|
|
|
|
// name: "analytics_summary",
|
|
|
|
|
// table_type: "fact",
|
|
|
|
|
// columns: [
|
|
|
|
|
// { name: "summary_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
// { name: "date", data_type: "DATE", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "total_revenue", data_type: "DECIMAL(15,2)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "total_orders", data_type: "INTEGER", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "unique_customers", data_type: "INTEGER", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
// ]
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 10,
|
|
|
|
|
// name: "user_sessions",
|
|
|
|
|
// table_type: "stage",
|
|
|
|
|
// columns: [
|
|
|
|
|
// { name: "session_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
// { name: "customer_id", data_type: "INTEGER", is_primary_key: false, is_foreign_key: true },
|
|
|
|
|
// { name: "session_start", data_type: "TIMESTAMP", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "session_end", data_type: "TIMESTAMP", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "pages_viewed", data_type: "INTEGER", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "device_type", data_type: "VARCHAR(50)", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
// ]
|
|
|
|
|
// },
|
|
|
|
|
// {
|
|
|
|
|
// id: 11,
|
|
|
|
|
// name: "reports",
|
|
|
|
|
// table_type: "dimension",
|
|
|
|
|
// columns: [
|
|
|
|
|
// { name: "report_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
// { name: "report_name", data_type: "VARCHAR(100)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "report_type", data_type: "VARCHAR(50)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "created_by", data_type: "VARCHAR(50)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
// { name: "created_date", data_type: "TIMESTAMP", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
// ]
|
|
|
|
|
// }
|
|
|
|
|
// ]
|
|
|
|
|
// }
|
|
|
|
|
// ]
|
|
|
|
|
// };
|
|
|
|
|
const mockDatabaseData = {
|
|
|
|
|
id: 1,
|
|
|
|
|
name: "Sample Database",
|
|
|
|
|
slug: "sample_database",
|
|
|
|
|
description: "Sample Database Structure (Mock Data)",
|
|
|
|
|
service: selectedService?.name || "Unknown Service",
|
|
|
|
|
dataSource: selectedDataSource?.name || "Unknown DataSource",
|
|
|
|
|
schemas: [
|
|
|
|
|
{
|
|
|
|
|
sch: "FINANCE_MART",
|
|
|
|
|
tables: [
|
|
|
|
|
{
|
|
|
|
|
id: 1,
|
|
|
|
|
name: "accounts",
|
|
|
|
|
table_type: "dimension",
|
|
|
|
|
columns: [
|
|
|
|
|
{ name: "account_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
{ name: "account_number", data_type: "VARCHAR(20)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
{ name: "account_name", data_type: "VARCHAR(100)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
{ name: "account_type", data_type: "VARCHAR(50)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
{ name: "balance", data_type: "DECIMAL(15,2)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
{ name: "created_date", data_type: "TIMESTAMP", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 2,
|
|
|
|
|
name: "transactions",
|
|
|
|
|
table_type: "fact",
|
|
|
|
|
columns: [
|
|
|
|
|
{ name: "transaction_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
{ name: "account_id", data_type: "INTEGER", is_primary_key: false, is_foreign_key: true },
|
|
|
|
|
{ name: "transaction_date", data_type: "DATE", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
{ name: "amount", data_type: "DECIMAL(12,2)", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
sch: "SALES_MART",
|
|
|
|
|
name: "Sales Mart",
|
|
|
|
|
tables: [
|
|
|
|
|
{
|
|
|
|
|
id: 3,
|
|
|
|
|
name: "customers",
|
|
|
|
|
table_type: "dimension",
|
|
|
|
|
columns: [
|
|
|
|
|
{ name: "customer_id", data_type: "INTEGER", is_primary_key: true, is_foreign_key: false },
|
|
|
|
|
{ name: "customer_name", data_type: "VARCHAR(100)", is_primary_key: false, is_foreign_key: false },
|
|
|
|
|
{ name: "email", data_type: "VARCHAR(100)", is_primary_key: false, is_foreign_key: false }
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// API Functions for fetching real data
|
|
|
|
|
const fetchDatabases = async () => {
|
|
|
|
|
@ -1155,24 +1049,60 @@ const ERDiagramCanvasContent = () => {
|
|
|
|
|
try {
|
|
|
|
|
console.log('Adding new table:', tableData);
|
|
|
|
|
|
|
|
|
|
// Here you would typically make an API call to create the table
|
|
|
|
|
// For now, we'll add it to the current diagram
|
|
|
|
|
|
|
|
|
|
// Find the target schema
|
|
|
|
|
const targetSchema = availableSchemas.find(schema => schema.sch === tableData.schema);
|
|
|
|
|
if (!targetSchema) {
|
|
|
|
|
throw new Error('Target schema not found');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create a new table object
|
|
|
|
|
const newTable = {
|
|
|
|
|
id: `new-table-${Date.now()}`,
|
|
|
|
|
// Prepare API payload
|
|
|
|
|
const apiPayload = {
|
|
|
|
|
token: token,
|
|
|
|
|
org: orgSlug,
|
|
|
|
|
con: selectedDatabase?.slug || "my_dwh", // Use selected database slug
|
|
|
|
|
sch: tableData.schema,
|
|
|
|
|
name: tableData.name,
|
|
|
|
|
external_name: null,
|
|
|
|
|
table_type: tableData.table_type,
|
|
|
|
|
description: tableData.description,
|
|
|
|
|
columns: tableData.columns.map(col => ({
|
|
|
|
|
column_name: col.name,
|
|
|
|
|
data_type: col.data_type,
|
|
|
|
|
is_nullable: col.is_nullable
|
|
|
|
|
})),
|
|
|
|
|
keys: tableData.keys.map(key => ({
|
|
|
|
|
key_name: key.name,
|
|
|
|
|
key_type: key.key_type,
|
|
|
|
|
key_columns: [{
|
|
|
|
|
column_name: key.column_name,
|
|
|
|
|
sequence: key.sequence
|
|
|
|
|
}]
|
|
|
|
|
}))
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
console.log('API Payload:', apiPayload);
|
|
|
|
|
|
|
|
|
|
// Make API call to create the table
|
|
|
|
|
const response = await axios.post(ENDPOINTS.TABLE_CREATE, apiPayload, {
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
console.log('API Response:', response.data);
|
|
|
|
|
|
|
|
|
|
if (response.data.status === 200) {
|
|
|
|
|
// API call successful, create new table object for local state
|
|
|
|
|
const newTable = {
|
|
|
|
|
id: response.data.id || `new-table-${Date.now()}`,
|
|
|
|
|
name: tableData.name,
|
|
|
|
|
tbl: response.data.tbl || tableData.name.toLowerCase(), // Table slug from API or fallback
|
|
|
|
|
description: tableData.description,
|
|
|
|
|
table_type: tableData.table_type,
|
|
|
|
|
columns: tableData.columns,
|
|
|
|
|
schema: tableData.schema,
|
|
|
|
|
database: selectedDatabase?.name || 'Unknown'
|
|
|
|
|
database: selectedDatabase?.slug || 'Unknown',
|
|
|
|
|
created_at: new Date().toISOString()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Add the table to existing tables list
|
|
|
|
|
@ -1188,15 +1118,30 @@ const ERDiagramCanvasContent = () => {
|
|
|
|
|
}
|
|
|
|
|
updatedDatabase.schemas[schemaIndex].tables.push(newTable);
|
|
|
|
|
|
|
|
|
|
// Update the selected database state
|
|
|
|
|
setSelectedDatabase(updatedDatabase);
|
|
|
|
|
|
|
|
|
|
// Regenerate the ER diagram with the new table
|
|
|
|
|
generateERDiagram(updatedDatabase);
|
|
|
|
|
|
|
|
|
|
console.log('Table added successfully:', newTable);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error(response.data.message || 'Failed to create table');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error adding table:', error);
|
|
|
|
|
throw error;
|
|
|
|
|
|
|
|
|
|
// Check if it's an API error
|
|
|
|
|
if (error.response) {
|
|
|
|
|
const errorMessage = error.response.data?.message || `API Error: ${error.response.status}`;
|
|
|
|
|
throw new Error(errorMessage);
|
|
|
|
|
} else if (error.request) {
|
|
|
|
|
throw new Error('Network error: Unable to connect to the API');
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error(error.message || 'Unknown error occurred');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|