From afa910e6b8bbe596f1f606e66721f2b1f648cfba Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 8 Jan 2026 14:02:38 +0000
Subject: [PATCH] Refactor TableManagerTab and ColumnManagerTab to use
ComponentTreeRenderer
Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
---
src/components/admin/ColumnManagerTab.tsx | 148 ++-----
src/components/admin/TableManagerTab.tsx | 91 +---
src/config/features.json | 487 ++++++++++++++++++++++
3 files changed, 542 insertions(+), 184 deletions(-)
diff --git a/src/components/admin/ColumnManagerTab.tsx b/src/components/admin/ColumnManagerTab.tsx
index 8baaefa..34612d1 100644
--- a/src/components/admin/ColumnManagerTab.tsx
+++ b/src/components/admin/ColumnManagerTab.tsx
@@ -1,24 +1,8 @@
'use client';
-import AddIcon from '@mui/icons-material/Add';
-import DeleteIcon from '@mui/icons-material/Delete';
-import EditIcon from '@mui/icons-material/Edit';
-import {
- Box,
- Button,
- MenuItem,
- Paper,
- Select,
- Table,
- TableBody,
- TableCell,
- TableContainer,
- TableHead,
- TableRow,
- Typography,
-} from '@mui/material';
import { useEffect, useState } from 'react';
-import { getDataTypes, getFeatureById } from '@/utils/featureConfig';
+import { getComponentTree, getDataTypes, getFeatureById } from '@/utils/featureConfig';
+import ComponentTreeRenderer from '@/utils/ComponentTreeRenderer';
import ColumnDialog from './ColumnDialog';
type ColumnManagerTabProps = {
@@ -99,106 +83,38 @@ export default function ColumnManagerTab({
setDialogState({ ...dialogState, open: false });
};
+ const handleTableChange = (event: any) => {
+ setSelectedTable(event.target.value);
+ };
+
+ // Get component tree from features.json
+ const tree = getComponentTree('ColumnManagerTab');
+
+ // Prepare data for the component tree
+ const data = {
+ feature,
+ tables,
+ selectedTable,
+ tableSchema,
+ canAdd,
+ canModify,
+ canDelete,
+ };
+
+ // Define handlers for the component tree
+ const handlers = {
+ handleTableChange,
+ openAddDialog: () => openDialog('add'),
+ openModifyDialog: () => openDialog('modify'),
+ openDropDialog: () => openDialog('drop'),
+ };
+
return (
<>
-
- {feature?.name || 'Column Manager'}
-
-
- {feature?.description && (
-
- {feature.description}
-
- )}
-
-
-
- Select a table to manage its columns:
-
-
-
-
- {selectedTable && (
- <>
-
- {canAdd && (
- }
- onClick={() => openDialog('add')}
- sx={{ mr: 2 }}
- >
- Add Column
-
- )}
- {canModify && (
- }
- onClick={() => openDialog('modify')}
- sx={{ mr: 2 }}
- >
- Modify Column
-
- )}
- {canDelete && (
- }
- onClick={() => openDialog('drop')}
- >
- Drop Column
-
- )}
-
-
- {tableSchema && (
-
-
-
- Current Columns for {selectedTable}
-
-
-
-
-
- Column Name
- Data Type
- Nullable
- Default
-
-
-
- {tableSchema.columns?.map((col: any) => (
-
- {col.column_name}
- {col.data_type}
- {col.is_nullable}
- {col.column_default || 'NULL'}
-
- ))}
-
-
-
-
-
- )}
- >
+ {tree ? (
+
+ ) : (
+
Error: Component tree not found
)}
setOpenCreateDialog(true),
+ openDropDialog: () => setOpenDropDialog(true),
+ };
+
return (
<>
-
- {feature?.name || 'Table Manager'}
-
-
- {feature?.description && (
-
- {feature.description}
-
+ {tree ? (
+
+ ) : (
+ Error: Component tree not found
)}
-
- {canCreate && (
- }
- onClick={() => setOpenCreateDialog(true)}
- sx={{ mr: 2 }}
- >
- Create Table
-
- )}
- {canDelete && (
- }
- onClick={() => setOpenDropDialog(true)}
- >
- Drop Table
-
- )}
-
-
-
-
-
- Existing Tables
-
-
- {tables.map(table => (
-
-
-
-
-
-
- ))}
- {tables.length === 0 && (
-
-
-
- )}
-
-
-
-
setOpenCreateDialog(false)}
diff --git a/src/config/features.json b/src/config/features.json
index 77fc987..590408c 100644
--- a/src/config/features.json
+++ b/src/config/features.json
@@ -1474,6 +1474,493 @@
]
}
]
+ },
+ "ConstraintManagerTab": {
+ "component": "Box",
+ "children": [
+ {
+ "component": "Typography",
+ "props": {
+ "variant": "h5",
+ "gutterBottom": true,
+ "text": "{{feature.name}}"
+ }
+ },
+ {
+ "component": "Typography",
+ "condition": "feature.description",
+ "props": {
+ "variant": "body2",
+ "color": "text.secondary",
+ "gutterBottom": true,
+ "text": "{{feature.description}}"
+ }
+ },
+ {
+ "component": "Paper",
+ "props": {
+ "sx": { "p": 2, "mb": 2 }
+ },
+ "children": [
+ {
+ "component": "FormControl",
+ "props": {
+ "fullWidth": true
+ },
+ "children": [
+ {
+ "component": "InputLabel",
+ "props": {
+ "text": "Select Table"
+ }
+ },
+ {
+ "component": "Select",
+ "props": {
+ "value": "{{selectedTable}}",
+ "label": "Select Table",
+ "onChange": "handleTableChange"
+ },
+ "children": [
+ {
+ "component": "MenuItem",
+ "forEach": "tables",
+ "props": {
+ "value": "{{table.table_name}}",
+ "text": "{{table.table_name}}"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "component": "Box",
+ "condition": "selectedTable && canAdd",
+ "props": {
+ "sx": { "mb": 2 }
+ },
+ "children": [
+ {
+ "component": "Button",
+ "condition": "canAdd",
+ "props": {
+ "variant": "contained",
+ "startIcon": "Add",
+ "onClick": "openAddDialog",
+ "text": "Add Constraint"
+ }
+ }
+ ]
+ },
+ {
+ "component": "Paper",
+ "condition": "constraints && constraints.length > 0",
+ "props": {
+ "sx": { "mt": 2 }
+ },
+ "children": [
+ {
+ "component": "TableContainer",
+ "children": [
+ {
+ "component": "Table",
+ "props": {
+ "size": "small"
+ },
+ "children": [
+ {
+ "component": "TableHead",
+ "children": [
+ {
+ "component": "TableRow",
+ "children": [
+ {
+ "component": "TableCell",
+ "props": {
+ "text": "Constraint Name"
+ }
+ },
+ {
+ "component": "TableCell",
+ "props": {
+ "text": "Type"
+ }
+ },
+ {
+ "component": "TableCell",
+ "props": {
+ "text": "Definition"
+ }
+ },
+ {
+ "component": "TableCell",
+ "condition": "canDelete",
+ "props": {
+ "text": "Actions"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "component": "TableBody",
+ "children": [
+ {
+ "component": "TableRow",
+ "forEach": "constraints",
+ "children": [
+ {
+ "component": "TableCell",
+ "props": {
+ "text": "{{constraint.constraint_name}}"
+ }
+ },
+ {
+ "component": "TableCell",
+ "props": {
+ "text": "{{constraint.constraint_type}}"
+ }
+ },
+ {
+ "component": "TableCell",
+ "props": {
+ "text": "{{constraint.definition || '-'}}"
+ }
+ },
+ {
+ "component": "TableCell",
+ "condition": "canDelete",
+ "children": [
+ {
+ "component": "IconButton",
+ "props": {
+ "size": "small",
+ "color": "error",
+ "onClick": "handleDeleteConstraint"
+ },
+ "children": [
+ {
+ "component": "Typography",
+ "props": {
+ "text": "🗑️"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "IndexManagerTab": {
+ "component": "Box",
+ "children": [
+ {
+ "component": "Typography",
+ "props": {
+ "variant": "h5",
+ "gutterBottom": true,
+ "text": "{{feature.name}}"
+ }
+ },
+ {
+ "component": "Typography",
+ "condition": "feature.description",
+ "props": {
+ "variant": "body2",
+ "color": "text.secondary",
+ "gutterBottom": true,
+ "text": "{{feature.description}}"
+ }
+ },
+ {
+ "component": "Paper",
+ "props": {
+ "sx": { "p": 2, "mb": 2 }
+ },
+ "children": [
+ {
+ "component": "FormControl",
+ "props": {
+ "fullWidth": true
+ },
+ "children": [
+ {
+ "component": "InputLabel",
+ "props": {
+ "text": "Select Table"
+ }
+ },
+ {
+ "component": "Select",
+ "props": {
+ "value": "{{selectedTable}}",
+ "label": "Select Table",
+ "onChange": "handleTableChange"
+ },
+ "children": [
+ {
+ "component": "MenuItem",
+ "forEach": "tables",
+ "props": {
+ "value": "{{table.table_name}}",
+ "text": "{{table.table_name}}"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "component": "Box",
+ "condition": "selectedTable",
+ "props": {
+ "sx": { "mb": 2 }
+ },
+ "children": [
+ {
+ "component": "Button",
+ "props": {
+ "variant": "contained",
+ "startIcon": "Add",
+ "onClick": "openCreateDialog",
+ "text": "Create Index"
+ }
+ }
+ ]
+ },
+ {
+ "component": "Paper",
+ "condition": "indexes && indexes.length > 0",
+ "props": {
+ "sx": { "mt": 2 }
+ },
+ "children": [
+ {
+ "component": "Box",
+ "props": {
+ "sx": { "p": 2 }
+ },
+ "children": [
+ {
+ "component": "Typography",
+ "props": {
+ "variant": "h6",
+ "gutterBottom": true,
+ "text": "Existing Indexes"
+ }
+ },
+ {
+ "component": "List",
+ "children": [
+ {
+ "component": "ListItem",
+ "forEach": "indexes",
+ "children": [
+ {
+ "component": "ListItemIcon",
+ "children": [
+ {
+ "component": "Typography",
+ "props": {
+ "text": "⚡"
+ }
+ }
+ ]
+ },
+ {
+ "component": "ListItemText",
+ "props": {
+ "primary": "{{index.indexname}}",
+ "secondary": "{{index.indexdef}}"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "QueryBuilderTab": {
+ "component": "Box",
+ "children": [
+ {
+ "component": "Typography",
+ "props": {
+ "variant": "h5",
+ "gutterBottom": true,
+ "text": "Query Builder"
+ }
+ },
+ {
+ "component": "Typography",
+ "props": {
+ "variant": "body2",
+ "color": "text.secondary",
+ "gutterBottom": true,
+ "text": "Build and execute SELECT queries visually"
+ }
+ },
+ {
+ "component": "Paper",
+ "props": {
+ "sx": { "p": 2, "mb": 2 }
+ },
+ "children": [
+ {
+ "component": "FormControl",
+ "props": {
+ "fullWidth": true,
+ "sx": { "mb": 2 }
+ },
+ "children": [
+ {
+ "component": "InputLabel",
+ "props": {
+ "text": "Select Table"
+ }
+ },
+ {
+ "component": "Select",
+ "props": {
+ "value": "{{selectedTable}}",
+ "label": "Select Table",
+ "onChange": "handleTableChange"
+ },
+ "children": [
+ {
+ "component": "MenuItem",
+ "forEach": "tables",
+ "props": {
+ "value": "{{table.table_name}}",
+ "text": "{{table.table_name}}"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "component": "Box",
+ "condition": "selectedTable",
+ "children": [
+ {
+ "component": "Typography",
+ "props": {
+ "variant": "subtitle2",
+ "gutterBottom": true,
+ "text": "Select Columns"
+ }
+ },
+ {
+ "component": "Box",
+ "props": {
+ "sx": { "display": "flex", "flexWrap": "wrap", "gap": 1, "mb": 2 }
+ },
+ "children": [
+ {
+ "component": "Chip",
+ "forEach": "availableColumns",
+ "props": {
+ "label": "{{column}}",
+ "onClick": "handleColumnToggle",
+ "color": "{{selectedColumns.includes(column) ? 'primary' : 'default'}}"
+ }
+ }
+ ]
+ },
+ {
+ "component": "Box",
+ "props": {
+ "sx": { "mt": 2, "display": "flex", "gap": 2 }
+ },
+ "children": [
+ {
+ "component": "Button",
+ "props": {
+ "variant": "contained",
+ "startIcon": "PlayArrow",
+ "onClick": "handleExecuteQuery",
+ "disabled": "{{!selectedTable || selectedColumns.length === 0}}",
+ "text": "Execute Query"
+ }
+ },
+ {
+ "component": "Button",
+ "props": {
+ "variant": "outlined",
+ "onClick": "handleReset",
+ "text": "Reset"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "component": "Paper",
+ "condition": "generatedQuery",
+ "props": {
+ "sx": { "p": 2, "mb": 2, "backgroundColor": "#f5f5f5" }
+ },
+ "children": [
+ {
+ "component": "Typography",
+ "props": {
+ "variant": "subtitle2",
+ "gutterBottom": true,
+ "text": "Generated SQL"
+ }
+ },
+ {
+ "component": "Typography",
+ "props": {
+ "variant": "body2",
+ "sx": { "fontFamily": "monospace", "whiteSpace": "pre-wrap" },
+ "text": "{{generatedQuery}}"
+ }
+ }
+ ]
+ },
+ {
+ "component": "Box",
+ "condition": "result",
+ "props": {
+ "sx": { "mt": 2 }
+ },
+ "children": [
+ {
+ "component": "Typography",
+ "props": {
+ "variant": "h6",
+ "gutterBottom": true,
+ "text": "Query Results ({{result.rows?.length || 0}} rows)"
+ }
+ }
+ ]
+ }
+ ]
}
},
"componentProps": {