Duplicate Record
This commit is contained in:
parent
08c495943b
commit
30be61f2c7
10 changed files with 148 additions and 19 deletions
|
|
@ -18,6 +18,7 @@ public class GridEditingDto
|
||||||
public bool AllowDeleting { get; set; } = false;
|
public bool AllowDeleting { get; set; } = false;
|
||||||
public bool AllowAllDeleting { get; set; } = false;
|
public bool AllowAllDeleting { get; set; } = false;
|
||||||
public bool AllowAdding { get; set; } = false;
|
public bool AllowAdding { get; set; } = false;
|
||||||
|
public bool AllowDuplicate { get; set; } = false;
|
||||||
public bool UseIcons { get; set; } = false;
|
public bool UseIcons { get; set; } = false;
|
||||||
public bool ConfirmDelete { get; set; } = true;
|
public bool ConfirmDelete { get; set; } = true;
|
||||||
/// <summary>Accepted Values: 'first' | 'last' | 'pageBottom' | 'pageTop' | 'viewportBottom' | 'viewportTop'
|
/// <summary>Accepted Values: 'first' | 'last' | 'pageBottom' | 'pageTop' | 'viewportBottom' | 'viewportTop'
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ public class ListFormQueryPreviewAppService : PlatformAppService
|
||||||
|
|
||||||
var (_, _, dataSourceType) = await dynamicDataManager.GetAsync(listForm.IsTenant, listForm.DataSourceCode);
|
var (_, _, dataSourceType) = await dynamicDataManager.GetAsync(listForm.IsTenant, listForm.DataSourceCode);
|
||||||
|
|
||||||
return qManager.GenerateQuery(listForm, parameters, op, dataSourceType);
|
return qManager.GenerateQuery(listForm, listFormFields, parameters, op, dataSourceType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,5 +64,19 @@ public class ListFormDataAppService : PlatformAppService
|
||||||
var queryParameters = httpContext.Request.Query.ToDictionary(x => x.Key, x => x.Value);
|
var queryParameters = httpContext.Request.Query.ToDictionary(x => x.Key, x => x.Value);
|
||||||
return await qManager.GenerateAndRunQueryAsync<int>(input.ListFormCode, OperationEnum.Delete, input.Data, input.Keys, queryParameters);
|
return await qManager.GenerateAndRunQueryAsync<int>(input.ListFormCode, OperationEnum.Delete, input.Data, input.Keys, queryParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<int> 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<int>(input.ListFormCode, OperationEnum.Duplicate, input.Data, input.Keys, queryParameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4092,6 +4092,12 @@
|
||||||
"en": "Allow Detail",
|
"en": "Allow Detail",
|
||||||
"tr": "Detaya İzin Ver"
|
"tr": "Detaya İzin Ver"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormEdit.EditingAllowDuplicate",
|
||||||
|
"en": "Allow Duplicate",
|
||||||
|
"tr": "Çoğaltmaya İzin Ver"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormEdit.EditingAllowDeleting",
|
"key": "ListForms.ListFormEdit.EditingAllowDeleting",
|
||||||
|
|
@ -10338,6 +10344,18 @@
|
||||||
"tr": "Sil",
|
"tr": "Sil",
|
||||||
"en": "Delete"
|
"en": "Delete"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Platform.Duplicate",
|
||||||
|
"tr": "Çoğalt",
|
||||||
|
"en": "Duplicate"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Platform.DuplicateError",
|
||||||
|
"tr": "Çoğaltma Hatası",
|
||||||
|
"en": "Duplicate Error"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.Platform.Warning",
|
"key": "App.Platform.Warning",
|
||||||
|
|
|
||||||
|
|
@ -3421,15 +3421,6 @@
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp|Kurs"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"GroupName": "App.Administration",
|
|
||||||
"Name": "App.Reports.ReportTemplates.Note",
|
|
||||||
"ParentName": "App.Reports.ReportTemplates",
|
|
||||||
"DisplayName": "Note",
|
|
||||||
"IsEnabled": true,
|
|
||||||
"MultiTenancySide": 3,
|
|
||||||
"MenuGroup": "Erp|Kurs"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
"Name": "App.Reports.ReportTemplates.Update",
|
"Name": "App.Reports.ReportTemplates.Update",
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ public enum OperationEnum
|
||||||
Delete,
|
Delete,
|
||||||
DeleteBefore,
|
DeleteBefore,
|
||||||
DeleteAfter,
|
DeleteAfter,
|
||||||
Select
|
Select,
|
||||||
|
Duplicate,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ public interface IQueryManager
|
||||||
|
|
||||||
string GenerateQuery(
|
string GenerateQuery(
|
||||||
ListForm listForm,
|
ListForm listForm,
|
||||||
|
List<ListFormField> listFormFields,
|
||||||
Dictionary<string, object> parameters,
|
Dictionary<string, object> parameters,
|
||||||
OperationEnum op,
|
OperationEnum op,
|
||||||
DataSourceTypeEnum dataSourceType,
|
DataSourceTypeEnum dataSourceType,
|
||||||
|
|
@ -84,17 +85,17 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
|
|
||||||
var (dynamicDataRepository, connectionString, dataSourceType) = await dynamicDataManager.GetAsync(listForm.IsTenant, listForm.DataSourceCode);
|
var (dynamicDataRepository, connectionString, dataSourceType) = await dynamicDataManager.GetAsync(listForm.IsTenant, listForm.DataSourceCode);
|
||||||
|
|
||||||
var sql = GenerateQuery(listForm, parameters, op, dataSourceType, keys);
|
var sql = GenerateQuery(listForm, listFormFields, parameters, op, dataSourceType, keys);
|
||||||
|
|
||||||
// Sorguyu calistir
|
// Sorguyu calistir
|
||||||
if (!string.IsNullOrEmpty(sql))
|
if (!string.IsNullOrEmpty(sql))
|
||||||
{
|
{
|
||||||
// TODO: Log
|
// TODO: Log
|
||||||
if (op == OperationEnum.Insert)
|
if (op == OperationEnum.Insert || op == OperationEnum.Duplicate)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(listForm.InsertBeforeCommand))
|
if (!string.IsNullOrEmpty(listForm.InsertBeforeCommand))
|
||||||
{
|
{
|
||||||
var beforeSql = GenerateQuery(listForm, parameters, OperationEnum.InsertBefore, dataSourceType, keys);
|
var beforeSql = GenerateQuery(listForm, listFormFields, parameters, OperationEnum.InsertBefore, dataSourceType, keys);
|
||||||
await dynamicDataRepository.ExecuteAsync(beforeSql, connectionString, parameters);
|
await dynamicDataRepository.ExecuteAsync(beforeSql, connectionString, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,7 +103,7 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(listForm.InsertAfterCommand))
|
if (!string.IsNullOrEmpty(listForm.InsertAfterCommand))
|
||||||
{
|
{
|
||||||
var afterSql = GenerateQuery(listForm, parameters, OperationEnum.InsertAfter, dataSourceType, keys);
|
var afterSql = GenerateQuery(listForm, listFormFields, parameters, OperationEnum.InsertAfter, dataSourceType, keys);
|
||||||
await dynamicDataRepository.ExecuteAsync(afterSql, connectionString, parameters);
|
await dynamicDataRepository.ExecuteAsync(afterSql, connectionString, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,12 +114,12 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
// Before komutlari varsa calistir
|
// Before komutlari varsa calistir
|
||||||
if (op == OperationEnum.Update && !string.IsNullOrEmpty(listForm.UpdateBeforeCommand))
|
if (op == OperationEnum.Update && !string.IsNullOrEmpty(listForm.UpdateBeforeCommand))
|
||||||
{
|
{
|
||||||
var beforeSql = GenerateQuery(listForm, parameters, OperationEnum.UpdateBefore, dataSourceType, keys);
|
var beforeSql = GenerateQuery(listForm, listFormFields, parameters, OperationEnum.UpdateBefore, dataSourceType, keys);
|
||||||
await dynamicDataRepository.ExecuteAsync(beforeSql, connectionString, parameters);
|
await dynamicDataRepository.ExecuteAsync(beforeSql, connectionString, parameters);
|
||||||
}
|
}
|
||||||
else if (op == OperationEnum.Delete && !string.IsNullOrEmpty(listForm.DeleteBeforeCommand))
|
else if (op == OperationEnum.Delete && !string.IsNullOrEmpty(listForm.DeleteBeforeCommand))
|
||||||
{
|
{
|
||||||
var beforeSql = GenerateQuery(listForm, parameters, OperationEnum.DeleteBefore, dataSourceType, keys);
|
var beforeSql = GenerateQuery(listForm, listFormFields, parameters, OperationEnum.DeleteBefore, dataSourceType, keys);
|
||||||
await dynamicDataRepository.ExecuteAsync(beforeSql, connectionString, parameters);
|
await dynamicDataRepository.ExecuteAsync(beforeSql, connectionString, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,12 +129,12 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
// After komutlari varsa calistir
|
// After komutlari varsa calistir
|
||||||
if (op == OperationEnum.Update && !string.IsNullOrEmpty(listForm.UpdateAfterCommand))
|
if (op == OperationEnum.Update && !string.IsNullOrEmpty(listForm.UpdateAfterCommand))
|
||||||
{
|
{
|
||||||
var afterSql = GenerateQuery(listForm, parameters, OperationEnum.UpdateAfter, dataSourceType, keys);
|
var afterSql = GenerateQuery(listForm, listFormFields, parameters, OperationEnum.UpdateAfter, dataSourceType, keys);
|
||||||
await dynamicDataRepository.ExecuteAsync(afterSql, connectionString, parameters);
|
await dynamicDataRepository.ExecuteAsync(afterSql, connectionString, parameters);
|
||||||
}
|
}
|
||||||
else if (op == OperationEnum.Delete && !string.IsNullOrEmpty(listForm.DeleteAfterCommand))
|
else if (op == OperationEnum.Delete && !string.IsNullOrEmpty(listForm.DeleteAfterCommand))
|
||||||
{
|
{
|
||||||
var afterSql = GenerateQuery(listForm, parameters, OperationEnum.DeleteAfter, dataSourceType, keys);
|
var afterSql = GenerateQuery(listForm, listFormFields, parameters, OperationEnum.DeleteAfter, dataSourceType, keys);
|
||||||
await dynamicDataRepository.ExecuteAsync(afterSql, connectionString, parameters);
|
await dynamicDataRepository.ExecuteAsync(afterSql, connectionString, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,6 +147,7 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
|
|
||||||
public string GenerateQuery(
|
public string GenerateQuery(
|
||||||
ListForm listForm,
|
ListForm listForm,
|
||||||
|
List<ListFormField> listFormField,
|
||||||
Dictionary<string, object> parameters,
|
Dictionary<string, object> parameters,
|
||||||
OperationEnum op,
|
OperationEnum op,
|
||||||
DataSourceTypeEnum dataSourceType,
|
DataSourceTypeEnum dataSourceType,
|
||||||
|
|
@ -186,6 +188,55 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
_ => string.Empty,
|
_ => 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<string, object>();
|
||||||
|
if (!string.IsNullOrWhiteSpace(listForm.InsertFieldsDefaultValueJson))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
insertDefaults = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(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)
|
else if (op == OperationEnum.Update)
|
||||||
{
|
{
|
||||||
var where = dataSourceType switch
|
var where = dataSourceType switch
|
||||||
|
|
|
||||||
|
|
@ -444,6 +444,7 @@ export interface GridEditingDto {
|
||||||
allowDeleting: boolean
|
allowDeleting: boolean
|
||||||
allowAllDeleting: boolean
|
allowAllDeleting: boolean
|
||||||
allowAdding: boolean
|
allowAdding: boolean
|
||||||
|
allowDuplicate: boolean
|
||||||
useIcons: boolean
|
useIcons: boolean
|
||||||
confirmDelete: boolean
|
confirmDelete: boolean
|
||||||
newRowPosition?: NewRowPosition
|
newRowPosition?: NewRowPosition
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,20 @@ function FormTabEdit(props: FormEditProps & { listFormCode: string }) {
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.EditingAllowDuplicate')}
|
||||||
|
invalid={
|
||||||
|
errors.editingOptionDto?.allowDuplicate && touched.editingOptionDto?.allowDuplicate
|
||||||
|
}
|
||||||
|
errorMessage={errors.editingOptionDto?.allowDuplicate}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
name="editingOptionDto.allowDuplicate"
|
||||||
|
placeholder={translate('::ListForms.ListFormEdit.EditingAllowDuplicate')}
|
||||||
|
component={Checkbox}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
label={translate('::ListForms.ListFormEdit.EditingAllowDeleting')}
|
label={translate('::ListForms.ListFormEdit.EditingAllowDeleting')}
|
||||||
invalid={
|
invalid={
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,10 @@ const useListFormColumns = ({
|
||||||
gridDto.gridOptions.editingOptionDto.allowDetail &&
|
gridDto.gridOptions.editingOptionDto.allowDetail &&
|
||||||
checkPermission(gridDto.gridOptions.permissionDto.u)
|
checkPermission(gridDto.gridOptions.permissionDto.u)
|
||||||
|
|
||||||
|
const hasDuplicate =
|
||||||
|
gridDto.gridOptions.editingOptionDto.allowDuplicate &&
|
||||||
|
checkPermission(gridDto.gridOptions.permissionDto.i)
|
||||||
|
|
||||||
const hasCommandButtons = gridDto.gridOptions.commandColumnDto.length > 0
|
const hasCommandButtons = gridDto.gridOptions.commandColumnDto.length > 0
|
||||||
|
|
||||||
// Eğer hiçbir buton eklenecek durumda değilse: çık
|
// Eğer hiçbir buton eklenecek durumda değilse: çık
|
||||||
|
|
@ -374,6 +378,40 @@ const useListFormColumns = ({
|
||||||
buttons.push(item)
|
buttons.push(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasDuplicate) {
|
||||||
|
const item = {
|
||||||
|
name: 'duplicate',
|
||||||
|
text: translate('::App.Platform.Duplicate'),
|
||||||
|
onClick: async (e: any) => {
|
||||||
|
if (typeof e.event?.preventDefault === 'function') {
|
||||||
|
e.event.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gridDto.gridOptions.keyFieldName) return
|
||||||
|
|
||||||
|
const id = e.row.data[gridDto.gridOptions.keyFieldName]
|
||||||
|
if (!id) return
|
||||||
|
|
||||||
|
// Backend'e duplicate isteği gönder
|
||||||
|
try {
|
||||||
|
await dynamicFetch('list-form-data/duplicate', 'POST', null, {
|
||||||
|
listFormCode,
|
||||||
|
keys: [id],
|
||||||
|
data: {},
|
||||||
|
})
|
||||||
|
// 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ı!')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
buttons.push(item)
|
||||||
|
}
|
||||||
|
|
||||||
gridDto.gridOptions.commandColumnDto.forEach((action) => {
|
gridDto.gridOptions.commandColumnDto.forEach((action) => {
|
||||||
if (action.buttonPosition !== UiCommandButtonPositionTypeEnum.CommandColumn) return
|
if (action.buttonPosition !== UiCommandButtonPositionTypeEnum.CommandColumn) return
|
||||||
if (!checkPermission(action.authName)) return
|
if (!checkPermission(action.authName)) return
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue