Sql Query Manager .sql dosyasının Preview özelliği
This commit is contained in:
parent
a3e66081e9
commit
f5b32d5a6b
9 changed files with 107 additions and 13 deletions
|
|
@ -46,6 +46,11 @@ public interface ISqlObjectManagerAppService : IApplicationService
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<List<SqlDataFileDto>> GetSqlDataFilesAsync(string dataDirectoryName = "SqlData", string relativePath = "");
|
Task<List<SqlDataFileDto>> GetSqlDataFilesAsync(string dataDirectoryName = "SqlData", string relativePath = "");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads a .sql seed file content from the selected data directory.
|
||||||
|
/// </summary>
|
||||||
|
Task<string> GetSqlDataFileContentAsync(string dataDirectoryName = "SqlData", string relativePath = "");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Moves a SQL seed file between the selected data directory root and HostData.
|
/// Moves a SQL seed file between the selected data directory root and HostData.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1005,6 +1005,25 @@ FROM (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("api/app/sql-object-manager/sql-data-file-content")]
|
||||||
|
public async Task<string> GetSqlDataFileContentAsync(
|
||||||
|
[FromQuery] string dataDirectoryName = "SqlData",
|
||||||
|
[FromQuery] string relativePath = "")
|
||||||
|
{
|
||||||
|
ValidateTenantAccess();
|
||||||
|
|
||||||
|
var rootPath = ResolveSqlDataOutputPath(dataDirectoryName);
|
||||||
|
var filePath = ResolveSqlDataChildPath(rootPath, relativePath);
|
||||||
|
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
throw new Volo.Abp.UserFriendlyException("SQL seed file was not found.");
|
||||||
|
|
||||||
|
if (!string.Equals(Path.GetExtension(filePath), ".sql", StringComparison.OrdinalIgnoreCase))
|
||||||
|
throw new Volo.Abp.UserFriendlyException("Only .sql files can be previewed.");
|
||||||
|
|
||||||
|
return await File.ReadAllTextAsync(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost("api/app/sql-object-manager/move-sql-data-file")]
|
[HttpPost("api/app/sql-object-manager/move-sql-data-file")]
|
||||||
public Task MoveSqlDataFileAsync(MoveSqlDataFileDto input)
|
public Task MoveSqlDataFileAsync(MoveSqlDataFileDto input)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17774,6 +17774,12 @@
|
||||||
"en": "Select key column",
|
"en": "Select key column",
|
||||||
"tr": "Anahtar sütunu seç"
|
"tr": "Anahtar sütunu seç"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.SqlQueryManager.ScriptLoadedToEditor",
|
||||||
|
"en": "Script loaded to editor",
|
||||||
|
"tr": "Komut dosyası düzenleyiciye yüklendi"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.SqlQueryManager.IndexKeys",
|
"key": "App.SqlQueryManager.IndexKeys",
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,16 @@ export class SqlObjectManagerService {
|
||||||
{ apiName: this.apiName, ...config },
|
{ apiName: this.apiName, ...config },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
getSqlDataFileContent = (dataDirectoryName = 'SqlData', relativePath: string, config?: Partial<Config>) =>
|
||||||
|
apiService.fetchData<string, void>(
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
url: '/api/app/sql-object-manager/sql-data-file-content',
|
||||||
|
params: { dataDirectoryName, relativePath },
|
||||||
|
},
|
||||||
|
{ apiName: this.apiName, ...config },
|
||||||
|
)
|
||||||
|
|
||||||
moveSqlDataFile = (
|
moveSqlDataFile = (
|
||||||
input: { dataDirectoryName: string; sourceRelativePath: string; targetRelativePath: string },
|
input: { dataDirectoryName: string; sourceRelativePath: string; targetRelativePath: string },
|
||||||
config?: Partial<Config>,
|
config?: Partial<Config>,
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import {
|
||||||
FaExclamationTriangle,
|
FaExclamationTriangle,
|
||||||
FaArrowLeft,
|
FaArrowLeft,
|
||||||
FaArrowRight,
|
FaArrowRight,
|
||||||
|
FaEye,
|
||||||
} from 'react-icons/fa'
|
} from 'react-icons/fa'
|
||||||
import { FaCheckCircle } from 'react-icons/fa'
|
import { FaCheckCircle } from 'react-icons/fa'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
|
@ -100,6 +101,7 @@ const SqlQueryManager = () => {
|
||||||
const [showSqlDataFilesDialog, setShowSqlDataFilesDialog] = useState(false)
|
const [showSqlDataFilesDialog, setShowSqlDataFilesDialog] = useState(false)
|
||||||
const [isLoadingSqlDataFiles, setIsLoadingSqlDataFiles] = useState(false)
|
const [isLoadingSqlDataFiles, setIsLoadingSqlDataFiles] = useState(false)
|
||||||
const [isMovingSqlDataFile, setIsMovingSqlDataFile] = useState(false)
|
const [isMovingSqlDataFile, setIsMovingSqlDataFile] = useState(false)
|
||||||
|
const [isPreviewingSqlDataFile, setIsPreviewingSqlDataFile] = useState(false)
|
||||||
const [sqlDataRootFiles, setSqlDataRootFiles] = useState<SqlDataExplorerEntry[]>([])
|
const [sqlDataRootFiles, setSqlDataRootFiles] = useState<SqlDataExplorerEntry[]>([])
|
||||||
const [sqlDataHostFiles, setSqlDataHostFiles] = useState<SqlDataExplorerEntry[]>([])
|
const [sqlDataHostFiles, setSqlDataHostFiles] = useState<SqlDataExplorerEntry[]>([])
|
||||||
const [selectedRootSqlDataFiles, setSelectedRootSqlDataFiles] = useState<string[]>([])
|
const [selectedRootSqlDataFiles, setSelectedRootSqlDataFiles] = useState<string[]>([])
|
||||||
|
|
@ -1118,6 +1120,47 @@ GO`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handlePreviewSqlDataFile = async (file: SqlDataExplorerEntry) => {
|
||||||
|
if (!file.relativePath || isPreviewingSqlDataFile) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsPreviewingSqlDataFile(true)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await sqlObjectManagerService.getSqlDataFileContent(
|
||||||
|
sqlDataDirectoryName,
|
||||||
|
file.relativePath,
|
||||||
|
)
|
||||||
|
|
||||||
|
setState((prev) => ({
|
||||||
|
...prev,
|
||||||
|
editorContent: response.data || '',
|
||||||
|
executionResult: null,
|
||||||
|
tableColumns: null,
|
||||||
|
isDirty: false,
|
||||||
|
}))
|
||||||
|
setShowSqlDataFilesDialog(false)
|
||||||
|
|
||||||
|
toast.push(
|
||||||
|
<Notification type="success" title={translate('::App.Platform.Success')}>
|
||||||
|
{translate('::App.SqlQueryManager.ScriptLoadedToEditor') ||
|
||||||
|
'SQL dosyasi Query Editor icine yuklendi.'}
|
||||||
|
</Notification>,
|
||||||
|
{ placement: 'top-center' },
|
||||||
|
)
|
||||||
|
} catch (error: any) {
|
||||||
|
toast.push(
|
||||||
|
<Notification type="danger" title={translate('::App.Platform.Error')}>
|
||||||
|
{error.response?.data?.error?.message || 'SQL dosyasi okunamadi.'}
|
||||||
|
</Notification>,
|
||||||
|
{ placement: 'top-center' },
|
||||||
|
)
|
||||||
|
} finally {
|
||||||
|
setIsPreviewingSqlDataFile(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const renderSqlDataPane = (
|
const renderSqlDataPane = (
|
||||||
title: string,
|
title: string,
|
||||||
files: SqlDataExplorerEntry[],
|
files: SqlDataExplorerEntry[],
|
||||||
|
|
@ -1154,28 +1197,39 @@ GO`,
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li key={file.relativePath || file.fileName}>
|
<li key={file.relativePath || file.fileName}>
|
||||||
<label
|
<div
|
||||||
className={`flex cursor-pointer items-center gap-3 px-3 py-2 text-xs ${
|
className={`flex cursor-pointer items-center gap-3 px-3 py-2 text-xs ${
|
||||||
selected
|
selected
|
||||||
? 'bg-blue-50 text-blue-700 dark:bg-blue-950/40 dark:text-blue-200'
|
? 'bg-blue-50 text-blue-700 dark:bg-blue-950/40 dark:text-blue-200'
|
||||||
: 'text-gray-700 hover:bg-gray-50 dark:text-gray-200 dark:hover:bg-gray-800'
|
: 'text-gray-700 hover:bg-gray-50 dark:text-gray-200 dark:hover:bg-gray-800'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<input
|
<label className="flex min-w-0 flex-1 cursor-pointer items-center gap-3">
|
||||||
type="checkbox"
|
<input
|
||||||
className="h-4 w-4 shrink-0"
|
type="checkbox"
|
||||||
checked={selected}
|
className="h-4 w-4 shrink-0"
|
||||||
disabled={isMovingSqlDataFile}
|
checked={selected}
|
||||||
onChange={() =>
|
disabled={isMovingSqlDataFile || isPreviewingSqlDataFile}
|
||||||
toggleSqlDataFileSelection(setSelectedFiles, file.relativePath)
|
onChange={() =>
|
||||||
}
|
toggleSqlDataFileSelection(setSelectedFiles, file.relativePath)
|
||||||
/>
|
}
|
||||||
<FaFileAlt className="shrink-0 text-gray-400" />
|
/>
|
||||||
<span className="min-w-0 flex-1 truncate">{file.name || file.fileName}</span>
|
<FaFileAlt className="shrink-0 text-gray-400" />
|
||||||
|
<span className="min-w-0 flex-1 truncate">{file.name || file.fileName}</span>
|
||||||
|
</label>
|
||||||
<span className="hidden shrink-0 text-xs text-gray-400 dark:text-gray-500 sm:inline">
|
<span className="hidden shrink-0 text-xs text-gray-400 dark:text-gray-500 sm:inline">
|
||||||
{new Date(file.createdAt).toLocaleString()}
|
{new Date(file.createdAt).toLocaleString()}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
<Button
|
||||||
|
size="xs"
|
||||||
|
variant="plain"
|
||||||
|
icon={<FaEye />}
|
||||||
|
onClick={() => handlePreviewSqlDataFile(file)}
|
||||||
|
loading={isPreviewingSqlDataFile}
|
||||||
|
disabled={isMovingSqlDataFile || isPreviewingSqlDataFile}
|
||||||
|
title={translate('::App.Platform.Preview') || 'Preview'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue