Route -> Component Type sütunu eklendi.

Dynamic component type
This commit is contained in:
Sedat ÖZTÜRK 2026-06-02 10:14:33 +03:00
parent daf0d51960
commit 9875ba3041
13 changed files with 162 additions and 51 deletions

View file

@ -7,6 +7,7 @@ public class RouteDto : EntityDto<Guid>
{
public string Key { get; set; }
public string Path { get; set; }
public string ComponentType { get; set; }
public string ComponentPath { get; set; }
public string RouteType { get; set; }
public string[] Authority { get; set; }

View file

@ -13856,6 +13856,12 @@
"en": "Component Path",
"tr": "Bileşen Yolu"
},
{
"resourceName": "Platform",
"key": "App.Listform.ListformField.ComponentType",
"en": "Component Type",
"tr": "Bileşen Türü"
},
{
"resourceName": "Platform",
"key": "App.Listform.ListformField.ConditionType",

View file

@ -104,7 +104,6 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
new EditingFormItemDto { Order=7, DataField = "PhoneNumber", ColSpan=1, IsRequired=false, EditorType2=EditorTypes.dxTextBox, EditorOptions=EditorOptionValues.PhoneEditorOptions },
new EditingFormItemDto { Order=8, DataField = "FaxNumber", ColSpan=1, IsRequired=false, EditorType2=EditorTypes.dxTextBox, EditorOptions=EditorOptionValues.PhoneEditorOptions },
new EditingFormItemDto { Order=9, DataField = "IsActive", ColSpan=1, IsRequired=false, EditorType2=EditorTypes.dxCheckBox },
new EditingFormItemDto { Order=10, DataField = "MaxConcurrentUsers", ColSpan=1, IsRequired=false, EditorType2=EditorTypes.dxNumberBox },
]
},
new() { Order=2, ColCount=3, ColSpan=1, ItemType="group", Items =
@ -119,6 +118,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
new EditingFormItemDto { Order=8, DataField = "Email", ColSpan=1, IsRequired=true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order=9, DataField = "Website", ColSpan=1, IsRequired=true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order=10, DataField = "MenuGroup", ColSpan=1, IsRequired=true, EditorType2=EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
new EditingFormItemDto { Order=11, DataField = "MaxConcurrentUsers", ColSpan=1, IsRequired=false, EditorType2=EditorTypes.dxNumberBox },
]
}
}),
@ -5469,7 +5469,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteCommand = $"UPDATE \"{FullNameTable(TableNameEnum.Route)}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id",
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 400, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 550, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
{
new() {
@ -5477,9 +5477,10 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
[
new EditingFormItemDto { Order = 1, DataField = "Key", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 2, DataField = "Path", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 3, DataField = "ComponentPath", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 4, DataField = "RouteType", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
new EditingFormItemDto { Order = 5, DataField = "Authority", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton }
new EditingFormItemDto { Order = 3, DataField = "ComponentType", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox },
new EditingFormItemDto { Order = 4, DataField = "ComponentPath", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 5, DataField = "RouteType", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
new EditingFormItemDto { Order = 6, DataField = "Authority", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton }
]
}
}),
@ -5541,6 +5542,33 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
},
new()
{
ListFormCode = listForm.ListFormCode,
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "ComponentType",
CaptionName = "App.Listform.ListformField.ComponentType",
Width = 0,
ListOrderNo = 5,
Visible = true,
IsActive = true,
AllowSearch = false,
LookupJson = JsonSerializer.Serialize(new LookupDto
{
DataSourceType = UiLookupDataSourceTypeEnum.StaticData,
DisplayExpr = "name",
ValueExpr = "key",
LookupQuery = JsonSerializer.Serialize(new LookupDataDto[] {
new () { Key="normal",Name="Normal" },
new () { Key="dynamic",Name="Dynamic" },
}),
}),
ValidationRuleJson = DefaultValidationRuleRequiredJson,
ColumnCustomizationJson = DefaultColumnCustomizationJson,
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
},
new()
{
ListFormCode = listForm.ListFormCode,
CultureName = LanguageCodes.En,
@ -5548,7 +5576,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
FieldName = "ComponentPath",
CaptionName = "App.Listform.ListformField.ComponentPath",
Width = 0,
ListOrderNo = 4,
ListOrderNo = 5,
Visible = true,
IsActive = true,
@ -5565,7 +5593,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
FieldName = "RouteType",
CaptionName = "App.Listform.ListformField.RouteType",
Width = 0,
ListOrderNo = 5,
ListOrderNo = 6,
Visible = true,
IsActive = true,
@ -5593,7 +5621,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
FieldName = "Authority",
CaptionName = "App.Listform.ListformField.Authority",
Width = 0,
ListOrderNo = 6,
ListOrderNo = 7,
Visible = true,
IsActive = true,

View file

@ -14,6 +14,7 @@ public class RouteSeedDto
{
public string Key { get; set; }
public string Path { get; set; }
public string ComponentType { get; set; }
public string ComponentPath { get; set; }
public string RouteType { get; set; }
public string[] Authority { get; set; }
@ -79,6 +80,7 @@ public class MenuDataSeeder : IDataSeedContributor, ITransientDependency
await _routeRepository.InsertAsync(new Route(
item.Key,
item.Path,
item.ComponentType,
item.ComponentPath,
item.RouteType,
item.Authority ?? []

View file

@ -1,15 +1,17 @@
{
"Routes": [
{
"key": "dynamic.RoleListComponent",
"key": "roleListComponent",
"path": "/admin/RoleListComponent",
"componentPath": "dynamic:RoleListComponent",
"componentType": "dynamic",
"componentPath": "RoleListComponent",
"routeType": "protected",
"authority": []
},
{
"key": "home",
"path": "/home",
"componentType": "normal",
"componentPath": "@/views/public/Home",
"routeType": "public",
"authority": []
@ -17,6 +19,7 @@
{
"key": "about",
"path": "/about",
"componentType": "normal",
"componentPath": "@/views/public/About",
"routeType": "public",
"authority": []
@ -24,6 +27,7 @@
{
"key": "products",
"path": "/products",
"componentType": "normal",
"componentPath": "@/views/public/Products",
"routeType": "public",
"authority": []
@ -31,6 +35,7 @@
{
"key": "checkout",
"path": "/checkout",
"componentType": "normal",
"componentPath": "@/views/public/Checkout",
"routeType": "public",
"authority": []
@ -38,6 +43,7 @@
{
"key": "payment",
"path": "/payment",
"componentType": "normal",
"componentPath": "@/views/public/Payment",
"routeType": "public",
"authority": []
@ -45,6 +51,7 @@
{
"key": "success",
"path": "/success",
"componentType": "normal",
"componentPath": "@/views/public/Success",
"routeType": "public",
"authority": []
@ -52,6 +59,7 @@
{
"key": "services",
"path": "/services",
"componentType": "normal",
"componentPath": "@/views/public/Services",
"routeType": "public",
"authority": []
@ -59,6 +67,7 @@
{
"key": "blog",
"path": "/blog",
"componentType": "normal",
"componentPath": "@/views/public/Blog",
"routeType": "public",
"authority": []
@ -66,6 +75,7 @@
{
"key": "blogDetail",
"path": "/blog/:id",
"componentType": "normal",
"componentPath": "@/views/public/BlogDetail",
"routeType": "public",
"authority": []
@ -73,6 +83,7 @@
{
"key": "demo",
"path": "/demo",
"componentType": "normal",
"componentPath": "@/views/public/Demo",
"routeType": "public",
"authority": []
@ -80,6 +91,7 @@
{
"key": "contact",
"path": "/contact",
"componentType": "normal",
"componentPath": "@/views/public/Contact",
"routeType": "public",
"authority": []
@ -87,6 +99,7 @@
{
"key": "access-denied",
"path": "/access-denied",
"componentType": "normal",
"componentPath": "@/views/AccessDenied",
"routeType": "public",
"authority": []
@ -94,6 +107,7 @@
{
"key": "login",
"path": "/login",
"componentType": "normal",
"componentPath": "@/views/auth/Login",
"routeType": "authenticated",
"authority": []
@ -101,6 +115,7 @@
{
"key": "register",
"path": "/register",
"componentType": "normal",
"componentPath": "@/views/auth/Register",
"routeType": "authenticated",
"authority": []
@ -108,6 +123,7 @@
{
"key": "forgotPassword",
"path": "/forgot-password",
"componentType": "normal",
"componentPath": "@/views/auth/ForgotPassword",
"routeType": "authenticated",
"authority": []
@ -115,6 +131,7 @@
{
"key": "resetPassword",
"path": "/reset-password",
"componentType": "normal",
"componentPath": "@/views/auth/ResetPassword",
"routeType": "authenticated",
"authority": []
@ -122,6 +139,7 @@
{
"key": "sendConfirmationCode",
"path": "/confirm",
"componentType": "normal",
"componentPath": "@/views/auth/SendConfirmationCode",
"routeType": "authenticated",
"authority": []
@ -129,6 +147,7 @@
{
"key": "sendExtendLogin",
"path": "/extend-login",
"componentType": "normal",
"componentPath": "@/views/auth/ExtendLogin",
"routeType": "authenticated",
"authority": []
@ -136,6 +155,7 @@
{
"key": "verifyConfirmationCode",
"path": "/confirm/:userId/:token",
"componentType": "normal",
"componentPath": "@/views/auth/VerifyConfirmationCode",
"routeType": "authenticated",
"authority": []
@ -143,6 +163,7 @@
{
"key": "admin.dashboard",
"path": "/admin/dashboard",
"componentType": "normal",
"componentPath": "@/views/Dashboard",
"routeType": "protected",
"authority": []
@ -150,6 +171,7 @@
{
"key": "admin.menuManager",
"path": "/admin/menuManager",
"componentType": "normal",
"componentPath": "@/views/menu/MenuManager",
"routeType": "protected",
"authority": ["App.Menus.Manager"]
@ -157,6 +179,7 @@
{
"key": "admin.listFormManagement.wizard",
"path": "/admin/listform/wizard",
"componentType": "normal",
"componentPath": "@/views/admin/listForm/wizard/Wizard",
"routeType": "protected",
"authority": ["App.Listforms.Wizard"]
@ -164,6 +187,7 @@
{
"key": "admin.listFormManagement.wizardManager",
"path": "/admin/listform/wizardManager",
"componentType": "normal",
"componentPath": "@/views/admin/listForm/wizard/WizardFileManager",
"routeType": "protected",
"authority": ["App.Listforms.Wizard"]
@ -171,6 +195,7 @@
{
"key": "admin.listFormManagement.edit",
"path": "/admin/listform/edit/:listFormCode",
"componentType": "normal",
"componentPath": "@/views/admin/listForm/edit/FormEdit",
"routeType": "protected",
"authority": []
@ -178,6 +203,7 @@
{
"key": "admin.forumManagement",
"path": "/admin/forumManagement",
"componentType": "normal",
"componentPath": "@/views/forum/Management",
"routeType": "protected",
"authority": ["App.ForumManagement"]
@ -185,6 +211,7 @@
{
"key": "admin.ai",
"path": "/admin/ai",
"componentType": "normal",
"componentPath": "@/views/ai/Assistant",
"routeType": "protected",
"authority": ["App.Definitions.AiBot.Asistant"]
@ -192,6 +219,7 @@
{
"key": "admin.profile.general",
"path": "/admin/profile/general",
"componentType": "normal",
"componentPath": "@/views/admin/profile/Profile",
"routeType": "protected",
"authority": []
@ -199,6 +227,7 @@
{
"key": "admin.profile.password",
"path": "/admin/profile/password",
"componentType": "normal",
"componentPath": "@/views/admin/profile/Profile",
"routeType": "protected",
"authority": []
@ -206,6 +235,7 @@
{
"key": "admin.profile.notificationSettings",
"path": "/admin/profile/notification-settings",
"componentType": "normal",
"componentPath": "@/views/admin/profile/Profile",
"routeType": "protected",
"authority": []
@ -213,6 +243,7 @@
{
"key": "admin.activityLog",
"path": "/admin/activityLog",
"componentType": "normal",
"componentPath": "@/views/admin/activityLog/ActivityLog",
"routeType": "protected",
"authority": []
@ -220,6 +251,7 @@
{
"key": "admin.changeLog",
"path": "/admin/changeLog",
"componentType": "normal",
"componentPath": "@/views/version/ChangeLog",
"routeType": "protected",
"authority": []
@ -227,6 +259,7 @@
{
"key": "admin.settings",
"path": "/admin/settings",
"componentType": "normal",
"componentPath": "@/views/settings/Settings",
"routeType": "protected",
"authority": ["App.Setting"]
@ -234,6 +267,7 @@
{
"key": "admin.identity.user.detail",
"path": "/admin/users/detail/:userId",
"componentType": "normal",
"componentPath": "@/views/admin/user-management/Details",
"routeType": "protected",
"authority": ["AbpIdentity.Users.Update"]
@ -241,6 +275,7 @@
{
"key": "admin.identity.ous",
"path": "/admin/ous",
"componentType": "normal",
"componentPath": "@/views/admin/organization-unit/OrganizationUnits",
"routeType": "protected",
"authority": ["Abp.Identity.OrganizationUnits"]
@ -248,6 +283,7 @@
{
"key": "admin.hr.organization",
"path": "/admin/organization",
"componentType": "normal",
"componentPath": "@/views/admin/hr/OrgChart",
"routeType": "protected",
"authority": ["App.Definitions.Department"]
@ -255,6 +291,7 @@
{
"key": "admin.forum",
"path": "/admin/forum",
"componentType": "normal",
"componentPath": "@/views/forum/Forum",
"routeType": "protected",
"authority": ["App.ForumManagement.Publish"]
@ -262,6 +299,7 @@
{
"key": "admin.list",
"path": "/admin/list/:listFormCode",
"componentType": "normal",
"componentPath": "@/views/list/List",
"routeType": "protected",
"authority": []
@ -269,6 +307,7 @@
{
"key": "admin.formNew",
"path": "/admin/form/:listFormCode",
"componentType": "normal",
"componentPath": "@/views/form/FormNew",
"routeType": "protected",
"authority": []
@ -276,6 +315,7 @@
{
"key": "admin.formView",
"path": "/admin/form/:listFormCode/:id",
"componentType": "normal",
"componentPath": "@/views/form/FormView",
"routeType": "protected",
"authority": []
@ -283,6 +323,7 @@
{
"key": "admin.formEdit",
"path": "/admin/form/:listFormCode/:id/edit",
"componentType": "normal",
"componentPath": "@/views/form/FormEdit",
"routeType": "protected",
"authority": []
@ -290,6 +331,7 @@
{
"key": "admin.chart",
"path": "/admin/chart/:listFormCode",
"componentType": "normal",
"componentPath": "@/views/list/Chart",
"routeType": "protected",
"authority": []
@ -297,6 +339,7 @@
{
"key": "admin.sqlQueryManager",
"path": "/admin/sqlQueryManager",
"componentType": "normal",
"componentPath": "@/views/developerKit/SqlQueryManager",
"routeType": "protected",
"authority": ["App.SqlQueryManager"]
@ -304,6 +347,7 @@
{
"key": "admin.developerkit.endpoints",
"path": "/admin/developerkit/endpoints",
"componentType": "normal",
"componentPath": "@/views/developerKit/CrudEndpointManager",
"routeType": "protected",
"authority": ["App.DeveloperKit.CrudEndpoints"]
@ -311,6 +355,7 @@
{
"key": "admin.developerkit.dynamic-services",
"path": "/admin/developerkit/dynamic-services",
"componentType": "normal",
"componentPath": "@/views/developerKit/DynamicServiceManager",
"routeType": "protected",
"authority": ["App.DeveloperKit.DynamicServices"]
@ -318,6 +363,7 @@
{
"key": "admin.developerkit.dynamic-services.new",
"path": "/admin/developerkit/dynamic-services/new",
"componentType": "normal",
"componentPath": "@/views/developerKit/DynamicServiceEditor",
"routeType": "protected",
"authority": ["App.DeveloperKit.DynamicServices"]
@ -325,6 +371,7 @@
{
"key": "admin.developerkit.dynamic-services.edit",
"path": "/admin/developerkit/dynamic-services/edit/:id",
"componentType": "normal",
"componentPath": "@/views/developerKit/DynamicServiceEditor",
"routeType": "protected",
"authority": ["App.DeveloperKit.DynamicServices"]
@ -332,6 +379,7 @@
{
"key": "admin.developerkit.components",
"path": "/admin/developerkit/components",
"componentType": "normal",
"componentPath": "@/views/developerKit/ComponentManagerPage",
"routeType": "protected",
"authority": ["App.DeveloperKit.Components"]
@ -339,6 +387,7 @@
{
"key": "admin.developerkit.components.new",
"path": "/admin/developerkit/components/new",
"componentType": "normal",
"componentPath": "@/views/developerKit/ComponentEditorPage",
"routeType": "protected",
"authority": ["App.DeveloperKit.Components"]
@ -346,6 +395,7 @@
{
"key": "admin.developerkit.components.view",
"path": "/admin/developerkit/components/view/:id",
"componentType": "normal",
"componentPath": "@/views/developerKit/ComponentEditorPage",
"routeType": "protected",
"authority": ["App.DeveloperKit.Components"]
@ -353,6 +403,7 @@
{
"key": "admin.developerkit.components.edit",
"path": "/admin/developerkit/components/edit/:id",
"componentType": "normal",
"componentPath": "@/views/developerKit/ComponentCodeLayout",
"routeType": "protected",
"authority": ["App.DeveloperKit.Components"]
@ -360,6 +411,7 @@
{
"key": "admin.fileManagement",
"path": "/admin/files",
"componentType": "normal",
"componentPath": "@/views/admin/files/FileManager",
"routeType": "protected",
"authority": ["App.Files"]
@ -367,6 +419,7 @@
{
"key": "admin.devexpressReportView",
"path": "/admin/reports/:id/view",
"componentType": "normal",
"componentPath": "@/views/report/DevexpressReportViewer",
"routeType": "protected",
"authority": []
@ -374,6 +427,7 @@
{
"key": "admin.devexpressReportDesigner",
"path": "/admin/reports/:id/design",
"componentType": "normal",
"componentPath": "@/views/report/DevexpressReportDesigner",
"routeType": "protected",
"authority": []
@ -381,6 +435,7 @@
{
"key": "homeDesigner",
"path": "/admin/public/home/designer",
"componentType": "normal",
"componentPath": "@/views/public/Home",
"routeType": "protected",
"authority": ["App.Home"]
@ -388,6 +443,7 @@
{
"key": "aboutDesigner",
"path": "/admin/public/about/designer",
"componentType": "normal",
"componentPath": "@/views/public/About",
"routeType": "protected",
"authority": ["App.About"]
@ -395,6 +451,7 @@
{
"key": "servicesDesigner",
"path": "/admin/public/services/designer",
"componentType": "normal",
"componentPath": "@/views/public/Services",
"routeType": "protected",
"authority": ["App.Services"]
@ -402,6 +459,7 @@
{
"key": "contactDesigner",
"path": "/admin/public/contact/designer",
"componentType": "normal",
"componentPath": "@/views/public/Contact",
"routeType": "protected",
"authority": ["App.Contact"]
@ -409,6 +467,7 @@
{
"key": "admin.videoroom.dashboard",
"path": "/admin/videoroom/dashboard",
"componentType": "normal",
"componentPath": "@/views/admin/videoroom/Dashboard",
"routeType": "protected",
"authority": ["App.Videoroom.Dashboard"]
@ -416,6 +475,7 @@
{
"key": "admin.videoroom.list",
"path": "/admin/videoroom/list",
"componentType": "normal",
"componentPath": "@/views/admin/videoroom/RoomList",
"routeType": "protected",
"authority": ["App.Videoroom.List"]
@ -423,6 +483,7 @@
{
"key": "admin.videoroom.roomdetail",
"path": "/admin/videoroom/room/:id",
"componentType": "normal",
"componentPath": "@/views/admin/videoroom/RoomDetail",
"routeType": "protected",
"authority": ["App.Videoroom.RoomDetail"]

View file

@ -7,14 +7,16 @@ public class Route : FullAuditedEntity<Guid>
{
public string Key { get; set; }
public string Path { get; set; }
public string ComponentType { get; set; }
public string ComponentPath { get; set; }
public string RouteType { get; set; }
public string[] Authority { get; set; }
public Route(string key, string path, string componentPath, string routeType, string[] authority)
public Route(string key, string path, string componentType, string componentPath, string routeType, string[] authority)
{
Key = key;
Path = path;
ComponentType = componentType;
ComponentPath = componentPath;
RouteType = routeType;
Authority = authority;

View file

@ -254,6 +254,7 @@ public class PlatformDbContext :
b.Property(x => x.Key).IsRequired().HasMaxLength(128);
b.Property(x => x.Path).IsRequired().HasMaxLength(256);
b.Property(x => x.ComponentType).HasMaxLength(32);
b.Property(x => x.ComponentPath).IsRequired().HasMaxLength(256);
b.Property(x => x.RouteType).HasMaxLength(64);

View file

@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace Sozsoft.Platform.Migrations
{
[DbContext(typeof(PlatformDbContext))]
[Migration("20260526185809_Initial")]
[Migration("20260602070242_Initial")]
partial class Initial
{
/// <inheritdoc />
@ -4153,6 +4153,10 @@ namespace Sozsoft.Platform.Migrations
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("ComponentType")
.HasMaxLength(32)
.HasColumnType("nvarchar(32)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");

View file

@ -1604,6 +1604,7 @@ namespace Sozsoft.Platform.Migrations
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Key = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
Path = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
ComponentType = table.Column<string>(type: "nvarchar(32)", maxLength: 32, nullable: true),
ComponentPath = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
RouteType = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
Authority = table.Column<string>(type: "nvarchar(max)", nullable: true),

View file

@ -4150,6 +4150,10 @@ namespace Sozsoft.Platform.Migrations
.HasMaxLength(256)
.HasColumnType("nvarchar(256)");
b.Property<string>("ComponentType")
.HasMaxLength(32)
.HasColumnType("nvarchar(32)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");

View file

@ -4,6 +4,7 @@ export interface RouteDto extends FullAuditedEntityDto<string> {
id: string;
key: string;
path: string;
componentType: string;
componentPath: string;
routeType: string;
authority: string[];

View file

@ -1,6 +1,5 @@
import { RouteDto } from '@/proxy/routes/models'
import { lazy } from 'react'
import { useComponents } from '@/contexts/ComponentContext'
// Tüm view bileşenlerini import et (vite özel)
// shared klasörü hariç, çünkü bu bileşenler genellikle başka yerlerde statik import ediliyor
@ -8,25 +7,12 @@ const modules = import.meta.glob(['../views/**/*.tsx', '!../views/shared/**/*.ts
const lazyComponentCache = new Map<string, React.LazyExoticComponent<React.ComponentType<any>>>()
// ComponentPath'in fiziksel mi yoksa dinamik mi olduğunu belirle
function isPhysicalComponent(componentPath: string): boolean {
// @ ile başlayan path'ler fiziksel dosya yolu
// Başka bir kural: dynamic: ile başlayan path'ler dinamik
return componentPath.startsWith('@/') || componentPath.startsWith('../')
}
function isDynamicComponent(componentPath: string): boolean {
// dynamic: ile başlayan path'ler dinamik komponent
return componentPath.startsWith('dynamic:')
}
// Fiziksel komponent yükleme (mevcut mantık)
function loadPhysicalComponent(componentPath: string) {
const cleanedPath = componentPath.replace(/^@\//, '')
const fullPath = `../${cleanedPath}.tsx`
if (lazyComponentCache.has(fullPath)) {
// console.log(`Physical component loaded from cache: ${fullPath}`)
return lazyComponentCache.get(fullPath)!
}
@ -43,53 +29,65 @@ function loadPhysicalComponent(componentPath: string) {
// Dinamik komponent yükleme (yeni mantık)
function loadDynamicComponent(
componentPath: string,
componentPath: string,
registeredComponents: Record<string, React.ComponentType<unknown>>,
renderComponent?: (name: string, props?: any) => React.ReactNode,
isComponentRegistered?: (name: string) => boolean
isComponentRegistered?: (name: string) => boolean,
) {
const componentName = componentPath.replace('dynamic:', '')
if (lazyComponentCache.has(componentPath)) {
// console.log(`Dynamic component loaded from cache: ${componentName}`)
return lazyComponentCache.get(componentPath)!
}
// Önce manuel registered komponentleri kontrol et
let DynamicComponent = registeredComponents[componentName]
let DynamicComponent = registeredComponents[componentPath]
// Eğer manuel registered'da yoksa, database compiled komponentleri kontrol et
if (!DynamicComponent && isComponentRegistered && renderComponent && isComponentRegistered(componentName)) {
DynamicComponent = (props: any) => renderComponent(componentName, props) as React.ReactElement
if (
!DynamicComponent &&
isComponentRegistered &&
renderComponent &&
isComponentRegistered(componentPath)
) {
DynamicComponent = (props: any) => renderComponent(componentPath, props) as React.ReactElement
}
if (!DynamicComponent) {
if (isComponentRegistered) {
console.log('Database component registry available - checking...')
}
throw new Error(`Dynamic component not found: ${componentName}`)
throw new Error(`Dynamic component not found: ${componentPath}`)
}
// console.log(`Dynamic component loaded: ${componentName}`)
// console.log(`Dynamic component loaded: ${componentPath}`)
// Dinamik komponent için lazy wrapper oluştur
const LazyComponent = lazy(() => Promise.resolve({ default: DynamicComponent as React.ComponentType<any> }))
const LazyComponent = lazy(() =>
Promise.resolve({ default: DynamicComponent as React.ComponentType<any> }),
)
lazyComponentCache.set(componentPath, LazyComponent)
return LazyComponent
}
export function loadComponent(
componentPath: string,
componentType: string,
componentPath: string,
registeredComponents?: Record<string, React.ComponentType<unknown>>,
renderComponent?: (name: string, props?: any) => React.ReactNode,
isComponentRegistered?: (name: string) => boolean
isComponentRegistered?: (name: string) => boolean,
) {
if (isPhysicalComponent(componentPath)) {
if (componentType === 'normal') {
return loadPhysicalComponent(componentPath)
} else if (isDynamicComponent(componentPath)) {
} else if (componentType === 'dynamic') {
if (!registeredComponents) {
throw new Error('Registered components required for dynamic component loading')
}
return loadDynamicComponent(componentPath, registeredComponents, renderComponent, isComponentRegistered)
return loadDynamicComponent(
componentPath,
registeredComponents,
renderComponent,
isComponentRegistered,
)
} else {
// Backward compatibility: varsayılan olarak fiziksel komponent kabul et
return loadPhysicalComponent(componentPath)
@ -103,13 +101,12 @@ export interface DynamicReactRoute {
getComponent: (
registeredComponents?: Record<string, React.ComponentType<unknown>>,
renderComponent?: (name: string, props?: any) => React.ReactNode,
isComponentRegistered?: (name: string) => boolean
isComponentRegistered?: (name: string) => boolean,
) => React.LazyExoticComponent<React.ComponentType<any>>
routeType: string
authority?: string[]
componentType: string
componentPath: string
isPhysical: boolean
isDynamic: boolean
}
// API'den gelen route objesini, React Router için uygun hale getirir
@ -117,12 +114,17 @@ export function mapDynamicRoutes(routes: RouteDto[]): DynamicReactRoute[] {
return routes.map((route) => ({
key: route.path,
path: route.path,
getComponent: (registeredComponents, renderComponent, isComponentRegistered) =>
loadComponent(route.componentPath, registeredComponents, renderComponent, isComponentRegistered),
getComponent: (registeredComponents, renderComponent, isComponentRegistered) =>
loadComponent(
route.componentType,
route.componentPath,
registeredComponents,
renderComponent,
isComponentRegistered,
),
routeType: route.routeType,
authority: route.authority,
componentType: route.componentType,
componentPath: route.componentPath,
isPhysical: isPhysicalComponent(route.componentPath),
isDynamic: isDynamicComponent(route.componentPath),
}))
}

View file

@ -178,8 +178,6 @@ export const MenuItemComponent: React.FC<MenuItemComponentProps> = ({
>
{translate('::' + item.displayName)}
</button>
{item.url && <FaExternalLinkAlt size={12} className="flex-shrink-0 text-gray-400 dark:text-gray-500" />}
</div>
<div className="flex items-center gap-2 flex-shrink-0">