Developer Kits Dynamic Services düzeltildi
This commit is contained in:
parent
7c4bfd4b41
commit
ce84b3baac
9 changed files with 392 additions and 395 deletions
|
|
@ -685,6 +685,18 @@
|
||||||
"en": "Custom Components",
|
"en": "Custom Components",
|
||||||
"tr": "Özel Bileşenler"
|
"tr": "Özel Bileşenler"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.DeveloperKit.DynamicServices",
|
||||||
|
"en": "Dynamic Services",
|
||||||
|
"tr": "Dinamik Servisler"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.DeveloperKit.DynamicServices.Description",
|
||||||
|
"en": "Create and publish dynamic AppServices by writing C# code",
|
||||||
|
"tr": "C# kod yazarak dinamik AppService'ler oluşturun ve yayınlayın"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.Forum",
|
"key": "App.Forum",
|
||||||
|
|
@ -9913,12 +9925,6 @@
|
||||||
"en": "fields",
|
"en": "fields",
|
||||||
"tr": "alan"
|
"tr": "alan"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"resourceName": "Platform",
|
|
||||||
"key": "App.DeveloperKit.DynamicServices",
|
|
||||||
"en": "Dynamic Services",
|
|
||||||
"tr": "Dinamik Hizmetler"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.DeveloperKit.Migration.Generating",
|
"key": "App.DeveloperKit.Migration.Generating",
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ public static class TableNameResolver
|
||||||
_map = new(StringComparer.OrdinalIgnoreCase)
|
_map = new(StringComparer.OrdinalIgnoreCase)
|
||||||
{
|
{
|
||||||
// 🔹 MODULE TABLOLARI
|
// 🔹 MODULE TABLOLARI
|
||||||
{ nameof(TableNameEnum.DynamicService), (TablePrefix.PlatformByName, MenuPrefix.Platform) },
|
|
||||||
{ nameof(TableNameEnum.LogEntry), (TablePrefix.PlatformByName, MenuPrefix.Platform) },
|
{ nameof(TableNameEnum.LogEntry), (TablePrefix.PlatformByName, MenuPrefix.Platform) },
|
||||||
{ nameof(TableNameEnum.Language), (TablePrefix.PlatformByName, MenuPrefix.Platform) },
|
{ nameof(TableNameEnum.Language), (TablePrefix.PlatformByName, MenuPrefix.Platform) },
|
||||||
{ nameof(TableNameEnum.LanguageKey), (TablePrefix.PlatformByName, MenuPrefix.Platform) },
|
{ nameof(TableNameEnum.LanguageKey), (TablePrefix.PlatformByName, MenuPrefix.Platform) },
|
||||||
|
|
@ -57,6 +56,7 @@ public static class TableNameResolver
|
||||||
{ nameof(TableNameEnum.CrudEndpoint), (TablePrefix.TenantByName, MenuPrefix.Saas) },
|
{ nameof(TableNameEnum.CrudEndpoint), (TablePrefix.TenantByName, MenuPrefix.Saas) },
|
||||||
{ nameof(TableNameEnum.CustomEndpoint), (TablePrefix.TenantByName, MenuPrefix.Saas) },
|
{ nameof(TableNameEnum.CustomEndpoint), (TablePrefix.TenantByName, MenuPrefix.Saas) },
|
||||||
{ nameof(TableNameEnum.CustomComponent), (TablePrefix.TenantByName, MenuPrefix.Saas) },
|
{ nameof(TableNameEnum.CustomComponent), (TablePrefix.TenantByName, MenuPrefix.Saas) },
|
||||||
|
{ nameof(TableNameEnum.DynamicService), (TablePrefix.TenantByName, MenuPrefix.Saas) },
|
||||||
{ nameof(TableNameEnum.ReportCategory), (TablePrefix.TenantByName, MenuPrefix.Saas) },
|
{ nameof(TableNameEnum.ReportCategory), (TablePrefix.TenantByName, MenuPrefix.Saas) },
|
||||||
{ nameof(TableNameEnum.ReportTemplate), (TablePrefix.TenantByName, MenuPrefix.Saas) },
|
{ nameof(TableNameEnum.ReportTemplate), (TablePrefix.TenantByName, MenuPrefix.Saas) },
|
||||||
{ nameof(TableNameEnum.ReportParameter), (TablePrefix.TenantByName, MenuPrefix.Saas) },
|
{ nameof(TableNameEnum.ReportParameter), (TablePrefix.TenantByName, MenuPrefix.Saas) },
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
|
||||||
namespace Kurs.Platform.Migrations
|
namespace Kurs.Platform.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(PlatformDbContext))]
|
[DbContext(typeof(PlatformDbContext))]
|
||||||
[Migration("20251105082644_Initial")]
|
[Migration("20251105111749_Initial")]
|
||||||
partial class Initial
|
partial class Initial
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -3648,7 +3648,7 @@ namespace Kurs.Platform.Migrations
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("Plat_H_DynamicService", (string)null);
|
b.ToTable("Sas_T_DynamicService", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Kurs.Platform.Entities.EducationStatus", b =>
|
modelBuilder.Entity("Kurs.Platform.Entities.EducationStatus", b =>
|
||||||
|
|
@ -1477,37 +1477,6 @@ namespace Kurs.Platform.Migrations
|
||||||
table.UniqueConstraint("AK_Plat_H_BackgroundWorker_MailQueueTableFormat_TableName", x => x.TableName);
|
table.UniqueConstraint("AK_Plat_H_BackgroundWorker_MailQueueTableFormat_TableName", x => x.TableName);
|
||||||
});
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
|
||||||
name: "Plat_H_DynamicService",
|
|
||||||
columns: table => new
|
|
||||||
{
|
|
||||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
|
||||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
|
||||||
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
|
|
||||||
DisplayName = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true),
|
|
||||||
Description = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: true),
|
|
||||||
Code = table.Column<string>(type: "text", nullable: false),
|
|
||||||
IsActive = table.Column<bool>(type: "bit", nullable: false, defaultValue: true),
|
|
||||||
CompilationStatus = table.Column<string>(type: "nvarchar(20)", maxLength: 20, nullable: false),
|
|
||||||
LastCompilationError = table.Column<string>(type: "text", nullable: true),
|
|
||||||
LastSuccessfulCompilation = table.Column<DateTime>(type: "datetime2", nullable: true),
|
|
||||||
Version = table.Column<int>(type: "int", nullable: false, defaultValue: 1),
|
|
||||||
CodeHash = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
|
|
||||||
PrimaryEntityType = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
|
||||||
ControllerName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
|
||||||
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
|
|
||||||
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
|
||||||
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
|
|
||||||
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
|
||||||
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
|
|
||||||
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
|
||||||
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
|
|
||||||
},
|
|
||||||
constraints: table =>
|
|
||||||
{
|
|
||||||
table.PrimaryKey("PK_Plat_H_DynamicService", x => x.Id);
|
|
||||||
});
|
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "Plat_H_Language",
|
name: "Plat_H_Language",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
|
|
@ -2186,6 +2155,37 @@ namespace Kurs.Platform.Migrations
|
||||||
table.PrimaryKey("PK_Sas_T_CustomEntity", x => x.Id);
|
table.PrimaryKey("PK_Sas_T_CustomEntity", x => x.Id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Sas_T_DynamicService",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
||||||
|
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
|
||||||
|
DisplayName = table.Column<string>(type: "nvarchar(512)", maxLength: 512, nullable: true),
|
||||||
|
Description = table.Column<string>(type: "nvarchar(2000)", maxLength: 2000, nullable: true),
|
||||||
|
Code = table.Column<string>(type: "text", nullable: false),
|
||||||
|
IsActive = table.Column<bool>(type: "bit", nullable: false, defaultValue: true),
|
||||||
|
CompilationStatus = table.Column<string>(type: "nvarchar(20)", maxLength: 20, nullable: false),
|
||||||
|
LastCompilationError = table.Column<string>(type: "text", nullable: true),
|
||||||
|
LastSuccessfulCompilation = table.Column<DateTime>(type: "datetime2", nullable: true),
|
||||||
|
Version = table.Column<int>(type: "int", nullable: false, defaultValue: 1),
|
||||||
|
CodeHash = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
|
||||||
|
PrimaryEntityType = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
||||||
|
ControllerName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
||||||
|
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||||
|
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
||||||
|
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
|
||||||
|
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
||||||
|
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
|
||||||
|
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
||||||
|
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Sas_T_DynamicService", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "Sas_T_GlobalSearch",
|
name: "Sas_T_GlobalSearch",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
|
|
@ -6370,9 +6370,6 @@ namespace Kurs.Platform.Migrations
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "Plat_H_BackgroundWorker_MailQueueEvents");
|
name: "Plat_H_BackgroundWorker_MailQueueEvents");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
|
||||||
name: "Plat_H_DynamicService");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "Plat_H_LanguageText");
|
name: "Plat_H_LanguageText");
|
||||||
|
|
||||||
|
|
@ -6454,6 +6451,9 @@ namespace Kurs.Platform.Migrations
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "Sas_T_CustomEntityField");
|
name: "Sas_T_CustomEntityField");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Sas_T_DynamicService");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "Sas_T_GlobalSearch");
|
name: "Sas_T_GlobalSearch");
|
||||||
|
|
||||||
|
|
@ -3645,7 +3645,7 @@ namespace Kurs.Platform.Migrations
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.ToTable("Plat_H_DynamicService", (string)null);
|
b.ToTable("Sas_T_DynamicService", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Kurs.Platform.Entities.EducationStatus", b =>
|
modelBuilder.Entity("Kurs.Platform.Entities.EducationStatus", b =>
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ const ComponentManager: React.FC = () => {
|
||||||
<div className="flex items-center justify-between mb-4">
|
<div className="flex items-center justify-between mb-4">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-2xl font-bold text-slate-900">
|
<h1 className="text-2xl font-bold text-slate-900">
|
||||||
{translate('::App.DeveloperKit.Component')}
|
{translate('::App.DeveloperKit.Components')}
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-slate-600">{translate('::App.DeveloperKit.Component.Description')}</p>
|
<p className="text-slate-600">{translate('::App.DeveloperKit.Component.Description')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import {
|
||||||
type PublishResult,
|
type PublishResult,
|
||||||
type DynamicServiceDto,
|
type DynamicServiceDto,
|
||||||
postTestCompile,
|
postTestCompile,
|
||||||
TestCompileRequestDto,
|
TestCompileDto,
|
||||||
} from '@/services/dynamicService.service'
|
} from '@/services/dynamicService.service'
|
||||||
|
|
||||||
const DynamicAppServiceEditor: React.FC = () => {
|
const DynamicAppServiceEditor: React.FC = () => {
|
||||||
|
|
@ -131,10 +131,9 @@ namespace DynamicServices
|
||||||
setIsCompiling(true)
|
setIsCompiling(true)
|
||||||
setCompileResult(null)
|
setCompileResult(null)
|
||||||
console.log('Test compile code:', code)
|
console.log('Test compile code:', code)
|
||||||
const input = { code: code } as TestCompileRequestDto
|
const input = { code: code } as TestCompileDto
|
||||||
const result = await postTestCompile(input)
|
const result = await postTestCompile(input)
|
||||||
setCompileResult(result.data)
|
setCompileResult(result.data)
|
||||||
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('Test compile error:', error)
|
console.error('Test compile error:', error)
|
||||||
console.error('Error response:', error.response?.data)
|
console.error('Error response:', error.response?.data)
|
||||||
|
|
@ -193,14 +192,14 @@ namespace DynamicServices
|
||||||
const loadService = async (service: DynamicServiceDto) => {
|
const loadService = async (service: DynamicServiceDto) => {
|
||||||
try {
|
try {
|
||||||
const data = await dynamicServiceService.getById(service.id)
|
const data = await dynamicServiceService.getById(service.id)
|
||||||
|
|
||||||
setSelectedService(data)
|
setSelectedService(data)
|
||||||
setCode(data.code)
|
setCode(data.code)
|
||||||
setServiceName(data.name)
|
setServiceName(data.name)
|
||||||
setDisplayName(data.displayName || '')
|
setDisplayName(data.displayName || '')
|
||||||
setDescription(data.description || '')
|
setDescription(data.description || '')
|
||||||
setPrimaryEntityType(data.primaryEntityType || '')
|
setPrimaryEntityType(data.primaryEntityType || '')
|
||||||
|
|
||||||
setCompileResult(null)
|
setCompileResult(null)
|
||||||
setPublishResult(null)
|
setPublishResult(null)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -256,367 +255,363 @@ namespace DynamicServices
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gray-50 p-4">
|
<div className="space-y-4">
|
||||||
<div className="mx-auto">
|
{/* Header */}
|
||||||
{/* Header */}
|
<div className="flex items-center justify-between mb-4">
|
||||||
<div className="bg-white rounded-lg shadow-sm border p-6 mb-6">
|
<div>
|
||||||
<div className="flex items-center justify-between">
|
<h1 className="text-2xl font-bold text-slate-900">
|
||||||
<div>
|
{translate('::App.DeveloperKit.DynamicServices')}
|
||||||
<h1 className="text-2xl font-bold text-gray-900 mb-2">Dynamic AppService Editor</h1>
|
</h1>
|
||||||
<p className="text-gray-600">
|
<p className="text-slate-600">
|
||||||
C# kod yazarak dinamik AppService'ler oluşturun ve yayınlayın
|
{translate('::App.DeveloperKit.DynamicServices.Description')}
|
||||||
</p>
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<button
|
||||||
|
onClick={openSwagger}
|
||||||
|
className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors"
|
||||||
|
>
|
||||||
|
<FaExternalLinkAlt className="w-4 h-4" />
|
||||||
|
Swagger
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setShowServiceList(!showServiceList)}
|
||||||
|
className="flex items-center gap-2 bg-gray-600 text-white px-4 py-2 rounded-lg hover:bg-gray-700 transition-colors"
|
||||||
|
>
|
||||||
|
<FaCode className="w-4 h-4" />
|
||||||
|
{showServiceList ? 'Listeyi Gizle' : 'Listeyi Göster'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-12 gap-6">
|
||||||
|
{/* Service List */}
|
||||||
|
{showServiceList && (
|
||||||
|
<div className="col-span-12 lg:col-span-4">
|
||||||
|
<div className="bg-white rounded-lg shadow-sm border">
|
||||||
|
<div className="p-4 border-b">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<h3 className="text-lg font-semibold">Mevcut Servisler</h3>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button
|
||||||
|
onClick={newService}
|
||||||
|
className="bg-green-600 text-white px-3 py-1 rounded text-sm hover:bg-green-700"
|
||||||
|
>
|
||||||
|
<FaCode className="w-4 h-4 inline mr-1" />
|
||||||
|
Yeni
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={loadServices}
|
||||||
|
className="bg-gray-600 text-white px-3 py-1 rounded text-sm hover:bg-gray-700"
|
||||||
|
>
|
||||||
|
<FaSync className="w-4 h-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="max-h-96 overflow-y-auto">
|
||||||
|
{isLoading ? (
|
||||||
|
<div className="p-4 text-center">
|
||||||
|
<FaSpinner className="w-6 h-6 animate-spin mx-auto mb-2" />
|
||||||
|
Yükleniyor...
|
||||||
|
</div>
|
||||||
|
) : services.length > 0 ? (
|
||||||
|
services.map((service) => (
|
||||||
|
<div
|
||||||
|
key={service.id}
|
||||||
|
className={`p-3 border-b hover:bg-gray-50 cursor-pointer ${
|
||||||
|
selectedService?.id === service.id
|
||||||
|
? 'bg-blue-50 border-l-4 border-l-blue-500'
|
||||||
|
: ''
|
||||||
|
}`}
|
||||||
|
onClick={() => loadService(service)}
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex-1">
|
||||||
|
<h4 className="font-medium text-gray-900">{service.name}</h4>
|
||||||
|
{service.displayName && (
|
||||||
|
<p className="text-sm text-gray-600">{service.displayName}</p>
|
||||||
|
)}
|
||||||
|
<div className="flex items-center gap-2 mt-1">
|
||||||
|
<span
|
||||||
|
className={`px-2 py-1 text-xs rounded ${
|
||||||
|
service.compilationStatus === 'Success'
|
||||||
|
? 'bg-green-100 text-green-800'
|
||||||
|
: service.compilationStatus === 'Failed'
|
||||||
|
? 'bg-red-100 text-red-800'
|
||||||
|
: 'bg-yellow-100 text-yellow-800'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{service.compilationStatus}
|
||||||
|
</span>
|
||||||
|
<span className="text-xs text-gray-500">v{service.version}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
deleteService(service.id)
|
||||||
|
}}
|
||||||
|
className="text-red-600 hover:text-red-800 p-1"
|
||||||
|
>
|
||||||
|
<FaTrash className="w-4 h-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<div className="p-4 text-center text-gray-500">Henüz servis yok</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-3">
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Main Editor */}
|
||||||
|
<div className={`col-span-12 ${showServiceList ? 'lg:col-span-8' : ''}`}>
|
||||||
|
{/* Service Info Form */}
|
||||||
|
<div className="bg-white rounded-lg shadow-sm border p-4 mb-4">
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">Servis Adı *</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={serviceName}
|
||||||
|
onChange={(e) => setServiceName(e.target.value)}
|
||||||
|
placeholder="ör: DynamicCustomerAppService"
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">Görünen Ad</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={displayName}
|
||||||
|
onChange={(e) => setDisplayName(e.target.value)}
|
||||||
|
placeholder="ör: Müşteri Yönetimi"
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="md:col-span-2">
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">Açıklama</label>
|
||||||
|
<textarea
|
||||||
|
value={description}
|
||||||
|
onChange={(e) => setDescription(e.target.value)}
|
||||||
|
placeholder="Bu servisin ne yaptığını açıklayın..."
|
||||||
|
rows={2}
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Ana Entity Türü
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={primaryEntityType}
|
||||||
|
onChange={(e) => setPrimaryEntityType(e.target.value)}
|
||||||
|
placeholder="ör: Customer"
|
||||||
|
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Action Buttons */}
|
||||||
|
<div className="bg-white rounded-lg shadow-sm border p-4 mb-4">
|
||||||
|
<div className="flex flex-wrap items-center gap-3">
|
||||||
<button
|
<button
|
||||||
onClick={openSwagger}
|
onClick={handleTestCompile}
|
||||||
className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors"
|
disabled={isCompiling || !code.trim()}
|
||||||
|
className="flex items-center gap-2 bg-orange-600 text-white px-4 py-2 rounded-lg hover:bg-orange-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
||||||
>
|
>
|
||||||
<FaExternalLinkAlt className="w-4 h-4" />
|
{isCompiling ? (
|
||||||
Swagger
|
<FaSpinner className="w-4 h-4 animate-spin" />
|
||||||
|
) : (
|
||||||
|
<FaPlay className="w-4 h-4" />
|
||||||
|
)}
|
||||||
|
Test Compile
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => setShowServiceList(!showServiceList)}
|
onClick={handlePublish}
|
||||||
|
disabled={isPublishing || !code.trim() || !serviceName.trim()}
|
||||||
|
className="flex items-center gap-2 bg-green-600 text-white px-4 py-2 rounded-lg hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
||||||
|
>
|
||||||
|
{isPublishing ? (
|
||||||
|
<FaSpinner className="w-4 h-4 animate-spin" />
|
||||||
|
) : (
|
||||||
|
<FaUpload className="w-4 h-4" />
|
||||||
|
)}
|
||||||
|
Publish
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={copyCode}
|
||||||
className="flex items-center gap-2 bg-gray-600 text-white px-4 py-2 rounded-lg hover:bg-gray-700 transition-colors"
|
className="flex items-center gap-2 bg-gray-600 text-white px-4 py-2 rounded-lg hover:bg-gray-700 transition-colors"
|
||||||
>
|
>
|
||||||
<FaCode className="w-4 h-4" />
|
<FaCopy className="w-4 h-4" />
|
||||||
{showServiceList ? 'Listeyi Gizle' : 'Listeyi Göster'}
|
Kopyala
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-12 gap-6">
|
{/* Results */}
|
||||||
{/* Service List */}
|
{(compileResult || publishResult) && (
|
||||||
{showServiceList && (
|
<div className="space-y-4 mb-4">
|
||||||
<div className="col-span-12 lg:col-span-4">
|
{/* Compile Result */}
|
||||||
<div className="bg-white rounded-lg shadow-sm border">
|
{compileResult && (
|
||||||
<div className="p-4 border-b">
|
<div
|
||||||
<div className="flex items-center justify-between">
|
className={`rounded-lg border p-4 ${
|
||||||
<h3 className="text-lg font-semibold">Mevcut Servisler</h3>
|
compileResult.success
|
||||||
<div className="flex gap-2">
|
? 'bg-green-50 border-green-200'
|
||||||
<button
|
: 'bg-red-50 border-red-200'
|
||||||
onClick={newService}
|
}`}
|
||||||
className="bg-green-600 text-white px-3 py-1 rounded text-sm hover:bg-green-700"
|
>
|
||||||
>
|
<div className="flex items-center gap-2 mb-2">
|
||||||
<FaCode className="w-4 h-4 inline mr-1" />
|
{compileResult.success ? (
|
||||||
Yeni
|
<FaCheckCircle className="w-5 h-5 text-green-600" />
|
||||||
</button>
|
) : (
|
||||||
<button
|
<FaExclamationCircle className="w-5 h-5 text-red-600" />
|
||||||
onClick={loadServices}
|
)}
|
||||||
className="bg-gray-600 text-white px-3 py-1 rounded text-sm hover:bg-gray-700"
|
<h4
|
||||||
>
|
className={`font-medium ${
|
||||||
<FaSync className="w-4 h-4" />
|
compileResult.success ? 'text-green-800' : 'text-red-800'
|
||||||
</button>
|
}`}
|
||||||
</div>
|
>
|
||||||
|
Derleme {compileResult.success ? 'Başarılı' : 'Başarısız'}
|
||||||
|
</h4>
|
||||||
|
<span className="text-sm text-gray-600">
|
||||||
|
({compileResult.compilationTimeMs}ms)
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="max-h-96 overflow-y-auto">
|
{!compileResult.success &&
|
||||||
{isLoading ? (
|
compileResult.errors &&
|
||||||
<div className="p-4 text-center">
|
compileResult.errors.length > 0 && (
|
||||||
<FaSpinner className="w-6 h-6 animate-spin mx-auto mb-2" />
|
<div className="space-y-2">
|
||||||
Yükleniyor...
|
{compileResult.errors.map((error, index) => (
|
||||||
</div>
|
<div key={index} className="bg-white rounded p-3 border">
|
||||||
) : services.length > 0 ? (
|
<div className="flex items-start gap-2">
|
||||||
services.map((service) => (
|
<span className="text-red-600 font-mono text-sm">{error.code}</span>
|
||||||
<div
|
<div className="flex-1">
|
||||||
key={service.id}
|
<p className="text-sm text-gray-800">{error.message}</p>
|
||||||
className={`p-3 border-b hover:bg-gray-50 cursor-pointer ${
|
<p className="text-xs text-gray-600 mt-1">
|
||||||
selectedService?.id === service.id
|
Satır {error.line}, Sütun {error.column}
|
||||||
? 'bg-blue-50 border-l-4 border-l-blue-500'
|
</p>
|
||||||
: ''
|
</div>
|
||||||
}`}
|
|
||||||
onClick={() => loadService(service)}
|
|
||||||
>
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<div className="flex-1">
|
|
||||||
<h4 className="font-medium text-gray-900">{service.name}</h4>
|
|
||||||
{service.displayName && (
|
|
||||||
<p className="text-sm text-gray-600">{service.displayName}</p>
|
|
||||||
)}
|
|
||||||
<div className="flex items-center gap-2 mt-1">
|
|
||||||
<span
|
|
||||||
className={`px-2 py-1 text-xs rounded ${
|
|
||||||
service.compilationStatus === 'Success'
|
|
||||||
? 'bg-green-100 text-green-800'
|
|
||||||
: service.compilationStatus === 'Failed'
|
|
||||||
? 'bg-red-100 text-red-800'
|
|
||||||
: 'bg-yellow-100 text-yellow-800'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{service.compilationStatus}
|
|
||||||
</span>
|
|
||||||
<span className="text-xs text-gray-500">v{service.version}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
))}
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation()
|
|
||||||
deleteService(service.id)
|
|
||||||
}}
|
|
||||||
className="text-red-600 hover:text-red-800 p-1"
|
|
||||||
>
|
|
||||||
<FaTrash className="w-4 h-4" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
))
|
)}
|
||||||
) : (
|
|
||||||
<div className="p-4 text-center text-gray-500">Henüz servis yok</div>
|
{compileResult.hasWarnings && compileResult.warnings && (
|
||||||
|
<div className="mt-3">
|
||||||
|
<h5 className="text-sm font-medium text-yellow-800 mb-2">Uyarılar:</h5>
|
||||||
|
<ul className="list-disc list-inside space-y-1">
|
||||||
|
{compileResult.warnings.map((warning, index) => (
|
||||||
|
<li key={index} className="text-sm text-yellow-700">
|
||||||
|
{warning}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
|
|
||||||
|
{/* Publish Result */}
|
||||||
|
{publishResult && (
|
||||||
|
<div
|
||||||
|
className={`rounded-lg border p-4 ${
|
||||||
|
publishResult.success
|
||||||
|
? 'bg-green-50 border-green-200'
|
||||||
|
: 'bg-red-50 border-red-200'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-2 mb-2">
|
||||||
|
{publishResult.success ? (
|
||||||
|
<FaCheckCircle className="w-5 h-5 text-green-600" />
|
||||||
|
) : (
|
||||||
|
<FaExclamationCircle className="w-5 h-5 text-red-600" />
|
||||||
|
)}
|
||||||
|
<h4
|
||||||
|
className={`font-medium ${
|
||||||
|
publishResult.success ? 'text-green-800' : 'text-red-800'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
Yayınlama {publishResult.success ? 'Başarılı' : 'Başarısız'}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{publishResult.success && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<p className="text-green-700 text-sm">
|
||||||
|
AppService başarıyla yayınlandı ve Swagger'a eklendi.
|
||||||
|
</p>
|
||||||
|
{publishResult.controllerName && (
|
||||||
|
<p className="text-sm text-gray-600">
|
||||||
|
Controller:{' '}
|
||||||
|
<code className="bg-gray-100 px-2 py-1 rounded">
|
||||||
|
{publishResult.controllerName}
|
||||||
|
</code>
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{publishResult.generatedEndpoints &&
|
||||||
|
publishResult.generatedEndpoints.length > 0 && (
|
||||||
|
<div>
|
||||||
|
<h5 className="text-sm font-medium text-gray-700 mb-1">
|
||||||
|
Oluşturulan Endpoint'ler:
|
||||||
|
</h5>
|
||||||
|
<ul className="list-disc list-inside space-y-1">
|
||||||
|
{publishResult.generatedEndpoints.map((endpoint, index) => (
|
||||||
|
<li key={index} className="text-sm text-gray-600 font-mono">
|
||||||
|
{endpoint}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="flex gap-2 mt-3">
|
||||||
|
<button
|
||||||
|
onClick={openSwagger}
|
||||||
|
className="flex items-center gap-1 bg-blue-600 text-white px-3 py-1 rounded text-sm hover:bg-blue-700"
|
||||||
|
>
|
||||||
|
<FaExternalLinkAlt className="w-3 h-3" />
|
||||||
|
Swagger'da Gör
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!publishResult.success && publishResult.errorMessage && (
|
||||||
|
<p className="text-red-700 text-sm">{publishResult.errorMessage}</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Main Editor */}
|
{/* Monaco Editor */}
|
||||||
<div className={`col-span-12 ${showServiceList ? 'lg:col-span-8' : ''}`}>
|
<div className="bg-white rounded-lg shadow-sm border overflow-hidden">
|
||||||
{/* Service Info Form */}
|
<div className="p-3 bg-gray-50 border-b flex items-center justify-between">
|
||||||
<div className="bg-white rounded-lg shadow-sm border p-4 mb-4">
|
<h3 className="font-medium text-gray-700">C# Code Editor</h3>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div className="flex items-center gap-2 text-sm text-gray-600">
|
||||||
<div>
|
<span>Lines: {code.split('\n').length}</span>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<span>|</span>
|
||||||
Servis Adı *
|
<span>Characters: {code.length}</span>
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={serviceName}
|
|
||||||
onChange={(e) => setServiceName(e.target.value)}
|
|
||||||
placeholder="ör: DynamicCustomerAppService"
|
|
||||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">Görünen Ad</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={displayName}
|
|
||||||
onChange={(e) => setDisplayName(e.target.value)}
|
|
||||||
placeholder="ör: Müşteri Yönetimi"
|
|
||||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="md:col-span-2">
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">Açıklama</label>
|
|
||||||
<textarea
|
|
||||||
value={description}
|
|
||||||
onChange={(e) => setDescription(e.target.value)}
|
|
||||||
placeholder="Bu servisin ne yaptığını açıklayın..."
|
|
||||||
rows={2}
|
|
||||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
|
||||||
Ana Entity Türü
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={primaryEntityType}
|
|
||||||
onChange={(e) => setPrimaryEntityType(e.target.value)}
|
|
||||||
placeholder="ör: Customer"
|
|
||||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div style={{ height: '600px' }}>
|
||||||
{/* Action Buttons */}
|
<Editor
|
||||||
<div className="bg-white rounded-lg shadow-sm border p-4 mb-4">
|
defaultLanguage="csharp"
|
||||||
<div className="flex flex-wrap items-center gap-3">
|
value={code}
|
||||||
<button
|
onChange={(value) => setCode(value || '')}
|
||||||
onClick={handleTestCompile}
|
options={editorOptions}
|
||||||
disabled={isCompiling || !code.trim()}
|
theme="vs-dark"
|
||||||
className="flex items-center gap-2 bg-orange-600 text-white px-4 py-2 rounded-lg hover:bg-orange-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
/>
|
||||||
>
|
|
||||||
{isCompiling ? (
|
|
||||||
<FaSpinner className="w-4 h-4 animate-spin" />
|
|
||||||
) : (
|
|
||||||
<FaPlay className="w-4 h-4" />
|
|
||||||
)}
|
|
||||||
Test Compile
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
onClick={handlePublish}
|
|
||||||
disabled={isPublishing || !code.trim() || !serviceName.trim()}
|
|
||||||
className="flex items-center gap-2 bg-green-600 text-white px-4 py-2 rounded-lg hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
||||||
>
|
|
||||||
{isPublishing ? (
|
|
||||||
<FaSpinner className="w-4 h-4 animate-spin" />
|
|
||||||
) : (
|
|
||||||
<FaUpload className="w-4 h-4" />
|
|
||||||
)}
|
|
||||||
Publish
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
onClick={copyCode}
|
|
||||||
className="flex items-center gap-2 bg-gray-600 text-white px-4 py-2 rounded-lg hover:bg-gray-700 transition-colors"
|
|
||||||
>
|
|
||||||
<FaCopy className="w-4 h-4" />
|
|
||||||
Kopyala
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Results */}
|
|
||||||
{(compileResult || publishResult) && (
|
|
||||||
<div className="space-y-4 mb-4">
|
|
||||||
{/* Compile Result */}
|
|
||||||
{compileResult && (
|
|
||||||
<div
|
|
||||||
className={`rounded-lg border p-4 ${
|
|
||||||
compileResult.success
|
|
||||||
? 'bg-green-50 border-green-200'
|
|
||||||
: 'bg-red-50 border-red-200'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<div className="flex items-center gap-2 mb-2">
|
|
||||||
{compileResult.success ? (
|
|
||||||
<FaCheckCircle className="w-5 h-5 text-green-600" />
|
|
||||||
) : (
|
|
||||||
<FaExclamationCircle className="w-5 h-5 text-red-600" />
|
|
||||||
)}
|
|
||||||
<h4
|
|
||||||
className={`font-medium ${
|
|
||||||
compileResult.success ? 'text-green-800' : 'text-red-800'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
Derleme {compileResult.success ? 'Başarılı' : 'Başarısız'}
|
|
||||||
</h4>
|
|
||||||
<span className="text-sm text-gray-600">
|
|
||||||
({compileResult.compilationTimeMs}ms)
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{!compileResult.success &&
|
|
||||||
compileResult.errors &&
|
|
||||||
compileResult.errors.length > 0 && (
|
|
||||||
<div className="space-y-2">
|
|
||||||
{compileResult.errors.map((error, index) => (
|
|
||||||
<div key={index} className="bg-white rounded p-3 border">
|
|
||||||
<div className="flex items-start gap-2">
|
|
||||||
<span className="text-red-600 font-mono text-sm">{error.code}</span>
|
|
||||||
<div className="flex-1">
|
|
||||||
<p className="text-sm text-gray-800">{error.message}</p>
|
|
||||||
<p className="text-xs text-gray-600 mt-1">
|
|
||||||
Satır {error.line}, Sütun {error.column}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{compileResult.hasWarnings && compileResult.warnings && (
|
|
||||||
<div className="mt-3">
|
|
||||||
<h5 className="text-sm font-medium text-yellow-800 mb-2">Uyarılar:</h5>
|
|
||||||
<ul className="list-disc list-inside space-y-1">
|
|
||||||
{compileResult.warnings.map((warning, index) => (
|
|
||||||
<li key={index} className="text-sm text-yellow-700">
|
|
||||||
{warning}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Publish Result */}
|
|
||||||
{publishResult && (
|
|
||||||
<div
|
|
||||||
className={`rounded-lg border p-4 ${
|
|
||||||
publishResult.success
|
|
||||||
? 'bg-green-50 border-green-200'
|
|
||||||
: 'bg-red-50 border-red-200'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<div className="flex items-center gap-2 mb-2">
|
|
||||||
{publishResult.success ? (
|
|
||||||
<FaCheckCircle className="w-5 h-5 text-green-600" />
|
|
||||||
) : (
|
|
||||||
<FaExclamationCircle className="w-5 h-5 text-red-600" />
|
|
||||||
)}
|
|
||||||
<h4
|
|
||||||
className={`font-medium ${
|
|
||||||
publishResult.success ? 'text-green-800' : 'text-red-800'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
Yayınlama {publishResult.success ? 'Başarılı' : 'Başarısız'}
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{publishResult.success && (
|
|
||||||
<div className="space-y-2">
|
|
||||||
<p className="text-green-700 text-sm">
|
|
||||||
AppService başarıyla yayınlandı ve Swagger'a eklendi.
|
|
||||||
</p>
|
|
||||||
{publishResult.controllerName && (
|
|
||||||
<p className="text-sm text-gray-600">
|
|
||||||
Controller:{' '}
|
|
||||||
<code className="bg-gray-100 px-2 py-1 rounded">
|
|
||||||
{publishResult.controllerName}
|
|
||||||
</code>
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
{publishResult.generatedEndpoints &&
|
|
||||||
publishResult.generatedEndpoints.length > 0 && (
|
|
||||||
<div>
|
|
||||||
<h5 className="text-sm font-medium text-gray-700 mb-1">
|
|
||||||
Oluşturulan Endpoint'ler:
|
|
||||||
</h5>
|
|
||||||
<ul className="list-disc list-inside space-y-1">
|
|
||||||
{publishResult.generatedEndpoints.map((endpoint, index) => (
|
|
||||||
<li key={index} className="text-sm text-gray-600 font-mono">
|
|
||||||
{endpoint}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="flex gap-2 mt-3">
|
|
||||||
<button
|
|
||||||
onClick={openSwagger}
|
|
||||||
className="flex items-center gap-1 bg-blue-600 text-white px-3 py-1 rounded text-sm hover:bg-blue-700"
|
|
||||||
>
|
|
||||||
<FaExternalLinkAlt className="w-3 h-3" />
|
|
||||||
Swagger'da Gör
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{!publishResult.success && publishResult.errorMessage && (
|
|
||||||
<p className="text-red-700 text-sm">{publishResult.errorMessage}</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Monaco Editor */}
|
|
||||||
<div className="bg-white rounded-lg shadow-sm border overflow-hidden">
|
|
||||||
<div className="p-3 bg-gray-50 border-b flex items-center justify-between">
|
|
||||||
<h3 className="font-medium text-gray-700">C# Code Editor</h3>
|
|
||||||
<div className="flex items-center gap-2 text-sm text-gray-600">
|
|
||||||
<span>Lines: {code.split('\n').length}</span>
|
|
||||||
<span>|</span>
|
|
||||||
<span>Characters: {code.length}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style={{ height: '600px' }}>
|
|
||||||
<Editor
|
|
||||||
defaultLanguage="csharp"
|
|
||||||
value={code}
|
|
||||||
onChange={(value) => setCode(value || '')}
|
|
||||||
options={editorOptions}
|
|
||||||
theme="vs-dark"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -162,8 +162,8 @@ const MigrationManager: React.FC = () => {
|
||||||
|
|
||||||
<div className="flex items-center justify-between mb-4">
|
<div className="flex items-center justify-between mb-4">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-xl font-bold text-slate-900 mb-2">
|
<h1 className="text-2xl font-bold text-slate-900">
|
||||||
{translate('::App.DeveloperKit.Migration')}
|
{translate('::App.DeveloperKit.Migrations')}
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-slate-600">{translate('::App.DeveloperKit.Migration.Description')}</p>
|
<p className="text-slate-600">{translate('::App.DeveloperKit.Migration.Description')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -48,10 +48,6 @@ export interface TestCompileDto {
|
||||||
code: string
|
code: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TestCompileRequestDto {
|
|
||||||
Code: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PublishDto {
|
export interface PublishDto {
|
||||||
name: string
|
name: string
|
||||||
code: string
|
code: string
|
||||||
|
|
@ -65,7 +61,7 @@ export interface DynamicAppServiceListResult {
|
||||||
totalCount: number
|
totalCount: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export const postTestCompile = (input: TestCompileRequestDto) =>
|
export const postTestCompile = (input: TestCompileDto) =>
|
||||||
apiService.fetchData<CompileResult>({
|
apiService.fetchData<CompileResult>({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `/api/app/dynamic-app-service/test-compile`,
|
url: `/api/app/dynamic-app-service/test-compile`,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue