SqlQueryManager içerisinde Modal SqlDataFiles

This commit is contained in:
Sedat Öztürk 2026-05-04 00:35:04 +03:00
parent 953b4e7d98
commit 61751a48c4
6 changed files with 131 additions and 0 deletions

View file

@ -39,4 +39,9 @@ public interface ISqlObjectManagerAppService : IApplicationService
/// Non-existing files are ignored.
/// </summary>
Task DeleteSqlDataFilesAsync(DeleteSqlDataFilesDto input);
/// <summary>
/// Lists .sql files currently available under DbMigrator Seeds/SqlData.
/// </summary>
Task<List<SqlDataFileDto>> GetSqlDataFilesAsync();
}

View file

@ -0,0 +1,9 @@
using System;
namespace Sozsoft.SqlQueryManager.Application.Contracts;
public class SqlDataFileDto
{
public string FileName { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; }
}

View file

@ -616,6 +616,36 @@ public class SqlObjectManagerAppService : ApplicationService, ISqlObjectManagerA
return Task.CompletedTask;
}
[HttpGet("api/app/sql-object-manager/sql-data-files")]
public Task<List<SqlDataFileDto>> GetSqlDataFilesAsync()
{
ValidateTenantAccess();
try
{
var outputPath = ResolveSqlDataOutputPath();
if (!Directory.Exists(outputPath))
return Task.FromResult(new List<SqlDataFileDto>());
var files = Directory.GetFiles(outputPath, "*.sql", SearchOption.TopDirectoryOnly)
.Select(f => new SqlDataFileDto
{
FileName = Path.GetFileName(f)!,
CreatedAt = File.GetCreationTime(f)
})
.Where(x => !string.IsNullOrWhiteSpace(x.FileName))
.OrderBy(x => x.FileName, StringComparer.OrdinalIgnoreCase)
.ToList();
return Task.FromResult(files);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to list SQL seed files: {Message}", ex.Message);
return Task.FromResult(new List<SqlDataFileDto>());
}
}
private string ResolveSqlDataOutputPath()
{
const string dbMigratorName = "Sozsoft.Platform.DbMigrator";

View file

@ -16821,6 +16821,12 @@
"en": "Edit Table",
"tr": "Tablo Düzenle"
},
{
"resourceName": "Platform",
"key": "App.SqlQueryManager.SqlDataFiles",
"en": "SQL Data Files",
"tr": "SQL Veri Dosyaları"
},
{
"resourceName": "Platform",
"key": "App.SqlQueryManager.EditModeDescription",

View file

@ -68,6 +68,15 @@ export class SqlObjectManagerService {
},
{ apiName: this.apiName, ...config },
)
getSqlDataFiles = (config?: Partial<Config>) =>
apiService.fetchData<{ fileName: string; createdAt: string }[], void>(
{
method: 'GET',
url: '/api/app/sql-object-manager/sql-data-files',
},
{ apiName: this.apiName, ...config },
)
}
export const sqlObjectManagerService = new SqlObjectManagerService()

View file

@ -19,6 +19,7 @@ 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[]
@ -78,6 +79,9 @@ const SqlQueryManager = () => {
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()
@ -852,6 +856,28 @@ GO`,
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(
<Notification type="danger" title={translate('::App.Platform.Error')}>
{error.response?.data?.error?.message ||
translate('::App.Platform.FailedToLoadFiles') ||
'SQL dosya listesi yuklenemedi.'}
</Notification>,
{ placement: 'top-center' },
)
} finally {
setIsLoadingSqlDataFiles(false)
}
}
return (
<Container className="flex flex-col overflow-hidden" style={{ height: 'calc(100vh - 130px)' }}>
<Helmet
@ -891,6 +917,16 @@ GO`,
>
{translate('::ListForms.ListForm.DbMigrate') || 'DB Migrate'}
</Button>
<Button
size="xs"
variant="default"
icon={<FaFolderOpen />}
onClick={handleOpenSqlDataFilesDialog}
className="shadow-sm px-2 py-1"
title={translate('::App.SqlQueryManager.SqlDataFiles') || 'Show SqlData files'}
>
{translate('::App.SqlQueryManager.SqlDataFiles') || 'SqlData Files'}
</Button>
</div>
<div className="flex flex-wrap items-center gap-2 sm:gap-3">
@ -1053,6 +1089,42 @@ GO`,
</p>
</ConfirmDialog>
<Dialog
isOpen={showSqlDataFilesDialog}
onClose={() => setShowSqlDataFilesDialog(false)}
onRequestClose={() => setShowSqlDataFilesDialog(false)}
contentClassName="max-h-[90vh] overflow-hidden"
>
<div className="flex max-h-[72vh] min-h-[320px] flex-col">
<h5 className="mb-4 shrink-0">
{translate('::App.SqlQueryManager.SqlDataFiles') || 'SqlData Files'}
</h5>
{isLoadingSqlDataFiles ? (
<p className="mb-4 text-gray-600 dark:text-gray-400">
{translate('::App.Platform.Loading') || 'Loading...'}
</p>
) : sqlDataFiles.length === 0 ? (
<p className="mb-4 text-gray-600 dark:text-gray-400">
{translate('::App.SqlQueryManager.NoSqlDataFiles') || 'SqlData klasorunde .sql dosyasi bulunamadi.'}
</p>
) : (
<div className="mb-4 h-[70vh] min-h-[220px] overflow-y-auto rounded border border-gray-200 dark:border-gray-700">
<ul className="divide-y divide-gray-200 dark:divide-gray-700">
{sqlDataFiles.map((file) => (
<li key={file.fileName} className="flex items-center justify-between px-3 py-2 text-sm text-gray-700 dark:text-gray-200">
<span>{file.fileName}</span>
<span className="ml-4 shrink-0 text-xs text-gray-400 dark:text-gray-500">
{new Date(file.createdAt).toLocaleString()}
</span>
</li>
))}
</ul>
</div>
)}
</div>
</Dialog>
{/* Template Confirmation Dialog */}
<Dialog
isOpen={showTemplateConfirmDialog}