From 9d5c5ccf09b2f4be6839dc3fc56eb9c88c4b2176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96ZT=C3=9CRK?= <76204082+iamsedatozturk@users.noreply.github.com> Date: Mon, 30 Mar 2026 12:16:28 +0300 Subject: [PATCH] =?UTF-8?q?Duplicate=20Record=20d=C3=BCzenlemesi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ListFormQueryPreviewAppService.cs | 1 + .../ListForms/ListFormDataAppService.cs | 54 +++- .../Seeds/LanguagesData.json | 6 + .../Seeds/ListFormSeeder_Administration.cs | 300 +++++++++--------- .../Seeds/ListFormSeeder_Saas.cs | 5 +- .../ListForms/ListFormManager.cs | 2 +- .../Queries/DefaultValueManager.cs | 2 + .../Queries/QueryManager.cs | 58 +--- ui/src/views/list/useListFormColumns.ts | 11 +- 9 files changed, 215 insertions(+), 224 deletions(-) diff --git a/api/src/Sozsoft.Platform.Application/ListForms/Administration/ListFormQueryPreviewAppService.cs b/api/src/Sozsoft.Platform.Application/ListForms/Administration/ListFormQueryPreviewAppService.cs index f1ad979..9fd73cd 100644 --- a/api/src/Sozsoft.Platform.Application/ListForms/Administration/ListFormQueryPreviewAppService.cs +++ b/api/src/Sozsoft.Platform.Application/ListForms/Administration/ListFormQueryPreviewAppService.cs @@ -83,6 +83,7 @@ public class ListFormQueryPreviewAppService : PlatformAppService { var authType = op switch { + OperationEnum.Duplicate => AuthorizationTypeEnum.Create, OperationEnum.Insert => AuthorizationTypeEnum.Create, OperationEnum.Update => AuthorizationTypeEnum.Update, OperationEnum.Delete => AuthorizationTypeEnum.Delete, diff --git a/api/src/Sozsoft.Platform.Application/ListForms/ListFormDataAppService.cs b/api/src/Sozsoft.Platform.Application/ListForms/ListFormDataAppService.cs index 824fb23..3f333f1 100644 --- a/api/src/Sozsoft.Platform.Application/ListForms/ListFormDataAppService.cs +++ b/api/src/Sozsoft.Platform.Application/ListForms/ListFormDataAppService.cs @@ -6,6 +6,8 @@ using Sozsoft.Platform.Localization; using Sozsoft.Platform.Queries; using Microsoft.AspNetCore.Http; using static Sozsoft.Platform.PlatformConsts; +using System.Collections.Generic; +using System.Text.Json; namespace Sozsoft.Platform.ListForms.Select; @@ -14,15 +16,18 @@ public class ListFormDataAppService : PlatformAppService private readonly IListFormAuthorizationManager authManager; private readonly IQueryManager qManager; private readonly IHttpContextAccessor httpContextAccessor; + private readonly IListFormSelectAppService listFormSelectAppService; public ListFormDataAppService( IListFormAuthorizationManager authManager, IQueryManager qManager, - IHttpContextAccessor httpContextAccessor) + IHttpContextAccessor httpContextAccessor, + IListFormSelectAppService listFormSelectAppService) { this.authManager = authManager; this.qManager = qManager; this.httpContextAccessor = httpContextAccessor; + this.listFormSelectAppService = listFormSelectAppService; LocalizationResource = typeof(PlatformResource); } @@ -38,6 +43,39 @@ public class ListFormDataAppService : PlatformAppService var queryParameters = httpContext.Request.Query.ToDictionary(x => x.Key, x => x.Value); return await qManager.GenerateAndRunQueryAsync(input.ListFormCode, OperationEnum.Insert, input.Data, queryParameters: queryParameters); } + + public async Task PostDuplicateAsync(DataRequestDto input) + { + // Izin logic process + if (!await authManager.CanAccess(input.ListFormCode, AuthorizationTypeEnum.Create)) + throw new Volo.Abp.UserFriendlyException(L[AppErrorCodes.NoAuth]); + + var httpContext = httpContextAccessor.HttpContext + ?? throw new InvalidOperationException("HTTP Context bulunamadı."); + + var queryParameters = httpContext.Request.Query.ToDictionary(x => x.Key, x => x.Value); + + object filter = new object[] { input.Data[0], "=", input.Keys[0] }; + + var selectRequest = new SelectRequestDto + { + ListFormCode = input.ListFormCode, + Filter = filter.ToString(), + Skip = 0, + Take = 1, + RequireTotalCount = false, + RequireGroupCount = false, + }; + var selectResult = await listFormSelectAppService.GetSelectAsync(selectRequest); + var record = ((selectResult?.Data as System.Collections.IEnumerable)?.Cast()?.FirstOrDefault()) ?? throw new Volo.Abp.UserFriendlyException("Kopyalanacak kayıt bulunamadı."); + + if (record is not IDictionary dict) + throw new Exception("DapperRow IDictionary'e çevrilemedi."); + + input.Data = JsonSerializer.Serialize(dict); + + return await qManager.GenerateAndRunQueryAsync(input.ListFormCode, OperationEnum.Duplicate, input.Data, null, queryParameters); + } public async Task PostUpdateAsync(DataRequestDto input) { @@ -64,19 +102,5 @@ public class ListFormDataAppService : PlatformAppService var queryParameters = httpContext.Request.Query.ToDictionary(x => x.Key, x => x.Value); return await qManager.GenerateAndRunQueryAsync(input.ListFormCode, OperationEnum.Delete, input.Data, input.Keys, queryParameters); } - - public async Task PostDuplicateAsync(DataRequestDto input) - { - // Izin logic process - if (!await authManager.CanAccess(input.ListFormCode, AuthorizationTypeEnum.Create)) - throw new Volo.Abp.UserFriendlyException(L[AppErrorCodes.NoAuth]); - - var httpContext = httpContextAccessor.HttpContext - ?? throw new InvalidOperationException("HTTP Context bulunamadı."); - - var queryParameters = httpContext.Request.Query.ToDictionary(x => x.Key, x => x.Value); - // Duplicate işlemi için OperationEnum.Duplicate kullanılır - return await qManager.GenerateAndRunQueryAsync(input.ListFormCode, OperationEnum.Duplicate, input.Data, input.Keys, queryParameters); - } } diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json b/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json index d7ff9d1..3b6549d 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json @@ -10356,6 +10356,12 @@ "tr": "Çoğaltma Hatası", "en": "Duplicate Error" }, + { + "resourceName": "Platform", + "key": "App.Platform.DuplicateConfirm", + "tr": "Kopyalama işlemini onaylıyor musunuz?", + "en": "Do you confirm the duplication process?" + }, { "resourceName": "Platform", "key": "App.Platform.Warning", diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Administration.cs b/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Administration.cs index 1bac9b0..f06b24f 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Administration.cs +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Administration.cs @@ -1016,150 +1016,6 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep } #endregion - #region Ip Restriction - listFormName = AppCodes.Restrictions.IpRestrictions; - if (!await _listFormRepository.AnyAsync(a => a.ListFormCode == listFormName)) - { - var listForm = await _listFormRepository.InsertAsync( - new ListForm() - { - ListFormType = ListFormTypeEnum.List, - PageSize = 10, - ExportJson = DefaultExportJson, - IsSubForm = false, - ShowNote = true, - LayoutJson = DefaultLayoutJson(), - CultureName = LanguageCodes.En, - ListFormCode = listFormName, - Name = listFormName, - Title = listFormName, - DataSourceCode = SeedConsts.DataSources.DefaultCode, - IsTenant = true, - IsBranch = false, - IsOrganizationUnit = false, - Description = listFormName, - SelectCommandType = SelectCommandTypeEnum.Table, - SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.IpRestriction)), - KeyFieldName = "Id", - KeyFieldDbSourceType = DbType.Guid, - DefaultFilter = DefaultFilterJson, - SortMode = GridOptions.SortModeSingle, - FilterRowJson = DefaultFilterRowJson, - HeaderFilterJson = DefaultHeaderFilterJson, - SearchPanelJson = DefaultSearchPanelJson, - GroupPanelJson = DefaultGroupPanelJson, - SelectionJson = DefaultSelectionSingleJson, - ColumnOptionJson = DefaultColumnOptionJson(), - PermissionJson = DefaultPermissionJson(listFormName), - DeleteCommand = $"UPDATE \"{FullNameTable(TableNameEnum.IpRestriction)}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id", - DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(), - PagerOptionJson = DefaultPagerOptionJson, - EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 350, true, true, true, true, false), - EditingFormJson = JsonSerializer.Serialize(new List() { - new() { - Order=1, ColCount=1, ColSpan=1, ItemType="group", Items= - [ - new EditingFormItemDto { Order = 1, DataField = "ResourceType", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton }, - new EditingFormItemDto { Order = 2, DataField = "ResourceId", ColSpan = 1, EditorType2=EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton }, - new EditingFormItemDto { Order = 3, DataField = "IP", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxTextBox }, - ]} - }), - InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(), - } - ); - - #region Ip Restriction Fields - await _listFormFieldRepository.InsertManyAsync([ - new() { - ListFormCode = listForm.ListFormCode, - CultureName = LanguageCodes.En, - SourceDbType = DbType.Guid, - FieldName = "Id", - CaptionName = "App.Listform.ListformField.Id", - Width = 100, - ListOrderNo = 1, - Visible = false, - IsActive = true, - IsDeleted = false, - ColumnCustomizationJson = DefaultColumnCustomizationJson, - PermissionJson = DefaultFieldPermissionJson(listForm.Name), - PivotSettingsJson = DefaultPivotSettingsJson - }, - new() { - ListFormCode = listForm.ListFormCode, - CultureName = LanguageCodes.En, - SourceDbType = DbType.String, - FieldName = "ResourceType", - CaptionName = "App.Listform.ListformField.ResourceType", - Width = 400, - ListOrderNo = 2, - Visible = true, - IsActive = true, - IsDeleted = false, - SortIndex = 1, - SortDirection = GridColumnOptions.SortOrderAsc, - AllowSearch = true, - LookupJson = JsonSerializer.Serialize(new LookupDto - { - DataSourceType = UiLookupDataSourceTypeEnum.StaticData, - DisplayExpr = "name", - ValueExpr = "key", - LookupQuery = JsonSerializer.Serialize(new LookupDataDto[] { - new () { Key="User", Name="User" }, - new () { Key="Role", Name="Role" }, - new () { Key="Global", Name="Global" }, - }), - }), - ValidationRuleJson = DefaultValidationRuleRequiredJson, - ColumnCustomizationJson = DefaultColumnCustomizationJson, - PermissionJson = DefaultFieldPermissionJson(listForm.Name), - PivotSettingsJson = DefaultPivotSettingsJson - }, - new() { - ListFormCode = listForm.ListFormCode, - CultureName = LanguageCodes.En, - SourceDbType = DbType.String, - FieldName = "ResourceId", - CaptionName = "App.Listform.ListformField.ResourceId", - Width = 400, - ListOrderNo = 3, - Visible = true, - IsActive = true, - IsDeleted = false, - AllowSearch = true, - LookupJson = JsonSerializer.Serialize(new LookupDto { - DataSourceType = UiLookupDataSourceTypeEnum.Query, - DisplayExpr = "Name", - ValueExpr = "Key", - LookupQuery = $"SELECT \"UserName\" AS \"Key\", \"UserName\" AS \"Name\" FROM \"AbpUsers\" UNION SELECT \"Name\" AS \"Key\", \"Name\" AS \"Name\" FROM \"AbpRoles\"", - }), - ColumnCustomizationJson = DefaultColumnCustomizationJson, - PermissionJson = DefaultFieldPermissionJson(listForm.Name), - PivotSettingsJson = DefaultPivotSettingsJson - }, - new() - { - ListFormCode = listForm.ListFormCode, - CultureName = LanguageCodes.En, - SourceDbType = DbType.String, - FieldName = "IP", - CaptionName = "App.Listform.ListformField.IP", - Width = 100, - ListOrderNo = 4, - Visible = true, - IsActive = true, - IsDeleted = false, - AllowSearch = true, - ValidationRuleJson = DefaultValidationRuleRequiredJson, - ColumnCustomizationJson = DefaultColumnCustomizationJson, - PermissionJson = DefaultFieldPermissionJson(listForm.Name), - PivotSettingsJson = DefaultPivotSettingsJson - }, - ]); - #endregion - } - #endregion - #region Audit Logs listFormName = AppCodes.IdentityManagement.AuditLogs; if (!await _listFormRepository.AnyAsync(a => a.ListFormCode == listFormName)) @@ -1709,7 +1565,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep SelectCommandType = SelectCommandTypeEnum.Table, SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.Sector)), KeyFieldName = "Id", - KeyFieldDbSourceType = DbType.String, + KeyFieldDbSourceType = DbType.Guid, DefaultFilter = DefaultFilterJson, SortMode = GridOptions.SortModeSingle, FilterRowJson = DefaultFilterRowJson, @@ -1720,9 +1576,9 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep ColumnOptionJson = DefaultColumnOptionJson(), PermissionJson = DefaultPermissionJson(listFormName), DeleteCommand = DefaultDeleteCommand(nameof(TableNameEnum.Sector)), - DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(DbType.String), + DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(), PagerOptionJson = DefaultPagerOptionJson, - InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(DbType.String, "Name"), + InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(), EditingOptionJson = DefaultEditingOptionJson(listFormName, 400, 200, true, true, true, true, false), EditingFormJson = JsonSerializer.Serialize(new List { @@ -1803,7 +1659,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep SelectCommandType = SelectCommandTypeEnum.Table, SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.WorkHour)), KeyFieldName = "Id", - KeyFieldDbSourceType = DbType.String, + KeyFieldDbSourceType = DbType.Guid, DefaultFilter = DefaultFilterJson, SortMode = GridOptions.SortModeSingle, FilterRowJson = DefaultFilterRowJson, @@ -1814,8 +1670,8 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep ColumnOptionJson = DefaultColumnOptionJson(), PermissionJson = DefaultPermissionJson(listFormName), DeleteCommand = DefaultDeleteCommand(nameof(TableNameEnum.WorkHour)), - DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(DbType.String), - InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(DbType.String, "Name"), + DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(), + InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(), PagerOptionJson = DefaultPagerOptionJson, EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 600, true, true, true, true, false), EditingFormJson = JsonSerializer.Serialize(new List() { @@ -2034,6 +1890,150 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep #endregion } #endregion + + #region Ip Restriction + listFormName = AppCodes.Restrictions.IpRestrictions; + if (!await _listFormRepository.AnyAsync(a => a.ListFormCode == listFormName)) + { + var listForm = await _listFormRepository.InsertAsync( + new ListForm() + { + ListFormType = ListFormTypeEnum.List, + PageSize = 10, + ExportJson = DefaultExportJson, + IsSubForm = false, + ShowNote = true, + LayoutJson = DefaultLayoutJson(), + CultureName = LanguageCodes.En, + ListFormCode = listFormName, + Name = listFormName, + Title = listFormName, + DataSourceCode = SeedConsts.DataSources.DefaultCode, + IsTenant = true, + IsBranch = false, + IsOrganizationUnit = false, + Description = listFormName, + SelectCommandType = SelectCommandTypeEnum.Table, + SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.IpRestriction)), + KeyFieldName = "Id", + KeyFieldDbSourceType = DbType.Guid, + DefaultFilter = DefaultFilterJson, + SortMode = GridOptions.SortModeSingle, + FilterRowJson = DefaultFilterRowJson, + HeaderFilterJson = DefaultHeaderFilterJson, + SearchPanelJson = DefaultSearchPanelJson, + GroupPanelJson = DefaultGroupPanelJson, + SelectionJson = DefaultSelectionSingleJson, + ColumnOptionJson = DefaultColumnOptionJson(), + PermissionJson = DefaultPermissionJson(listFormName), + DeleteCommand = $"UPDATE \"{FullNameTable(TableNameEnum.IpRestriction)}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id", + DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(), + PagerOptionJson = DefaultPagerOptionJson, + EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 350, true, true, true, true, false), + EditingFormJson = JsonSerializer.Serialize(new List() { + new() { + Order=1, ColCount=1, ColSpan=1, ItemType="group", Items= + [ + new EditingFormItemDto { Order = 1, DataField = "ResourceType", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton }, + new EditingFormItemDto { Order = 2, DataField = "ResourceId", ColSpan = 1, EditorType2=EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton }, + new EditingFormItemDto { Order = 3, DataField = "IP", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxTextBox }, + ]} + }), + InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(), + } + ); + + #region Ip Restriction Fields + await _listFormFieldRepository.InsertManyAsync([ + new() { + ListFormCode = listForm.ListFormCode, + CultureName = LanguageCodes.En, + SourceDbType = DbType.Guid, + FieldName = "Id", + CaptionName = "App.Listform.ListformField.Id", + Width = 100, + ListOrderNo = 1, + Visible = false, + IsActive = true, + IsDeleted = false, + ColumnCustomizationJson = DefaultColumnCustomizationJson, + PermissionJson = DefaultFieldPermissionJson(listForm.Name), + PivotSettingsJson = DefaultPivotSettingsJson + }, + new() { + ListFormCode = listForm.ListFormCode, + CultureName = LanguageCodes.En, + SourceDbType = DbType.String, + FieldName = "ResourceType", + CaptionName = "App.Listform.ListformField.ResourceType", + Width = 400, + ListOrderNo = 2, + Visible = true, + IsActive = true, + IsDeleted = false, + SortIndex = 1, + SortDirection = GridColumnOptions.SortOrderAsc, + AllowSearch = true, + LookupJson = JsonSerializer.Serialize(new LookupDto + { + DataSourceType = UiLookupDataSourceTypeEnum.StaticData, + DisplayExpr = "name", + ValueExpr = "key", + LookupQuery = JsonSerializer.Serialize(new LookupDataDto[] { + new () { Key="User", Name="User" }, + new () { Key="Role", Name="Role" }, + new () { Key="Global", Name="Global" }, + }), + }), + ValidationRuleJson = DefaultValidationRuleRequiredJson, + ColumnCustomizationJson = DefaultColumnCustomizationJson, + PermissionJson = DefaultFieldPermissionJson(listForm.Name), + PivotSettingsJson = DefaultPivotSettingsJson + }, + new() { + ListFormCode = listForm.ListFormCode, + CultureName = LanguageCodes.En, + SourceDbType = DbType.String, + FieldName = "ResourceId", + CaptionName = "App.Listform.ListformField.ResourceId", + Width = 400, + ListOrderNo = 3, + Visible = true, + IsActive = true, + IsDeleted = false, + AllowSearch = true, + LookupJson = JsonSerializer.Serialize(new LookupDto { + DataSourceType = UiLookupDataSourceTypeEnum.Query, + DisplayExpr = "Name", + ValueExpr = "Key", + LookupQuery = $"SELECT \"UserName\" AS \"Key\", \"UserName\" AS \"Name\" FROM \"AbpUsers\" UNION SELECT \"Name\" AS \"Key\", \"Name\" AS \"Name\" FROM \"AbpRoles\"", + }), + ColumnCustomizationJson = DefaultColumnCustomizationJson, + PermissionJson = DefaultFieldPermissionJson(listForm.Name), + PivotSettingsJson = DefaultPivotSettingsJson + }, + new() + { + ListFormCode = listForm.ListFormCode, + CultureName = LanguageCodes.En, + SourceDbType = DbType.String, + FieldName = "IP", + CaptionName = "App.Listform.ListformField.IP", + Width = 100, + ListOrderNo = 4, + Visible = true, + IsActive = true, + IsDeleted = false, + AllowSearch = true, + ValidationRuleJson = DefaultValidationRuleRequiredJson, + ColumnCustomizationJson = DefaultColumnCustomizationJson, + PermissionJson = DefaultFieldPermissionJson(listForm.Name), + PivotSettingsJson = DefaultPivotSettingsJson + }, + ]); + #endregion + } + #endregion } } diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Saas.cs b/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Saas.cs index 8c58325..dfa913c 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Saas.cs +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Saas.cs @@ -1218,7 +1218,10 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency PagerOptionJson = DefaultPagerOptionJson, DeleteCommand = $"DELETE FROM \"{TableNameResolver.GetFullTableName(nameof(TableNameEnum.AiBot))}\" WHERE \"Id\"=@Id", DeleteFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] { - new() { FieldName = "Id", FieldDbType = DbType.Int32, Value = "@ID", CustomValueType = FieldCustomValueTypeEnum.CustomKey } + new() { FieldName = "Id", FieldDbType = DbType.Guid, Value = "@ID", CustomValueType = FieldCustomValueTypeEnum.CustomKey } + }), + InsertFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] { + new() { FieldName = "Id", FieldDbType = DbType.Guid, Value = "@NEWID", CustomValueType = FieldCustomValueTypeEnum.CustomKey } }), EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 450, true, true, true, true, false), EditingFormJson = JsonSerializer.Serialize(new List() diff --git a/api/src/Sozsoft.Platform.Domain/ListForms/ListFormManager.cs b/api/src/Sozsoft.Platform.Domain/ListForms/ListFormManager.cs index 1efcae4..1a9c048 100644 --- a/api/src/Sozsoft.Platform.Domain/ListForms/ListFormManager.cs +++ b/api/src/Sozsoft.Platform.Domain/ListForms/ListFormManager.cs @@ -7,7 +7,6 @@ using Microsoft.Extensions.Localization; using Microsoft.Extensions.Primitives; using System; using System.Collections.Generic; -using System.Data; using System.Globalization; using System.Linq; using System.Text.Json; @@ -95,6 +94,7 @@ public class ListFormManager : PlatformDomainService, IListFormManager var field = listFormFields.FirstOrDefault(c => c.FieldName == item.Key); if (field == null || (op == OperationEnum.Insert && !field.CanCreate) + || (op == OperationEnum.Duplicate && !field.CanCreate) || (op == OperationEnum.Update && !field.CanUpdate) ) { diff --git a/api/src/Sozsoft.Platform.Domain/Queries/DefaultValueManager.cs b/api/src/Sozsoft.Platform.Domain/Queries/DefaultValueManager.cs index 524509f..291cbba 100644 --- a/api/src/Sozsoft.Platform.Domain/Queries/DefaultValueManager.cs +++ b/api/src/Sozsoft.Platform.Domain/Queries/DefaultValueManager.cs @@ -52,6 +52,7 @@ public class DefaultValueManager : PlatformDomainService, IDefaultValueManager var defaultFieldsJson = op switch { OperationEnum.Insert => listForm.InsertFieldsDefaultValueJson, + OperationEnum.Duplicate => listForm.InsertFieldsDefaultValueJson, OperationEnum.Update => listForm.UpdateFieldsDefaultValueJson, OperationEnum.Delete => listForm.DeleteFieldsDefaultValueJson, OperationEnum.Select => listForm.FormFieldsDefaultValueJson, @@ -103,6 +104,7 @@ public class DefaultValueManager : PlatformDomainService, IDefaultValueManager var field = listFormFields.FirstOrDefault(c => c.FieldName == item.Key); if (field == null || (op == OperationEnum.Insert && !field.CanCreate) + || (op == OperationEnum.Duplicate && !field.CanCreate) || (op == OperationEnum.Update && !field.CanUpdate) ) { diff --git a/api/src/Sozsoft.Platform.Domain/Queries/QueryManager.cs b/api/src/Sozsoft.Platform.Domain/Queries/QueryManager.cs index 52dc7a9..b15cb16 100644 --- a/api/src/Sozsoft.Platform.Domain/Queries/QueryManager.cs +++ b/api/src/Sozsoft.Platform.Domain/Queries/QueryManager.cs @@ -78,11 +78,7 @@ public class QueryManager : PlatformDomainService, IQueryManager var listFormFields = await listFormFieldManager.GetUserListFormFields(listFormCode); var parameters = await listFormManager.GetParametersAsync(listForm, listFormFields, inputParams, op, keys, queryParameters); - // if (parameters == null || parameters.Count == 0) - // { - // throw new UserFriendlyException(localizer[AppErrorCodes.ParameterNotValid]); - // } - + var (dynamicDataRepository, connectionString, dataSourceType) = await dynamicDataManager.GetAsync(listForm.IsTenant, listForm.DataSourceCode); var sql = GenerateQuery(listForm, listFormFields, parameters, op, dataSourceType, keys); @@ -155,6 +151,7 @@ public class QueryManager : PlatformDomainService, IQueryManager { var command = op switch { + OperationEnum.Duplicate => listForm.InsertCommand, OperationEnum.Insert => listForm.InsertCommand, OperationEnum.InsertBefore => listForm.InsertBeforeCommand, OperationEnum.InsertAfter => listForm.InsertAfterCommand, @@ -179,7 +176,7 @@ public class QueryManager : PlatformDomainService, IQueryManager var fieldString = string.Join(',', parameters.Keys.Select(a => $"\"{a}\"").ToList()); var fieldParams = string.Join(',', parameters.Keys.Select(a => $"@{a}")); - if (op == OperationEnum.Insert) + if (op == OperationEnum.Insert || op == OperationEnum.Duplicate) { sql = dataSourceType switch { @@ -188,55 +185,6 @@ public class QueryManager : PlatformDomainService, IQueryManager _ => string.Empty, }; } - else if (op == OperationEnum.Duplicate) - { - // Key parametresi yoksa ekle - if (!parameters.ContainsKey(listForm.KeyFieldName) && keys != null && keys.Length > 0) - { - parameters[listForm.KeyFieldName] = keys[0]; - } - - // InsertFieldsDefaultValueJson'u oku - var insertDefaults = new Dictionary(); - if (!string.IsNullOrWhiteSpace(listForm.InsertFieldsDefaultValueJson)) - { - try - { - insertDefaults = System.Text.Json.JsonSerializer.Deserialize>(listForm.InsertFieldsDefaultValueJson); - } - catch { } - } - - // Tüm alanları (id/key dahil) listFormField listesinden sırala - var allFields = listFormField.Select(f => f.FieldName).ToList(); - - // Insert kısmı için alan adları - var insertFieldString = string.Join(",", allFields.Select(a => $"[{a}]")); - - // Select kısmı için: eğer default value varsa onu kullan, yoksa select ile gelen değeri kullan - var selectFieldString = string.Join(",", allFields.Select(a => - { - if (insertDefaults.ContainsKey(a) && insertDefaults[a] != null) - { - // String ise tek tırnakla, sayı ise direkt - var val = insertDefaults[a]; - if (val is string || val?.GetType() == typeof(string)) - return $"'{val.ToString().Replace("'", "''")}'"; - else if (val is bool) - return (bool)val ? "1" : "0"; - else if (val is null) - return "NULL"; - else - return val.ToString(); - } - // Key/id alanı için, default yoksa NULL ata (veya istenirse farklı bir şey) - if (string.Equals(a, listForm.KeyFieldName, StringComparison.OrdinalIgnoreCase)) - return "NULL"; - return $"[{a}]"; - })); - - sql = $"INSERT INTO [{listForm.SelectCommand}] ({insertFieldString}) SELECT {selectFieldString} FROM [{listForm.SelectCommand}] WHERE [{listForm.KeyFieldName}] = @{listForm.KeyFieldName}"; - } else if (op == OperationEnum.Update) { var where = dataSourceType switch diff --git a/ui/src/views/list/useListFormColumns.ts b/ui/src/views/list/useListFormColumns.ts index e67569b..0cef20c 100644 --- a/ui/src/views/list/useListFormColumns.ts +++ b/ui/src/views/list/useListFormColumns.ts @@ -387,6 +387,12 @@ const useListFormColumns = ({ e.event.preventDefault() } + // Onay penceresi + const confirmed = window.confirm( + translate('::App.Platform.DuplicateConfirm') || 'Kopyalama işlemini onaylıyor musunuz?', + ) + if (!confirmed) return + if (!gridDto.gridOptions.keyFieldName) return const id = e.row.data[gridDto.gridOptions.keyFieldName] @@ -397,15 +403,16 @@ const useListFormColumns = ({ await dynamicFetch('list-form-data/duplicate', 'POST', null, { listFormCode, keys: [id], - data: {}, + data: [gridDto.gridOptions.keyFieldName], }) + // Başarılı ise grid'i yenile if (gridRef?.current?.instance()) { gridRef.current.instance().refresh() } } catch (err) { // Hata yönetimi - alert(translate('::App.Platform.DuplicateError') || 'Kayıt kopyalanamadı!') + alert(translate('::App.Platform.DuplicateError')) } }, }