import { useState, useCallback, useEffect, useRef } from 'react' import { Button, Dialog, Notification, toast } from '@/components/ui' import Container from '@/components/shared/Container' import ConfirmDialog from '@/components/shared/ConfirmDialog' import { getDataSources } from '@/services/data-source.service' import type { DataSourceDto } from '@/proxy/data-source' import type { SqlQueryExecutionResultDto } from '@/proxy/sql-query-manager/models' import { sqlObjectManagerService } from '@/services/sql-query-manager.service' import { FaDatabase, FaPlay, FaFileAlt, FaCopy, FaExclamationTriangle } from 'react-icons/fa' import { FaCheckCircle } from 'react-icons/fa' import { useLocalization } from '@/utils/hooks/useLocalization' import SqlObjectExplorer, { type SqlExplorerSelectedObject } from './SqlObjectExplorer' import SqlEditor, { SqlEditorRef } from './SqlEditor' import SqlResultsGrid from './SqlResultsGrid' import SqlTableDesignerDialog from './SqlTableDesignerDialog' import { Splitter } from '@/components/codeLayout/Splitter' import { Helmet } from 'react-helmet' import { useStoreState } from '@/store/store' import { APP_NAME } from '@/constants/app.constant' import { UiEvalService } from '@/services/UiEvalService' import { FcAcceptDatabase } from 'react-icons/fc' import { FaFolderOpen } from "react-icons/fa" interface SqlManagerState { dataSources: DataSourceDto[] selectedDataSource: string | null editorContent: string isExecuting: boolean executionResult: SqlQueryExecutionResultDto | null showProperties: boolean isDirty: boolean tableColumns: any | null refreshTrigger: number } interface SqlCopyResultItem { targetDataSource: string objectFullName: string objectType: SqlExplorerSelectedObject['objectType'] status: 'success' | 'error' | 'skipped' message: string } const SqlQueryManager = () => { const { translate } = useLocalization() const editorRef = useRef(null) const tenantName = useStoreState((state) => state.locale.currentTenantName) const [state, setState] = useState({ dataSources: [], selectedDataSource: tenantName ?? null, editorContent: '', isExecuting: false, refreshTrigger: 0, executionResult: null, showProperties: false, isDirty: false, tableColumns: null, }) const [showTemplateConfirmDialog, setShowTemplateConfirmDialog] = useState(false) const [pendingTemplate, setPendingTemplate] = useState<{ content: string; type: string } | null>( null, ) const [showTableDesignerDialog, setShowTableDesignerDialog] = useState(false) const [designTableData, setDesignTableData] = useState<{ schemaName: string tableName: string } | null>(null) const [selectedExplorerObjects, setSelectedExplorerObjects] = useState< SqlExplorerSelectedObject[] >([]) const [showDbMigrateConfirmDialog, setShowDbMigrateConfirmDialog] = useState(false) const [showCopyDialog, setShowCopyDialog] = useState(false) const [copyTargetDataSources, setCopyTargetDataSources] = useState([]) const [overwriteIfExists, setOverwriteIfExists] = useState(false) const [isCopyingObjects, setIsCopyingObjects] = useState(false) const [copyResults, setCopyResults] = useState([]) const [showCopyResultDialog, setShowCopyResultDialog] = useState(false) const [copyDialogMode, setCopyDialogMode] = useState<'objects' | 'sql'>('objects') const [sqlScriptForCopy, setSqlScriptForCopy] = useState('') const [showSqlDataFilesDialog, setShowSqlDataFilesDialog] = useState(false) const [isLoadingSqlDataFiles, setIsLoadingSqlDataFiles] = useState(false) const [sqlDataFiles, setSqlDataFiles] = useState<{ fileName: string; createdAt: string }[]>([]) useEffect(() => { loadDataSources() }, []) const loadDataSources = async () => { try { const response = await getDataSources() const items = response.data.items || [] if (items.length > 0) { setState((prev) => ({ ...prev, dataSources: items, selectedDataSource: items[0].code ?? null, })) } } catch (error) { toast.push( {translate('::App.Platform.FailedtoloadDatasources')} , { placement: 'top-center' }, ) } } const handleDataSourceChange = useCallback((dataSource: DataSourceDto) => { setState((prev) => ({ ...prev, selectedDataSource: dataSource.code ?? null, editorContent: '', executionResult: null, isDirty: false, })) }, []) const handleNewTable = useCallback(() => { setDesignTableData(null) setShowTableDesignerDialog(true) }, []) const handleDesignTable = useCallback((schemaName: string, tableName: string) => { setDesignTableData({ schemaName, tableName }) setShowTableDesignerDialog(true) }, []) const handleEditorChange = useCallback((value: string | undefined) => { setState((prev) => ({ ...prev, editorContent: value || '', isDirty: true, })) }, []) const escapeSqlLiteral = (value: string) => value.replace(/'/g, "''") const escapeSqlIdentifier = (value: string) => value.replace(/]/g, ']]') const getSafeFullName = (schemaName: string, objectName: string) => `[${escapeSqlIdentifier(schemaName)}].[${escapeSqlIdentifier(objectName)}]` const buildTableScriptQuery = (schemaName: string, tableName: string) => { const fullName = getSafeFullName(schemaName, tableName) const escapedFullName = escapeSqlLiteral(fullName) return `DECLARE @ObjectId INT = OBJECT_ID(N'${escapedFullName}'); IF @ObjectId IS NULL BEGIN SELECT CAST('' AS NVARCHAR(MAX)) AS Script; RETURN; END; ;WITH cols AS ( SELECT c.column_id, ' ' + QUOTENAME(c.name) + ' ' + CASE WHEN t.name IN ('varchar', 'char', 'varbinary', 'binary') THEN t.name + '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length AS VARCHAR(10)) END + ')' WHEN t.name IN ('nvarchar', 'nchar') THEN t.name + '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length / 2 AS VARCHAR(10)) END + ')' WHEN t.name IN ('decimal', 'numeric') THEN t.name + '(' + CAST(c.precision AS VARCHAR(10)) + ',' + CAST(c.scale AS VARCHAR(10)) + ')' WHEN t.name IN ('datetime2', 'datetimeoffset', 'time') THEN t.name + '(' + CAST(c.scale AS VARCHAR(10)) + ')' ELSE t.name END + CASE WHEN ic.object_id IS NOT NULL THEN ' IDENTITY(' + CAST(ic.seed_value AS VARCHAR(30)) + ',' + CAST(ic.increment_value AS VARCHAR(30)) + ')' ELSE '' END + CASE WHEN c.is_nullable = 1 THEN ' NULL' ELSE ' NOT NULL' END + ISNULL(' DEFAULT ' + dc.definition, '') AS line FROM sys.columns c INNER JOIN sys.types t ON c.user_type_id = t.user_type_id LEFT JOIN sys.identity_columns ic ON c.object_id = ic.object_id AND c.column_id = ic.column_id LEFT JOIN sys.default_constraints dc ON c.default_object_id = dc.object_id WHERE c.object_id = @ObjectId ), pk AS ( SELECT ' CONSTRAINT ' + QUOTENAME(k.name) + ' PRIMARY KEY ' + CASE WHEN i.type = 1 THEN 'CLUSTERED' ELSE 'NONCLUSTERED' END + CHAR(13) + CHAR(10) + ' (' + CHAR(13) + CHAR(10) + ( SELECT ' ' + QUOTENAME(c.name) + CASE WHEN ic.is_descending_key = 1 THEN ' DESC' ELSE ' ASC' END + CHAR(13) + CHAR(10) FROM sys.index_columns ic INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id WHERE ic.object_id = i.object_id AND ic.index_id = i.index_id AND ic.is_included_column = 0 ORDER BY ic.key_ordinal FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') + ' )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]' AS line FROM sys.key_constraints k INNER JOIN sys.indexes i ON k.parent_object_id = i.object_id AND k.unique_index_id = i.index_id WHERE k.parent_object_id = @ObjectId AND k.type = 'PK' ) SELECT 'IF OBJECT_ID(N''${escapedFullName}'', ''U'') IS NULL' + CHAR(13) + CHAR(10) + 'BEGIN' + CHAR(13) + CHAR(10) + ' CREATE TABLE ${fullName}' + CHAR(13) + CHAR(10) + ' (' + CHAR(13) + CHAR(10) + STUFF( ( SELECT ',' + CHAR(13) + CHAR(10) + line FROM cols ORDER BY column_id FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,3,'') + ISNULL( ( SELECT ',' + CHAR(13) + CHAR(10) + line FROM pk ), '' ) + CHAR(13) + CHAR(10) + ' ) ON [PRIMARY]' + CHAR(13) + CHAR(10) + 'END' + CHAR(13) + CHAR(10) + 'GO' AS Script;` } const getTableCreateScript = async (schemaName: string, tableName: string): Promise => { if (!state.selectedDataSource) return '' const result = await sqlObjectManagerService.executeQuery({ queryText: buildTableScriptQuery(schemaName, tableName), dataSourceCode: state.selectedDataSource, }) const firstRow = result.data?.data?.[0] if (!firstRow) return '' return firstRow.Script || firstRow.script || '' } const normalizeNativeDefinitionToCreate = (definition: string) => { if (!definition?.trim()) return '' return definition.replace(/^\s*(?:CREATE|ALTER)\s+(?:OR\s+ALTER\s+)?/i, 'CREATE OR ALTER ') } const buildDropIfExistsScript = (obj: SqlExplorerSelectedObject) => { const fullName = getSafeFullName(obj.schemaName, obj.objectName) if (obj.objectType === 'table') { return `IF OBJECT_ID(N'${escapeSqlLiteral(fullName)}', N'U') IS NOT NULL DROP TABLE ${fullName};` } if (obj.objectType === 'view') { return `IF OBJECT_ID(N'${escapeSqlLiteral(fullName)}', N'V') IS NOT NULL DROP VIEW ${fullName};` } if (obj.objectType === 'procedure') { return `IF OBJECT_ID(N'${escapeSqlLiteral(fullName)}', N'P') IS NOT NULL DROP PROCEDURE ${fullName};` } return `IF OBJECT_ID(N'${escapeSqlLiteral(fullName)}', N'FN') IS NOT NULL OR OBJECT_ID(N'${escapeSqlLiteral(fullName)}', N'IF') IS NOT NULL OR OBJECT_ID(N'${escapeSqlLiteral(fullName)}', N'TF') IS NOT NULL DROP FUNCTION ${fullName};` } const buildObjectExistsCheckQuery = (obj: SqlExplorerSelectedObject) => { const fullName = getSafeFullName(obj.schemaName, obj.objectName) const escapedFullName = escapeSqlLiteral(fullName) if (obj.objectType === 'table') { return `SELECT CASE WHEN OBJECT_ID(N'${escapedFullName}', N'U') IS NOT NULL THEN 1 ELSE 0 END AS ExistsFlag;` } if (obj.objectType === 'view') { return `SELECT CASE WHEN OBJECT_ID(N'${escapedFullName}', N'V') IS NOT NULL THEN 1 ELSE 0 END AS ExistsFlag;` } if (obj.objectType === 'procedure') { return `SELECT CASE WHEN OBJECT_ID(N'${escapedFullName}', N'P') IS NOT NULL THEN 1 ELSE 0 END AS ExistsFlag;` } return `SELECT CASE WHEN OBJECT_ID(N'${escapedFullName}', N'FN') IS NOT NULL OR OBJECT_ID(N'${escapedFullName}', N'IF') IS NOT NULL OR OBJECT_ID(N'${escapedFullName}', N'TF') IS NOT NULL THEN 1 ELSE 0 END AS ExistsFlag;` } const checkObjectExistsInTarget = async ( targetDataSource: string, obj: SqlExplorerSelectedObject, ) => { const result = await sqlObjectManagerService.executeQuery({ queryText: buildObjectExistsCheckQuery(obj), dataSourceCode: targetDataSource, }) const firstRow = result.data?.data?.[0] const flag = firstRow?.ExistsFlag ?? firstRow?.existsFlag ?? 0 return Number(flag) === 1 } const getTemplateContent = (templateType: string): string => { const templates: Record = { select: `-- Basic SELECT query SELECT Column1, Column2, Column3 FROM TableName WHERE -- Add your conditions Column1 = 'value' AND IsActive = 1 ORDER BY Column1 ASC;`, insert: `-- Basic INSERT query INSERT INTO TableName (Column1, Column2, Column3) VALUES ('Value1', 'Value2', 'Value3');`, update: `-- Basic UPDATE query UPDATE TableName SET Column1 = 'NewValue1', Column2 = 'NewValue2' WHERE -- Add your conditions Id = 1;`, delete: `-- Basic DELETE query DELETE FROM TableName WHERE -- Add your conditions Id = 1;`, 'create-procedure': `-- Create Stored Procedure CREATE PROCEDURE [dbo].[ProcedureName] @Parameter1 INT, @Parameter2 NVARCHAR(100) AS BEGIN SET NOCOUNT ON; -- Add your logic here SELECT Column1, Column2 FROM TableName WHERE Column1 = @Parameter1 AND Column2 = @Parameter2; END GO`, 'create-view': `-- Create View CREATE VIEW [dbo].[ViewName] AS SELECT t1.Column1, t1.Column2, t2.Column3 FROM TableName1 t1 INNER JOIN TableName2 t2 ON t1.Id = t2.TableName1Id WHERE t1.IsActive = 1; GO`, 'create-scalar-function': `-- Create Scalar Function CREATE FUNCTION [dbo].[ScalarFunctionName] ( @Parameter1 INT, @Parameter2 NVARCHAR(100) ) RETURNS NVARCHAR(200) AS BEGIN DECLARE @Result NVARCHAR(200); -- Add your logic here SELECT @Result = Column1 + ' ' + @Parameter2 FROM TableName WHERE Id = @Parameter1; RETURN @Result; END GO`, 'create-table-function': `-- Create Table-Valued Function CREATE FUNCTION [dbo].[TableFunctionName] ( @Parameter1 INT, @Parameter2 NVARCHAR(100) ) RETURNS TABLE AS RETURN ( SELECT t.Column1, t.Column2, t.Column3, t.Column4 FROM TableName t WHERE t.Id = @Parameter1 AND t.Column2 LIKE '%' + @Parameter2 + '%' AND t.IsActive = 1 ) GO`, } return templates[templateType] || templates['select'] } const applyTemplate = useCallback((templateContent: string) => { setState((prev) => ({ ...prev, editorContent: templateContent, executionResult: null, isDirty: false, })) }, []) const handleUseTemplateFromDialog = useCallback( (templateContent: string, templateType: string) => { // Check if editor has content const hasUserContent = state.editorContent?.trim() && state.isDirty if (hasUserContent) { // Ask for confirmation setPendingTemplate({ content: templateContent, type: templateType }) setShowTemplateConfirmDialog(true) } else { // Apply template directly applyTemplate(templateContent) } }, [state.editorContent, state.isDirty, applyTemplate], ) const handleTemplateSelect = useCallback( (template: string, templateType: string) => { // If template is already provided (e.g., from table click), use it const templateContent = template || getTemplateContent(templateType) // Check if editor has content and it's not from a previous template const hasUserContent = state.editorContent?.trim() && state.isDirty if (hasUserContent) { // Ask for confirmation setPendingTemplate({ content: templateContent, type: templateType }) setShowTemplateConfirmDialog(true) } else { // Apply template directly applyTemplate(templateContent) } }, [translate, state.editorContent, state.isDirty, applyTemplate], ) const handleConfirmTemplateReplace = useCallback(() => { if (pendingTemplate) { applyTemplate(pendingTemplate.content) } setShowTemplateConfirmDialog(false) setPendingTemplate(null) }, [pendingTemplate, applyTemplate]) const handleCancelTemplateReplace = useCallback(() => { setShowTemplateConfirmDialog(false) setPendingTemplate(null) }, []) const handleNewQuery = useCallback(() => { setState((prev) => ({ ...prev, editorContent: '', executionResult: null, tableColumns: null, isDirty: false, })) }, []) const handleExecute = async () => { if (!state.selectedDataSource) { toast.push( {translate('::App.Platform.PleaseSelectDataSource')} , { placement: 'top-center' }, ) return } // Seçili text varsa onu, yoksa tüm editor içeriğini kullan const selectedText = editorRef.current?.getSelectedText() || '' const queryToExecute = selectedText.trim() || state.editorContent?.trim() || '' if (!queryToExecute) { toast.push( {translate('::App.Platform.PleaseEnterQuery')} , { placement: 'top-center' }, ) return } // Seçili metni koru const savedSelection = editorRef.current?.preserveSelection() setState((prev) => ({ ...prev, isExecuting: true, executionResult: null, tableColumns: null })) try { const result = await sqlObjectManagerService.executeQuery({ queryText: queryToExecute, dataSourceCode: state.selectedDataSource || '', }) setState((prev) => ({ ...prev, executionResult: result.data, isExecuting: false, tableColumns: null, })) // Seçili metni geri yükle setTimeout(() => { if (savedSelection) { editorRef.current?.restoreSelection(savedSelection) } }, 100) } catch (error: any) { setState((prev) => ({ ...prev, isExecuting: false })) // Hata durumunda da seçili metni geri yükle setTimeout(() => { if (savedSelection) { editorRef.current?.restoreSelection(savedSelection) } }, 100) toast.push( {error.response?.data?.error?.message || translate('::App.Platform.FailedToExecuteQuery')} , { placement: 'top-center' }, ) } } const handleViewDefinition = async (schemaName: string, objectName: string) => { if (!state.selectedDataSource) return try { const result = await sqlObjectManagerService.getNativeObjectDefinition( state.selectedDataSource, schemaName, objectName, ) if (result.data) { const definition = normalizeNativeDefinitionToCreate(result.data) setState((prev) => ({ ...prev, editorContent: definition, executionResult: null, tableColumns: null, isDirty: false, })) } } catch (error: any) { toast.push( {error.response?.data?.error?.message || translate('::App.Platform.FailedToLoadDefinition')} , { placement: 'top-center' }, ) } } const handleGenerateTableScript = async (schemaName: string, tableName: string) => { if (!state.selectedDataSource) return try { const script = await getTableCreateScript(schemaName, tableName) if (!script?.trim()) { toast.push( {translate('::App.Platform.ScriptNotGenerated') || 'Tablo scripti olusturulamadi.'} , { placement: 'top-center' }, ) return } setState((prev) => ({ ...prev, editorContent: script, executionResult: null, tableColumns: null, isDirty: false, })) toast.push( {'Script Query Editor alanina yuklendi.'} , { placement: 'top-center' }, ) } catch (error: any) { toast.push( {error.response?.data?.error?.message || 'Tablo scripti olusturulurken hata olustu.'} , { placement: 'top-center' }, ) } } const handleOpenCopyDialog = () => { if (!state.selectedDataSource) return setCopyDialogMode('objects') setCopyTargetDataSources([]) setOverwriteIfExists(false) setSqlScriptForCopy('') setShowCopyDialog(true) // Eğer seçili obje yoksa uyarı göster if (selectedExplorerObjects.length === 0) { // SQL mode'da obje seçimi zorunlu değil, object mode'da zorunlu // Bu uyarı sadece object mode'da gerekirse return } } const handleCopyObjects = async () => { if ( !state.selectedDataSource || selectedExplorerObjects.length === 0 || copyTargetDataSources.length === 0 ) { return } setIsCopyingObjects(true) const results: SqlCopyResultItem[] = [] try { const scriptsByObjectId = new Map() for (const obj of selectedExplorerObjects) { let createScript = '' if (obj.objectType === 'table') { createScript = await getTableCreateScript(obj.schemaName, obj.objectName) } else { const response = await sqlObjectManagerService.getNativeObjectDefinition( state.selectedDataSource, obj.schemaName, obj.objectName, ) createScript = normalizeNativeDefinitionToCreate(response.data || '') } if (!createScript?.trim()) { results.push({ targetDataSource: state.selectedDataSource, objectFullName: obj.fullName, objectType: obj.objectType, status: 'error', message: translate('::App.Platform.CreateScriptFailed'), }) continue } scriptsByObjectId.set(obj.id, createScript) } for (const targetDataSource of copyTargetDataSources) { for (const obj of selectedExplorerObjects) { const createScript = scriptsByObjectId.get(obj.id) if (!createScript) continue if (!overwriteIfExists) { const exists = await checkObjectExistsInTarget(targetDataSource, obj) if (exists) { results.push({ targetDataSource, objectFullName: obj.fullName, objectType: obj.objectType, status: 'skipped', message: translate('::App.SqlQueryManager.SkippedDescription'), }) continue } } const command = overwriteIfExists ? `${buildDropIfExistsScript(obj)}\n${createScript}` : createScript try { await sqlObjectManagerService.executeQuery({ queryText: command, dataSourceCode: targetDataSource, }) results.push({ targetDataSource, objectFullName: obj.fullName, objectType: obj.objectType, status: 'success', message: translate('::App.Platform.CopyCompleted'), }) } catch (error: any) { results.push({ targetDataSource, objectFullName: obj.fullName, objectType: obj.objectType, status: 'error', message: error.response?.data?.error?.message || 'Kopyalama basarisiz.', }) } } } const successCount = results.filter((x) => x.status === 'success').length const errorCount = results.filter((x) => x.status === 'error').length const skippedCount = results.filter((x) => x.status === 'skipped').length const notificationType = errorCount > 0 ? 'warning' : 'success' toast.push( 0 ? translate('::App.Platform.Warning') : translate('::App.Platform.Success') } > {translate('::App.Platform.CopyCompleted') || `translate('::App.Platform.Successful'): ${successCount}, ${translate('::App.Platform.Error')}: ${errorCount}, ${translate('::App.Platform.Skipped')}: ${skippedCount}`} , { placement: 'top-center' }, ) setCopyResults(results) setShowCopyResultDialog(true) setShowCopyDialog(false) } finally { setIsCopyingObjects(false) } } const handleExecuteDirectSql = async () => { if (!sqlScriptForCopy?.trim()) { toast.push( {translate('::App.Platform.PleaseEnterQuery')} , { placement: 'top-center' }, ) return } if (copyTargetDataSources.length === 0) { toast.push( {translate('::App.Platform.PleaseSelectAtLeastOneTarget')} , { placement: 'top-center' }, ) return } setIsCopyingObjects(true) const results: SqlCopyResultItem[] = [] try { for (const targetDataSource of copyTargetDataSources) { try { await sqlObjectManagerService.executeQuery({ queryText: sqlScriptForCopy, dataSourceCode: targetDataSource, }) results.push({ targetDataSource, objectFullName: 'SQL Script', objectType: 'script' as any, status: 'success', message: 'Basariyla calistirildi.', }) } catch (error: any) { results.push({ targetDataSource, objectFullName: 'SQL Script', objectType: 'script' as any, status: 'error', message: error.response?.data?.error?.message || 'Calistirma basarisiz.', }) } } const successCount = results.filter((x) => x.status === 'success').length const errorCount = results.filter((x) => x.status === 'error').length const notificationType = errorCount > 0 ? 'warning' : 'success' toast.push( 0 ? translate('::App.Platform.Warning') : translate('::App.Platform.Success') } > {translate('::App.Platform.ExecutionCompleted') || `translate('::App.Platform.Successful'): ${successCount}, ${translate('::App.Platform.Error')}: ${errorCount}`} , { placement: 'top-center' }, ) setCopyResults(results) setShowCopyResultDialog(true) setShowCopyDialog(false) } finally { setIsCopyingObjects(false) } } const availableTargetDataSourceCodes = state.dataSources .filter((d) => d.code && d.code !== state.selectedDataSource) .map((d) => d.code || '') const allTargetsSelected = availableTargetDataSourceCodes.length > 0 && availableTargetDataSourceCodes.every((code) => copyTargetDataSources.includes(code)) const handleToggleSelectAllTargets = (checked: boolean) => { if (checked) { setCopyTargetDataSources(availableTargetDataSourceCodes) return } setCopyTargetDataSources([]) } const copySuccessCount = copyResults.filter((x) => x.status === 'success').length const copyErrorCount = copyResults.filter((x) => x.status === 'error').length const copySkippedCount = copyResults.filter((x) => x.status === 'skipped').length const handleOpenSqlDataFilesDialog = async () => { setShowSqlDataFilesDialog(true) setIsLoadingSqlDataFiles(true) try { const response = await sqlObjectManagerService.getSqlDataFiles() setSqlDataFiles(response.data || []) } catch (error: any) { setSqlDataFiles([]) toast.push( {error.response?.data?.error?.message || translate('::App.Platform.FailedToLoadFiles') || 'SQL dosya listesi yuklenemedi.'} , { placement: 'top-center' }, ) } finally { setIsLoadingSqlDataFiles(false) } } return (
{/* Toolbar */}
{/* Main Content Area */}
{/* Left Panel - Object Explorer */}
{translate('::App.Platform.ObjectExplorer')}
{/* Center Panel - Editor and Results */}
{state.executionResult || state.tableColumns ? (
{translate('::App.Platform.QueryEditor')}
{state.executionResult?.message || state.tableColumns?.message || translate('::App.Platform.QueryExecutedSuccessfully')}
{translate('::App.Platform.Rows')}:{' '} {state.executionResult?.rowsAffected || state.executionResult?.data?.length || state.tableColumns?.rowsAffected || 0} {state.executionResult && ( {translate('::App.Platform.Time')}:{' '} {state.executionResult.executionTimeMs}ms )}
) : (
{translate('::App.Platform.QueryEditor')}
)}
{/* DB Migrate Confirmation Dialog */} setShowDbMigrateConfirmDialog(false)} onClose={() => setShowDbMigrateConfirmDialog(false)} onConfirm={() => { setShowDbMigrateConfirmDialog(false) UiEvalService.ApiDbMigrate() }} >

{translate('::App.DbMigrate.ConfirmMessage') || 'Are you sure you want to start the database migration process?'}

setShowSqlDataFilesDialog(false)} onRequestClose={() => setShowSqlDataFilesDialog(false)} contentClassName="max-h-[90vh] overflow-hidden" >
{translate('::App.SqlQueryManager.SqlDataFiles') || 'SqlData Files'}
{isLoadingSqlDataFiles ? (

{translate('::App.Platform.Loading') || 'Loading...'}

) : sqlDataFiles.length === 0 ? (

{translate('::App.SqlQueryManager.NoSqlDataFiles') || 'SqlData klasorunde .sql dosyasi bulunamadi.'}

) : (
    {sqlDataFiles.map((file) => (
  • {file.fileName} {new Date(file.createdAt).toLocaleString()}
  • ))}
)}
{/* Template Confirmation Dialog */}
{translate('::App.Platform.ConfirmTemplateReplace')}

{translate('::App.Platform.TemplateReplaceWarning')}

{/* Table Designer Dialog */} { setShowTableDesignerDialog(false) setDesignTableData(null) }} dataSource={state.selectedDataSource ?? ''} initialTableData={designTableData} onDeployed={() => { setState((prev) => ({ ...prev, refreshTrigger: prev.refreshTrigger + 1 })) }} /> !isCopyingObjects && setShowCopyDialog(false)} onRequestClose={() => !isCopyingObjects && setShowCopyDialog(false)} width={1050} >
{translate('::App.Platform.CopySelectedObjects')}
{/* Mode Tabs */}
{copyDialogMode === 'objects' ? ( <> {/* Objects Mode */}

{translate('::App.Platform.SourceDataSource')}:{' '} {state.selectedDataSource}

{selectedExplorerObjects.length === 0 ? (

{translate('::App.Platform.NoObjectSelected') || 'Secili nesne yok. Lutfen Explorer alanından bir nesne secin.'}

) : ( selectedExplorerObjects.map((obj) => (
{obj.objectType.toUpperCase()} - {obj.fullName}
)) )}
{translate('::App.Platform.TargetDataSources')}
{availableTargetDataSourceCodes.map((code) => { const checked = copyTargetDataSources.includes(code) return ( ) })}
) : ( <> {/* SQL Mode */}

{translate('::App.Platform.SourceDataSource')}:{' '} {state.selectedDataSource}

setSqlScriptForCopy(value || '')} readOnly={isCopyingObjects} />
{translate('::App.Platform.TargetDataSources')}
{availableTargetDataSourceCodes.map((code) => { const checked = copyTargetDataSources.includes(code) return ( ) })}
)}
setShowCopyResultDialog(false)} onRequestClose={() => setShowCopyResultDialog(false)} width={1050} >
{translate('::App.Platform.Results') || 'Kopyalama Sonuc Detaylari'}
{translate('::App.Platform.Success')}: {copySuccessCount}
{translate('::App.Platform.Skipped')}: {copySkippedCount}
{translate('::App.Platform.Error')}: {copyErrorCount}
{copyResults.map((row, idx) => { const isError = row.status === 'error' const isSkipped = row.status === 'skipped' const cardClass = isError ? 'border-red-200 bg-red-50/60 dark:bg-red-900/20' : isSkipped ? 'border-amber-200 bg-amber-50/60 dark:bg-amber-900/20' : 'border-gray-200 bg-white dark:bg-gray-800' return (
{row.objectType} {row.status === 'success' && ( {translate('::App.Platform.Success')} )} {row.status === 'error' && ( {translate('::App.Platform.Error')} )} {row.status === 'skipped' && ( {translate('::App.Platform.Skipped')} )}
{row.objectFullName}
Hedef: {row.targetDataSource}
{row.message}
) })} {copyResults.length === 0 && (
{translate('::App.Platform.NoResults')}
)}
{copyResults.map((row, idx) => { const isError = row.status === 'error' const isSkipped = row.status === 'skipped' const rowClass = isError ? 'bg-red-50/60 dark:bg-red-900/20' : isSkipped ? 'bg-amber-50/60 dark:bg-amber-900/20' : idx % 2 === 0 ? 'bg-white dark:bg-gray-800' : 'bg-gray-50/40 dark:bg-gray-800/70' return ( ) })} {copyResults.length === 0 && ( )}
{translate('::App.Platform.Status')} {translate('::App.Platform.Object')} {translate('::App.Platform.Type')} {translate('::App.Platform.Target')} {translate('::App.Platform.Message')}
{row.status === 'success' && ( {translate('::App.Platform.Success')} )} {row.status === 'error' && ( {translate('::App.Platform.Error')} )} {row.status === 'skipped' && ( {translate('::App.Platform.Skipped')} )} {row.objectFullName} {row.objectType} {row.targetDataSource} {row.message}
{translate('::App.Platform.NoResults')}
) } export default SqlQueryManager