From e4cecc8a6244a7c61f6b3fa55bcb8941ea3efff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96ZT=C3=9CRK?= <76204082+iamsedatozturk@users.noreply.github.com> Date: Wed, 26 Aug 2026 12:10:12 +0300 Subject: [PATCH] =?UTF-8?q?Wizard=20Stepleri=20Lazy=20ile=20=C3=A7al=C4=B1?= =?UTF-8?q?=C5=9Ft=C4=B1r=C4=B1ld=C4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Migrations/LanguagesData.json | 12 + .../Migrations/ListFormSeeder_Saas.cs | 279 +++++++----- .../EntityFrameworkCore/PlatformDbContext.cs | 1 + ....cs => 20260826070015_Initial.Designer.cs} | 6 +- ...4_Initial.cs => 20260826070015_Initial.cs} | 2 +- .../PlatformDbContextModelSnapshot.cs | 4 +- ui/src/views/admin/listForm/wizard/Wizard.tsx | 428 +++++++++--------- .../admin/listForm/wizard/WizardStepMenu.tsx | 83 +--- .../views/admin/listForm/wizard/menuTree.ts | 84 ++++ .../developerKit/SqlTableDesignerDialog.tsx | 4 +- 10 files changed, 497 insertions(+), 406 deletions(-) rename api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/{20260824093234_Initial.Designer.cs => 20260826070015_Initial.Designer.cs} (99%) rename api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/{20260824093234_Initial.cs => 20260826070015_Initial.cs} (99%) create mode 100644 ui/src/views/admin/listForm/wizard/menuTree.ts diff --git a/api/src/Sozsoft.Platform.DbMigrator/Migrations/LanguagesData.json b/api/src/Sozsoft.Platform.DbMigrator/Migrations/LanguagesData.json index 6060cfe3..5e04e0b9 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Migrations/LanguagesData.json +++ b/api/src/Sozsoft.Platform.DbMigrator/Migrations/LanguagesData.json @@ -13842,6 +13842,18 @@ "en": "Is Tenant", "tr": "Tenant" }, + { + "resourceName": "Platform", + "key": "App.Listform.ListformField.IsBranch", + "en": "Is Branch", + "tr": "Şube" + }, + { + "resourceName": "Platform", + "key": "App.Listform.ListformField.ShowNote", + "en": "Show Note", + "tr": "Not Göster" + }, { "resourceName": "Platform", "key": "App.Listform.ListformField.Tenants", diff --git a/api/src/Sozsoft.Platform.DbMigrator/Migrations/ListFormSeeder_Saas.cs b/api/src/Sozsoft.Platform.DbMigrator/Migrations/ListFormSeeder_Saas.cs index 51270d52..7ef2f786 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Migrations/ListFormSeeder_Saas.cs +++ b/api/src/Sozsoft.Platform.DbMigrator/Migrations/ListFormSeeder_Saas.cs @@ -4469,8 +4469,8 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency EditingOptionJson = DefaultEditingOptionJson(listFormName, 950, 650, true, true, true, true, false), EditingFormJson = JsonSerializer.Serialize(new List() { new() { Order=1, ColCount=3, ColSpan=1, ItemType="group" }, - new() { - Order=2,ColCount=2,ColSpan=1,ItemType="group" }, + new() { Order=2, ColCount=3, ColSpan=1, ItemType="group" }, + new() { Order=3, ColCount=2, ColSpan=1, ItemType="group" }, }), InsertFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] { @@ -4495,14 +4495,21 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency } }), FormFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] { + new() { FieldName = "CultureName", FieldDbType = DbType.String, Value = "en", CustomValueType = FieldCustomValueTypeEnum.Value }, + new() { FieldName = "DataSourceCode", FieldDbType = DbType.String, Value = "Default", CustomValueType = FieldCustomValueTypeEnum.Value }, + new() { FieldName = "SelectCommandType", FieldDbType = DbType.Int32, Value = ((int)SelectCommandTypeEnum.Table).ToString(), CustomValueType = FieldCustomValueTypeEnum.Value }, + new() { FieldName = "KeyFieldName", FieldDbType = DbType.String, Value = "Id", CustomValueType = FieldCustomValueTypeEnum.Value }, + new() { FieldName = "KeyFieldDbSourceType", FieldDbType = DbType.Int32, Value = ((int)DbType.Guid).ToString(), CustomValueType = FieldCustomValueTypeEnum.Value }, new() { FieldName = "ListFormType", FieldDbType = DbType.String, Value = ListFormTypeEnum.List, CustomValueType = FieldCustomValueTypeEnum.Value }, new() { FieldName = "InsertServiceAddress", FieldDbType = DbType.String, Value = "list-form-data/insert", CustomValueType = FieldCustomValueTypeEnum.Value }, new() { FieldName = "DeleteServiceAddress", FieldDbType = DbType.String, Value = "list-form-data/delete", CustomValueType = FieldCustomValueTypeEnum.Value }, new() { FieldName = "UpdateServiceAddress", FieldDbType = DbType.String, Value = "list-form-data/update", CustomValueType = FieldCustomValueTypeEnum.Value }, new() { FieldName = "IsDisabled", FieldDbType = DbType.Boolean, Value = "false", CustomValueType = FieldCustomValueTypeEnum.Value }, new() { FieldName = "IsTenant", FieldDbType = DbType.Boolean, Value = "false", CustomValueType = FieldCustomValueTypeEnum.Value }, + new() { FieldName = "IsBranch", FieldDbType = DbType.Boolean, Value = "false", CustomValueType = FieldCustomValueTypeEnum.Value }, new() { FieldName = "IsOrganizationUnit", FieldDbType = DbType.Boolean, Value = "false", CustomValueType = FieldCustomValueTypeEnum.Value }, new() { FieldName = "IsSubForm", FieldDbType = DbType.Boolean, Value = "false", CustomValueType = FieldCustomValueTypeEnum.Value }, + new() { FieldName = "ShowNote", FieldDbType = DbType.Boolean, Value = "true", CustomValueType = FieldCustomValueTypeEnum.Value }, new() { FieldName = "SortMode", FieldDbType = DbType.String, Value = GridOptions.SortModeNone, CustomValueType = FieldCustomValueTypeEnum.Value }, }), } @@ -4557,26 +4564,6 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency PivotSettingsJson = DefaultPivotSettingsJson }, new ListFormField - { - ListFormCode = listForm.ListFormCode, - CultureName = LanguageCodes.En, - SourceDbType = DbType.String, - FieldName = "Description", - EditGroupOrderNo = 1, - EditOrderNo = 10, - EditorType2 = EditorTypes.dxTextBox, - ColSpan = 1, - CaptionName = "App.Listform.ListformField.Description", - Width = 0, - ListOrderNo = 3, - Visible = true, - IsActive = true, - - ColumnCustomizationJson = DefaultColumnCustomizationJson, - PermissionJson = DefaultFieldPermissionJson(listForm.Name), - PivotSettingsJson = DefaultPivotSettingsJson - }, - new ListFormField { ListFormCode = listForm.ListFormCode, CultureName = LanguageCodes.En, @@ -4588,7 +4575,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency ColSpan = 1, CaptionName = "App.Listform.ListformField.ListFormCode", Width = 0, - ListOrderNo = 4, + ListOrderNo = 3, Visible = true, IsActive = true, @@ -4612,7 +4599,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency EditorOptions = EditorOptionValues.ShowClearButton, CaptionName = "App.Listform.ListformField.ListFormType", Width = 0, - ListOrderNo = 5, + ListOrderNo = 4, Visible = true, IsActive = true, @@ -4623,7 +4610,6 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency LookupQuery = JsonSerializer.Serialize(new LookupDataDto[] { new() { Key = ListFormTypeEnum.Form, Name = "App.StaticLookup.Form" }, new() { Key = ListFormTypeEnum.List, Name = "App.StaticLookup.List" }, - new() { Key = ListFormTypeEnum.Chart, Name = "App.Platform.Chart" }, }), }), ValidationRuleJson = DefaultValidationRuleRequiredJson, @@ -4632,13 +4618,36 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency PivotSettingsJson = DefaultPivotSettingsJson }, new ListFormField + { + ListFormCode = listForm.ListFormCode, + CultureName = LanguageCodes.En, + SourceDbType = DbType.String, + FieldName = "DataSourceCode", + EditGroupOrderNo = 1, + EditOrderNo = 5, + EditorType2 = EditorTypes.dxSelectBox, + ColSpan = 1, + EditorOptions = EditorOptionValues.ShowClearButton, + CaptionName = "App.Listform.ListformField.DataSourceCode", + Width = 0, + ListOrderNo = 5, + Visible = true, + IsActive = true, + + LookupJson = LookupQueryValues.DefaultLookupQueryJson(nameof(TableNameEnum.DataSource), "Code", "Code"), + ValidationRuleJson = DefaultValidationRuleRequiredJson, + ColumnCustomizationJson = DefaultColumnCustomizationJson, + PermissionJson = DefaultFieldPermissionJson(listForm.Name), + PivotSettingsJson = DefaultPivotSettingsJson + }, + new ListFormField { ListFormCode = listForm.ListFormCode, CultureName = LanguageCodes.En, SourceDbType = DbType.Int32, FieldName = "SelectCommandType", EditGroupOrderNo = 1, - EditOrderNo = 5, + EditOrderNo = 6, EditorType2 = EditorTypes.dxSelectBox, ColSpan = 1, EditorOptions = EditorOptionValues.ShowClearButton, @@ -4653,11 +4662,11 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency DisplayExpr = "name", ValueExpr = "key", LookupQuery = JsonSerializer.Serialize(new LookupDataDto[] { - new() { Key=SelectCommandTypeEnum.Table, Name="App.StaticLookup.Table" }, - new() { Key=SelectCommandTypeEnum.View, Name="App.StaticLookup.View" }, - new() { Key=SelectCommandTypeEnum.TableValuedFunction, Name="App.StaticLookup.TableValuedFunction" }, - new() { Key=SelectCommandTypeEnum.Query, Name="App.StaticLookup.Query" }, - new() { Key=SelectCommandTypeEnum.StoredProcedure, Name="App.StaticLookup.StoredProcedure" }, + new() { Key = SelectCommandTypeEnum.Table, Name="App.StaticLookup.Table" }, + new() { Key = SelectCommandTypeEnum.View, Name="App.StaticLookup.View" }, + new() { Key = SelectCommandTypeEnum.TableValuedFunction, Name="App.StaticLookup.TableValuedFunction" }, + new() { Key = SelectCommandTypeEnum.Query, Name="App.StaticLookup.Query" }, + new() { Key = SelectCommandTypeEnum.StoredProcedure, Name="App.StaticLookup.StoredProcedure" }, }), }), ValidationRuleJson = DefaultValidationRuleRequiredJson, @@ -4672,7 +4681,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency SourceDbType = DbType.String, FieldName = "SelectCommand", EditGroupOrderNo = 1, - EditOrderNo = 6, + EditOrderNo = 7, EditorType2 = EditorTypes.dxTextBox, ColSpan = 1, CaptionName = "App.Listform.ListformField.SelectCommand", @@ -4693,7 +4702,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency SourceDbType = DbType.String, FieldName = "TableName", EditGroupOrderNo = 1, - EditOrderNo = 7, + EditOrderNo = 8, EditorType2 = EditorTypes.dxTextBox, ColSpan = 1, CaptionName = "App.Listform.ListformField.TableName", @@ -4713,7 +4722,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency SourceDbType = DbType.String, FieldName = "KeyFieldName", EditGroupOrderNo = 1, - EditOrderNo = 8, + EditOrderNo = 9, EditorType2 = EditorTypes.dxTextBox, ColSpan = 1, CaptionName = "App.Listform.ListformField.KeyFieldName", @@ -4734,7 +4743,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency SourceDbType = DbType.Int32, FieldName = "KeyFieldDbSourceType", EditGroupOrderNo = 1, - EditOrderNo = 9, + EditOrderNo = 10, EditorType2 = EditorTypes.dxSelectBox, ColSpan = 1, EditorOptions = EditorOptionValues.ShowClearButton, @@ -4750,33 +4759,33 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency DisplayExpr = "name", ValueExpr = "key", LookupQuery = JsonSerializer.Serialize(new LookupDataDto[] { - new() { Key=DbType.AnsiString, Name="App.StaticLookup.AnsiString" }, - new() { Key=DbType.Binary, Name="App.StaticLookup.Binary" }, - new() { Key=DbType.Byte, Name="App.StaticLookup.Byte" }, - new() { Key=DbType.Boolean, Name="App.StaticLookup.Boolean" }, - new() { Key=DbType.Currency, Name="App.Listform.ListformField.Currency" }, - new() { Key=DbType.Date, Name="App.Listform.ListformField.Date" }, - new() { Key=DbType.DateTime, Name="App.StaticLookup.DateTime" }, - new() { Key=DbType.Decimal, Name="App.StaticLookup.Decimal" }, - new() { Key=DbType.Double, Name="App.StaticLookup.Double" }, - new() { Key=DbType.Guid, Name="App.StaticLookup.Guid" }, - new() { Key=DbType.Int16, Name="App.StaticLookup.Int16" }, - new() { Key=DbType.Int32, Name="App.StaticLookup.Int32" }, - new() { Key=DbType.Int64, Name="App.StaticLookup.Int64" }, - new() { Key=DbType.Object, Name="App.StaticLookup.Object" }, - new() { Key=DbType.SByte, Name="App.StaticLookup.SByte" }, - new() { Key=DbType.Single, Name="App.StaticLookup.Single" }, - new() { Key=DbType.String, Name="App.StaticLookup.String" }, - new() { Key=DbType.Time, Name="App.StaticLookup.Time" }, - new() { Key=DbType.UInt16, Name="App.StaticLookup.UInt16" }, - new() { Key=DbType.UInt32, Name="App.StaticLookup.UInt32" }, - new() { Key=DbType.UInt64, Name="App.StaticLookup.UInt64" }, - new() { Key=DbType.VarNumeric, Name="App.StaticLookup.VarNumeric" }, - new() { Key=DbType.AnsiStringFixedLength, Name="App.StaticLookup.AnsiStringFixedLength" }, - new() { Key=DbType.StringFixedLength, Name="App.StaticLookup.StringFixedLength" }, - new() { Key=DbType.Xml, Name="App.StaticLookup.Xml" }, - new() { Key=DbType.DateTime2, Name="App.StaticLookup.DateTime2" }, - new() { Key=DbType.DateTimeOffset, Name="App.StaticLookup.DateTimeOffset" }, + new() { Key = DbType.AnsiString, Name="App.StaticLookup.AnsiString" }, + new() { Key = DbType.Binary, Name="App.StaticLookup.Binary" }, + new() { Key = DbType.Byte, Name="App.StaticLookup.Byte" }, + new() { Key = DbType.Boolean, Name="App.StaticLookup.Boolean" }, + new() { Key = DbType.Currency, Name="App.Listform.ListformField.Currency" }, + new() { Key = DbType.Date, Name="App.Listform.ListformField.Date" }, + new() { Key = DbType.DateTime, Name="App.StaticLookup.DateTime" }, + new() { Key = DbType.Decimal, Name="App.StaticLookup.Decimal" }, + new() { Key = DbType.Double, Name="App.StaticLookup.Double" }, + new() { Key = DbType.Guid, Name="App.StaticLookup.Guid" }, + new() { Key = DbType.Int16, Name="App.StaticLookup.Int16" }, + new() { Key = DbType.Int32, Name="App.StaticLookup.Int32" }, + new() { Key = DbType.Int64, Name="App.StaticLookup.Int64" }, + new() { Key = DbType.Object, Name="App.StaticLookup.Object" }, + new() { Key = DbType.SByte, Name="App.StaticLookup.SByte" }, + new() { Key = DbType.Single, Name="App.StaticLookup.Single" }, + new() { Key = DbType.String, Name="App.StaticLookup.String" }, + new() { Key = DbType.Time, Name="App.StaticLookup.Time" }, + new() { Key = DbType.UInt16, Name="App.StaticLookup.UInt16" }, + new() { Key = DbType.UInt32, Name="App.StaticLookup.UInt32" }, + new() { Key = DbType.UInt64, Name="App.StaticLookup.UInt64" }, + new() { Key = DbType.VarNumeric, Name="App.StaticLookup.VarNumeric" }, + new() { Key = DbType.AnsiStringFixedLength, Name="App.StaticLookup.AnsiStringFixedLength" }, + new() { Key = DbType.StringFixedLength, Name="App.StaticLookup.StringFixedLength" }, + new() { Key = DbType.Xml, Name="App.StaticLookup.Xml" }, + new() { Key = DbType.DateTime2, Name="App.StaticLookup.DateTime2" }, + new() { Key = DbType.DateTimeOffset, Name="App.StaticLookup.DateTimeOffset" }, }), }), ColumnCustomizationJson = DefaultColumnCustomizationJson, @@ -4808,15 +4817,35 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency ListFormCode = listForm.ListFormCode, CultureName = LanguageCodes.En, SourceDbType = DbType.String, - FieldName = "SortMode", + FieldName = "Description", EditGroupOrderNo = 1, EditOrderNo = 12, + EditorType2 = EditorTypes.dxTextBox, + ColSpan = 1, + CaptionName = "App.Listform.ListformField.Description", + Width = 0, + ListOrderNo = 12, + Visible = true, + IsActive = true, + + ColumnCustomizationJson = DefaultColumnCustomizationJson, + PermissionJson = DefaultFieldPermissionJson(listForm.Name), + PivotSettingsJson = DefaultPivotSettingsJson + }, + new ListFormField + { + ListFormCode = listForm.ListFormCode, + CultureName = LanguageCodes.En, + SourceDbType = DbType.String, + FieldName = "SortMode", + EditGroupOrderNo = 1, + EditOrderNo = 13, EditorType2 = EditorTypes.dxSelectBox, ColSpan = 1, EditorOptions = EditorOptionValues.ShowClearButton, CaptionName = "App.Listform.ListformField.SortMode", Width = 0, - ListOrderNo = 12, + ListOrderNo = 13, Visible = true, IsActive = true, @@ -4841,31 +4870,11 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency SourceDbType = DbType.Boolean, FieldName = "IsTenant", EditGroupOrderNo = 1, - EditOrderNo = 16, + EditOrderNo = 14, EditorType2 = EditorTypes.dxCheckBox, ColSpan = 1, CaptionName = "App.Listform.ListformField.IsTenant", Width = 0, - ListOrderNo = 13, - Visible = true, - IsActive = true, - - ColumnCustomizationJson = DefaultColumnCustomizationJson, - PermissionJson = DefaultFieldPermissionJson(listForm.Name), - PivotSettingsJson = DefaultPivotSettingsJson - }, - new ListFormField - { - ListFormCode = listForm.ListFormCode, - CultureName = LanguageCodes.En, - SourceDbType = DbType.Boolean, - FieldName = "IsOrganizationUnit", - EditGroupOrderNo = 1, - EditOrderNo = 17, - EditorType2 = EditorTypes.dxCheckBox, - ColSpan = 1, - CaptionName = "App.Listform.ListformField.IsOrganizationUnit", - Width = 0, ListOrderNo = 14, Visible = true, IsActive = true, @@ -4875,18 +4884,78 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency PivotSettingsJson = DefaultPivotSettingsJson }, new ListFormField + { + ListFormCode = listForm.ListFormCode, + CultureName = LanguageCodes.En, + SourceDbType = DbType.Boolean, + FieldName = "IsBranch", + EditGroupOrderNo = 1, + EditOrderNo = 15, + EditorType2 = EditorTypes.dxCheckBox, + ColSpan = 1, + CaptionName = "App.Listform.ListformField.IsBranch", + Width = 0, + ListOrderNo = 15, + Visible = true, + IsActive = true, + + ColumnCustomizationJson = DefaultColumnCustomizationJson, + PermissionJson = DefaultFieldPermissionJson(listForm.Name), + PivotSettingsJson = DefaultPivotSettingsJson + }, + new ListFormField + { + ListFormCode = listForm.ListFormCode, + CultureName = LanguageCodes.En, + SourceDbType = DbType.Boolean, + FieldName = "IsOrganizationUnit", + EditGroupOrderNo = 1, + EditOrderNo = 16, + EditorType2 = EditorTypes.dxCheckBox, + ColSpan = 1, + CaptionName = "App.Listform.ListformField.IsOrganizationUnit", + Width = 0, + ListOrderNo = 16, + Visible = true, + IsActive = true, + + ColumnCustomizationJson = DefaultColumnCustomizationJson, + PermissionJson = DefaultFieldPermissionJson(listForm.Name), + PivotSettingsJson = DefaultPivotSettingsJson + }, + new ListFormField { ListFormCode = listForm.ListFormCode, CultureName = LanguageCodes.En, SourceDbType = DbType.Boolean, FieldName = "IsSubForm", EditGroupOrderNo = 1, - EditOrderNo = 18, + EditOrderNo = 17, EditorType2 = EditorTypes.dxCheckBox, ColSpan = 1, CaptionName = "App.Listform.ListformField.IsSubForm", Width = 0, - ListOrderNo = 15, + ListOrderNo = 17, + Visible = true, + IsActive = true, + + ColumnCustomizationJson = DefaultColumnCustomizationJson, + PermissionJson = DefaultFieldPermissionJson(listForm.Name), + PivotSettingsJson = DefaultPivotSettingsJson + }, + new ListFormField + { + ListFormCode = listForm.ListFormCode, + CultureName = LanguageCodes.En, + SourceDbType = DbType.Boolean, + FieldName = "ShowNote", + EditGroupOrderNo = 1, + EditOrderNo = 18, + EditorType2 = EditorTypes.dxCheckBox, + ColSpan = 1, + CaptionName = "App.Listform.ListformField.ShowNote", + Width = 0, + ListOrderNo = 18, Visible = true, IsActive = true, @@ -4902,7 +4971,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency FieldName = "PermissionJson", CaptionName = "App.Listform.ListformField.PermissionJson", Width = 0, - ListOrderNo = 16, + ListOrderNo = 19, Visible = false, IsActive = true, @@ -4916,13 +4985,13 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency CultureName = LanguageCodes.En, SourceDbType = DbType.String, FieldName = "DeleteServiceAddress", - EditGroupOrderNo = 1, - EditOrderNo = 13, + EditGroupOrderNo = 2, + EditOrderNo = 1, EditorType2 = EditorTypes.dxTextBox, ColSpan = 1, CaptionName = "App.Listform.ListformField.DeleteServiceAddress", Width = 0, - ListOrderNo = 17, + ListOrderNo = 20, Visible = true, IsActive = true, @@ -4936,13 +5005,13 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency CultureName = LanguageCodes.En, SourceDbType = DbType.String, FieldName = "InsertServiceAddress", - EditGroupOrderNo = 1, - EditOrderNo = 14, + EditGroupOrderNo = 2, + EditOrderNo = 2, EditorType2 = EditorTypes.dxTextBox, ColSpan = 1, CaptionName = "App.Listform.ListformField.InsertServiceAddress", Width = 0, - ListOrderNo = 18, + ListOrderNo = 21, Visible = true, IsActive = true, @@ -4956,13 +5025,13 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency CultureName = LanguageCodes.En, SourceDbType = DbType.String, FieldName = "UpdateServiceAddress", - EditGroupOrderNo = 1, - EditOrderNo = 15, + EditGroupOrderNo = 2, + EditOrderNo = 3, EditorType2 = EditorTypes.dxTextBox, ColSpan = 1, CaptionName = "App.Listform.ListformField.UpdateServiceAddress", Width = 0, - ListOrderNo = 19, + ListOrderNo = 22, Visible = true, IsActive = true, @@ -4977,13 +5046,13 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency SourceDbType = DbType.String, FieldName = "PermissionJson:C", CaptionName = "PermissionJson:C", - EditGroupOrderNo = 2, + EditGroupOrderNo = 3, EditOrderNo = 1, EditorType2 = EditorTypes.dxTextBox, ColSpan = 1, Visible = false, IsActive = false, - ListOrderNo = 20, + ListOrderNo = 23, PermissionJson = DefaultFieldPermissionJson(listForm.Name), }, new ListFormField @@ -4993,13 +5062,13 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency SourceDbType = DbType.String, FieldName = "PermissionJson:R", CaptionName = "PermissionJson:R", - EditGroupOrderNo = 2, + EditGroupOrderNo = 3, EditOrderNo = 2, EditorType2 = EditorTypes.dxTextBox, ColSpan = 1, Visible = false, IsActive = false, - ListOrderNo = 21, + ListOrderNo = 24, PermissionJson = DefaultFieldPermissionJson(listForm.Name), }, new ListFormField @@ -5009,13 +5078,13 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency SourceDbType = DbType.String, FieldName = "PermissionJson:U", CaptionName = "PermissionJson:U", - EditGroupOrderNo = 2, + EditGroupOrderNo = 3, EditOrderNo = 3, EditorType2 = EditorTypes.dxTextBox, ColSpan = 1, Visible = false, IsActive = false, - ListOrderNo = 22, + ListOrderNo = 25, PermissionJson = DefaultFieldPermissionJson(listForm.Name), }, new ListFormField @@ -5025,13 +5094,13 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency SourceDbType = DbType.String, FieldName = "PermissionJson:D", CaptionName = "PermissionJson:D", - EditGroupOrderNo = 2, + EditGroupOrderNo = 3, EditOrderNo = 4, EditorType2 = EditorTypes.dxTextBox, ColSpan = 1, Visible = false, IsActive = false, - ListOrderNo = 23, + ListOrderNo = 26, PermissionJson = DefaultFieldPermissionJson(listForm.Name), }, ]); diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs b/api/src/Sozsoft.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs index 8a56a496..dae86dab 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs @@ -353,6 +353,7 @@ public class PlatformDbContext : b.Property(a => a.Title).HasMaxLength(256); b.Property(a => a.SortMode).HasMaxLength(20); b.Property(a => a.PageSize).HasDefaultValue(50); + b.Property(a => a.FullHeight).HasDefaultValue(false); b.Property(a => a.UpdateServiceAddress).HasMaxLength(256); b.Property(a => a.InsertServiceAddress).HasMaxLength(256); b.Property(a => a.DeleteServiceAddress).HasMaxLength(256); diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260824093234_Initial.Designer.cs b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260826070015_Initial.Designer.cs similarity index 99% rename from api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260824093234_Initial.Designer.cs rename to api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260826070015_Initial.Designer.cs index 19e209e0..4452a68b 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260824093234_Initial.Designer.cs +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260826070015_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace Sozsoft.Platform.Migrations { [DbContext(typeof(PlatformDbContext))] - [Migration("20260824093234_Initial")] + [Migration("20260826070015_Initial")] partial class Initial { /// @@ -3349,7 +3349,9 @@ namespace Sozsoft.Platform.Migrations .HasColumnType("nvarchar(max)"); b.Property("FullHeight") - .HasColumnType("bit"); + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); b.Property("GanttOptionJson") .HasColumnType("nvarchar(max)"); diff --git a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260824093234_Initial.cs b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260826070015_Initial.cs similarity index 99% rename from api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260824093234_Initial.cs rename to api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260826070015_Initial.cs index 0e238666..24a07b25 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260824093234_Initial.cs +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/20260826070015_Initial.cs @@ -1469,7 +1469,7 @@ namespace Sozsoft.Platform.Migrations PageSize = table.Column(type: "int", nullable: false, defaultValue: 50), Width = table.Column(type: "int", nullable: true), Height = table.Column(type: "int", nullable: true), - FullHeight = table.Column(type: "bit", nullable: false), + FullHeight = table.Column(type: "bit", nullable: false, defaultValue: false), DefaultFilter = table.Column(type: "nvarchar(max)", nullable: true), ColumnOptionJson = table.Column(type: "nvarchar(max)", nullable: true), PivotOptionJson = 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 ea97aea0..86b55864 100644 --- a/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs +++ b/api/src/Sozsoft.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs @@ -3346,7 +3346,9 @@ namespace Sozsoft.Platform.Migrations .HasColumnType("nvarchar(max)"); b.Property("FullHeight") - .HasColumnType("bit"); + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); b.Property("GanttOptionJson") .HasColumnType("nvarchar(max)"); diff --git a/ui/src/views/admin/listForm/wizard/Wizard.tsx b/ui/src/views/admin/listForm/wizard/Wizard.tsx index ab2274bf..4427cd2f 100644 --- a/ui/src/views/admin/listForm/wizard/Wizard.tsx +++ b/ui/src/views/admin/listForm/wizard/Wizard.tsx @@ -4,7 +4,7 @@ import { SelectBoxOption } from '@/types/shared' import { useLocalization } from '@/utils/hooks/useLocalization' import { Form, Formik, FormikProps } from 'formik' import type { KeyboardEvent } from 'react' -import { useCallback, useEffect, useRef, useState } from 'react' +import { Suspense, lazy, useCallback, useEffect, useRef, useState } from 'react' import PageTitle from '@/components/shared/PageTitle' import { useLocation, useNavigate } from 'react-router-dom' import * as Yup from 'yup' @@ -14,24 +14,10 @@ import { getDataSources } from '@/services/data-source.service' import { sqlObjectManagerService } from '@/services/sql-query-manager.service' import type { SqlObjectExplorerDto, DatabaseColumnDto } from '@/proxy/sql-query-manager/models' import { MenuItem } from '@/proxy/menus/menu' -// Adım bileşenleri, sihirbazda göründükleri sırayla. -import WizardStepMenu, { - MenuTreeNode, - buildMenuTree, - filterNonLinkNodes, - findRootCode, -} from './WizardStepMenu' -import WizardStepDataSettings from './WizardStepDataSettings' -import WizardStepFields, { WizardGroup, WizardGroupItem } from './WizardStepFields' -import WizardStepSubForms from './WizardStepSubForms' -import WizardStepWidgets from './WizardStepWidgets' -import WizardStepWorkflow from './WizardStepWorkflow' -import WizardStepTodoLayout from './WizardStepTodoLayout' -import WizardStepTreeLayout from './WizardStepTreeLayout' -import WizardStepGanttLayout from './WizardStepGanttLayout' -import WizardStepSchedulerLayout from './WizardStepSchedulerLayout' -import WizardStepDeploy from './WizardStepDeploy' +import { MenuTreeNode, buildMenuTree, filterNonLinkNodes, findRootCode } from './menuTree' +import type { WizardGroup, WizardGroupItem } from './WizardStepFields' import { Container } from '@/components/shared' +import Loading from '@/components/shared/Loading' import { sqlDataTypeToDbType } from '../edit/options' import { useStoreActions } from '@/store/store' import { useStoreState } from '@/store' @@ -42,8 +28,6 @@ import { postListFormWizard, } from '@/services/wizard.service' import { ListFormWizardDto, WizardComponentKindEnum } from '@/proxy/admin/wizard/models' -import WizardStepComponent from './WizardStepComponent' -import WizardStepCustomComponent from './WizardStepCustomComponent' import { ListFormWorkflowCriteriaDto, SubFormDto, @@ -54,6 +38,22 @@ import { SelectCommandTypeEnum, } from '@/proxy/form/models' +// Adım bileşenleri, sihirbazda göründükleri sırayla. Her adım kendi paketinde yüklenir; +// aynı anda yalnızca görünen adım indirilir, sihirbaz açılışı adım sayısından bağımsız kalır. +const WizardStepMenu = lazy(() => import('./WizardStepMenu')) +const WizardStepDataSettings = lazy(() => import('./WizardStepDataSettings')) +const WizardStepFields = lazy(() => import('./WizardStepFields')) +const WizardStepSubForms = lazy(() => import('./WizardStepSubForms')) +const WizardStepWidgets = lazy(() => import('./WizardStepWidgets')) +const WizardStepWorkflow = lazy(() => import('./WizardStepWorkflow')) +const WizardStepTodoLayout = lazy(() => import('./WizardStepTodoLayout')) +const WizardStepTreeLayout = lazy(() => import('./WizardStepTreeLayout')) +const WizardStepGanttLayout = lazy(() => import('./WizardStepGanttLayout')) +const WizardStepSchedulerLayout = lazy(() => import('./WizardStepSchedulerLayout')) +const WizardStepDeploy = lazy(() => import('./WizardStepDeploy')) +const WizardStepComponent = lazy(() => import('./WizardStepComponent')) +const WizardStepCustomComponent = lazy(() => import('./WizardStepCustomComponent')) + // ─── Formik initial values & validation ────────────────────────────────────── const initialValues: ListFormWizardDto = { wizardName: '', @@ -1306,211 +1306,213 @@ const Wizard = () => {
= 2 ? undefined : 'sm'}> - {/* ─── Step 1: Component Type (yol ayrımı) ─────────────── */} - {resolvedStep === STEP.component && ( - - setCurrentStep( - values.componentKind === WizardComponentKindEnum.Custom - ? STEP.customComponent - : STEP.menu, - ) - } - /> - )} + }> + {/* ─── Step 1: Component Type (yol ayrımı) ─────────────── */} + {resolvedStep === STEP.component && ( + + setCurrentStep( + values.componentKind === WizardComponentKindEnum.Custom + ? STEP.customComponent + : STEP.menu, + ) + } + /> + )} - {/* ─── Step 2: Custom Component seçimi ─────────────────── */} - {resolvedStep === STEP.customComponent && ( - setCurrentStep(STEP.component)} - onNext={() => setCurrentStep(STEP.menu)} - /> - )} + {/* ─── Step 2: Custom Component seçimi ─────────────────── */} + {resolvedStep === STEP.customComponent && ( + setCurrentStep(STEP.component)} + onNext={() => setCurrentStep(STEP.menu)} + /> + )} - {/* ─── Step 3: Menu ───────────────────────────────────── */} - {resolvedStep === STEP.menu && ( - - setCurrentStep( - values.componentKind === WizardComponentKindEnum.Custom - ? STEP.customComponent - : STEP.component, - ) - } - onNext={() => - handleMenuNext(values.componentKind === WizardComponentKindEnum.Custom) - } - translate={translate} - /> - )} + {/* ─── Step 3: Menu ───────────────────────────────────── */} + {resolvedStep === STEP.menu && ( + + setCurrentStep( + values.componentKind === WizardComponentKindEnum.Custom + ? STEP.customComponent + : STEP.component, + ) + } + onNext={() => + handleMenuNext(values.componentKind === WizardComponentKindEnum.Custom) + } + translate={translate} + /> + )} - {/* ─── Step 4: Data Settings ───────────────────────────── */} - {resolvedStep === STEP.settings && ( - { - setSelectCommandColumns([]) - setSelectedColumns(new Set()) - }} - onToggleColumn={toggleColumn} - onToggleAllColumns={(all) => toggleAllColumns(all, values.isTenant)} - onTenantChange={handleTenantChange} - translate={translate} - onBack={handleBack} - onNext={handleNext2} - /> - )} + {/* ─── Step 4: Data Settings ───────────────────────────── */} + {resolvedStep === STEP.settings && ( + { + setSelectCommandColumns([]) + setSelectedColumns(new Set()) + }} + onToggleColumn={toggleColumn} + onToggleAllColumns={(all) => toggleAllColumns(all, values.isTenant)} + onTenantChange={handleTenantChange} + translate={translate} + onBack={handleBack} + onNext={handleNext2} + /> + )} - {/* ─── Step 5: List Form Fields ───────────────────────────── */} - {resolvedStep === STEP.fields && ( - setCurrentStep(STEP.settings)} - onNext={() => setCurrentStep(STEP.subForms)} - /> - )} + {/* ─── Step 5: List Form Fields ───────────────────────────── */} + {resolvedStep === STEP.fields && ( + setCurrentStep(STEP.settings)} + onNext={() => setCurrentStep(STEP.subForms)} + /> + )} - {/* ─── Step 6: Sub Forms ───────────────────────────── */} - {resolvedStep === STEP.subForms && ( - setCurrentStep(STEP.fields)} - onNext={() => setCurrentStep(STEP.widgets)} - /> - )} + {/* ─── Step 6: Sub Forms ───────────────────────────── */} + {resolvedStep === STEP.subForms && ( + setCurrentStep(STEP.fields)} + onNext={() => setCurrentStep(STEP.widgets)} + /> + )} - {/* ─── Step 7: Widgets ───────────────────────────── */} - {resolvedStep === STEP.widgets && ( - setCurrentStep(STEP.subForms)} - onNext={() => setCurrentStep(STEP.workflow)} - /> - )} + {/* ─── Step 7: Widgets ───────────────────────────── */} + {resolvedStep === STEP.widgets && ( + setCurrentStep(STEP.subForms)} + onNext={() => setCurrentStep(STEP.workflow)} + /> + )} - {/* ─── Step 8: Workflow ───────────────────────────── */} - {resolvedStep === STEP.workflow && ( - setCurrentStep(STEP.widgets)} - onNext={() => goToAdjacentStep(1)} - /> - )} + {/* ─── Step 8: Workflow ───────────────────────────── */} + {resolvedStep === STEP.workflow && ( + setCurrentStep(STEP.widgets)} + onNext={() => goToAdjacentStep(1)} + /> + )} - {/* ─── Step 9: Todo / Kanban ────────────────────── */} - {resolvedStep === STEP.todo && values.todo && ( - goToAdjacentStep(-1)} - onNext={() => goToAdjacentStep(1)} - /> - )} + {/* ─── Step 9: Todo / Kanban ────────────────────── */} + {resolvedStep === STEP.todo && values.todo && ( + goToAdjacentStep(-1)} + onNext={() => goToAdjacentStep(1)} + /> + )} - {/* ─── Step 10: Tree ─────────────────────────────── */} - {resolvedStep === STEP.tree && values.tree && ( - goToAdjacentStep(-1)} - onNext={() => goToAdjacentStep(1)} - /> - )} + {/* ─── Step 10: Tree ─────────────────────────────── */} + {resolvedStep === STEP.tree && values.tree && ( + goToAdjacentStep(-1)} + onNext={() => goToAdjacentStep(1)} + /> + )} - {/* ─── Step 11: Gantt ────────────────────────────── */} - {resolvedStep === STEP.gantt && values.gantt && ( - goToAdjacentStep(-1)} - onNext={() => goToAdjacentStep(1)} - /> - )} + {/* ─── Step 11: Gantt ────────────────────────────── */} + {resolvedStep === STEP.gantt && values.gantt && ( + goToAdjacentStep(-1)} + onNext={() => goToAdjacentStep(1)} + /> + )} - {/* ─── Step 12: Scheduler ───────────────────────── */} - {resolvedStep === STEP.scheduler && values.scheduler && ( - goToAdjacentStep(-1)} - onNext={() => goToAdjacentStep(1)} - /> - )} + {/* ─── Step 12: Scheduler ───────────────────────── */} + {resolvedStep === STEP.scheduler && values.scheduler && ( + goToAdjacentStep(-1)} + onNext={() => goToAdjacentStep(1)} + /> + )} - {/* ─── Step 13: Deploy ──────────────────────────── */} - {resolvedStep === STEP.deploy && ( - goToAdjacentStep(-1)} - onSubmit={handleDeploy} - /> - )} + {/* ─── Step 13: Deploy ──────────────────────────── */} + {resolvedStep === STEP.deploy && ( + goToAdjacentStep(-1)} + onSubmit={handleDeploy} + /> + )} +
diff --git a/ui/src/views/admin/listForm/wizard/WizardStepMenu.tsx b/ui/src/views/admin/listForm/wizard/WizardStepMenu.tsx index e3eabbfc..fc2e8504 100644 --- a/ui/src/views/admin/listForm/wizard/WizardStepMenu.tsx +++ b/ui/src/views/admin/listForm/wizard/WizardStepMenu.tsx @@ -29,74 +29,7 @@ import { import { useLocalization } from '@/utils/hooks/useLocalization' import { IconPickerField, MenuAddDialog } from '@/views/shared/MenuAddDialog' import { ListFormWizardDto, WizardComponentKindEnum } from '@/proxy/admin/wizard/models' - -// ─── Types (exported for Wizard.tsx) ───────────────────────────────────────── - -export interface MenuTreeNode { - code: string - displayName: string - shortName?: string - icon?: string - url?: string - order?: number - children: MenuTreeNode[] -} - -// ─── Helpers (exported for Wizard.tsx) ─────────────────────────────────────── - -export function buildMenuTree(items: MenuItem[]): MenuTreeNode[] { - const map = new Map() - const roots: MenuTreeNode[] = [] - items.forEach((item) => { - map.set(item.code!, { - code: item.code!, - displayName: item.displayName ?? item.code!, - shortName: item.shortName ?? undefined, - icon: item.icon ?? undefined, - url: item.url ?? undefined, - order: item.order ?? undefined, - children: [], - }) - }) - items.forEach((item) => { - const node = map.get(item.code!)! - if (item.parentCode && map.has(item.parentCode)) { - map.get(item.parentCode)!.children.push(node) - } else { - roots.push(node) - } - }) - return roots -} - -export function filterNonLinkNodes(nodes: MenuTreeNode[]): MenuTreeNode[] { - return nodes - .filter((n) => !n.url) - .map((n) => ({ ...n, children: filterNonLinkNodes(n.children) })) -} - -/** code → parentCode haritası; her aramada listeyi taramamak için. */ -function buildParentMap(rawItems: MenuItem[]): Map { - const map = new Map() - rawItems.forEach((item) => { - if (item.code) map.set(item.code, item.parentCode ?? undefined) - }) - return map -} - -export function findRootCode(rawItems: MenuItem[], code: string): string { - const parents = buildParentMap(rawItems) - const visited = new Set() - let current = code - // visited: veri bozulsa bile (döngüsel parent) sonsuz döngüye girilmez - while (!visited.has(current)) { - visited.add(current) - const parentCode = parents.get(current) - if (!parentCode) return current - current = parentCode - } - return current -} +import { MenuTreeNode, findRootCode, getAncestorCodes } from './menuTree' // ─── MenuService singleton ──────────────────────────────────────────────────── @@ -233,20 +166,6 @@ function TreeNode({ // ─── MenuTreeInline ─────────────────────────────────────────────────────────── -/** Returns all ancestor codes of `code` in the flat rawItems list */ -function getAncestorCodes(rawItems: MenuItem[], code: string): Set { - const parents = buildParentMap(rawItems) - const result = new Set() - let current = code - while (true) { - const parentCode = parents.get(current) - if (!parentCode || result.has(parentCode)) break - result.add(parentCode) - current = parentCode - } - return result -} - interface MenuTreeInlineProps { value: string onChange: (code: string) => void diff --git a/ui/src/views/admin/listForm/wizard/menuTree.ts b/ui/src/views/admin/listForm/wizard/menuTree.ts new file mode 100644 index 00000000..213ee6dc --- /dev/null +++ b/ui/src/views/admin/listForm/wizard/menuTree.ts @@ -0,0 +1,84 @@ +import { MenuItem } from '@/proxy/menus/menu' + +/** + * Menu agaci yardimcilari. Adim bilesenlerinden ayri bir modulde durur; boylece Wizard ve + * SqlTableDesignerDialog bu fonksiyonlari kullanirken adim bilesenlerini (ve onlarin + * bagimliliklarini) pakete cekmez, adimlar lazy yuklenebilir. + */ +export interface MenuTreeNode { + code: string + displayName: string + shortName?: string + icon?: string + url?: string + order?: number + children: MenuTreeNode[] +} + +export function buildMenuTree(items: MenuItem[]): MenuTreeNode[] { + const map = new Map() + const roots: MenuTreeNode[] = [] + items.forEach((item) => { + map.set(item.code!, { + code: item.code!, + displayName: item.displayName ?? item.code!, + shortName: item.shortName ?? undefined, + icon: item.icon ?? undefined, + url: item.url ?? undefined, + order: item.order ?? undefined, + children: [], + }) + }) + items.forEach((item) => { + const node = map.get(item.code!)! + if (item.parentCode && map.has(item.parentCode)) { + map.get(item.parentCode)!.children.push(node) + } else { + roots.push(node) + } + }) + return roots +} + +export function filterNonLinkNodes(nodes: MenuTreeNode[]): MenuTreeNode[] { + return nodes + .filter((n) => !n.url) + .map((n) => ({ ...n, children: filterNonLinkNodes(n.children) })) +} + +/** code → parentCode haritası; her aramada listeyi taramamak için. */ +function buildParentMap(rawItems: MenuItem[]): Map { + const map = new Map() + rawItems.forEach((item) => { + if (item.code) map.set(item.code, item.parentCode ?? undefined) + }) + return map +} + +export function findRootCode(rawItems: MenuItem[], code: string): string { + const parents = buildParentMap(rawItems) + const visited = new Set() + let current = code + // visited: veri bozulsa bile (döngüsel parent) sonsuz döngüye girilmez + while (!visited.has(current)) { + visited.add(current) + const parentCode = parents.get(current) + if (!parentCode) return current + current = parentCode + } + return current +} + +/** Returns all ancestor codes of `code` in the flat rawItems list */ +export function getAncestorCodes(rawItems: MenuItem[], code: string): Set { + const parents = buildParentMap(rawItems) + const result = new Set() + let current = code + while (true) { + const parentCode = parents.get(current) + if (!parentCode || result.has(parentCode)) break + result.add(parentCode) + current = parentCode + } + return result +} diff --git a/ui/src/views/developerKit/SqlTableDesignerDialog.tsx b/ui/src/views/developerKit/SqlTableDesignerDialog.tsx index 4b65ba97..ea052a05 100644 --- a/ui/src/views/developerKit/SqlTableDesignerDialog.tsx +++ b/ui/src/views/developerKit/SqlTableDesignerDialog.tsx @@ -1,4 +1,4 @@ -import React, { useState, useCallback, useMemo, useEffect, useRef } from 'react' +import React, { useState, useCallback, useMemo, useEffect, useRef } from 'react' import { createPortal } from 'react-dom' import { Button, Checkbox, Dialog, Notification, Select, toast } from '@/components/ui' import { @@ -35,7 +35,7 @@ import { MenuTreeNode, buildMenuTree, filterNonLinkNodes, -} from '@/views/admin/listForm/wizard/WizardStepMenu' +} from '@/views/admin/listForm/wizard/menuTree' import { MenuAddDialog } from '../shared/MenuAddDialog' import { useStoreActions, useStoreState } from '@/store' import { usePermission } from '@/utils/hooks/usePermission'