Sql Query Manager güncellemeleri

This commit is contained in:
Sedat Öztürk 2026-03-01 20:40:25 +03:00
parent 79c72430ab
commit a746fea95e
5 changed files with 1841 additions and 22 deletions

View file

@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace Sozsoft.Platform.Migrations
{
[DbContext(typeof(PlatformDbContext))]
[Migration("20260225082054_Initial")]
[Migration("20260301173343_Initial")]
partial class Initial
{
/// <inheritdoc />

View file

@ -13,7 +13,7 @@ import type {
} from '@/proxy/sql-query-manager/models'
import { SqlObjectType } from '@/proxy/sql-query-manager/models'
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
import { FaDatabase, FaPlay, FaSave, FaSyncAlt, FaCloudUploadAlt, FaCode } from 'react-icons/fa'
import { FaDatabase, FaPlay, FaSave, FaCloudUploadAlt, FaCode, FaTable } from 'react-icons/fa'
import { FaCheckCircle } from 'react-icons/fa'
import { useLocalization } from '@/utils/hooks/useLocalization'
import SqlObjectExplorer from './components/SqlObjectExplorer'
@ -21,6 +21,7 @@ import SqlEditor, { SqlEditorRef } from './components/SqlEditor'
import SqlResultsGrid from './components/SqlResultsGrid'
import SqlObjectProperties from './components/SqlObjectProperties'
import TemplateDialog from './components/TemplateDialog'
import TableDesignerDialog from './components/TableDesignerDialog'
import { Splitter } from '@/components/codeLayout/Splitter'
import { Helmet } from 'react-helmet'
import { useStoreState } from '@/store/store'
@ -72,11 +73,18 @@ const SqlQueryManager = () => {
isExistingObject: false,
})
const [showTemplateDialog, setShowTemplateDialog] = useState(false)
const [showTableDesignerDialog, setShowTableDesignerDialog] = useState(false)
const [designTableData, setDesignTableData] = useState<{ schemaName: string; tableName: string } | null>(null)
const [showTemplateConfirmDialog, setShowTemplateConfirmDialog] = useState(false)
const [pendingTemplate, setPendingTemplate] = useState<{ content: string; type: string } | null>(
null,
)
const handleDesignTable = (schemaName: string, tableName: string) => {
setDesignTableData({ schemaName, tableName })
setShowTableDesignerDialog(true)
}
useEffect(() => {
loadDataSources()
}, [])
@ -802,16 +810,6 @@ GO`,
</div>
<div className="flex items-center gap-3">
<Button
size="sm"
variant="solid"
color="orange-500"
icon={<FaCode />}
onClick={() => setShowTemplateDialog(true)}
className="shadow-sm"
>
{translate('::App.Platform.Templates')}
</Button>
<Button
size="sm"
variant="solid"
@ -880,6 +878,11 @@ GO`,
selectedObject={state.selectedObject}
onTemplateSelect={handleTemplateSelect}
onShowTableColumns={handleShowTableColumns}
onDesignTable={handleDesignTable}
onNewTable={() => {
setDesignTableData(null)
setShowTableDesignerDialog(true)
}}
refreshTrigger={state.refreshTrigger}
/>
</div>
@ -972,6 +975,20 @@ GO`,
</div>
</div>
{/* Table Designer Dialog */}
<TableDesignerDialog
isOpen={showTableDesignerDialog}
onClose={() => {
setShowTableDesignerDialog(false)
setDesignTableData(null)
}}
dataSource={state.selectedDataSource}
initialTableData={designTableData}
onDeployed={() => {
setState((prev) => ({ ...prev, refreshTrigger: prev.refreshTrigger + 1 }))
}}
/>
{/* Template Dialog */}
<TemplateDialog
isOpen={showTemplateDialog}

View file

@ -11,6 +11,7 @@ import {
FaEdit,
FaTrash,
FaTable,
FaPlus,
} from 'react-icons/fa'
import type {
SqlFunctionDto,
@ -42,6 +43,8 @@ interface SqlObjectExplorerProps {
selectedObject: SqlObject | null
onTemplateSelect?: (template: string, templateType: string) => void
onShowTableColumns?: (schemaName: string, tableName: string) => void
onDesignTable?: (schemaName: string, tableName: string) => void
onNewTable?: () => void
refreshTrigger?: number
}
@ -51,6 +54,8 @@ const SqlObjectExplorer = ({
selectedObject,
onTemplateSelect,
onShowTableColumns,
onDesignTable,
onNewTable,
refreshTrigger,
}: SqlObjectExplorerProps) => {
const { translate } = useLocalization()
@ -506,6 +511,22 @@ const SqlObjectExplorer = ({
className="fixed z-50 bg-white dark:bg-gray-800 shadow-lg rounded border border-gray-200 dark:border-gray-700 py-1"
style={{ top: contextMenu.y, left: contextMenu.x }}
>
{contextMenu.node?.id?.startsWith('table-') && (
<button
className="w-full px-4 py-2 text-left hover:bg-gray-100 dark:hover:bg-gray-700 text-sm"
onClick={() => {
const tableData = contextMenu.node?.data as any
if (tableData && onDesignTable) {
onDesignTable(tableData.schemaName, tableData.tableName)
}
setContextMenu({ show: false, x: 0, y: 0, node: null })
}}
>
<FaTable className="inline mr-2 text-teal-600" />
Design
</button>
)}
{contextMenu.node?.type === 'object' && contextMenu.node?.objectType && contextMenu.node?.data?.isCustom && (
<>
<button
@ -547,6 +568,83 @@ const SqlObjectExplorer = ({
)}
{contextMenu.node?.type === 'folder' && (
<>
{/* Tables folder */}
{contextMenu.node.id === 'tables' && (
<button
className="w-full px-4 py-2 text-left hover:bg-gray-100 dark:hover:bg-gray-700 text-sm"
onClick={() => {
onNewTable?.()
setContextMenu({ show: false, x: 0, y: 0, node: null })
}}
>
<FaPlus className="inline mr-2 text-teal-600" />
New Table
</button>
)}
{/* Stored Procedures folder */}
{contextMenu.node.id === 'procedures' && (
<button
className="w-full px-4 py-2 text-left hover:bg-gray-100 dark:hover:bg-gray-700 text-sm"
onClick={() => {
onTemplateSelect?.('', 'create-procedure')
setContextMenu({ show: false, x: 0, y: 0, node: null })
}}
>
<FaPlus className="inline mr-2 text-green-600" />
New Stored Procedure
</button>
)}
{/* Views folder */}
{contextMenu.node.id === 'views' && (
<button
className="w-full px-4 py-2 text-left hover:bg-gray-100 dark:hover:bg-gray-700 text-sm"
onClick={() => {
onTemplateSelect?.('', 'create-view')
setContextMenu({ show: false, x: 0, y: 0, node: null })
}}
>
<FaPlus className="inline mr-2 text-purple-600" />
New View
</button>
)}
{/* Functions folder */}
{contextMenu.node.id === 'functions' && (
<button
className="w-full px-4 py-2 text-left hover:bg-gray-100 dark:hover:bg-gray-700 text-sm"
onClick={() => {
onTemplateSelect?.('', 'create-scalar-function')
setContextMenu({ show: false, x: 0, y: 0, node: null })
}}
>
<FaPlus className="inline mr-2 text-red-500" />
New Function
</button>
)}
{/* Queries folder */}
{contextMenu.node.id === 'queries' && (
<button
className="w-full px-4 py-2 text-left hover:bg-gray-100 dark:hover:bg-gray-700 text-sm"
onClick={() => {
onTemplateSelect?.('', 'select')
setContextMenu({ show: false, x: 0, y: 0, node: null })
}}
>
<FaPlus className="inline mr-2 text-yellow-600" />
New Query
</button>
)}
{/* Separator */}
{contextMenu.node.id !== 'root' && (
<div className="my-1 border-t border-gray-100 dark:border-gray-700" />
)}
{/* Refresh — all folders */}
<button
className="w-full px-4 py-2 text-left hover:bg-gray-100 dark:hover:bg-gray-700 text-sm"
onClick={() => {
@ -557,6 +655,7 @@ const SqlObjectExplorer = ({
<FaSyncAlt className="inline mr-2" />
{translate('::App.Platform.Refresh')}
</button>
</>
)}
</div>
</>

File diff suppressed because it is too large Load diff