Seçilenleri ve Tümünü Sil butonları
This commit is contained in:
parent
bade0bab98
commit
1d15c44a3d
7 changed files with 476 additions and 38 deletions
|
|
@ -3642,6 +3642,36 @@
|
||||||
"en": "The record was deleted",
|
"en": "The record was deleted",
|
||||||
"tr": "Kayıt silindi"
|
"tr": "Kayıt silindi"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "TumKayitlarSilindi",
|
||||||
|
"en": "All records were deleted.",
|
||||||
|
"tr": "Tüm kayıtlar silindi."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "SeciliKayitBekliyor",
|
||||||
|
"en": "The selected record is not waiting for this approval step or approval user.",
|
||||||
|
"tr": "Seçili kayit bu onay adımında veya onay kullanıcısında beklemiyor."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "WorkflowAlreadyStarted",
|
||||||
|
"en": "Workflow has already been started for the selected record",
|
||||||
|
"tr": "Seçili kayıt icin workflow zaten başlamış."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "SeciliKayitlarSilmekIstiyormusunuz",
|
||||||
|
"en": "{0} records will be deleted. Are you sure you want to delete?",
|
||||||
|
"tr": "{0} kayit silinecek. Silmek istediginize emin misiniz?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "TumKayitlariSilmekIstiyormusunuz",
|
||||||
|
"en": "Are you sure to delete all {0} records?",
|
||||||
|
"tr": "Tüm {0} kayıtları silmek istediğinize emin misiniz?"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "KayitEklendi",
|
"key": "KayitEklendi",
|
||||||
|
|
@ -16736,6 +16766,12 @@
|
||||||
"en": "Approver",
|
"en": "Approver",
|
||||||
"tr": "Onayla"
|
"tr": "Onayla"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.Rejecter",
|
||||||
|
"en": "Rejecter",
|
||||||
|
"tr": "Reddet"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.Listform.ListformField.NextOnStart",
|
"key": "App.Listform.ListformField.NextOnStart",
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ public static class ListFormSeeder_DefaultJsons
|
||||||
{
|
{
|
||||||
public static string DefaultDeleteCommand(string tableName)
|
public static string DefaultDeleteCommand(string tableName)
|
||||||
{
|
{
|
||||||
return $"UPDATE \"{TableNameResolver.GetFullTableName(tableName)}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id";
|
return $"UPDATE \"{TableNameResolver.GetFullTableName(tableName)}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\" IN @Id";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string DefaultInsertFieldsDefaultValueJson(DbType dbType = DbType.Guid, string newId = "@NEWID") => JsonSerializer.Serialize(new FieldsDefaultValue[]
|
public static string DefaultInsertFieldsDefaultValueJson(DbType dbType = DbType.Guid, string newId = "@NEWID") => JsonSerializer.Serialize(new FieldsDefaultValue[]
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ public static class WizardConsts
|
||||||
|
|
||||||
public static string DefaultDeleteCommand(string tableName)
|
public static string DefaultDeleteCommand(string tableName)
|
||||||
{
|
{
|
||||||
return $"UPDATE \"{tableName}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id";
|
return $"UPDATE \"{tableName}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\" IN @Id";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string DefaultInsertFieldsDefaultValueJson(DbType dbType = DbType.Guid)
|
public static string DefaultInsertFieldsDefaultValueJson(DbType dbType = DbType.Guid)
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,9 @@ public class DefaultValueManager : PlatformDomainService, IDefaultValueManager
|
||||||
else if (defaultField.Value == PlatformConsts.DefaultValues.Year)
|
else if (defaultField.Value == PlatformConsts.DefaultValues.Year)
|
||||||
value = Clock.Now.Year;
|
value = Clock.Now.Year;
|
||||||
else if (defaultField.Value == PlatformConsts.DefaultValues.Id)
|
else if (defaultField.Value == PlatformConsts.DefaultValues.Id)
|
||||||
value = keys?.FirstOrDefault();
|
value = op == OperationEnum.Delete
|
||||||
|
? keys
|
||||||
|
: keys?.FirstOrDefault();
|
||||||
else if (defaultField.Value == PlatformConsts.DefaultValues.NewId)
|
else if (defaultField.Value == PlatformConsts.DefaultValues.NewId)
|
||||||
value = Guid.NewGuid();
|
value = Guid.NewGuid();
|
||||||
else if (defaultField.Value == PlatformConsts.DefaultValues.Selected_Ids)
|
else if (defaultField.Value == PlatformConsts.DefaultValues.Selected_Ids)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Sozsoft.Platform.DynamicData;
|
using Sozsoft.Platform.DynamicData;
|
||||||
using Sozsoft.Platform.Entities;
|
using Sozsoft.Platform.Entities;
|
||||||
|
|
@ -169,7 +170,7 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
// oncelik Command alanindadir, dolu ise silme islemi buradaki sorguya yonlendirilir
|
// oncelik Command alanindadir, dolu ise silme islemi buradaki sorguya yonlendirilir
|
||||||
if (!string.IsNullOrEmpty(command))
|
if (!string.IsNullOrEmpty(command))
|
||||||
{
|
{
|
||||||
sql = command;
|
sql = NormalizeCollectionParameterCommand(command, parameters, dataSourceType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -189,7 +190,7 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
{
|
{
|
||||||
var where = dataSourceType switch
|
var where = dataSourceType switch
|
||||||
{
|
{
|
||||||
DataSourceTypeEnum.Mssql => $"\"{listForm.KeyFieldName}\" IN (@{listForm.KeyFieldName})",
|
DataSourceTypeEnum.Mssql => $"\"{listForm.KeyFieldName}\" IN @{listForm.KeyFieldName}",
|
||||||
DataSourceTypeEnum.Postgresql => $"\"{listForm.KeyFieldName}\" = ANY(@{listForm.KeyFieldName})",
|
DataSourceTypeEnum.Postgresql => $"\"{listForm.KeyFieldName}\" = ANY(@{listForm.KeyFieldName})",
|
||||||
_ => string.Empty,
|
_ => string.Empty,
|
||||||
};
|
};
|
||||||
|
|
@ -209,7 +210,14 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
string where = string.Empty;
|
string where = string.Empty;
|
||||||
if (parameters.Any())
|
if (parameters.Any())
|
||||||
{
|
{
|
||||||
where = string.Join(" AND ", parameters.Select(a => $"\"{a.Key}\" IN (@{a.Key})").ToList());
|
where = string.Join(
|
||||||
|
" AND ",
|
||||||
|
parameters.Select(a => dataSourceType switch
|
||||||
|
{
|
||||||
|
DataSourceTypeEnum.Mssql => $"\"{a.Key}\" IN @{a.Key}",
|
||||||
|
DataSourceTypeEnum.Postgresql => $"\"{a.Key}\" = ANY(@{a.Key})",
|
||||||
|
_ => "1 = 0",
|
||||||
|
}).ToList());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -220,7 +228,7 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
|
|
||||||
where = dataSourceType switch
|
where = dataSourceType switch
|
||||||
{
|
{
|
||||||
DataSourceTypeEnum.Mssql => $"\"{listForm.KeyFieldName}\" IN (@{listForm.KeyFieldName})",
|
DataSourceTypeEnum.Mssql => $"\"{listForm.KeyFieldName}\" IN @{listForm.KeyFieldName}",
|
||||||
DataSourceTypeEnum.Postgresql => $"\"{listForm.KeyFieldName}\" = ANY(@{listForm.KeyFieldName})",
|
DataSourceTypeEnum.Postgresql => $"\"{listForm.KeyFieldName}\" = ANY(@{listForm.KeyFieldName})",
|
||||||
_ => "1 = 0",
|
_ => "1 = 0",
|
||||||
};
|
};
|
||||||
|
|
@ -231,5 +239,78 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
|
|
||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string NormalizeCollectionParameterCommand(
|
||||||
|
string command,
|
||||||
|
Dictionary<string, object> parameters,
|
||||||
|
DataSourceTypeEnum dataSourceType)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(command) || parameters == null || parameters.Count == 0)
|
||||||
|
{
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sql = command;
|
||||||
|
foreach (var parameter in parameters)
|
||||||
|
{
|
||||||
|
if (!IsCollectionParameter(parameter.Value))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var escapedParameterName = Regex.Escape(parameter.Key);
|
||||||
|
sql = dataSourceType switch
|
||||||
|
{
|
||||||
|
DataSourceTypeEnum.Mssql => NormalizeMssqlCollectionParameter(sql, escapedParameterName, parameter.Key),
|
||||||
|
DataSourceTypeEnum.Postgresql => NormalizePostgresqlCollectionParameter(sql, escapedParameterName, parameter.Key),
|
||||||
|
_ => sql
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsCollectionParameter(object value)
|
||||||
|
{
|
||||||
|
return value is System.Collections.IEnumerable
|
||||||
|
&& value is not string
|
||||||
|
&& value is not byte[];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NormalizeMssqlCollectionParameter(
|
||||||
|
string sql,
|
||||||
|
string escapedParameterName,
|
||||||
|
string parameterName)
|
||||||
|
{
|
||||||
|
sql = Regex.Replace(
|
||||||
|
sql,
|
||||||
|
$@"IN\s*\(\s*@{escapedParameterName}\s*\)",
|
||||||
|
$"IN @{parameterName}",
|
||||||
|
RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
return Regex.Replace(
|
||||||
|
sql,
|
||||||
|
$@"(?<column>(""[^""]+""|\[[^\]]+\]|`[^`]+`|\w+))\s*=\s*@{escapedParameterName}\b",
|
||||||
|
match => $"{match.Groups["column"].Value} IN @{parameterName}",
|
||||||
|
RegexOptions.IgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NormalizePostgresqlCollectionParameter(
|
||||||
|
string sql,
|
||||||
|
string escapedParameterName,
|
||||||
|
string parameterName)
|
||||||
|
{
|
||||||
|
sql = Regex.Replace(
|
||||||
|
sql,
|
||||||
|
$@"IN\s*\(\s*@{escapedParameterName}\s*\)",
|
||||||
|
$"= ANY(@{parameterName})",
|
||||||
|
RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
return Regex.Replace(
|
||||||
|
sql,
|
||||||
|
$@"(?<column>(""[^""]+""|\[[^\]]+\]|`[^`]+`|\w+))\s*=\s*@{escapedParameterName}\b",
|
||||||
|
match => $"{match.Groups["column"].Value} = ANY(@{parameterName})",
|
||||||
|
RegexOptions.IgnoreCase);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,12 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Dapper;
|
using Dapper;
|
||||||
|
using Sozsoft.Platform;
|
||||||
using Sozsoft.Platform.DynamicData;
|
using Sozsoft.Platform.DynamicData;
|
||||||
using Microsoft.Data.SqlClient;
|
using Microsoft.Data.SqlClient;
|
||||||
using Volo.Abp.DependencyInjection;
|
using Volo.Abp.DependencyInjection;
|
||||||
|
|
@ -178,7 +182,7 @@ public class MsDynamicDataRepository : IDynamicDataRepository, IScopedDependency
|
||||||
|
|
||||||
public virtual async Task<List<T>> QueryAsync<T>(string sql, string cs, Dictionary<string, object> parameters = null)
|
public virtual async Task<List<T>> QueryAsync<T>(string sql, string cs, Dictionary<string, object> parameters = null)
|
||||||
{
|
{
|
||||||
var param = new DynamicParameters(parameters);
|
var param = CreateDynamicParameters(parameters);
|
||||||
var dbConnection = await GetOrCreateConnectionAsync(cs);
|
var dbConnection = await GetOrCreateConnectionAsync(cs);
|
||||||
var transaction = await GetOrCreateTransactionAsync(dbConnection, cs);
|
var transaction = await GetOrCreateTransactionAsync(dbConnection, cs);
|
||||||
|
|
||||||
|
|
@ -188,7 +192,7 @@ public class MsDynamicDataRepository : IDynamicDataRepository, IScopedDependency
|
||||||
|
|
||||||
public virtual async Task<IEnumerable<dynamic>> QueryAsync(string sql, string cs, Dictionary<string, object> parameters = null)
|
public virtual async Task<IEnumerable<dynamic>> QueryAsync(string sql, string cs, Dictionary<string, object> parameters = null)
|
||||||
{
|
{
|
||||||
var param = new DynamicParameters(parameters);
|
var param = CreateDynamicParameters(parameters);
|
||||||
var dbConnection = await GetOrCreateConnectionAsync(cs);
|
var dbConnection = await GetOrCreateConnectionAsync(cs);
|
||||||
var transaction = await GetOrCreateTransactionAsync(dbConnection, cs);
|
var transaction = await GetOrCreateTransactionAsync(dbConnection, cs);
|
||||||
|
|
||||||
|
|
@ -197,7 +201,7 @@ public class MsDynamicDataRepository : IDynamicDataRepository, IScopedDependency
|
||||||
|
|
||||||
public virtual async Task<T> QuerySingleAsync<T>(string sql, string cs, Dictionary<string, object> parameters = null)
|
public virtual async Task<T> QuerySingleAsync<T>(string sql, string cs, Dictionary<string, object> parameters = null)
|
||||||
{
|
{
|
||||||
var param = new DynamicParameters(parameters);
|
var param = CreateDynamicParameters(parameters);
|
||||||
var dbConnection = await GetOrCreateConnectionAsync(cs);
|
var dbConnection = await GetOrCreateConnectionAsync(cs);
|
||||||
var transaction = await GetOrCreateTransactionAsync(dbConnection, cs);
|
var transaction = await GetOrCreateTransactionAsync(dbConnection, cs);
|
||||||
|
|
||||||
|
|
@ -206,7 +210,7 @@ public class MsDynamicDataRepository : IDynamicDataRepository, IScopedDependency
|
||||||
|
|
||||||
public virtual async Task<T> ExecuteScalarAsync<T>(string sql, string cs, Dictionary<string, object> parameters = null)
|
public virtual async Task<T> ExecuteScalarAsync<T>(string sql, string cs, Dictionary<string, object> parameters = null)
|
||||||
{
|
{
|
||||||
var param = new DynamicParameters(parameters);
|
var param = CreateDynamicParameters(parameters);
|
||||||
var dbConnection = await GetOrCreateConnectionAsync(cs);
|
var dbConnection = await GetOrCreateConnectionAsync(cs);
|
||||||
var transaction = await GetOrCreateTransactionAsync(dbConnection, cs);
|
var transaction = await GetOrCreateTransactionAsync(dbConnection, cs);
|
||||||
|
|
||||||
|
|
@ -237,13 +241,257 @@ public class MsDynamicDataRepository : IDynamicDataRepository, IScopedDependency
|
||||||
|
|
||||||
public virtual async Task<int> ExecuteAsync(string sql, string cs, Dictionary<string, object> parameters = null)
|
public virtual async Task<int> ExecuteAsync(string sql, string cs, Dictionary<string, object> parameters = null)
|
||||||
{
|
{
|
||||||
var param = new DynamicParameters(parameters);
|
var param = CreateDynamicParameters(parameters);
|
||||||
var dbConnection = await GetOrCreateConnectionAsync(cs);
|
var dbConnection = await GetOrCreateConnectionAsync(cs);
|
||||||
var transaction = await GetOrCreateTransactionAsync(dbConnection, cs);
|
var transaction = await GetOrCreateTransactionAsync(dbConnection, cs);
|
||||||
|
|
||||||
return await dbConnection.ExecuteAsync(sql, param, transaction);
|
return await dbConnection.ExecuteAsync(sql, param, transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static DynamicParameters CreateDynamicParameters(Dictionary<string, object> parameters)
|
||||||
|
{
|
||||||
|
var dynamicParameters = new DynamicParameters();
|
||||||
|
|
||||||
|
if (parameters == null)
|
||||||
|
{
|
||||||
|
return dynamicParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var parameter in parameters)
|
||||||
|
{
|
||||||
|
dynamicParameters.Add(parameter.Key, NormalizeParameterValue(parameter.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return dynamicParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object NormalizeParameterValue(object value)
|
||||||
|
{
|
||||||
|
if (value == null || value == DBNull.Value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value is JsonElement jsonElement)
|
||||||
|
{
|
||||||
|
return NormalizeJsonElement(jsonElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value is Array array && value is not byte[])
|
||||||
|
{
|
||||||
|
return NormalizeArrayParameter(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object NormalizeArrayParameter(Array values)
|
||||||
|
{
|
||||||
|
var normalizedValues = values
|
||||||
|
.Cast<object>()
|
||||||
|
.Select(NormalizeParameterValue)
|
||||||
|
.Where(value => value != null && value != DBNull.Value)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
if (normalizedValues.Length == 0)
|
||||||
|
{
|
||||||
|
return Array.Empty<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryBuildGuidArray(normalizedValues, out var guidValues))
|
||||||
|
{
|
||||||
|
return guidValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryBuildIntArray(normalizedValues, out var intValues))
|
||||||
|
{
|
||||||
|
return intValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryBuildLongArray(normalizedValues, out var longValues))
|
||||||
|
{
|
||||||
|
return longValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryBuildDecimalArray(normalizedValues, out var decimalValues))
|
||||||
|
{
|
||||||
|
return decimalValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryBuildBoolArray(normalizedValues, out var boolValues))
|
||||||
|
{
|
||||||
|
return boolValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryBuildDateTimeOffsetArray(normalizedValues, out var dateTimeOffsetValues))
|
||||||
|
{
|
||||||
|
return dateTimeOffsetValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
var stringValues = normalizedValues.Select(value => value.ToString()).ToArray();
|
||||||
|
|
||||||
|
if (stringValues.Length == 1 && stringValues[0]?.Contains(PlatformConsts.MultiValueDelimiter) == true)
|
||||||
|
{
|
||||||
|
return stringValues[0].Split(PlatformConsts.MultiValueDelimiter, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object NormalizeJsonElement(JsonElement value)
|
||||||
|
{
|
||||||
|
return value.ValueKind switch
|
||||||
|
{
|
||||||
|
JsonValueKind.String => value.GetString(),
|
||||||
|
JsonValueKind.Number when value.TryGetInt32(out var intValue) => intValue,
|
||||||
|
JsonValueKind.Number when value.TryGetInt64(out var longValue) => longValue,
|
||||||
|
JsonValueKind.Number when value.TryGetDecimal(out var decimalValue) => decimalValue,
|
||||||
|
JsonValueKind.True => true,
|
||||||
|
JsonValueKind.False => false,
|
||||||
|
JsonValueKind.Null => null,
|
||||||
|
JsonValueKind.Undefined => null,
|
||||||
|
_ => value.ToString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryBuildGuidArray(object[] values, out Guid[] result)
|
||||||
|
{
|
||||||
|
result = new Guid[values.Length];
|
||||||
|
|
||||||
|
for (var i = 0; i < values.Length; i++)
|
||||||
|
{
|
||||||
|
if (values[i] is Guid guidValue)
|
||||||
|
{
|
||||||
|
result[i] = guidValue;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Guid.TryParse(values[i]?.ToString(), out result[i]))
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryBuildIntArray(object[] values, out int[] result)
|
||||||
|
{
|
||||||
|
result = new int[values.Length];
|
||||||
|
|
||||||
|
for (var i = 0; i < values.Length; i++)
|
||||||
|
{
|
||||||
|
if (values[i] is int intValue)
|
||||||
|
{
|
||||||
|
result[i] = intValue;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!int.TryParse(values[i]?.ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture, out result[i]))
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryBuildLongArray(object[] values, out long[] result)
|
||||||
|
{
|
||||||
|
result = new long[values.Length];
|
||||||
|
|
||||||
|
for (var i = 0; i < values.Length; i++)
|
||||||
|
{
|
||||||
|
if (values[i] is long longValue)
|
||||||
|
{
|
||||||
|
result[i] = longValue;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!long.TryParse(values[i]?.ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture, out result[i]))
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryBuildDecimalArray(object[] values, out decimal[] result)
|
||||||
|
{
|
||||||
|
result = new decimal[values.Length];
|
||||||
|
|
||||||
|
for (var i = 0; i < values.Length; i++)
|
||||||
|
{
|
||||||
|
if (values[i] is decimal decimalValue)
|
||||||
|
{
|
||||||
|
result[i] = decimalValue;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!decimal.TryParse(values[i]?.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out result[i]))
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryBuildBoolArray(object[] values, out bool[] result)
|
||||||
|
{
|
||||||
|
result = new bool[values.Length];
|
||||||
|
|
||||||
|
for (var i = 0; i < values.Length; i++)
|
||||||
|
{
|
||||||
|
if (values[i] is bool boolValue)
|
||||||
|
{
|
||||||
|
result[i] = boolValue;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bool.TryParse(values[i]?.ToString(), out result[i]))
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryBuildDateTimeOffsetArray(object[] values, out DateTimeOffset[] result)
|
||||||
|
{
|
||||||
|
result = new DateTimeOffset[values.Length];
|
||||||
|
|
||||||
|
for (var i = 0; i < values.Length; i++)
|
||||||
|
{
|
||||||
|
if (values[i] is DateTimeOffset dateTimeOffsetValue)
|
||||||
|
{
|
||||||
|
result[i] = dateTimeOffsetValue;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values[i] is DateTime dateTimeValue)
|
||||||
|
{
|
||||||
|
result[i] = dateTimeValue;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DateTimeOffset.TryParse(values[i]?.ToString(), CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out result[i]))
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------ Dispose ------------------
|
// ------------------ Dispose ------------------
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ const useToolbar = ({
|
||||||
}: {
|
}: {
|
||||||
gridDto?: GridDto
|
gridDto?: GridDto
|
||||||
listFormCode: string
|
listFormCode: string
|
||||||
getSelectedRowKeys: () => void
|
getSelectedRowKeys: () => unknown[] | Promise<unknown[]>
|
||||||
getSelectedRowsData: () => any
|
getSelectedRowsData: () => any
|
||||||
refreshData: () => void
|
refreshData: () => void
|
||||||
getFilter: () => void
|
getFilter: () => void
|
||||||
|
|
@ -113,7 +113,8 @@ const useToolbar = ({
|
||||||
})
|
})
|
||||||
|
|
||||||
const workflowOptions = grdOpt.workflowDto
|
const workflowOptions = grdOpt.workflowDto
|
||||||
const approvalCriteria = workflowOptions?.criteria?.filter((item) => item.kind === 'Approval') ?? []
|
const approvalCriteria =
|
||||||
|
workflowOptions?.criteria?.filter((item) => item.kind === 'Approval') ?? []
|
||||||
if (
|
if (
|
||||||
workflowOptions?.approvalStatusFieldName &&
|
workflowOptions?.approvalStatusFieldName &&
|
||||||
approvalCriteria.length > 0 &&
|
approvalCriteria.length > 0 &&
|
||||||
|
|
@ -149,7 +150,7 @@ const useToolbar = ({
|
||||||
) {
|
) {
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification type="warning" duration={2500}>
|
<Notification type="warning" duration={2500}>
|
||||||
Secili kayit icin workflow zaten baslamis.
|
{translate('::WorkflowAlreadyStarted')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{ placement: 'top-end' },
|
{ placement: 'top-end' },
|
||||||
)
|
)
|
||||||
|
|
@ -211,7 +212,7 @@ const useToolbar = ({
|
||||||
if (activeRows.length !== selectedRows.length) {
|
if (activeRows.length !== selectedRows.length) {
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification type="warning" duration={2500}>
|
<Notification type="warning" duration={2500}>
|
||||||
Secili kayit bu onay adiminda veya onay kullanicisinda beklemiyor.
|
{translate('::SeciliKayitBekliyor')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{ placement: 'top-end' },
|
{ placement: 'top-end' },
|
||||||
)
|
)
|
||||||
|
|
@ -302,16 +303,75 @@ const useToolbar = ({
|
||||||
text: translate('::ListForms.ListForm.DeleteSelectedRecords'),
|
text: translate('::ListForms.ListForm.DeleteSelectedRecords'),
|
||||||
icon: 'trash',
|
icon: 'trash',
|
||||||
visible: false,
|
visible: false,
|
||||||
onClick() {
|
async onClick() {
|
||||||
if (!grdOpt.deleteServiceAddress) {
|
if (!grdOpt.deleteServiceAddress) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamicFetch(grdOpt.deleteServiceAddress, 'POST', null, {
|
const selectedKeys = await Promise.resolve(getSelectedRowKeys())
|
||||||
keys: getSelectedRowKeys(),
|
const keys = Array.isArray(selectedKeys) ? [...selectedKeys] : []
|
||||||
listFormCode,
|
|
||||||
}).then(() => {
|
if (!keys.length) {
|
||||||
refreshData()
|
toast.push(
|
||||||
|
<Notification type="warning" duration={2000}>
|
||||||
|
{translate('::ListForms.ListForm.SelectRecord')}
|
||||||
|
</Notification>,
|
||||||
|
{ placement: 'top-end' },
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setToolbarModalData({
|
||||||
|
open: true,
|
||||||
|
content: (
|
||||||
|
<>
|
||||||
|
<h5 className="mb-4">
|
||||||
|
{translate('::ListForms.ListForm.DeleteSelectedRecords')}
|
||||||
|
</h5>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{translate('::SeciliKayitlarSilmekIstiyormusunuz', {
|
||||||
|
0: keys.length,
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="text-right mt-6">
|
||||||
|
<Button
|
||||||
|
className="ltr:mr-2 rtl:ml-2"
|
||||||
|
variant="plain"
|
||||||
|
onClick={() => setToolbarModalData(undefined)}
|
||||||
|
>
|
||||||
|
{translate('::Cancel')}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="solid"
|
||||||
|
onClick={() => {
|
||||||
|
dynamicFetch(grdOpt.deleteServiceAddress!, 'POST', null, {
|
||||||
|
keys,
|
||||||
|
listFormCode,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
refreshData()
|
||||||
|
setToolbarModalData(undefined)
|
||||||
|
})
|
||||||
|
.catch((error: any) => {
|
||||||
|
toast.push(
|
||||||
|
<Notification type="danger" duration={3000}>
|
||||||
|
{error?.response?.data?.error?.message ||
|
||||||
|
error?.response?.data?.message ||
|
||||||
|
error?.message ||
|
||||||
|
translate('::SilmeIslemiBasarisiz')}
|
||||||
|
</Notification>,
|
||||||
|
{ placement: 'top-end' },
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{translate('::Delete')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -342,9 +402,13 @@ const useToolbar = ({
|
||||||
open: true,
|
open: true,
|
||||||
content: (
|
content: (
|
||||||
<>
|
<>
|
||||||
<h5 className="mb-4">Delete All Records</h5>
|
<h5 className="mb-4">{translate('::ListForms.ListForm.DeleteAllRecords')}</h5>
|
||||||
|
|
||||||
<p>Are you sure to delete all {r.data.totalCount} records?</p>
|
<p>
|
||||||
|
{translate('::TumKayitlariSilmekIstiyormusunuz', {
|
||||||
|
0: r.data.totalCount,
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
|
||||||
<div className="text-right mt-6">
|
<div className="text-right mt-6">
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -362,7 +426,7 @@ const useToolbar = ({
|
||||||
dynamicFetch('list-form-select/select', 'GET', parameters).then(() => {
|
dynamicFetch('list-form-select/select', 'GET', parameters).then(() => {
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification type="success" duration={2000}>
|
<Notification type="success" duration={2000}>
|
||||||
{'Tüm kayıtlar silindi.'}
|
{translate('::TumKayitlarSilindi')}
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{
|
{
|
||||||
placement: 'top-end',
|
placement: 'top-end',
|
||||||
|
|
@ -521,7 +585,9 @@ function isWorkflowApprovalCriteriaActive(
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeWorkflowValue(value: unknown) {
|
function normalizeWorkflowValue(value: unknown) {
|
||||||
return String(value ?? '').trim().toLocaleLowerCase('tr-TR')
|
return String(value ?? '')
|
||||||
|
.trim()
|
||||||
|
.toLocaleLowerCase('tr-TR')
|
||||||
}
|
}
|
||||||
|
|
||||||
function isWorkflowNotStarted(row: Record<string, unknown>, workflowOptions: WorkflowDto) {
|
function isWorkflowNotStarted(row: Record<string, unknown>, workflowOptions: WorkflowDto) {
|
||||||
|
|
@ -546,7 +612,8 @@ export function updateWorkflowApprovalToolbarItems(
|
||||||
name?: string
|
name?: string
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
const approvalCriteria = workflowOptions?.criteria?.filter((item) => item.kind === 'Approval') ?? []
|
const approvalCriteria =
|
||||||
|
workflowOptions?.criteria?.filter((item) => item.kind === 'Approval') ?? []
|
||||||
if (!component || !workflowOptions?.approvalStatusFieldName || !approvalCriteria.length) {
|
if (!component || !workflowOptions?.approvalStatusFieldName || !approvalCriteria.length) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -585,7 +652,12 @@ export function updateWorkflowApprovalToolbarItems(
|
||||||
const enabled =
|
const enabled =
|
||||||
selectedRowsData.length > 0 &&
|
selectedRowsData.length > 0 &&
|
||||||
selectedRowsData.every((row) =>
|
selectedRowsData.every((row) =>
|
||||||
isWorkflowApprovalCriteriaActive(row, workflowOptions, criteria.title, currentUserIdentities),
|
isWorkflowApprovalCriteriaActive(
|
||||||
|
row,
|
||||||
|
workflowOptions,
|
||||||
|
criteria.title,
|
||||||
|
currentUserIdentities,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
const optionPath = `toolbar.items[${toolbarItemIndex}].options.disabled`
|
const optionPath = `toolbar.items[${toolbarItemIndex}].options.disabled`
|
||||||
|
|
@ -620,13 +692,7 @@ function WorkflowApprovalDecisionDialog({
|
||||||
try {
|
try {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
keys.map((key) =>
|
keys.map((key) =>
|
||||||
workflowService.decideWorkflow(
|
workflowService.decideWorkflow(listFormCode, [key], approved, note, criteriaId),
|
||||||
listFormCode,
|
|
||||||
[key],
|
|
||||||
approved,
|
|
||||||
note,
|
|
||||||
criteriaId,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
onCompleted()
|
onCompleted()
|
||||||
|
|
@ -659,14 +725,19 @@ function WorkflowApprovalDecisionDialog({
|
||||||
onChange={(event) => setNote(event.target.value)}
|
onChange={(event) => setNote(event.target.value)}
|
||||||
/>
|
/>
|
||||||
<div className="text-right mt-6">
|
<div className="text-right mt-6">
|
||||||
<Button className="ltr:mr-2 rtl:ml-2" variant="plain" disabled={submitting} onClick={onCancel}>
|
<Button
|
||||||
|
className="ltr:mr-2 rtl:ml-2"
|
||||||
|
variant="plain"
|
||||||
|
disabled={submitting}
|
||||||
|
onClick={onCancel}
|
||||||
|
>
|
||||||
{translate('::Cancel')}
|
{translate('::Cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button className="ltr:mr-2 rtl:ml-2" disabled={submitting} onClick={() => decide(false)}>
|
<Button className="ltr:mr-2 rtl:ml-2" disabled={submitting} onClick={() => decide(false)}>
|
||||||
Reddet
|
{translate('::App.Listform.ListformField.Rejecter')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="solid" disabled={submitting} onClick={() => decide(true)}>
|
<Button variant="solid" disabled={submitting} onClick={() => decide(true)}>
|
||||||
Onayla
|
{translate('::App.Listform.ListformField.Approver')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue