From 9875ba304187887c9670f887e9319f07d820d4c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96ZT=C3=9CRK?= <76204082+iamsedatozturk@users.noreply.github.com> Date: Tue, 2 Jun 2026 10:14:33 +0300 Subject: [PATCH] =?UTF-8?q?Route=20->=20Component=20Type=20s=C3=BCtunu=20e?= =?UTF-8?q?klendi.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dynamic component type --- .../Routes/RouteDto.cs | 1 + .../Seeds/LanguagesData.json | 6 ++ .../Seeds/ListFormSeeder_Saas.cs | 44 +++++++++-- .../Seeds/MenuDataSeeder.cs | 2 + .../Seeds/MenusData.json | 65 +++++++++++++++- .../Entities/Tenant/Administration/Route.cs | 4 +- .../EntityFrameworkCore/PlatformDbContext.cs | 1 + ....cs => 20260602070242_Initial.Designer.cs} | 6 +- ...9_Initial.cs => 20260602070242_Initial.cs} | 1 + .../PlatformDbContextModelSnapshot.cs | 4 + ui/src/proxy/routes/models.ts | 1 + ui/src/routes/dynamicRouteLoader.tsx | 76 ++++++++++--------- ui/src/views/menu/MenuItemComponent.tsx | 2 - 13 files changed, 162 insertions(+), 51 deletions(-) rename api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/{20260526185809_Initial.Designer.cs => 20260602070242_Initial.Designer.cs} (99%) rename api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/{20260526185809_Initial.cs => 20260602070242_Initial.cs} (99%) diff --git a/api/src/Sozsoft.Platform.Application.Contracts/Routes/RouteDto.cs b/api/src/Sozsoft.Platform.Application.Contracts/Routes/RouteDto.cs index d27e54b..5db9146 100644 --- a/api/src/Sozsoft.Platform.Application.Contracts/Routes/RouteDto.cs +++ b/api/src/Sozsoft.Platform.Application.Contracts/Routes/RouteDto.cs @@ -7,6 +7,7 @@ public class RouteDto : EntityDto { 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; } diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json b/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json index a5175dc..7e71872 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json @@ -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", diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Saas.cs b/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Saas.cs index 2b9707e..bc59dfd 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Saas.cs +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Saas.cs @@ -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 { 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, diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/MenuDataSeeder.cs b/api/src/Sozsoft.Platform.DbMigrator/Seeds/MenuDataSeeder.cs index 4531a82..bf636c2 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/MenuDataSeeder.cs +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/MenuDataSeeder.cs @@ -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 ?? [] diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/MenusData.json b/api/src/Sozsoft.Platform.DbMigrator/Seeds/MenusData.json index a74edbe..1c3b35e 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/MenusData.json +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/MenusData.json @@ -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"] diff --git a/api/src/Sozsoft.Platform.Domain/Entities/Tenant/Administration/Route.cs b/api/src/Sozsoft.Platform.Domain/Entities/Tenant/Administration/Route.cs index 0da79eb..e775555 100644 --- a/api/src/Sozsoft.Platform.Domain/Entities/Tenant/Administration/Route.cs +++ b/api/src/Sozsoft.Platform.Domain/Entities/Tenant/Administration/Route.cs @@ -7,14 +7,16 @@ public class Route : FullAuditedEntity { 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; diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs b/api/src/Sozsoft.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs index 78d4a53..f96d409 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs @@ -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); diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260526185809_Initial.Designer.cs b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260602070242_Initial.Designer.cs similarity index 99% rename from api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260526185809_Initial.Designer.cs rename to api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260602070242_Initial.Designer.cs index 539a801..b0f10d6 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260526185809_Initial.Designer.cs +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260602070242_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace Sozsoft.Platform.Migrations { [DbContext(typeof(PlatformDbContext))] - [Migration("20260526185809_Initial")] + [Migration("20260602070242_Initial")] partial class Initial { /// @@ -4153,6 +4153,10 @@ namespace Sozsoft.Platform.Migrations .HasMaxLength(256) .HasColumnType("nvarchar(256)"); + b.Property("ComponentType") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + b.Property("CreationTime") .HasColumnType("datetime2") .HasColumnName("CreationTime"); diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260526185809_Initial.cs b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260602070242_Initial.cs similarity index 99% rename from api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260526185809_Initial.cs rename to api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260602070242_Initial.cs index 50cd40d..40ec417 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260526185809_Initial.cs +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260602070242_Initial.cs @@ -1604,6 +1604,7 @@ namespace Sozsoft.Platform.Migrations Id = table.Column(type: "uniqueidentifier", nullable: false), Key = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), Path = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + ComponentType = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: true), ComponentPath = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), RouteType = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), Authority = table.Column(type: "nvarchar(max)", nullable: true), diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs index 2471ab0..b9c07cc 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs @@ -4150,6 +4150,10 @@ namespace Sozsoft.Platform.Migrations .HasMaxLength(256) .HasColumnType("nvarchar(256)"); + b.Property("ComponentType") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + b.Property("CreationTime") .HasColumnType("datetime2") .HasColumnName("CreationTime"); diff --git a/ui/src/proxy/routes/models.ts b/ui/src/proxy/routes/models.ts index 783763c..c75ba02 100644 --- a/ui/src/proxy/routes/models.ts +++ b/ui/src/proxy/routes/models.ts @@ -4,6 +4,7 @@ export interface RouteDto extends FullAuditedEntityDto { id: string; key: string; path: string; + componentType: string; componentPath: string; routeType: string; authority: string[]; diff --git a/ui/src/routes/dynamicRouteLoader.tsx b/ui/src/routes/dynamicRouteLoader.tsx index b5caeac..2e8beb9 100644 --- a/ui/src/routes/dynamicRouteLoader.tsx +++ b/ui/src/routes/dynamicRouteLoader.tsx @@ -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>>() -// 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>, 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 })) + const LazyComponent = lazy(() => + Promise.resolve({ default: DynamicComponent as React.ComponentType }), + ) lazyComponentCache.set(componentPath, LazyComponent) return LazyComponent } export function loadComponent( - componentPath: string, + componentType: string, + componentPath: string, registeredComponents?: Record>, 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>, renderComponent?: (name: string, props?: any) => React.ReactNode, - isComponentRegistered?: (name: string) => boolean + isComponentRegistered?: (name: string) => boolean, ) => React.LazyExoticComponent> 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), })) } diff --git a/ui/src/views/menu/MenuItemComponent.tsx b/ui/src/views/menu/MenuItemComponent.tsx index 8ba5b5c..0a23782 100644 --- a/ui/src/views/menu/MenuItemComponent.tsx +++ b/ui/src/views/menu/MenuItemComponent.tsx @@ -178,8 +178,6 @@ export const MenuItemComponent: React.FC = ({ > {translate('::' + item.displayName)} - - {item.url && }