Compare commits
14 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab6a33c340 | ||
|
|
319afbcb13 | ||
|
|
b87d7a94c8 | ||
|
|
95b0b0ce89 | ||
|
|
24e92fcb82 | ||
|
|
412ad236cc | ||
|
|
d38e4f851a | ||
|
|
6174253a40 | ||
|
|
248af7ca1a | ||
|
|
535ed6835f | ||
|
|
4805e8c4d9 | ||
|
|
28ec641275 | ||
|
|
1d05d24e41 | ||
|
|
b53a4243ab |
132 changed files with 11562 additions and 3977 deletions
|
|
@ -10,6 +10,11 @@ namespace Sozsoft.Platform.ListForms;
|
||||||
|
|
||||||
public class ColumnFormatDto : AuditedEntityDto<Guid>
|
public class ColumnFormatDto : AuditedEntityDto<Guid>
|
||||||
{
|
{
|
||||||
|
private static readonly JsonSerializerOptions EditorOptionsSerializerOptions = new()
|
||||||
|
{
|
||||||
|
PropertyNameCaseInsensitive = true
|
||||||
|
};
|
||||||
|
|
||||||
public ColumnFormatDto() { }
|
public ColumnFormatDto() { }
|
||||||
|
|
||||||
public string FieldName { get; set; }
|
public string FieldName { get; set; }
|
||||||
|
|
@ -240,6 +245,41 @@ public class ColumnFormatDto : AuditedEntityDto<Guid>
|
||||||
|
|
||||||
public string Alignment { get; set; }
|
public string Alignment { get; set; }
|
||||||
public string Format { get; set; }
|
public string Format { get; set; }
|
||||||
|
|
||||||
|
public int? EditOrderNo { get; set; }
|
||||||
|
public int? EditGroupOrderNo { get; set; }
|
||||||
|
public string EditorType2 { get; set; }
|
||||||
|
public int? ColSpan { get; set; }
|
||||||
|
|
||||||
public string EditorOptions { get; set; }
|
public string EditorOptions { get; set; }
|
||||||
|
public GridBoxOptionsDto GridBoxOptions =>
|
||||||
|
DeserializeEditorOptions<GridBoxOptionsDto>(PlatformConsts.EditorTypes.dxGridBox);
|
||||||
|
public TagBoxOptionsDto TagBoxOptions =>
|
||||||
|
DeserializeEditorOptions<TagBoxOptionsDto>(PlatformConsts.EditorTypes.dxTagBox);
|
||||||
|
public ImageUploadOptionsDto ImageUploadOptions =>
|
||||||
|
DeserializeEditorOptions<ImageUploadOptionsDto>(
|
||||||
|
PlatformConsts.EditorTypes.dxImageUpload,
|
||||||
|
PlatformConsts.EditorTypes.dxImageViewer);
|
||||||
|
public string EditorScript { get; set; }
|
||||||
|
|
||||||
|
private T DeserializeEditorOptions<T>(params string[] editorTypes) where T : class
|
||||||
|
{
|
||||||
|
if (!Array.Exists(
|
||||||
|
editorTypes,
|
||||||
|
editorType => string.Equals(EditorType2, editorType, StringComparison.OrdinalIgnoreCase)) ||
|
||||||
|
string.IsNullOrWhiteSpace(EditorOptions))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return JsonSerializer.Deserialize<T>(EditorOptions, EditorOptionsSerializerOptions);
|
||||||
|
}
|
||||||
|
catch (JsonException)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,35 +16,5 @@ public class EditingFormDto
|
||||||
public string Caption { get; set; }
|
public string Caption { get; set; }
|
||||||
public int ColCount { get; set; } = 2;
|
public int ColCount { get; set; } = 2;
|
||||||
public int ColSpan { get; set; } = 2;
|
public int ColSpan { get; set; } = 2;
|
||||||
/// <summary> Type: Array<Simple Form Item | Group Form Item | Tabbed Form Item | Empty Form Item | Button Form Item>
|
|
||||||
/// Bu kisma suan sadece string olarak doldurulacak
|
|
||||||
/// items: ['FirstName', 'LastName',
|
|
||||||
/// { dataField: 'Notes', editorType: 'dxTextArea', colSpan: 2, editorOptions: { height: 100, }, }
|
|
||||||
/// ],
|
|
||||||
/// </summary>
|
|
||||||
//[TextArea]
|
|
||||||
//public string[] Items { get; set; }
|
|
||||||
public EditingFormItemDto[] Items { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EditingFormItemDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// DataField Accepted Values: 'dxAutocomplete' | 'dxCalendar' | 'dxCheckBox' | 'dxColorBox' | 'dxDateBox' | 'dxDateRangeBox' | 'dxDropDownBox' | 'dxHtmlEditor' | 'dxLookup' | 'dxNumberBox' | 'dxRadioGroup' | 'dxRangeSlider' | 'dxSelectBox' | 'dxSlider' | 'dxSwitch' | 'dxTagBox' | 'dxTextArea' | 'dxTextBox' | 'dxImageViewer' | 'dxImageUpload';
|
|
||||||
/// </summary>
|
|
||||||
[JsonPropertyName("order")]
|
|
||||||
public int Order { get; set; }
|
|
||||||
[JsonPropertyName("dataField")]
|
|
||||||
public string DataField { get; set; }
|
|
||||||
[JsonPropertyName("editorType2")]
|
|
||||||
public string EditorType2 { get; set; }
|
|
||||||
[JsonPropertyName("colSpan")]
|
|
||||||
public int ColSpan { get; set; }
|
|
||||||
[JsonPropertyName("editorOptions")]
|
|
||||||
public string EditorOptions { get; set; }
|
|
||||||
public GridBoxOptionsDto GridBoxOptions { get; set; }
|
|
||||||
public TagBoxOptionsDto TagBoxOptions { get; set; }
|
|
||||||
[JsonPropertyName("editorScript")]
|
|
||||||
public string EditorScript { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,19 @@ public class GridOptionsDto : AuditedEntityDto<Guid>
|
||||||
set { SchedulerOptionJson = JsonSerializer.Serialize(value); }
|
set { SchedulerOptionJson = JsonSerializer.Serialize(value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public string TodoOptionJson { get; set; }
|
||||||
|
public TodoOptionDto TodoOptionDto
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(TodoOptionJson))
|
||||||
|
return JsonSerializer.Deserialize<TodoOptionDto>(TodoOptionJson);
|
||||||
|
return new TodoOptionDto();
|
||||||
|
}
|
||||||
|
set { TodoOptionJson = JsonSerializer.Serialize(value); }
|
||||||
|
}
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string PagerOptionJson { get; set; }
|
public string PagerOptionJson { get; set; }
|
||||||
public GridPagerOptionDto PagerOptionDto
|
public GridPagerOptionDto PagerOptionDto
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
namespace Sozsoft.Platform.ListForms;
|
||||||
|
|
||||||
|
public class ImageUploadOptionsDto
|
||||||
|
{
|
||||||
|
public string UploadUrl { get; set; }
|
||||||
|
public string Accept { get; set; }
|
||||||
|
public bool? Multiple { get; set; }
|
||||||
|
public long? MaxFileSize { get; set; }
|
||||||
|
public int? Width { get; set; }
|
||||||
|
public int? Height { get; set; }
|
||||||
|
}
|
||||||
|
|
@ -3,11 +3,13 @@
|
||||||
public class LayoutDto
|
public class LayoutDto
|
||||||
{
|
{
|
||||||
public bool Grid { get; set; } = true;
|
public bool Grid { get; set; } = true;
|
||||||
|
public bool Card { get; set; } = true;
|
||||||
public bool Pivot { get; set; } = true;
|
public bool Pivot { get; set; } = true;
|
||||||
public bool Chart { get; set; } = true;
|
public bool Chart { get; set; } = true;
|
||||||
public bool Tree { get; set; } = true;
|
public bool Tree { get; set; } = true;
|
||||||
public bool Gantt { get; set; } = true;
|
public bool Gantt { get; set; } = true;
|
||||||
public bool Scheduler { get; set; } = true;
|
public bool Scheduler { get; set; } = true;
|
||||||
|
public bool Todo { get; set; } = false;
|
||||||
public string DefaultLayout { get; set; } = "grid";
|
public string DefaultLayout { get; set; } = "grid";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
namespace Sozsoft.Platform.ListForms;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dinamik bir listeyi Todo/Kanban panosu olarak gostermek icin alan eslemeleri.
|
||||||
|
/// TitleExpr ve StatusExpr zorunlu, diger alanlar opsiyoneldir.
|
||||||
|
/// </summary>
|
||||||
|
public class TodoOptionDto
|
||||||
|
{
|
||||||
|
public string TitleExpr { get; set; }
|
||||||
|
public string StatusExpr { get; set; }
|
||||||
|
public string DescriptionExpr { get; set; }
|
||||||
|
public string DueDateExpr { get; set; }
|
||||||
|
public string TagExpr { get; set; }
|
||||||
|
public string AssigneeExpr { get; set; }
|
||||||
|
public string PriorityExpr { get; set; }
|
||||||
|
public string CompletedExpr { get; set; }
|
||||||
|
public string OrderExpr { get; set; }
|
||||||
|
public string StatusOrder { get; set; }
|
||||||
|
public bool AllowDragging { get; set; } = true;
|
||||||
|
}
|
||||||
|
|
@ -5,10 +5,10 @@ namespace Sozsoft.Platform.ListForms;
|
||||||
public class WorkflowDto
|
public class WorkflowDto
|
||||||
{
|
{
|
||||||
public string ApprovalUserFieldName { get; set; }
|
public string ApprovalUserFieldName { get; set; }
|
||||||
public bool IsFilterUserName { get; set; }
|
|
||||||
public string ApprovalDateFieldName { get; set; }
|
public string ApprovalDateFieldName { get; set; }
|
||||||
public string ApprovalStatusFieldName { get; set; }
|
public string ApprovalStatusFieldName { get; set; }
|
||||||
public string ApprovalDescriptionFieldName { get; set; }
|
public string ApprovalDescriptionFieldName { get; set; }
|
||||||
|
public bool ApprovalIsFilterUserName { get; set; }
|
||||||
|
|
||||||
public List<ListFormWorkflowCriteriaDto> Criteria { get; set; } = [];
|
public List<ListFormWorkflowCriteriaDto> Criteria { get; set; } = [];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ public class ListFormEditTabs
|
||||||
public const string TreeForm = "tree";
|
public const string TreeForm = "tree";
|
||||||
public const string GanttForm = "gantt";
|
public const string GanttForm = "gantt";
|
||||||
public const string SchedulerForm = "scheduler";
|
public const string SchedulerForm = "scheduler";
|
||||||
|
public const string TodoForm = "todo";
|
||||||
public const string PagerForm = "pager";
|
public const string PagerForm = "pager";
|
||||||
public const string StateForm = "state";
|
public const string StateForm = "state";
|
||||||
public const string SubFormJsonRow = "subForm";
|
public const string SubFormJsonRow = "subForm";
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,13 @@ public class ListFormWizardDto
|
||||||
|
|
||||||
public string DefaultLayout { get; set; }
|
public string DefaultLayout { get; set; }
|
||||||
public bool Grid { get; set; }
|
public bool Grid { get; set; }
|
||||||
|
public bool Card { get; set; }
|
||||||
public bool Pivot { get; set; }
|
public bool Pivot { get; set; }
|
||||||
public bool Tree { get; set; }
|
public bool Tree { get; set; }
|
||||||
public bool Chart { get; set; }
|
public bool Chart { get; set; }
|
||||||
public bool Gantt { get; set; }
|
public bool Gantt { get; set; }
|
||||||
public bool Scheduler { get; set; }
|
public bool Scheduler { get; set; }
|
||||||
|
public bool Todo { get; set; }
|
||||||
|
|
||||||
public string LanguageTextMenuEn { get; set; }
|
public string LanguageTextMenuEn { get; set; }
|
||||||
public string LanguageTextMenuTr { get; set; }
|
public string LanguageTextMenuTr { get; set; }
|
||||||
|
|
@ -39,6 +41,7 @@ public class ListFormWizardDto
|
||||||
|
|
||||||
public string PermissionGroupName { get; set; }
|
public string PermissionGroupName { get; set; }
|
||||||
public string MenuParentCode { get; set; }
|
public string MenuParentCode { get; set; }
|
||||||
|
public string MenuParentShortName { get; set; }
|
||||||
public string MenuParentIcon { get; set; }
|
public string MenuParentIcon { get; set; }
|
||||||
public string MenuIcon { get; set; }
|
public string MenuIcon { get; set; }
|
||||||
public string DataSourceCode { get; set; }
|
public string DataSourceCode { get; set; }
|
||||||
|
|
@ -68,9 +71,28 @@ public class ListFormWizardDto
|
||||||
public string SchedulerStartDateExpr { get; set; }
|
public string SchedulerStartDateExpr { get; set; }
|
||||||
public string SchedulerEndDateExpr { get; set; }
|
public string SchedulerEndDateExpr { get; set; }
|
||||||
|
|
||||||
|
// Todo options (required when DefaultLayout = "todo")
|
||||||
|
public string TodoTitleExpr { get; set; }
|
||||||
|
public string TodoStatusExpr { get; set; }
|
||||||
|
public string TodoDescriptionExpr { get; set; }
|
||||||
|
public string TodoDueDateExpr { get; set; }
|
||||||
|
public string TodoTagExpr { get; set; }
|
||||||
|
public string TodoAssigneeExpr { get; set; }
|
||||||
|
public string TodoPriorityExpr { get; set; }
|
||||||
|
public string TodoCompletedExpr { get; set; }
|
||||||
|
public string TodoOrderExpr { get; set; }
|
||||||
|
public string TodoStatusOrder { get; set; }
|
||||||
|
public bool TodoAllowDragging { get; set; } = true;
|
||||||
|
|
||||||
|
// Workflow options (required when DefaultLayout = "workflow")
|
||||||
|
public string ApprovalUserFieldName { get; set; }
|
||||||
|
public string ApprovalDateFieldName { get; set; }
|
||||||
|
public string ApprovalStatusFieldName { get; set; }
|
||||||
|
public string ApprovalDescriptionFieldName { get; set; }
|
||||||
|
public bool ApprovalIsFilterUserName { get; set; }
|
||||||
|
public List<ListFormWorkflowCriteriaDto> Criteria { get; set; } = [];
|
||||||
|
|
||||||
public List<WizardColumnGroupInputDto> Groups { get; set; } = new();
|
public List<WizardColumnGroupInputDto> Groups { get; set; } = new();
|
||||||
public List<SubFormDto> SubForms { get; set; } = new();
|
public List<SubFormDto> SubForms { get; set; } = new();
|
||||||
public List<WidgetEditDto> Widgets { get; set; } = new();
|
public List<WidgetEditDto> Widgets { get; set; } = new();
|
||||||
public WorkflowDto Workflow { get; set; } = new();
|
|
||||||
public List<ListFormWorkflowCriteriaDto> WorkflowCriteria { get; set; } = new();
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ namespace Sozsoft.Platform.ListForms;
|
||||||
|
|
||||||
public class WizardColumnItemInputDto
|
public class WizardColumnItemInputDto
|
||||||
{
|
{
|
||||||
public string DataField { get; set; }
|
public string FieldName { get; set; }
|
||||||
public string CaptionName { get; set; }
|
public string CaptionName { get; set; }
|
||||||
public string EditorType { get; set; }
|
public string EditorType { get; set; }
|
||||||
public string EditorOptions { get; set; }
|
public string EditorOptions { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,7 @@ public static class LookupQueryValues
|
||||||
$"LEFT OUTER JOIN \"{FullNameTable(TableNameEnum.LanguageText)}\" " +
|
$"LEFT OUTER JOIN \"{FullNameTable(TableNameEnum.LanguageText)}\" " +
|
||||||
$"ON \"{FullNameTable(TableNameEnum.Product)}\".\"Name\" = \"{FullNameTable(TableNameEnum.LanguageText)}\".\"Key\" " +
|
$"ON \"{FullNameTable(TableNameEnum.Product)}\".\"Name\" = \"{FullNameTable(TableNameEnum.LanguageText)}\".\"Key\" " +
|
||||||
$"WHERE \"{FullNameTable(TableNameEnum.Product)}\".\"IsDeleted\" = 'false' " +
|
$"WHERE \"{FullNameTable(TableNameEnum.Product)}\".\"IsDeleted\" = 'false' " +
|
||||||
|
$"AND \"{FullNameTable(TableNameEnum.LanguageText)}\".\"CultureName\" = 'tr' " +
|
||||||
$"ORDER BY \"{FullNameTable(TableNameEnum.LanguageText)}\".\"Value\";";
|
$"ORDER BY \"{FullNameTable(TableNameEnum.LanguageText)}\".\"Value\";";
|
||||||
|
|
||||||
public static string MenuCodeValues =
|
public static string MenuCodeValues =
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using Volo.Abp.Application.Services;
|
||||||
using Volo.Abp.Domain.Repositories;
|
using Volo.Abp.Domain.Repositories;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Sozsoft.Platform.AiBots;
|
namespace Sozsoft.Platform.AiBots;
|
||||||
|
|
||||||
|
|
@ -25,16 +26,31 @@ public class AiBotAppService : CrudAppService<
|
||||||
{
|
{
|
||||||
await CheckGetListPolicyAsync();
|
await CheckGetListPolicyAsync();
|
||||||
|
|
||||||
var query = await CreateFilteredQueryAsync(input);
|
|
||||||
|
|
||||||
if (CurrentTenant.IsAvailable && !string.IsNullOrWhiteSpace(CurrentTenant.Name))
|
if (CurrentTenant.IsAvailable && !string.IsNullOrWhiteSpace(CurrentTenant.Name))
|
||||||
{
|
{
|
||||||
var tenantName = CurrentTenant.Name;
|
var tenantName = CurrentTenant.Name;
|
||||||
query = query.Where(aiBot =>
|
List<AiBot> tenantEntities;
|
||||||
string.IsNullOrWhiteSpace(aiBot.Tenants) ||
|
|
||||||
aiBot.Tenants.Contains($"\"{tenantName}\""));
|
using (CurrentTenant.Change(null))
|
||||||
|
{
|
||||||
|
var hostQuery = await CreateFilteredQueryAsync(input);
|
||||||
|
tenantEntities = await AsyncExecuter.ToListAsync(hostQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var filteredQuery = tenantEntities
|
||||||
|
.Where(aiBot => IsAvailableForTenant(aiBot.Tenants, tenantName))
|
||||||
|
.AsQueryable();
|
||||||
|
|
||||||
|
var tenantTotalCount = filteredQuery.LongCount();
|
||||||
|
filteredQuery = ApplySorting(filteredQuery, input);
|
||||||
|
filteredQuery = ApplyPaging(filteredQuery, input);
|
||||||
|
|
||||||
|
var tenantDtos = await MapToGetListOutputDtosAsync(filteredQuery.ToList());
|
||||||
|
|
||||||
|
return new PagedResultDto<AiBotDto>(tenantTotalCount, tenantDtos);
|
||||||
|
}
|
||||||
|
|
||||||
|
var query = await CreateFilteredQueryAsync(input);
|
||||||
var totalCount = await AsyncExecuter.CountAsync(query);
|
var totalCount = await AsyncExecuter.CountAsync(query);
|
||||||
query = ApplySorting(query, input);
|
query = ApplySorting(query, input);
|
||||||
query = ApplyPaging(query, input);
|
query = ApplyPaging(query, input);
|
||||||
|
|
@ -44,5 +60,17 @@ public class AiBotAppService : CrudAppService<
|
||||||
|
|
||||||
return new PagedResultDto<AiBotDto>(totalCount, dtos);
|
return new PagedResultDto<AiBotDto>(totalCount, dtos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsAvailableForTenant(string tenants, string tenantName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(tenants))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tenants
|
||||||
|
.Split('|', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
||||||
|
.Any(name => string.Equals(name, tenantName, StringComparison.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,26 +47,33 @@ public class ListFormFieldsAppService : CrudAppService<
|
||||||
|
|
||||||
protected override void MapToEntity(ColumnFormatEditDto updateInput, ListFormField entity)
|
protected override void MapToEntity(ColumnFormatEditDto updateInput, ListFormField entity)
|
||||||
{
|
{
|
||||||
|
entity.CultureName = updateInput.CultureName;
|
||||||
entity.RoleId = updateInput.RoleId;
|
entity.RoleId = updateInput.RoleId;
|
||||||
entity.ListFormCode = updateInput.ListFormCode;
|
entity.ListFormCode = updateInput.ListFormCode;
|
||||||
entity.FieldName = updateInput.FieldName;
|
entity.FieldName = updateInput.FieldName;
|
||||||
entity.CultureName = updateInput.CultureName;
|
|
||||||
entity.CaptionName = updateInput.CaptionName;
|
entity.CaptionName = updateInput.CaptionName;
|
||||||
entity.PlaceHolder = updateInput.PlaceHolder;
|
entity.PlaceHolder = updateInput.PlaceHolder;
|
||||||
entity.BandName = updateInput.BandName;
|
entity.BandName = updateInput.BandName;
|
||||||
entity.IsActive = updateInput.IsActive;
|
entity.IsActive = updateInput.IsActive;
|
||||||
entity.Visible = updateInput.Visible;
|
entity.Visible = updateInput.Visible;
|
||||||
entity.AllowSearch = updateInput.AllowSearch;
|
entity.AllowSearch = updateInput.AllowSearch;
|
||||||
entity.AllowEditing = updateInput.AllowEditing;
|
|
||||||
entity.AllowAdding = updateInput.AllowAdding;
|
|
||||||
entity.ListOrderNo = updateInput.ListOrderNo;
|
|
||||||
entity.SourceDbType = updateInput.SourceDbType;
|
entity.SourceDbType = updateInput.SourceDbType;
|
||||||
|
entity.Alignment = updateInput.Alignment;
|
||||||
|
entity.Format = updateInput.Format;
|
||||||
|
entity.EditorOptions = updateInput.EditorOptions;
|
||||||
|
entity.EditorScript = updateInput.EditorScript;
|
||||||
|
entity.ListOrderNo = updateInput.ListOrderNo;
|
||||||
entity.Width = updateInput.Width;
|
entity.Width = updateInput.Width;
|
||||||
entity.SortDirection = updateInput.SortDirection;
|
entity.SortDirection = updateInput.SortDirection;
|
||||||
entity.SortIndex = updateInput.SortIndex;
|
entity.SortIndex = updateInput.SortIndex;
|
||||||
entity.Format = updateInput.Format;
|
entity.EditOrderNo = updateInput.EditOrderNo;
|
||||||
entity.Alignment = updateInput.Alignment;
|
entity.EditGroupOrderNo = updateInput.EditGroupOrderNo;
|
||||||
entity.EditorOptions = updateInput.EditorOptions;
|
entity.ColSpan = updateInput.ColSpan;
|
||||||
|
entity.EditorType2 = updateInput.EditorType2;
|
||||||
|
entity.AllowEditing = updateInput.AllowEditing;
|
||||||
|
entity.AllowAdding = updateInput.AllowAdding;
|
||||||
|
entity.PermissionJson = JsonSerializer.Serialize(updateInput.PermissionDto);
|
||||||
|
entity.LookupJson = JsonSerializer.Serialize(updateInput.LookupDto);
|
||||||
entity.ColumnCustomizationJson = JsonSerializer.Serialize(updateInput.ColumnCustomizationDto);
|
entity.ColumnCustomizationJson = JsonSerializer.Serialize(updateInput.ColumnCustomizationDto);
|
||||||
entity.ColumnFilterJson = JsonSerializer.Serialize(updateInput.ColumnFilterDto);
|
entity.ColumnFilterJson = JsonSerializer.Serialize(updateInput.ColumnFilterDto);
|
||||||
entity.ColumnHeaderJson = JsonSerializer.Serialize(updateInput.ColumnHeaderDto);
|
entity.ColumnHeaderJson = JsonSerializer.Serialize(updateInput.ColumnHeaderDto);
|
||||||
|
|
@ -74,12 +81,10 @@ public class ListFormFieldsAppService : CrudAppService<
|
||||||
entity.GroupSummaryJson = updateInput.ColumnGroupSummaryDto.SummaryType.IsNullOrEmpty() ? "" : JsonSerializer.Serialize(updateInput.ColumnGroupSummaryDto);
|
entity.GroupSummaryJson = updateInput.ColumnGroupSummaryDto.SummaryType.IsNullOrEmpty() ? "" : JsonSerializer.Serialize(updateInput.ColumnGroupSummaryDto);
|
||||||
entity.TotalSummaryJson = updateInput.ColumnTotalSummaryDto.SummaryType.IsNullOrEmpty() ? "" : JsonSerializer.Serialize(updateInput.ColumnTotalSummaryDto);
|
entity.TotalSummaryJson = updateInput.ColumnTotalSummaryDto.SummaryType.IsNullOrEmpty() ? "" : JsonSerializer.Serialize(updateInput.ColumnTotalSummaryDto);
|
||||||
entity.JoinTableJson = JsonSerializer.Serialize(updateInput.ColumnJoinTableDto);
|
entity.JoinTableJson = JsonSerializer.Serialize(updateInput.ColumnJoinTableDto);
|
||||||
entity.LookupJson = JsonSerializer.Serialize(updateInput.LookupDto);
|
|
||||||
entity.ColumnCssClass = updateInput.ColumnCssClass;
|
entity.ColumnCssClass = updateInput.ColumnCssClass;
|
||||||
entity.ColumnCssValue = updateInput.ColumnCssValue;
|
entity.ColumnCssValue = updateInput.ColumnCssValue;
|
||||||
entity.ValidationRuleJson = JsonSerializer.Serialize(updateInput.ValidationRuleDto);
|
entity.ValidationRuleJson = JsonSerializer.Serialize(updateInput.ValidationRuleDto);
|
||||||
entity.ColumnStylingJson = JsonSerializer.Serialize(updateInput.ColumnStylingDto);
|
entity.ColumnStylingJson = JsonSerializer.Serialize(updateInput.ColumnStylingDto);
|
||||||
entity.PermissionJson = JsonSerializer.Serialize(updateInput.PermissionDto);
|
|
||||||
entity.PivotSettingsJson = JsonSerializer.Serialize(updateInput.PivotSettingsDto);
|
entity.PivotSettingsJson = JsonSerializer.Serialize(updateInput.PivotSettingsDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,6 +141,9 @@ public class ListFormFieldsAppService : CrudAppService<
|
||||||
item.Alignment = input.Alignment;
|
item.Alignment = input.Alignment;
|
||||||
item.Format = input.Format;
|
item.Format = input.Format;
|
||||||
item.EditorOptions = input.EditorOptions;
|
item.EditorOptions = input.EditorOptions;
|
||||||
|
item.IsActive = input.IsActive;
|
||||||
|
item.Visible = input.Visible;
|
||||||
|
item.AllowSearch = input.AllowSearch;
|
||||||
}
|
}
|
||||||
else if (input.EditType == ListFormFieldEditTabs.PermissionsForm)
|
else if (input.EditType == ListFormFieldEditTabs.PermissionsForm)
|
||||||
{
|
{
|
||||||
|
|
@ -152,6 +160,11 @@ public class ListFormFieldsAppService : CrudAppService<
|
||||||
item.AllowSearch = input.AllowSearch;
|
item.AllowSearch = input.AllowSearch;
|
||||||
item.AllowEditing = input.AllowEditing;
|
item.AllowEditing = input.AllowEditing;
|
||||||
item.AllowAdding = input.AllowAdding;
|
item.AllowAdding = input.AllowAdding;
|
||||||
|
item.EditGroupOrderNo = input.EditGroupOrderNo;
|
||||||
|
item.EditOrderNo = input.EditOrderNo;
|
||||||
|
item.ColSpan = input.ColSpan;
|
||||||
|
item.EditorType2 = input.EditorType2;
|
||||||
|
item.EditorScript = input.EditorScript;
|
||||||
}
|
}
|
||||||
else if (input.EditType == ListFormFieldEditTabs.CustomizationForm)
|
else if (input.EditType == ListFormFieldEditTabs.CustomizationForm)
|
||||||
{
|
{
|
||||||
|
|
@ -257,6 +270,9 @@ public class ListFormFieldsAppService : CrudAppService<
|
||||||
field.CaptionName = sourceField.CaptionName;
|
field.CaptionName = sourceField.CaptionName;
|
||||||
field.PlaceHolder = sourceField.PlaceHolder;
|
field.PlaceHolder = sourceField.PlaceHolder;
|
||||||
field.SourceDbType = sourceField.SourceDbType;
|
field.SourceDbType = sourceField.SourceDbType;
|
||||||
|
field.Alignment = sourceField.Alignment;
|
||||||
|
field.Format = sourceField.Format;
|
||||||
|
field.EditorOptions = sourceField.EditorOptions;
|
||||||
}
|
}
|
||||||
if (input.CopiedFields.All || input.CopiedFields.Options)
|
if (input.CopiedFields.All || input.CopiedFields.Options)
|
||||||
{
|
{
|
||||||
|
|
@ -269,35 +285,40 @@ public class ListFormFieldsAppService : CrudAppService<
|
||||||
field.AllowSearch = sourceField.AllowSearch;
|
field.AllowSearch = sourceField.AllowSearch;
|
||||||
field.AllowEditing = sourceField.AllowEditing;
|
field.AllowEditing = sourceField.AllowEditing;
|
||||||
field.AllowAdding = sourceField.AllowAdding;
|
field.AllowAdding = sourceField.AllowAdding;
|
||||||
|
field.EditGroupOrderNo = sourceField.EditGroupOrderNo;
|
||||||
|
field.EditOrderNo = sourceField.EditOrderNo;
|
||||||
|
field.ColSpan = sourceField.ColSpan;
|
||||||
|
field.EditorType2 = sourceField.EditorType2;
|
||||||
|
field.EditorScript = sourceField.EditorScript;
|
||||||
}
|
}
|
||||||
else if (input.CopiedFields.All || input.CopiedFields.Permission)
|
if (input.CopiedFields.All || input.CopiedFields.Permission)
|
||||||
{
|
{
|
||||||
field.PermissionJson = sourceField.PermissionJson;
|
field.PermissionJson = sourceField.PermissionJson;
|
||||||
}
|
}
|
||||||
else if (input.CopiedFields.All || input.CopiedFields.Customization)
|
if (input.CopiedFields.All || input.CopiedFields.Customization)
|
||||||
field.ColumnCustomizationJson = sourceField.ColumnCustomizationJson;
|
field.ColumnCustomizationJson = sourceField.ColumnCustomizationJson;
|
||||||
else if (input.CopiedFields.All || input.CopiedFields.Filtering)
|
if (input.CopiedFields.All || input.CopiedFields.Filtering)
|
||||||
field.ColumnFilterJson = sourceField.ColumnFilterJson;
|
field.ColumnFilterJson = sourceField.ColumnFilterJson;
|
||||||
else if (input.CopiedFields.All || input.CopiedFields.Headering)
|
if (input.CopiedFields.All || input.CopiedFields.Headering)
|
||||||
field.ColumnHeaderJson = sourceField.ColumnHeaderJson;
|
field.ColumnHeaderJson = sourceField.ColumnHeaderJson;
|
||||||
else if (input.CopiedFields.All || input.CopiedFields.Grouping)
|
if (input.CopiedFields.All || input.CopiedFields.Grouping)
|
||||||
field.GroupingJson = sourceField.GroupingJson;
|
field.GroupingJson = sourceField.GroupingJson;
|
||||||
else if (input.CopiedFields.All || input.CopiedFields.GroupSummary)
|
if (input.CopiedFields.All || input.CopiedFields.GroupSummary)
|
||||||
field.GroupSummaryJson = sourceField.GroupSummaryJson;
|
field.GroupSummaryJson = sourceField.GroupSummaryJson;
|
||||||
else if (input.CopiedFields.All || input.CopiedFields.TotalSummary)
|
if (input.CopiedFields.All || input.CopiedFields.TotalSummary)
|
||||||
field.TotalSummaryJson = sourceField.TotalSummaryJson;
|
field.TotalSummaryJson = sourceField.TotalSummaryJson;
|
||||||
else if (input.CopiedFields.All || input.CopiedFields.JoinOptions)
|
if (input.CopiedFields.All || input.CopiedFields.JoinOptions)
|
||||||
field.JoinTableJson = sourceField.JoinTableJson;
|
field.JoinTableJson = sourceField.JoinTableJson;
|
||||||
else if (input.CopiedFields.All || input.CopiedFields.CssOptions)
|
if (input.CopiedFields.All || input.CopiedFields.CssOptions)
|
||||||
{
|
{
|
||||||
field.ColumnCssClass = sourceField.ColumnCssClass;
|
field.ColumnCssClass = sourceField.ColumnCssClass;
|
||||||
field.ColumnCssValue = sourceField.ColumnCssValue;
|
field.ColumnCssValue = sourceField.ColumnCssValue;
|
||||||
}
|
}
|
||||||
else if (input.CopiedFields.All || input.CopiedFields.ValidationRules)
|
if (input.CopiedFields.All || input.CopiedFields.ValidationRules)
|
||||||
field.ValidationRuleJson = sourceField.ValidationRuleJson;
|
field.ValidationRuleJson = sourceField.ValidationRuleJson;
|
||||||
else if (input.CopiedFields.All || input.CopiedFields.Formatting)
|
if (input.CopiedFields.All || input.CopiedFields.Formatting)
|
||||||
field.ColumnStylingJson = sourceField.ColumnStylingJson;
|
field.ColumnStylingJson = sourceField.ColumnStylingJson;
|
||||||
else if (input.CopiedFields.All || input.CopiedFields.PivotSetting)
|
if (input.CopiedFields.All || input.CopiedFields.PivotSetting)
|
||||||
field.PivotSettingsJson = sourceField.PivotSettingsJson;
|
field.PivotSettingsJson = sourceField.PivotSettingsJson;
|
||||||
|
|
||||||
await Repository.InsertAsync(field);
|
await Repository.InsertAsync(field);
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,10 @@ public class ListFormsAppService : CrudAppService<
|
||||||
{
|
{
|
||||||
item.SchedulerOptionJson = JsonSerializer.Serialize(input.SchedulerOptionDto);
|
item.SchedulerOptionJson = JsonSerializer.Serialize(input.SchedulerOptionDto);
|
||||||
}
|
}
|
||||||
|
else if (input.EditType == ListFormEditTabs.TodoForm)
|
||||||
|
{
|
||||||
|
item.TodoOptionJson = JsonSerializer.Serialize(input.TodoOptionDto);
|
||||||
|
}
|
||||||
else if (input.EditType == ListFormEditTabs.PagerForm)
|
else if (input.EditType == ListFormEditTabs.PagerForm)
|
||||||
{
|
{
|
||||||
item.PageSize = input.PageSize;
|
item.PageSize = input.PageSize;
|
||||||
|
|
|
||||||
|
|
@ -180,11 +180,18 @@ public class ListFormWizardAppService(
|
||||||
Code = input.MenuParentCode,
|
Code = input.MenuParentCode,
|
||||||
DisplayName = input.MenuParentCode,
|
DisplayName = input.MenuParentCode,
|
||||||
IsDisabled = false,
|
IsDisabled = false,
|
||||||
|
ShortName = input.MenuParentShortName?.Trim(),
|
||||||
Icon = menuParentIcon,
|
Icon = menuParentIcon,
|
||||||
Order = maxRootOrder + 1,
|
Order = maxRootOrder + 1,
|
||||||
}, autoSave: false);
|
}, autoSave: false);
|
||||||
inserted.MenuCodes.Add(input.MenuParentCode);
|
inserted.MenuCodes.Add(input.MenuParentCode);
|
||||||
}
|
}
|
||||||
|
else if (string.IsNullOrWhiteSpace(menuParent.ShortName) &&
|
||||||
|
!string.IsNullOrWhiteSpace(input.MenuParentShortName))
|
||||||
|
{
|
||||||
|
menuParent.ShortName = input.MenuParentShortName.Trim();
|
||||||
|
await repoMenu.UpdateAsync(menuParent, autoSave: false);
|
||||||
|
}
|
||||||
|
|
||||||
//Menu
|
//Menu
|
||||||
var maxChildOrder = menuQueryable.Where(a => a.ParentCode == menuParent.Code).Select(a => (int?)a.Order).Max() ?? 0;
|
var maxChildOrder = menuQueryable.Where(a => a.ParentCode == menuParent.Code).Select(a => (int?)a.Order).Max() ?? 0;
|
||||||
|
|
@ -230,21 +237,9 @@ public class ListFormWizardAppService(
|
||||||
Caption = g.Caption,
|
Caption = g.Caption,
|
||||||
ColCount = g.ColCount,
|
ColCount = g.ColCount,
|
||||||
ColSpan = g.ColCount,
|
ColSpan = g.ColCount,
|
||||||
ItemType = "group",
|
ItemType = "group"
|
||||||
Items = g.Items
|
|
||||||
.Where(i => i.IncludeInEditingForm && i.DataField != input.KeyFieldName)
|
|
||||||
.Select((it, ii) => new EditingFormItemDto
|
|
||||||
{
|
|
||||||
Order = ii + 1,
|
|
||||||
DataField = it.DataField,
|
|
||||||
EditorType2 = it.EditorType,
|
|
||||||
ColSpan = it.ColSpan,
|
|
||||||
EditorOptions = string.IsNullOrWhiteSpace(it.EditorOptions) ? null : it.EditorOptions,
|
|
||||||
EditorScript = string.IsNullOrWhiteSpace(it.EditorScript) ? null : it.EditorScript,
|
|
||||||
})
|
})
|
||||||
.ToArray()
|
.Where((_, index) => input.Groups[index].Items.Any(i => i.IncludeInEditingForm && i.FieldName != input.KeyFieldName))
|
||||||
})
|
|
||||||
.Where(g => g.Items.Length > 0)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
//ListForm - varsa sil, yeniden ekle
|
//ListForm - varsa sil, yeniden ekle
|
||||||
|
|
@ -269,10 +264,18 @@ public class ListFormWizardAppService(
|
||||||
var tableColumns = await GetTableColumnNamesAsync(input.DataSourceCode, input.SelectCommandType, input.SelectCommand);
|
var tableColumns = await GetTableColumnNamesAsync(input.DataSourceCode, input.SelectCommandType, input.SelectCommand);
|
||||||
var isDeleted = tableColumns.Contains("IsDeleted");
|
var isDeleted = tableColumns.Contains("IsDeleted");
|
||||||
var isCreated = tableColumns.Contains("CreatorId");
|
var isCreated = tableColumns.Contains("CreatorId");
|
||||||
input.Workflow ??= new WorkflowDto();
|
input.Criteria ??= [];
|
||||||
input.Workflow.Criteria = input.WorkflowCriteria;
|
EnsureUniqueWorkflowCriteriaTitles(input.Criteria);
|
||||||
EnsureUniqueWorkflowCriteriaTitles(input.WorkflowCriteria);
|
NormalizeWorkflowCriteriaIds(listFormCode, input.Criteria);
|
||||||
NormalizeWorkflowCriteriaIds(listFormCode, input.WorkflowCriteria);
|
var workflow = new WorkflowDto
|
||||||
|
{
|
||||||
|
ApprovalUserFieldName = input.ApprovalUserFieldName,
|
||||||
|
ApprovalIsFilterUserName = input.ApprovalIsFilterUserName,
|
||||||
|
ApprovalDateFieldName = input.ApprovalDateFieldName,
|
||||||
|
ApprovalStatusFieldName = input.ApprovalStatusFieldName,
|
||||||
|
ApprovalDescriptionFieldName = input.ApprovalDescriptionFieldName,
|
||||||
|
Criteria = input.Criteria,
|
||||||
|
};
|
||||||
|
|
||||||
await repoListForm.InsertAsync(new ListForm
|
await repoListForm.InsertAsync(new ListForm
|
||||||
{
|
{
|
||||||
|
|
@ -280,8 +283,8 @@ public class ListFormWizardAppService(
|
||||||
PageSize = 10,
|
PageSize = 10,
|
||||||
ExportJson = WizardConsts.DefaultExportJson,
|
ExportJson = WizardConsts.DefaultExportJson,
|
||||||
IsSubForm = false,
|
IsSubForm = false,
|
||||||
ShowNote = input.SubForms.Count > 0 || input.WorkflowCriteria.Count > 0,
|
ShowNote = input.SubForms.Count > 0 || input.Criteria.Count > 0,
|
||||||
LayoutJson = WizardConsts.DefaultLayoutJson(input.DefaultLayout, input.Grid, input.Pivot, input.Tree, input.Chart, input.Gantt, input.Scheduler),
|
LayoutJson = WizardConsts.DefaultLayoutJson(input.DefaultLayout, input.Grid, input.Card, input.Pivot, input.Tree, input.Chart, input.Gantt, input.Scheduler, input.Todo),
|
||||||
CultureName = LanguageCodes.En,
|
CultureName = LanguageCodes.En,
|
||||||
ListFormCode = input.ListFormCode,
|
ListFormCode = input.ListFormCode,
|
||||||
Name = nameLangKey,
|
Name = nameLangKey,
|
||||||
|
|
@ -301,18 +304,18 @@ public class ListFormWizardAppService(
|
||||||
HeaderFilterJson = WizardConsts.DefaultHeaderFilterJson(),
|
HeaderFilterJson = WizardConsts.DefaultHeaderFilterJson(),
|
||||||
SearchPanelJson = WizardConsts.DefaultSearchPanelJson(),
|
SearchPanelJson = WizardConsts.DefaultSearchPanelJson(),
|
||||||
GroupPanelJson = WizardConsts.DefaultGroupPanelJson(),
|
GroupPanelJson = WizardConsts.DefaultGroupPanelJson(),
|
||||||
SelectionJson = WizardConsts.DefaultSelectionSingleJson(input.WorkflowCriteria.Count > 0 ? PlatformConsts.GridOptions.SelectionModeSingle : PlatformConsts.GridOptions.SelectionModeNone),
|
SelectionJson = WizardConsts.DefaultSelectionSingleJson(input.Criteria.Count > 0 ? PlatformConsts.GridOptions.SelectionModeSingle : PlatformConsts.GridOptions.SelectionModeNone),
|
||||||
ColumnOptionJson = WizardConsts.DefaultColumnOptionJson(),
|
ColumnOptionJson = WizardConsts.DefaultColumnOptionJson(),
|
||||||
PermissionJson = WizardConsts.DefaultPermissionJson(code),
|
PermissionJson = WizardConsts.DefaultPermissionJson(code),
|
||||||
DeleteCommand = isDeleted ? WizardConsts.DefaultDeleteCommand(input.SelectCommand) : null,
|
DeleteCommand = isDeleted ? WizardConsts.DefaultDeleteCommand(input.SelectCommand) : null,
|
||||||
DeleteFieldsDefaultValueJson = isDeleted ? WizardConsts.DefaultDeleteFieldsDefaultValueJson(input.KeyFieldDbSourceType) : WizardConsts.DefaultFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
DeleteFieldsDefaultValueJson = isDeleted ? WizardConsts.DefaultDeleteFieldsDefaultValueJson(input.KeyFieldDbSourceType) : WizardConsts.DefaultDeleteFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
||||||
InsertFieldsDefaultValueJson = isCreated ? WizardConsts.DefaultInsertFieldsDefaultValueJson(input.KeyFieldDbSourceType) : WizardConsts.DefaultFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
InsertFieldsDefaultValueJson = isCreated ? WizardConsts.DefaultInsertFieldsDefaultValueJson(input.KeyFieldDbSourceType) : WizardConsts.DefaultInsertFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
||||||
PagerOptionJson = WizardConsts.DefaultPagerOptionJson,
|
PagerOptionJson = WizardConsts.DefaultPagerOptionJson,
|
||||||
EditingOptionJson = WizardConsts.DefaultEditingOptionJson(titleLangKey, 600, 500, input.AllowDeleting, input.AllowAdding, input.AllowUpdating, input.ConfirmDelete, false, input.AllowDetail),
|
EditingOptionJson = WizardConsts.DefaultEditingOptionJson(titleLangKey, 600, 500, input.AllowDeleting, input.AllowAdding, input.AllowUpdating, input.ConfirmDelete, false, input.AllowDetail),
|
||||||
EditingFormJson = editingFormDtos.Count > 0 ? JsonSerializer.Serialize(editingFormDtos) : null,
|
EditingFormJson = editingFormDtos.Count > 0 ? JsonSerializer.Serialize(editingFormDtos) : null,
|
||||||
SubFormsJson = input.SubForms.Count > 0 ? JsonSerializer.Serialize(input.SubForms) : null,
|
SubFormsJson = input.SubForms.Count > 0 ? JsonSerializer.Serialize(input.SubForms) : null,
|
||||||
WidgetsJson = input.Widgets.Count > 0 ? JsonSerializer.Serialize(input.Widgets) : null,
|
WidgetsJson = input.Widgets.Count > 0 ? JsonSerializer.Serialize(input.Widgets) : null,
|
||||||
WorkflowJson = HasWorkflow(input.Workflow, input.WorkflowCriteria) ? JsonSerializer.Serialize(input.Workflow) : null,
|
WorkflowJson = HasWorkflow(workflow, input.Criteria) ? JsonSerializer.Serialize(workflow) : null,
|
||||||
TreeOptionJson = (input.Tree || input.DefaultLayout == "tree") && !string.IsNullOrEmpty(input.TreeParentIdExpr)
|
TreeOptionJson = (input.Tree || input.DefaultLayout == "tree") && !string.IsNullOrEmpty(input.TreeParentIdExpr)
|
||||||
? JsonSerializer.Serialize(new TreeOptionDto
|
? JsonSerializer.Serialize(new TreeOptionDto
|
||||||
{
|
{
|
||||||
|
|
@ -341,25 +344,58 @@ public class ListFormWizardAppService(
|
||||||
EndDateExpr = input.SchedulerEndDateExpr,
|
EndDateExpr = input.SchedulerEndDateExpr,
|
||||||
})
|
})
|
||||||
: null,
|
: null,
|
||||||
|
TodoOptionJson = (input.Todo || input.DefaultLayout == "todo") &&
|
||||||
|
!string.IsNullOrEmpty(input.TodoTitleExpr) &&
|
||||||
|
!string.IsNullOrEmpty(input.TodoStatusExpr)
|
||||||
|
? JsonSerializer.Serialize(new TodoOptionDto
|
||||||
|
{
|
||||||
|
TitleExpr = input.TodoTitleExpr,
|
||||||
|
StatusExpr = input.TodoStatusExpr,
|
||||||
|
DescriptionExpr = input.TodoDescriptionExpr,
|
||||||
|
DueDateExpr = input.TodoDueDateExpr,
|
||||||
|
TagExpr = input.TodoTagExpr,
|
||||||
|
AssigneeExpr = input.TodoAssigneeExpr,
|
||||||
|
PriorityExpr = input.TodoPriorityExpr,
|
||||||
|
CompletedExpr = input.TodoCompletedExpr,
|
||||||
|
OrderExpr = input.TodoOrderExpr,
|
||||||
|
StatusOrder = input.TodoStatusOrder,
|
||||||
|
AllowDragging = input.TodoAllowDragging,
|
||||||
|
})
|
||||||
|
: null,
|
||||||
}, autoSave: true);
|
}, autoSave: true);
|
||||||
|
|
||||||
// ListFormField - each item in each group becomes a visible field record
|
// ListFormField - each item in each group becomes a visible field record
|
||||||
var fieldOrder = 0;
|
var fieldOrder = 0;
|
||||||
|
var editGroupOrder = 0;
|
||||||
foreach (var group in input.Groups)
|
foreach (var group in input.Groups)
|
||||||
{
|
{
|
||||||
|
editGroupOrder++;
|
||||||
|
var editOrder = 0;
|
||||||
foreach (var item in group.Items)
|
foreach (var item in group.Items)
|
||||||
{
|
{
|
||||||
fieldOrder++;
|
fieldOrder++;
|
||||||
|
if (item.IncludeInEditingForm && item.FieldName != input.KeyFieldName)
|
||||||
|
{
|
||||||
|
editOrder++;
|
||||||
|
}
|
||||||
await repoListFormField.InsertAsync(new ListFormField
|
await repoListFormField.InsertAsync(new ListFormField
|
||||||
{
|
{
|
||||||
ListFormCode = input.ListFormCode,
|
ListFormCode = input.ListFormCode,
|
||||||
FieldName = item.DataField,
|
FieldName = item.FieldName,
|
||||||
CaptionName = item.CaptionName,
|
CaptionName = item.CaptionName,
|
||||||
Visible = item.DataField != input.KeyFieldName,
|
Visible = item.FieldName != input.KeyFieldName,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
AllowSearch = true,
|
AllowSearch = true,
|
||||||
Width = 0,
|
Width = 0,
|
||||||
ListOrderNo = fieldOrder,
|
ListOrderNo = fieldOrder,
|
||||||
|
EditGroupOrderNo = item.IncludeInEditingForm ? editGroupOrder : null,
|
||||||
|
EditOrderNo = item.IncludeInEditingForm && item.FieldName != input.KeyFieldName
|
||||||
|
? editOrder
|
||||||
|
: null,
|
||||||
|
EditorType2 = item.EditorType,
|
||||||
|
ColSpan = item.ColSpan,
|
||||||
|
EditorOptions = string.IsNullOrWhiteSpace(item.EditorOptions) ? null : item.EditorOptions,
|
||||||
|
EditorScript = string.IsNullOrWhiteSpace(item.EditorScript) ? null : item.EditorScript,
|
||||||
SourceDbType = item.DbSourceType,
|
SourceDbType = item.DbSourceType,
|
||||||
CultureName = PlatformConsts.DefaultLanguage,
|
CultureName = PlatformConsts.DefaultLanguage,
|
||||||
PermissionJson = WizardConsts.DefaultFieldPermissionJson(code),
|
PermissionJson = WizardConsts.DefaultFieldPermissionJson(code),
|
||||||
|
|
@ -373,7 +409,7 @@ public class ListFormWizardAppService(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var criteria in input.WorkflowCriteria)
|
foreach (var criteria in input.Criteria)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(criteria.Id))
|
if (string.IsNullOrWhiteSpace(criteria.Id))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ using Volo.Abp.PermissionManagement;
|
||||||
using Volo.Abp.TenantManagement;
|
using Volo.Abp.TenantManagement;
|
||||||
using static Sozsoft.Platform.Data.Seeds.SeedConsts;
|
using static Sozsoft.Platform.Data.Seeds.SeedConsts;
|
||||||
using Sozsoft.Languages;
|
using Sozsoft.Languages;
|
||||||
|
using Sozsoft.Languages.Languages;
|
||||||
using Sozsoft.Platform.ListForms;
|
using Sozsoft.Platform.ListForms;
|
||||||
|
|
||||||
namespace Sozsoft.Platform.Menus;
|
namespace Sozsoft.Platform.Menus;
|
||||||
|
|
@ -131,6 +132,30 @@ public class MenuAppService : CrudAppService<
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
entityDtos = await base.MapToGetListOutputDtosAsync(entities);
|
entityDtos = await base.MapToGetListOutputDtosAsync(entities);
|
||||||
|
|
||||||
|
var languageKeys = entityDtos
|
||||||
|
.Select(item => string.IsNullOrWhiteSpace(item.DisplayName) ? item.Code : item.DisplayName)
|
||||||
|
.Where(key => !string.IsNullOrWhiteSpace(key))
|
||||||
|
.Distinct()
|
||||||
|
.ToList();
|
||||||
|
var languageTexts = await _repositoryText.GetListAsync(text =>
|
||||||
|
text.ResourceName == PlatformConsts.AppName &&
|
||||||
|
languageKeys.Contains(text.Key) &&
|
||||||
|
(text.CultureName == PlatformConsts.DefaultLanguage ||
|
||||||
|
text.CultureName == LanguageCodes.Tr));
|
||||||
|
|
||||||
|
foreach (var menu in entityDtos)
|
||||||
|
{
|
||||||
|
var languageKey = string.IsNullOrWhiteSpace(menu.DisplayName)
|
||||||
|
? menu.Code
|
||||||
|
: menu.DisplayName;
|
||||||
|
menu.MenuTextEn = languageTexts.FirstOrDefault(text =>
|
||||||
|
text.Key == languageKey &&
|
||||||
|
text.CultureName == PlatformConsts.DefaultLanguage)?.Value;
|
||||||
|
menu.MenuTextTr = languageTexts.FirstOrDefault(text =>
|
||||||
|
text.Key == languageKey &&
|
||||||
|
text.CultureName == LanguageCodes.Tr)?.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PagedResultDto<MenuDto>(
|
return new PagedResultDto<MenuDto>(
|
||||||
|
|
|
||||||
|
|
@ -1443,8 +1443,8 @@
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.Reports.List",
|
"key": "App.Reports.List",
|
||||||
"en": "List Report",
|
"en": "Grid Report",
|
||||||
"tr": "Liste Raporu"
|
"tr": "Tablo Raporu"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
|
|
@ -1506,6 +1506,18 @@
|
||||||
"en": "Settings",
|
"en": "Settings",
|
||||||
"tr": "Ayarlar"
|
"tr": "Ayarlar"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Licence",
|
||||||
|
"en": "Licence",
|
||||||
|
"tr": "Lisans"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.LicenceItem",
|
||||||
|
"en": "Licence Items",
|
||||||
|
"tr": "Lisans Kalemleri"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.Settings",
|
"key": "App.Settings",
|
||||||
|
|
@ -4428,6 +4440,24 @@
|
||||||
"en": "Tree",
|
"en": "Tree",
|
||||||
"tr": "Ağaç"
|
"tr": "Ağaç"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormEdit.TabCard",
|
||||||
|
"en": "Card",
|
||||||
|
"tr": "Kart"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormEdit.TabChart",
|
||||||
|
"en": "Chart",
|
||||||
|
"tr": "Grafik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormEdit.TabGrid",
|
||||||
|
"en": "Grid",
|
||||||
|
"tr": "Tablo"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormEdit.TabGantt",
|
"key": "ListForms.ListFormEdit.TabGantt",
|
||||||
|
|
@ -4656,6 +4686,12 @@
|
||||||
"en": "Scheduler Layout",
|
"en": "Scheduler Layout",
|
||||||
"tr": "Zamanlayıcı Düzeni"
|
"tr": "Zamanlayıcı Düzeni"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormEdit.DetailsLayoutDto.TodoLayout",
|
||||||
|
"en": "Todo Layout",
|
||||||
|
"tr": "İşler Düzeni"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormEdit.DetailsLayoutDto.GanttLayout",
|
"key": "ListForms.ListFormEdit.DetailsLayoutDto.GanttLayout",
|
||||||
|
|
@ -4668,6 +4704,12 @@
|
||||||
"en": "Grid Layout",
|
"en": "Grid Layout",
|
||||||
"tr": "Liste Düzeni"
|
"tr": "Liste Düzeni"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormEdit.DetailsLayoutDto.CardLayout",
|
||||||
|
"en": "Card Layout",
|
||||||
|
"tr": "Kart Düzeni"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormEdit.DetailsLayoutDto.PivotLayout",
|
"key": "ListForms.ListFormEdit.DetailsLayoutDto.PivotLayout",
|
||||||
|
|
@ -5150,15 +5192,15 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormEdit.EditingFormFormFields",
|
"key": "ListForms.ListFormEdit.EditingFormFormGroups",
|
||||||
"en": "Editing Form Fields",
|
"en": "Editing Form Groups",
|
||||||
"tr": "Düzenleme Form Alanları"
|
"tr": "Düzenleme Form Grupları"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormEdit.EditingFormFormFieldsDescription",
|
"key": "ListForms.ListFormEdit.EditingFormFormGroupsDescription",
|
||||||
"en": "Edit formunda çıkacak field'lar",
|
"en": "Groups that will appear in Edit form",
|
||||||
"tr": "Form Sütunları"
|
"tr": "Düzenleme formunda çıkacak gruplar"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
|
|
@ -5880,6 +5922,30 @@
|
||||||
"en": "Field Name",
|
"en": "Field Name",
|
||||||
"tr": "Alan Adı"
|
"tr": "Alan Adı"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.EditorType",
|
||||||
|
"en": "Editor Type",
|
||||||
|
"tr": "Editör Tipi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.EditFormGroup",
|
||||||
|
"en": "Edit Form Group",
|
||||||
|
"tr": "Düzenleme Form Grubu"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.EditFormOrderNo",
|
||||||
|
"en": "Edit Order No",
|
||||||
|
"tr": "Düzenleme Sıra No"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.EditFormColSpan",
|
||||||
|
"en": "Edit Col Span",
|
||||||
|
"tr": "Düzenleme Col Span"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormFieldEdit.PlaceHolder",
|
"key": "ListForms.ListFormFieldEdit.PlaceHolder",
|
||||||
|
|
@ -9318,12 +9384,6 @@
|
||||||
"tr": "Seçili bölümün düzenlenebilir alanları burada gösterilir.",
|
"tr": "Seçili bölümün düzenlenebilir alanları burada gösterilir.",
|
||||||
"en": "Select a block on the page to edit its properties here."
|
"en": "Select a block on the page to edit its properties here."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"resourceName": "Platform",
|
|
||||||
"key": "Public.designer.save",
|
|
||||||
"tr": "Kaydet",
|
|
||||||
"en": "Save"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.DeveloperKit.Component.Description",
|
"key": "App.DeveloperKit.Component.Description",
|
||||||
|
|
@ -10152,12 +10212,6 @@
|
||||||
"en": "Save Entity",
|
"en": "Save Entity",
|
||||||
"tr": "Varlığı Kaydet"
|
"tr": "Varlığı Kaydet"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"resourceName": "Platform",
|
|
||||||
"key": "App.DeveloperKit.EntityEditor.Saving",
|
|
||||||
"en": "Saving...",
|
|
||||||
"tr": "Kaydediliyor..."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.DeveloperKit.EntityEditor.BasicInfo",
|
"key": "App.DeveloperKit.EntityEditor.BasicInfo",
|
||||||
|
|
@ -10290,18 +10344,6 @@
|
||||||
"en": "Inactive",
|
"en": "Inactive",
|
||||||
"tr": "Pasif"
|
"tr": "Pasif"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"resourceName": "Platform",
|
|
||||||
"key": "App.DeveloperKit.ComponentEditor.Save",
|
|
||||||
"en": "Save",
|
|
||||||
"tr": "Kaydet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceName": "Platform",
|
|
||||||
"key": "App.DeveloperKit.ComponentEditor.Saving",
|
|
||||||
"en": "Saving...",
|
|
||||||
"tr": "Kaydediliyor..."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.DeveloperKit.ComponentEditor.ValidationError.Title",
|
"key": "App.DeveloperKit.ComponentEditor.ValidationError.Title",
|
||||||
|
|
@ -11598,12 +11640,6 @@
|
||||||
"tr": "Hedef Data Sourcelar",
|
"tr": "Hedef Data Sourcelar",
|
||||||
"en": "Target Data Sources"
|
"en": "Target Data Sources"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"resourceName": "Platform",
|
|
||||||
"key": "App.Platform.Save",
|
|
||||||
"tr": "Kaydet",
|
|
||||||
"en": "Save"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.Platform.SaveQuery",
|
"key": "App.Platform.SaveQuery",
|
||||||
|
|
@ -12306,12 +12342,6 @@
|
||||||
"tr": "Alan seçin...",
|
"tr": "Alan seçin...",
|
||||||
"en": "Select field..."
|
"en": "Select field..."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"resourceName": "Platform",
|
|
||||||
"key": "App.Platform.ChartDrawer.Save",
|
|
||||||
"tr": "Kaydet",
|
|
||||||
"en": "Save"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.Platform.ChartDrawer.ChartSaved",
|
"key": "App.Platform.ChartDrawer.ChartSaved",
|
||||||
|
|
@ -18792,12 +18822,6 @@
|
||||||
"en": "If checked, existing object in the target will be dropped and recreated.",
|
"en": "If checked, existing object in the target will be dropped and recreated.",
|
||||||
"tr": "İşaretlenirse hedefteki mevcut obje silinip yeniden oluşturulur."
|
"tr": "İşaretlenirse hedefteki mevcut obje silinip yeniden oluşturulur."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"resourceName": "Platform",
|
|
||||||
"key": "App.SqlQueryManager.Save",
|
|
||||||
"en": "Save",
|
|
||||||
"tr": "Kaydet"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.SqlQueryManager.Next",
|
"key": "App.SqlQueryManager.Next",
|
||||||
|
|
@ -19374,6 +19398,396 @@
|
||||||
"en": "Successfully Saved",
|
"en": "Successfully Saved",
|
||||||
"tr": "Başarıyla Kaydedildi"
|
"tr": "Başarıyla Kaydedildi"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoTitleExpr",
|
||||||
|
"en": "Title Field",
|
||||||
|
"tr": "Başlık alanı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoStatusExpr",
|
||||||
|
"en": "Column / Status Field",
|
||||||
|
"tr": "Kolon / durum alanı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoDescriptionExpr",
|
||||||
|
"en": "Description Field",
|
||||||
|
"tr": "Açıklama alanı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoDueDateExpr",
|
||||||
|
"en": "Due Date Field",
|
||||||
|
"tr": "Termin tarihi alanı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoTagExpr",
|
||||||
|
"en": "Tag Field",
|
||||||
|
"tr": "Etiket alanı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoAssigneeExpr",
|
||||||
|
"en": "Assignee Field",
|
||||||
|
"tr": "Atanan kişi alanı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoPriorityExpr",
|
||||||
|
"en": "Priority Field",
|
||||||
|
"tr": "Öncelik alanı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoCompletedExpr",
|
||||||
|
"en": "Completed Field",
|
||||||
|
"tr": "Tamamlandı alanı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoOrderExpr",
|
||||||
|
"en": "Card Order Field",
|
||||||
|
"tr": "Kart sıra alanı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoFieldsLoadFailed",
|
||||||
|
"en": "Fields could not be loaded: {0}",
|
||||||
|
"tr": "Alanlar getirilemedi: {0}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoStatusOrder",
|
||||||
|
"en": "Status order (comma-separated)",
|
||||||
|
"tr": "Durum sırası (virgülle ayırın)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoStatusOrderPlaceholder",
|
||||||
|
"en": "Backlog, Ready to Start, In Progress, Code Review, Testing, Staging",
|
||||||
|
"tr": "Gelen Kutusu, Bugün, Bu Hafta, Bu Ay, Daha Sonra, Tamamlandı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoAllowDragging",
|
||||||
|
"en": "Allow cards to be dragged between columns",
|
||||||
|
"tr": "Kartları kolonlar arasında sürüklemeye izin ver"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoRequiredFields",
|
||||||
|
"en": "Title field and column / status field are required.",
|
||||||
|
"tr": "Başlık alanı ve kolon / durum alanı zorunludur."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormFieldEdit.TodoDisabledInListSettings",
|
||||||
|
"en": "Todo view is disabled in the list settings. You can skip this step or enable the Todo view in the previous steps.",
|
||||||
|
"tr": "Todo görünümü liste ayarlarında kapalı. Bu adımı atlayabilir veya önceki adımlardan Todo görünümünü etkinleştirebilirsiniz."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.Uncategorized",
|
||||||
|
"en": "Uncategorized",
|
||||||
|
"tr": "Kategorisiz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.PriorityRating",
|
||||||
|
"en": "{0}/5 priority",
|
||||||
|
"tr": "{0}/5 öncelik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.NoPriority",
|
||||||
|
"en": "No priority",
|
||||||
|
"tr": "Öncelik yok"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.DuplicateColumnName",
|
||||||
|
"en": "A Kanban column with this name already exists.",
|
||||||
|
"tr": "Bu isimde bir kanban zaten var."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.ColumnNotEmptyMessage",
|
||||||
|
"en": "This Kanban column cannot be deleted. First move its {0} todo item(s) to another column.",
|
||||||
|
"tr": "Bu kanban silinemez. Önce içindeki {0} todo’yu başka bir kanbana taşıyın."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.ConfirmDeleteColumn",
|
||||||
|
"en": "Delete the “{0}” Kanban column?",
|
||||||
|
"tr": "“{0}” kanbanı silinsin mi?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.RenameRequiresUpdateService",
|
||||||
|
"en": "An update service is required to rename a Kanban column that contains todo items.",
|
||||||
|
"tr": "Todo içeren bir kanbanı yeniden adlandırmak için update servisi gereklidir."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.ColumnNameSaveFailed",
|
||||||
|
"en": "The Kanban column name could not be saved. Please try again.",
|
||||||
|
"tr": "Kanban adı kaydedilemedi. Lütfen tekrar deneyin."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.ConfirmDeleteTodo",
|
||||||
|
"en": "Delete “{0}”?",
|
||||||
|
"tr": "“{0}” silinsin mi?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.Loading",
|
||||||
|
"en": "Loading…",
|
||||||
|
"tr": "Yükleniyor…"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.BackToBoard",
|
||||||
|
"en": "Back to board",
|
||||||
|
"tr": "Panoya dön"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.EditRequiresUpdateService",
|
||||||
|
"en": "An update service must be defined to edit.",
|
||||||
|
"tr": "Düzenlemek için update servisi tanımlanmalıdır."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.DeleteTodo",
|
||||||
|
"en": "Delete todo",
|
||||||
|
"tr": "Todo sil"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.Title",
|
||||||
|
"en": "Title",
|
||||||
|
"tr": "Başlık"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.Description",
|
||||||
|
"en": "Description",
|
||||||
|
"tr": "Açıklama"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.DescriptionPlaceholder",
|
||||||
|
"en": "Enter a todo description…",
|
||||||
|
"tr": "Todo açıklamasını yazın…"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.Assignees",
|
||||||
|
"en": "Assignees",
|
||||||
|
"tr": "Atanan kişiler"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.UsersLoading",
|
||||||
|
"en": "Loading users…",
|
||||||
|
"tr": "Kullanıcılar yükleniyor…"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.SelectUser",
|
||||||
|
"en": "Select a user",
|
||||||
|
"tr": "Kullanıcı seçin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.Tags",
|
||||||
|
"en": "Tags",
|
||||||
|
"tr": "Etiketler"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.TagsPlaceholder",
|
||||||
|
"en": "Select a tag or enter a new one",
|
||||||
|
"tr": "Etiket seçin veya yeni etiket yazın"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.Status",
|
||||||
|
"en": "Kanban / Status",
|
||||||
|
"tr": "Kanban / Durum"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.DueDate",
|
||||||
|
"en": "Due date",
|
||||||
|
"tr": "Termin tarihi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.Priority",
|
||||||
|
"en": "Priority",
|
||||||
|
"tr": "Öncelik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.PriorityVeryLow",
|
||||||
|
"en": "Very low",
|
||||||
|
"tr": "Çok düşük"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.PriorityLow",
|
||||||
|
"en": "Low",
|
||||||
|
"tr": "Düşük"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.PriorityMedium",
|
||||||
|
"en": "Medium",
|
||||||
|
"tr": "Orta"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.PriorityHigh",
|
||||||
|
"en": "High",
|
||||||
|
"tr": "Yüksek"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.PriorityUrgent",
|
||||||
|
"en": "Urgent",
|
||||||
|
"tr": "Acil"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.Completed",
|
||||||
|
"en": "Completed",
|
||||||
|
"tr": "Tamamlandı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.UndoChanges",
|
||||||
|
"en": "Undo changes",
|
||||||
|
"tr": "Değişiklikleri geri al"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.ReorderColumn",
|
||||||
|
"en": "Reorder Kanban column",
|
||||||
|
"tr": "Kanbanı sırala"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.ColumnName",
|
||||||
|
"en": "Kanban column name",
|
||||||
|
"tr": "Kanban adı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.Cancel",
|
||||||
|
"en": "Cancel",
|
||||||
|
"tr": "Vazgeç"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.RenameColumn",
|
||||||
|
"en": "Rename Kanban column",
|
||||||
|
"tr": "Kanban adını değiştir"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.NewTodo",
|
||||||
|
"en": "New todo",
|
||||||
|
"tr": "Yeni todo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.ColumnWithTodosCannotBeDeleted",
|
||||||
|
"en": "A Kanban column containing todo items cannot be deleted",
|
||||||
|
"tr": "İçinde todo bulunan kanban silinemez"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.DeleteColumn",
|
||||||
|
"en": "Delete Kanban column",
|
||||||
|
"tr": "Kanbanı sil"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.Close",
|
||||||
|
"en": "Close",
|
||||||
|
"tr": "Kapat"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.TodoTitlePlaceholder",
|
||||||
|
"en": "Todo title…",
|
||||||
|
"tr": "Todo başlığı…"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.DropHere",
|
||||||
|
"en": "Drop here",
|
||||||
|
"tr": "Buraya bırak"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.ChangePriority",
|
||||||
|
"en": "Change priority",
|
||||||
|
"tr": "Önceliği değiştir"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.ReopenTodo",
|
||||||
|
"en": "Reopen todo",
|
||||||
|
"tr": "Todo’yu yeniden aç"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.CompleteTodo",
|
||||||
|
"en": "Complete todo",
|
||||||
|
"tr": "Todo’yu tamamla"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.NewColumn",
|
||||||
|
"en": "New Kanban",
|
||||||
|
"tr": "Yeni kanban"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.AddNewColumn",
|
||||||
|
"en": "Add a new Kanban",
|
||||||
|
"tr": "Yeni kanban ekle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.NewColumnName",
|
||||||
|
"en": "New Kanban column name",
|
||||||
|
"tr": "Yeni kanban adı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.NewColumnPlaceholder",
|
||||||
|
"en": "E.g. In Review",
|
||||||
|
"tr": "Örn. İnceleniyor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.TodoBoard.AddColumn",
|
||||||
|
"en": "Add Kanban column",
|
||||||
|
"tr": "Kanbanı ekle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormEdit.TabTodo",
|
||||||
|
"en": "Todo",
|
||||||
|
"tr": "İşler"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormEdit.Workflow.Criteria",
|
"key": "ListForms.ListFormEdit.Workflow.Criteria",
|
||||||
|
|
@ -19448,7 +19862,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormEdit.Workflow.IsFilterUserName",
|
"key": "ListForms.ListFormEdit.Workflow.ApprovalIsFilterUserName",
|
||||||
"en": "Filter User Name?",
|
"en": "Filter User Name?",
|
||||||
"tr": "Kullanıcı Adı Filtresin mi?"
|
"tr": "Kullanıcı Adı Filtresin mi?"
|
||||||
},
|
},
|
||||||
|
|
@ -19949,6 +20363,72 @@
|
||||||
"key": "App.Tenant.Create",
|
"key": "App.Tenant.Create",
|
||||||
"en": "Tenant Create",
|
"en": "Tenant Create",
|
||||||
"tr": "Tenant Oluştur"
|
"tr": "Tenant Oluştur"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.CheckUpdate",
|
||||||
|
"en": "Checking...",
|
||||||
|
"tr": "Kontrol ediliyor..."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.CheckForUpdates",
|
||||||
|
"en": "Check for Updates",
|
||||||
|
"tr": "Güncellemeyi Kontrol Et"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.NotSupportServiceWorkerUpdate",
|
||||||
|
"en": "Your browser does not support service worker updates.",
|
||||||
|
"tr": "Tarayıcınız service worker güncellemelerini desteklemiyor."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.NewVersionAvailable",
|
||||||
|
"en": "A new service worker has been found. The application will automatically update when the files are ready.",
|
||||||
|
"tr": "Dosyalar hazırlandığında uygulama otomatik olarak güncellenecek."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.ManualUpdateFailed",
|
||||||
|
"en": "Please check your connection and try again.",
|
||||||
|
"tr": "Lütfen bağlantınızı kontrol edip tekrar deneyin."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.ChangeLogDescription",
|
||||||
|
"en": "Check if there's a new application version available on the server.",
|
||||||
|
"tr": "Sunucuda yeni bir uygulama sürümü olup olmadığını kontrol edin."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.NoNewVersionFound",
|
||||||
|
"en": "No new version was found available.",
|
||||||
|
"tr": "Kullanılabilir yeni bir sürüm bulunamadı."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.UpToDate",
|
||||||
|
"en": "The app is up to date.",
|
||||||
|
"tr": "Uygulama güncel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.UpdateCouldNotBeChecked",
|
||||||
|
"en": "Update could not be checked",
|
||||||
|
"tr": "Güncelleme kontrol edilemedi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.NewVersionFound",
|
||||||
|
"en": "New version found.",
|
||||||
|
"tr": "Yeni sürüm bulundu"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.UpdateCheckFailed",
|
||||||
|
"en": "Update check failed.",
|
||||||
|
"tr": "Güncelleme kontrolü başarısız"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -67,11 +67,13 @@ public static class ListFormSeeder_DefaultJsons
|
||||||
public static string DefaultLayoutJson(string DefaultLayout = "grid") => JsonSerializer.Serialize(new LayoutDto()
|
public static string DefaultLayoutJson(string DefaultLayout = "grid") => JsonSerializer.Serialize(new LayoutDto()
|
||||||
{
|
{
|
||||||
Grid = true,
|
Grid = true,
|
||||||
|
Card = true,
|
||||||
Pivot = true,
|
Pivot = true,
|
||||||
Chart = true,
|
Chart = true,
|
||||||
Tree = true,
|
Tree = true,
|
||||||
Gantt = true,
|
Gantt = true,
|
||||||
Scheduler = true,
|
Scheduler = true,
|
||||||
|
Todo = true,
|
||||||
DefaultLayout = DefaultLayout,
|
DefaultLayout = DefaultLayout,
|
||||||
});
|
});
|
||||||
public static readonly string DefaultExportJson = JsonSerializer.Serialize(new ChartExportDto
|
public static readonly string DefaultExportJson = JsonSerializer.Serialize(new ChartExportDto
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -984,22 +984,22 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ParentCode": "App.DeveloperKit",
|
"ParentCode": "App.DeveloperKit",
|
||||||
"Code": "App.DeveloperKit.Components",
|
"Code": "App.DeveloperKit.DynamicServices",
|
||||||
"DisplayName": "App.DeveloperKit.Components",
|
"DisplayName": "App.DeveloperKit.DynamicServices",
|
||||||
"Order": 4,
|
"Order": 4,
|
||||||
"Url": "/admin/developerkit/components",
|
"Url": "/admin/developerkit/dynamic-services",
|
||||||
"Icon": "FcBiohazard",
|
"Icon": "FcCommandLine",
|
||||||
"RequiredPermissionName": "App.DeveloperKit.Components",
|
"RequiredPermissionName": "App.DeveloperKit.DynamicServices",
|
||||||
"IsDisabled": false
|
"IsDisabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ParentCode": "App.DeveloperKit",
|
"ParentCode": "App.DeveloperKit",
|
||||||
"Code": "App.DeveloperKit.DynamicServices",
|
"Code": "App.DeveloperKit.Components",
|
||||||
"DisplayName": "App.DeveloperKit.DynamicServices",
|
"DisplayName": "App.DeveloperKit.Components",
|
||||||
"Order": 5,
|
"Order": 5,
|
||||||
"Url": "/admin/developerkit/dynamic-services",
|
"Url": "/admin/developerkit/components",
|
||||||
"Icon": "FcCommandLine",
|
"Icon": "FcBiohazard",
|
||||||
"RequiredPermissionName": "App.DeveloperKit.DynamicServices",
|
"RequiredPermissionName": "App.DeveloperKit.Components",
|
||||||
"IsDisabled": false
|
"IsDisabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -1083,11 +1083,21 @@
|
||||||
"RequiredPermissionName": "App.Definitions.OrgChart",
|
"RequiredPermissionName": "App.Definitions.OrgChart",
|
||||||
"IsDisabled": false
|
"IsDisabled": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ParentCode": "App.Administration",
|
||||||
|
"Code": "App.Licence",
|
||||||
|
"DisplayName": "App.Licence",
|
||||||
|
"Order": 2,
|
||||||
|
"Url": "/admin/form/App.Licence",
|
||||||
|
"Icon": "FcRules",
|
||||||
|
"RequiredPermissionName": "App.Licence",
|
||||||
|
"IsDisabled": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ParentCode": "App.Administration",
|
"ParentCode": "App.Administration",
|
||||||
"Code": "App.Setting",
|
"Code": "App.Setting",
|
||||||
"DisplayName": "App.Setting",
|
"DisplayName": "App.Setting",
|
||||||
"Order": 2,
|
"Order": 3,
|
||||||
"Url": "/admin/settings",
|
"Url": "/admin/settings",
|
||||||
"Icon": "FcSettings",
|
"Icon": "FcSettings",
|
||||||
"RequiredPermissionName": "App.Setting",
|
"RequiredPermissionName": "App.Setting",
|
||||||
|
|
@ -1097,7 +1107,7 @@
|
||||||
"ParentCode": "App.Administration",
|
"ParentCode": "App.Administration",
|
||||||
"Code": "App.Administration.Intranet",
|
"Code": "App.Administration.Intranet",
|
||||||
"DisplayName": "App.Intranet",
|
"DisplayName": "App.Intranet",
|
||||||
"Order": 3,
|
"Order": 4,
|
||||||
"Url": null,
|
"Url": null,
|
||||||
"Icon": "FcConferenceCall",
|
"Icon": "FcConferenceCall",
|
||||||
"RequiredPermissionName": null,
|
"RequiredPermissionName": null,
|
||||||
|
|
@ -1167,7 +1177,7 @@
|
||||||
"ParentCode": "App.Administration",
|
"ParentCode": "App.Administration",
|
||||||
"Code": "App.Administration.Restrictions",
|
"Code": "App.Administration.Restrictions",
|
||||||
"DisplayName": "App.Restrictions",
|
"DisplayName": "App.Restrictions",
|
||||||
"Order": 4,
|
"Order": 5,
|
||||||
"Url": null,
|
"Url": null,
|
||||||
"Icon": "FaLock",
|
"Icon": "FaLock",
|
||||||
"RequiredPermissionName": null,
|
"RequiredPermissionName": null,
|
||||||
|
|
@ -1197,7 +1207,7 @@
|
||||||
"ParentCode": "App.Administration",
|
"ParentCode": "App.Administration",
|
||||||
"Code": "Abp.Identity",
|
"Code": "Abp.Identity",
|
||||||
"DisplayName": "Abp.Identity",
|
"DisplayName": "Abp.Identity",
|
||||||
"Order": 5,
|
"Order": 6,
|
||||||
"Url": null,
|
"Url": null,
|
||||||
"Icon": "FcConferenceCall",
|
"Icon": "FcConferenceCall",
|
||||||
"RequiredPermissionName": null,
|
"RequiredPermissionName": null,
|
||||||
|
|
@ -1287,7 +1297,7 @@
|
||||||
"ParentCode": "App.Administration",
|
"ParentCode": "App.Administration",
|
||||||
"Code": "App.Reports.Management",
|
"Code": "App.Reports.Management",
|
||||||
"DisplayName": "App.Reports.Management",
|
"DisplayName": "App.Reports.Management",
|
||||||
"Order": 6,
|
"Order": 7,
|
||||||
"Url": null,
|
"Url": null,
|
||||||
"Icon": "FcDocument",
|
"Icon": "FcDocument",
|
||||||
"RequiredPermissionName": null,
|
"RequiredPermissionName": null,
|
||||||
|
|
@ -1317,7 +1327,7 @@
|
||||||
"ParentCode": "App.Administration",
|
"ParentCode": "App.Administration",
|
||||||
"Code": "App.Videoroom.Dashboard",
|
"Code": "App.Videoroom.Dashboard",
|
||||||
"DisplayName": "App.Videoroom.Dashboard",
|
"DisplayName": "App.Videoroom.Dashboard",
|
||||||
"Order": 7,
|
"Order": 8,
|
||||||
"Url": "/admin/videoroom/dashboard",
|
"Url": "/admin/videoroom/dashboard",
|
||||||
"Icon": "FcVideoCall",
|
"Icon": "FcVideoCall",
|
||||||
"RequiredPermissionName": "App.Videoroom.Dashboard",
|
"RequiredPermissionName": "App.Videoroom.Dashboard",
|
||||||
|
|
@ -1327,7 +1337,7 @@
|
||||||
"ParentCode": "App.Administration",
|
"ParentCode": "App.Administration",
|
||||||
"Code": "App.Files",
|
"Code": "App.Files",
|
||||||
"DisplayName": "App.Files",
|
"DisplayName": "App.Files",
|
||||||
"Order": 8,
|
"Order": 9,
|
||||||
"Url": "/admin/files",
|
"Url": "/admin/files",
|
||||||
"Icon": "FcFolder",
|
"Icon": "FcFolder",
|
||||||
"RequiredPermissionName": "App.Files",
|
"RequiredPermissionName": "App.Files",
|
||||||
|
|
@ -1337,7 +1347,7 @@
|
||||||
"ParentCode": "App.Administration",
|
"ParentCode": "App.Administration",
|
||||||
"Code": "App.Forum",
|
"Code": "App.Forum",
|
||||||
"DisplayName": "App.Forum",
|
"DisplayName": "App.Forum",
|
||||||
"Order": 9,
|
"Order": 10,
|
||||||
"Url": "/admin/forum",
|
"Url": "/admin/forum",
|
||||||
"Icon": "FcLink",
|
"Icon": "FcLink",
|
||||||
"RequiredPermissionName": "App.ForumManagement.Publish",
|
"RequiredPermissionName": "App.ForumManagement.Publish",
|
||||||
|
|
|
||||||
|
|
@ -4175,7 +4175,7 @@
|
||||||
"DisplayName": "App.Intranet.Survey",
|
"DisplayName": "App.Intranet.Survey",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4184,7 +4184,7 @@
|
||||||
"DisplayName": "Create",
|
"DisplayName": "Create",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4193,7 +4193,7 @@
|
||||||
"DisplayName": "Update",
|
"DisplayName": "Update",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4202,7 +4202,7 @@
|
||||||
"DisplayName": "Delete",
|
"DisplayName": "Delete",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4211,7 +4211,7 @@
|
||||||
"DisplayName": "Export",
|
"DisplayName": "Export",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4220,7 +4220,7 @@
|
||||||
"DisplayName": "Import",
|
"DisplayName": "Import",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4229,7 +4229,7 @@
|
||||||
"DisplayName": "Note",
|
"DisplayName": "Note",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4238,7 +4238,7 @@
|
||||||
"DisplayName": "Widget",
|
"DisplayName": "Widget",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4247,7 +4247,7 @@
|
||||||
"DisplayName": "App.Intranet.SurveyQuestion",
|
"DisplayName": "App.Intranet.SurveyQuestion",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4256,7 +4256,7 @@
|
||||||
"DisplayName": "Create",
|
"DisplayName": "Create",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4265,7 +4265,7 @@
|
||||||
"DisplayName": "Update",
|
"DisplayName": "Update",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4274,7 +4274,7 @@
|
||||||
"DisplayName": "Delete",
|
"DisplayName": "Delete",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4283,7 +4283,7 @@
|
||||||
"DisplayName": "Export",
|
"DisplayName": "Export",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4292,7 +4292,7 @@
|
||||||
"DisplayName": "Import",
|
"DisplayName": "Import",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4301,7 +4301,7 @@
|
||||||
"DisplayName": "Note",
|
"DisplayName": "Note",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4310,7 +4310,7 @@
|
||||||
"DisplayName": "App.Intranet.SurveyQuestionOption",
|
"DisplayName": "App.Intranet.SurveyQuestionOption",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4319,7 +4319,7 @@
|
||||||
"DisplayName": "Create",
|
"DisplayName": "Create",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4328,7 +4328,7 @@
|
||||||
"DisplayName": "Update",
|
"DisplayName": "Update",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4337,7 +4337,7 @@
|
||||||
"DisplayName": "Delete",
|
"DisplayName": "Delete",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4346,7 +4346,7 @@
|
||||||
"DisplayName": "Export",
|
"DisplayName": "Export",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4355,7 +4355,7 @@
|
||||||
"DisplayName": "Import",
|
"DisplayName": "Import",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4364,7 +4364,7 @@
|
||||||
"DisplayName": "App.Intranet.SurveyResponse",
|
"DisplayName": "App.Intranet.SurveyResponse",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4373,7 +4373,7 @@
|
||||||
"DisplayName": "Create",
|
"DisplayName": "Create",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4382,7 +4382,7 @@
|
||||||
"DisplayName": "Update",
|
"DisplayName": "Update",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4391,7 +4391,7 @@
|
||||||
"DisplayName": "Delete",
|
"DisplayName": "Delete",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4400,7 +4400,7 @@
|
||||||
"DisplayName": "Export",
|
"DisplayName": "Export",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4409,7 +4409,7 @@
|
||||||
"DisplayName": "Import",
|
"DisplayName": "Import",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4418,7 +4418,7 @@
|
||||||
"DisplayName": "Note",
|
"DisplayName": "Note",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4427,7 +4427,7 @@
|
||||||
"DisplayName": "App.Intranet.SurveyAnswer",
|
"DisplayName": "App.Intranet.SurveyAnswer",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4436,7 +4436,7 @@
|
||||||
"DisplayName": "Create",
|
"DisplayName": "Create",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4445,7 +4445,7 @@
|
||||||
"DisplayName": "Update",
|
"DisplayName": "Update",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4454,7 +4454,7 @@
|
||||||
"DisplayName": "Delete",
|
"DisplayName": "Delete",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4463,7 +4463,7 @@
|
||||||
"DisplayName": "Export",
|
"DisplayName": "Export",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4472,7 +4472,7 @@
|
||||||
"DisplayName": "Import",
|
"DisplayName": "Import",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4480,8 +4480,8 @@
|
||||||
"ParentName": null,
|
"ParentName": null,
|
||||||
"DisplayName": "App.Videoroom",
|
"DisplayName": "App.Videoroom",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 2,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Kurs"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4489,8 +4489,8 @@
|
||||||
"ParentName": "App.Videoroom",
|
"ParentName": "App.Videoroom",
|
||||||
"DisplayName": "App.Videoroom.Dashboard",
|
"DisplayName": "App.Videoroom.Dashboard",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 2,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Kurs"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4498,8 +4498,8 @@
|
||||||
"ParentName": "App.Videoroom",
|
"ParentName": "App.Videoroom",
|
||||||
"DisplayName": "App.Videoroom.List",
|
"DisplayName": "App.Videoroom.List",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 2,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Kurs"
|
"MenuGroup": "Erp|Kurs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
|
|
@ -4507,8 +4507,116 @@
|
||||||
"ParentName": "App.Videoroom",
|
"ParentName": "App.Videoroom",
|
||||||
"DisplayName": "App.Videoroom.RoomDetail",
|
"DisplayName": "App.Videoroom.RoomDetail",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 2,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Kurs"
|
"MenuGroup": "Erp|Kurs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.Licence",
|
||||||
|
"ParentName": null,
|
||||||
|
"DisplayName": "App.Licence",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 3,
|
||||||
|
"MenuGroup": "Erp|Kurs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.Licence.Create",
|
||||||
|
"ParentName": "App.Licence",
|
||||||
|
"DisplayName": "Create",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 3,
|
||||||
|
"MenuGroup": "Erp|Kurs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.Licence.Update",
|
||||||
|
"ParentName": "App.Licence",
|
||||||
|
"DisplayName": "Update",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 3,
|
||||||
|
"MenuGroup": "Erp|Kurs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.Licence.Delete",
|
||||||
|
"ParentName": "App.Licence",
|
||||||
|
"DisplayName": "Delete",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 3,
|
||||||
|
"MenuGroup": "Erp|Kurs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.Licence.Export",
|
||||||
|
"ParentName": "App.Licence",
|
||||||
|
"DisplayName": "Export",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 3,
|
||||||
|
"MenuGroup": "Erp|Kurs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.Licence.Import",
|
||||||
|
"ParentName": "App.Licence",
|
||||||
|
"DisplayName": "Import",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 3,
|
||||||
|
"MenuGroup": "Erp|Kurs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.LicenceItem",
|
||||||
|
"ParentName": null,
|
||||||
|
"DisplayName": "App.LicenceItem",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 3,
|
||||||
|
"MenuGroup": "Erp|Kurs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.LicenceItem.Create",
|
||||||
|
"ParentName": "App.LicenceItem",
|
||||||
|
"DisplayName": "Create",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 3,
|
||||||
|
"MenuGroup": "Erp|Kurs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.LicenceItem.Update",
|
||||||
|
"ParentName": "App.LicenceItem",
|
||||||
|
"DisplayName": "Update",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 3,
|
||||||
|
"MenuGroup": "Erp|Kurs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.LicenceItem.Delete",
|
||||||
|
"ParentName": "App.LicenceItem",
|
||||||
|
"DisplayName": "Delete",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 3,
|
||||||
|
"MenuGroup": "Erp|Kurs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.LicenceItem.Export",
|
||||||
|
"ParentName": "App.LicenceItem",
|
||||||
|
"DisplayName": "Export",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 3,
|
||||||
|
"MenuGroup": "Erp|Kurs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.LicenceItem.Import",
|
||||||
|
"ParentName": "App.LicenceItem",
|
||||||
|
"DisplayName": "Import",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 3,
|
||||||
|
"MenuGroup": "Erp|Kurs"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,917 @@
|
||||||
|
CREATE OR REPLACE FUNCTION dbo."Sas_H_ListFormFieldsDictionaryJson"
|
||||||
|
(
|
||||||
|
p_definition_culture_name VARCHAR(10) DEFAULT 'en',
|
||||||
|
p_ui_culture_name VARCHAR(10) DEFAULT 'tr',
|
||||||
|
p_list_form_code VARCHAR(64) DEFAULT NULL,
|
||||||
|
p_only_base_definitions BOOLEAN DEFAULT TRUE,
|
||||||
|
p_resource_name VARCHAR(64) DEFAULT NULL
|
||||||
|
)
|
||||||
|
RETURNS JSONB
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
v_result JSONB;
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
WITH list_form_source AS
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
l."Id",
|
||||||
|
l."ListFormCode",
|
||||||
|
l."CultureName",
|
||||||
|
l."Name",
|
||||||
|
|
||||||
|
lt_name."Value" AS name_value,
|
||||||
|
|
||||||
|
l."Title",
|
||||||
|
lt_title."Value" AS title_value,
|
||||||
|
|
||||||
|
l."Description",
|
||||||
|
lt_desc."Value" AS description_value,
|
||||||
|
|
||||||
|
l."TableName",
|
||||||
|
|
||||||
|
NULLIF(
|
||||||
|
BTRIM(l."SelectCommand"::TEXT),
|
||||||
|
''
|
||||||
|
) AS select_command_text,
|
||||||
|
|
||||||
|
l."KeyFieldName",
|
||||||
|
l."UserId",
|
||||||
|
l."RoleId"
|
||||||
|
|
||||||
|
FROM dbo."Sas_H_ListForm" l
|
||||||
|
|
||||||
|
/*
|
||||||
|
SQL Server OUTER APPLY TOP (1)
|
||||||
|
PostgreSQL LEFT JOIN LATERAL ... LIMIT 1
|
||||||
|
*/
|
||||||
|
LEFT JOIN LATERAL
|
||||||
|
(
|
||||||
|
SELECT lt."Value"
|
||||||
|
FROM dbo."Sas_H_LanguageText" lt
|
||||||
|
WHERE lt."CultureName" = p_ui_culture_name
|
||||||
|
AND lt."Key" = l."Name"
|
||||||
|
AND
|
||||||
|
(
|
||||||
|
p_resource_name IS NULL
|
||||||
|
OR lt."ResourceName" = p_resource_name
|
||||||
|
)
|
||||||
|
ORDER BY lt."ResourceName"
|
||||||
|
LIMIT 1
|
||||||
|
) lt_name ON TRUE
|
||||||
|
|
||||||
|
LEFT JOIN LATERAL
|
||||||
|
(
|
||||||
|
SELECT lt."Value"
|
||||||
|
FROM dbo."Sas_H_LanguageText" lt
|
||||||
|
WHERE lt."CultureName" = p_ui_culture_name
|
||||||
|
AND lt."Key" = l."Title"
|
||||||
|
AND
|
||||||
|
(
|
||||||
|
p_resource_name IS NULL
|
||||||
|
OR lt."ResourceName" = p_resource_name
|
||||||
|
)
|
||||||
|
ORDER BY lt."ResourceName"
|
||||||
|
LIMIT 1
|
||||||
|
) lt_title ON TRUE
|
||||||
|
|
||||||
|
LEFT JOIN LATERAL
|
||||||
|
(
|
||||||
|
SELECT lt."Value"
|
||||||
|
FROM dbo."Sas_H_LanguageText" lt
|
||||||
|
WHERE lt."CultureName" = p_ui_culture_name
|
||||||
|
AND lt."Key" = l."Description"
|
||||||
|
AND
|
||||||
|
(
|
||||||
|
p_resource_name IS NULL
|
||||||
|
OR lt."ResourceName" = p_resource_name
|
||||||
|
)
|
||||||
|
ORDER BY lt."ResourceName"
|
||||||
|
LIMIT 1
|
||||||
|
) lt_desc ON TRUE
|
||||||
|
|
||||||
|
WHERE
|
||||||
|
(
|
||||||
|
p_definition_culture_name IS NULL
|
||||||
|
OR l."CultureName" = p_definition_culture_name
|
||||||
|
)
|
||||||
|
|
||||||
|
AND
|
||||||
|
(
|
||||||
|
p_list_form_code IS NULL
|
||||||
|
OR l."ListFormCode" = p_list_form_code
|
||||||
|
)
|
||||||
|
|
||||||
|
AND
|
||||||
|
(
|
||||||
|
p_only_base_definitions = FALSE
|
||||||
|
|
||||||
|
OR
|
||||||
|
(
|
||||||
|
l."UserId" IS NULL
|
||||||
|
AND l."RoleId" IS NULL
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
list_forms_json AS
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
jsonb_build_object
|
||||||
|
(
|
||||||
|
'listFormCode',
|
||||||
|
l."ListFormCode",
|
||||||
|
|
||||||
|
'displayName',
|
||||||
|
COALESCE(
|
||||||
|
l.name_value::TEXT,
|
||||||
|
l."Name",
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
'title',
|
||||||
|
COALESCE(
|
||||||
|
l.title_value::TEXT,
|
||||||
|
l."Title",
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
'description',
|
||||||
|
COALESCE(
|
||||||
|
l.description_value::TEXT,
|
||||||
|
l."Description",
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
'tableName',
|
||||||
|
COALESCE(
|
||||||
|
l."TableName",
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
'sqlSourceName',
|
||||||
|
COALESCE(
|
||||||
|
NULLIF(
|
||||||
|
l."TableName",
|
||||||
|
''
|
||||||
|
),
|
||||||
|
l.select_command_text,
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
'sourceKind',
|
||||||
|
CASE
|
||||||
|
|
||||||
|
WHEN COALESCE(
|
||||||
|
NULLIF(
|
||||||
|
l."TableName",
|
||||||
|
''
|
||||||
|
),
|
||||||
|
l.select_command_text
|
||||||
|
) IS NULL
|
||||||
|
THEN 'unknown'
|
||||||
|
|
||||||
|
WHEN UPPER(
|
||||||
|
BTRIM(
|
||||||
|
COALESCE(
|
||||||
|
NULLIF(
|
||||||
|
l."TableName",
|
||||||
|
''
|
||||||
|
),
|
||||||
|
l.select_command_text
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) LIKE 'SELECT%'
|
||||||
|
THEN 'selectSql'
|
||||||
|
|
||||||
|
ELSE 'table'
|
||||||
|
|
||||||
|
END,
|
||||||
|
|
||||||
|
'keyFieldName',
|
||||||
|
COALESCE(
|
||||||
|
l."KeyFieldName",
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
'searchText',
|
||||||
|
CONCAT_WS(
|
||||||
|
' ',
|
||||||
|
l."ListFormCode",
|
||||||
|
l."TableName",
|
||||||
|
l.select_command_text,
|
||||||
|
|
||||||
|
COALESCE(
|
||||||
|
l.name_value::TEXT,
|
||||||
|
l."Name"
|
||||||
|
),
|
||||||
|
|
||||||
|
COALESCE(
|
||||||
|
l.title_value::TEXT,
|
||||||
|
l."Title"
|
||||||
|
),
|
||||||
|
|
||||||
|
COALESCE(
|
||||||
|
l.description_value::TEXT,
|
||||||
|
l."Description"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
'fields',
|
||||||
|
COALESCE
|
||||||
|
(
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
jsonb_agg
|
||||||
|
(
|
||||||
|
jsonb_build_object
|
||||||
|
(
|
||||||
|
'field',
|
||||||
|
f."FieldName",
|
||||||
|
|
||||||
|
'displayName',
|
||||||
|
COALESCE(
|
||||||
|
lt_cap."Value"::TEXT,
|
||||||
|
f."CaptionName",
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
'sqlDataType',
|
||||||
|
sc.sql_data_type,
|
||||||
|
|
||||||
|
'listOrderNo',
|
||||||
|
f."ListOrderNo",
|
||||||
|
|
||||||
|
'isVisible',
|
||||||
|
COALESCE(
|
||||||
|
f."Visible",
|
||||||
|
TRUE
|
||||||
|
),
|
||||||
|
|
||||||
|
'isBooleanColumn',
|
||||||
|
CASE
|
||||||
|
|
||||||
|
WHEN sc.sql_data_type = 'boolean'
|
||||||
|
THEN TRUE
|
||||||
|
|
||||||
|
WHEN f."FieldName" LIKE 'Is%'
|
||||||
|
THEN TRUE
|
||||||
|
|
||||||
|
WHEN f."FieldName" LIKE 'Has%'
|
||||||
|
THEN TRUE
|
||||||
|
|
||||||
|
WHEN f."FieldName" IN
|
||||||
|
(
|
||||||
|
'Monday',
|
||||||
|
'Tuesday',
|
||||||
|
'Wednesday',
|
||||||
|
'Thursday',
|
||||||
|
'Friday',
|
||||||
|
'Saturday',
|
||||||
|
'Sunday'
|
||||||
|
)
|
||||||
|
THEN TRUE
|
||||||
|
|
||||||
|
WHEN f."FieldName" IN
|
||||||
|
(
|
||||||
|
'EmailConfirmed',
|
||||||
|
'TwoFactorEnabled',
|
||||||
|
'IsVerified',
|
||||||
|
'IsDefault',
|
||||||
|
'IsPublic',
|
||||||
|
'IsEnabled',
|
||||||
|
'IsPublished',
|
||||||
|
'IsPinned',
|
||||||
|
'IsAnonymous',
|
||||||
|
'IsFixed',
|
||||||
|
'IsCustomized',
|
||||||
|
'IsEncrypted',
|
||||||
|
'IsInherited',
|
||||||
|
'ZipRequired',
|
||||||
|
'StateRequired'
|
||||||
|
)
|
||||||
|
THEN TRUE
|
||||||
|
|
||||||
|
ELSE FALSE
|
||||||
|
|
||||||
|
END,
|
||||||
|
|
||||||
|
'lookupJsonText',
|
||||||
|
lj.lookup_json_text_decoded,
|
||||||
|
|
||||||
|
'lookupTableName',
|
||||||
|
COALESCE
|
||||||
|
(
|
||||||
|
CASE
|
||||||
|
WHEN lj.lookup_json IS NOT NULL
|
||||||
|
THEN COALESCE
|
||||||
|
(
|
||||||
|
lj.lookup_json ->> 'tableName',
|
||||||
|
lj.lookup_json ->> 'sqlTableName',
|
||||||
|
lj.lookup_json ->> 'lookupTableName',
|
||||||
|
lj.lookup_json #>> '{dataSource,tableName}',
|
||||||
|
lj.lookup_json #>> '{dataSource,sqlTableName}'
|
||||||
|
)
|
||||||
|
END,
|
||||||
|
|
||||||
|
lkp.parsed_lookup_table_name
|
||||||
|
),
|
||||||
|
|
||||||
|
'lookupValueColumn',
|
||||||
|
COALESCE
|
||||||
|
(
|
||||||
|
CASE
|
||||||
|
WHEN lj.lookup_json IS NOT NULL
|
||||||
|
THEN COALESCE
|
||||||
|
(
|
||||||
|
lj.lookup_json ->> 'valueExpr',
|
||||||
|
lj.lookup_json ->> 'valueField',
|
||||||
|
lj.lookup_json ->> 'valueColumn',
|
||||||
|
lj.lookup_json ->> 'keyField',
|
||||||
|
lj.lookup_json ->> 'keyFieldName'
|
||||||
|
)
|
||||||
|
END,
|
||||||
|
|
||||||
|
lkp.parsed_lookup_value_column
|
||||||
|
),
|
||||||
|
|
||||||
|
'lookupDisplayColumn',
|
||||||
|
COALESCE
|
||||||
|
(
|
||||||
|
CASE
|
||||||
|
WHEN lj.lookup_json IS NOT NULL
|
||||||
|
THEN COALESCE
|
||||||
|
(
|
||||||
|
lj.lookup_json ->> 'displayExpr',
|
||||||
|
lj.lookup_json ->> 'displayField',
|
||||||
|
lj.lookup_json ->> 'displayColumn',
|
||||||
|
lj.lookup_json ->> 'textField',
|
||||||
|
lj.lookup_json ->> 'textColumn',
|
||||||
|
lj.lookup_json ->> 'nameField',
|
||||||
|
lj.lookup_json ->> 'nameColumn'
|
||||||
|
)
|
||||||
|
END,
|
||||||
|
|
||||||
|
lkp.parsed_lookup_display_column
|
||||||
|
),
|
||||||
|
|
||||||
|
'lookupJoinMode',
|
||||||
|
CASE
|
||||||
|
|
||||||
|
WHEN lj.lookup_json_text_decoded IS NOT NULL
|
||||||
|
AND f."FieldName" NOT LIKE '%Id'
|
||||||
|
AND COALESCE(
|
||||||
|
lkp.parsed_lookup_value_column,
|
||||||
|
''
|
||||||
|
) IN
|
||||||
|
(
|
||||||
|
'Name',
|
||||||
|
'Code',
|
||||||
|
'Key',
|
||||||
|
'Value',
|
||||||
|
'key',
|
||||||
|
'value'
|
||||||
|
)
|
||||||
|
THEN 'direct-string'
|
||||||
|
|
||||||
|
WHEN lj.lookup_json_text_decoded IS NOT NULL
|
||||||
|
AND f."FieldName" NOT LIKE '%Id'
|
||||||
|
THEN 'direct-string'
|
||||||
|
|
||||||
|
WHEN lj.lookup_json_text_decoded IS NOT NULL
|
||||||
|
OR f."FieldName" LIKE '%Id'
|
||||||
|
THEN 'convert-nvarchar-safe'
|
||||||
|
|
||||||
|
ELSE NULL
|
||||||
|
|
||||||
|
END,
|
||||||
|
|
||||||
|
'lookupFallbackToSourceColumn',
|
||||||
|
CASE
|
||||||
|
WHEN
|
||||||
|
lj.lookup_json_text_decoded IS NOT NULL
|
||||||
|
AND f."FieldName" NOT LIKE '%Id'
|
||||||
|
THEN TRUE
|
||||||
|
|
||||||
|
ELSE FALSE
|
||||||
|
END,
|
||||||
|
|
||||||
|
'lookupSearchText',
|
||||||
|
CASE
|
||||||
|
WHEN lj.lookup_json_text_decoded IS NOT NULL
|
||||||
|
THEN CONCAT_WS
|
||||||
|
(
|
||||||
|
' ',
|
||||||
|
f."FieldName",
|
||||||
|
f."CaptionName",
|
||||||
|
lt_cap."Value"::TEXT,
|
||||||
|
lj.lookup_json_text_decoded
|
||||||
|
)
|
||||||
|
END,
|
||||||
|
|
||||||
|
'isActiveStatusColumn',
|
||||||
|
f."FieldName" IN
|
||||||
|
(
|
||||||
|
'IsActive',
|
||||||
|
'IsEnabled',
|
||||||
|
'IsPublished'
|
||||||
|
),
|
||||||
|
|
||||||
|
'isDeletedStatusColumn',
|
||||||
|
f."FieldName" IN
|
||||||
|
(
|
||||||
|
'IsDeleted',
|
||||||
|
'Deleted',
|
||||||
|
'IsRemoved'
|
||||||
|
),
|
||||||
|
|
||||||
|
'isSensitive',
|
||||||
|
CASE
|
||||||
|
WHEN f."FieldName" LIKE '%Password%'
|
||||||
|
OR f."FieldName" LIKE '%ConnectionString%'
|
||||||
|
OR f."FieldName" LIKE '%Token%'
|
||||||
|
OR f."FieldName" LIKE '%Secret%'
|
||||||
|
OR f."FieldName" LIKE '%ApiKey%'
|
||||||
|
OR f."FieldName" LIKE '%PrivateKey%'
|
||||||
|
THEN TRUE
|
||||||
|
|
||||||
|
ELSE FALSE
|
||||||
|
END,
|
||||||
|
|
||||||
|
'isDefaultSelectColumn',
|
||||||
|
CASE
|
||||||
|
WHEN
|
||||||
|
COALESCE(
|
||||||
|
f."Visible",
|
||||||
|
TRUE
|
||||||
|
) = TRUE
|
||||||
|
|
||||||
|
AND COALESCE(
|
||||||
|
f."IsActive",
|
||||||
|
TRUE
|
||||||
|
) = TRUE
|
||||||
|
|
||||||
|
AND f."FieldName" NOT LIKE '%Password%'
|
||||||
|
|
||||||
|
AND f."FieldName" NOT LIKE '%ConnectionString%'
|
||||||
|
|
||||||
|
AND f."FieldName" NOT LIKE '%Token%'
|
||||||
|
|
||||||
|
AND f."FieldName" NOT LIKE '%Secret%'
|
||||||
|
|
||||||
|
AND f."FieldName" NOT LIKE '%ApiKey%'
|
||||||
|
|
||||||
|
AND f."FieldName" NOT LIKE '%PrivateKey%'
|
||||||
|
|
||||||
|
AND f."FieldName" NOT IN
|
||||||
|
(
|
||||||
|
'Avatar',
|
||||||
|
'ExtraProperties'
|
||||||
|
)
|
||||||
|
|
||||||
|
THEN TRUE
|
||||||
|
|
||||||
|
ELSE FALSE
|
||||||
|
END
|
||||||
|
)
|
||||||
|
|
||||||
|
ORDER BY
|
||||||
|
COALESCE(
|
||||||
|
f."ListOrderNo",
|
||||||
|
999999
|
||||||
|
),
|
||||||
|
f."FieldName"
|
||||||
|
)
|
||||||
|
|
||||||
|
FROM dbo."Sas_H_ListFormField" f
|
||||||
|
|
||||||
|
/*
|
||||||
|
SQL Server:
|
||||||
|
sys.tables
|
||||||
|
sys.columns
|
||||||
|
TYPE_NAME()
|
||||||
|
|
||||||
|
PostgreSQL:
|
||||||
|
information_schema.columns
|
||||||
|
*/
|
||||||
|
LEFT JOIN LATERAL
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
c.data_type AS sql_data_type
|
||||||
|
|
||||||
|
FROM information_schema.columns c
|
||||||
|
|
||||||
|
WHERE
|
||||||
|
c.table_schema = 'dbo'
|
||||||
|
|
||||||
|
AND c.table_name =
|
||||||
|
l."TableName"
|
||||||
|
|
||||||
|
AND c.column_name =
|
||||||
|
f."FieldName"
|
||||||
|
|
||||||
|
LIMIT 1
|
||||||
|
|
||||||
|
) sc ON TRUE
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
LookupJson decode
|
||||||
|
*/
|
||||||
|
LEFT JOIN LATERAL
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
|
||||||
|
NULLIF
|
||||||
|
(
|
||||||
|
BTRIM
|
||||||
|
(
|
||||||
|
REPLACE(
|
||||||
|
REPLACE(
|
||||||
|
REPLACE(
|
||||||
|
REPLACE(
|
||||||
|
REPLACE(
|
||||||
|
NULLIF(
|
||||||
|
BTRIM(
|
||||||
|
f."LookupJson"::TEXT
|
||||||
|
),
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
'\\u0022',
|
||||||
|
'"'
|
||||||
|
),
|
||||||
|
|
||||||
|
'\u0022',
|
||||||
|
'"'
|
||||||
|
),
|
||||||
|
|
||||||
|
'\\u0027',
|
||||||
|
''''
|
||||||
|
),
|
||||||
|
|
||||||
|
'\u0027',
|
||||||
|
''''
|
||||||
|
),
|
||||||
|
|
||||||
|
'"',
|
||||||
|
'"'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
''
|
||||||
|
) AS lookup_json_text_decoded
|
||||||
|
|
||||||
|
) lj_text ON TRUE
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
PostgreSQL'de ISJSON yerine
|
||||||
|
güvenli JSON parse işlemi gerekiyor.
|
||||||
|
|
||||||
|
LookupJson kolonu zaten JSON/JSONB ise
|
||||||
|
doğrudan kullanılabilir.
|
||||||
|
*/
|
||||||
|
LEFT JOIN LATERAL
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
|
||||||
|
lj_text.lookup_json_text_decoded,
|
||||||
|
|
||||||
|
CASE
|
||||||
|
|
||||||
|
WHEN
|
||||||
|
lj_text.lookup_json_text_decoded
|
||||||
|
~ '^\s*[\{\[]'
|
||||||
|
|
||||||
|
THEN
|
||||||
|
lj_text.lookup_json_text_decoded::JSONB
|
||||||
|
|
||||||
|
ELSE NULL
|
||||||
|
|
||||||
|
END AS lookup_json
|
||||||
|
|
||||||
|
) lj ON TRUE
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
LookupQuery değerini al
|
||||||
|
*/
|
||||||
|
LEFT JOIN LATERAL
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
|
||||||
|
CASE
|
||||||
|
WHEN lj.lookup_json IS NOT NULL
|
||||||
|
THEN
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'LookupQuery'
|
||||||
|
END AS lookup_query_text
|
||||||
|
|
||||||
|
) lq ON TRUE
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
LookupQuery temizleme
|
||||||
|
*/
|
||||||
|
LEFT JOIN LATERAL
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
|
||||||
|
NULLIF
|
||||||
|
(
|
||||||
|
BTRIM
|
||||||
|
(
|
||||||
|
REGEXP_REPLACE
|
||||||
|
(
|
||||||
|
REPLACE(
|
||||||
|
REPLACE(
|
||||||
|
REPLACE(
|
||||||
|
REPLACE(
|
||||||
|
COALESCE(
|
||||||
|
lq.lookup_query_text,
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
'"',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
'[',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
']',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
'`',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
'\s+',
|
||||||
|
' ',
|
||||||
|
'g'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
''
|
||||||
|
) AS clean_lookup_query
|
||||||
|
|
||||||
|
) lqc ON TRUE
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
SQL Server prosedürü LookupQuery içerisindeki
|
||||||
|
SELECT ... FROM ... ifadesini string işlemleri
|
||||||
|
ile parse ediyor.
|
||||||
|
|
||||||
|
PostgreSQL'de regexp_match daha temiz.
|
||||||
|
*/
|
||||||
|
LEFT JOIN LATERAL
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
|
||||||
|
(
|
||||||
|
REGEXP_MATCH
|
||||||
|
(
|
||||||
|
lqc.clean_lookup_query,
|
||||||
|
|
||||||
|
'(?i)\bFROM\s+([a-zA-Z0-9_\."]+)'
|
||||||
|
)
|
||||||
|
)[1] AS parsed_table,
|
||||||
|
|
||||||
|
COALESCE
|
||||||
|
(
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'ValueExpr',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'valueExpr',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'valueField',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'valueColumn',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'keyField',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'keyFieldName',
|
||||||
|
''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
AS parsed_lookup_value_column,
|
||||||
|
|
||||||
|
COALESCE
|
||||||
|
(
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'DisplayExpr',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'displayExpr',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'displayField',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'displayColumn',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'textField',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'textColumn',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'nameField',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
NULLIF(
|
||||||
|
lj.lookup_json
|
||||||
|
->> 'nameColumn',
|
||||||
|
''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
AS parsed_lookup_display_column
|
||||||
|
|
||||||
|
) parsed ON TRUE
|
||||||
|
|
||||||
|
|
||||||
|
LEFT JOIN LATERAL
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
|
||||||
|
NULLIF
|
||||||
|
(
|
||||||
|
REGEXP_REPLACE
|
||||||
|
(
|
||||||
|
COALESCE(
|
||||||
|
parsed.parsed_table,
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
'^(?i:dbo\.)',
|
||||||
|
|
||||||
|
''
|
||||||
|
),
|
||||||
|
|
||||||
|
''
|
||||||
|
)
|
||||||
|
AS parsed_lookup_table_name,
|
||||||
|
|
||||||
|
parsed.parsed_lookup_value_column,
|
||||||
|
|
||||||
|
parsed.parsed_lookup_display_column
|
||||||
|
|
||||||
|
) lkp ON TRUE
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Caption translation
|
||||||
|
*/
|
||||||
|
LEFT JOIN LATERAL
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
lt."Value"
|
||||||
|
|
||||||
|
FROM dbo."Sas_H_LanguageText" lt
|
||||||
|
|
||||||
|
WHERE
|
||||||
|
lt."CultureName" =
|
||||||
|
p_ui_culture_name
|
||||||
|
|
||||||
|
AND lt."Key" =
|
||||||
|
f."CaptionName"
|
||||||
|
|
||||||
|
AND
|
||||||
|
(
|
||||||
|
p_resource_name IS NULL
|
||||||
|
|
||||||
|
OR lt."ResourceName" =
|
||||||
|
p_resource_name
|
||||||
|
)
|
||||||
|
|
||||||
|
ORDER BY
|
||||||
|
lt."ResourceName"
|
||||||
|
|
||||||
|
LIMIT 1
|
||||||
|
|
||||||
|
) lt_cap ON TRUE
|
||||||
|
|
||||||
|
|
||||||
|
WHERE
|
||||||
|
|
||||||
|
f."ListFormCode" =
|
||||||
|
l."ListFormCode"
|
||||||
|
|
||||||
|
AND f."CultureName" =
|
||||||
|
l."CultureName"
|
||||||
|
|
||||||
|
AND
|
||||||
|
(
|
||||||
|
p_definition_culture_name IS NULL
|
||||||
|
|
||||||
|
OR f."CultureName" =
|
||||||
|
p_definition_culture_name
|
||||||
|
)
|
||||||
|
|
||||||
|
AND
|
||||||
|
(
|
||||||
|
p_only_base_definitions = FALSE
|
||||||
|
|
||||||
|
OR
|
||||||
|
(
|
||||||
|
f."UserId" IS NULL
|
||||||
|
AND f."RoleId" IS NULL
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
),
|
||||||
|
|
||||||
|
'[]'::JSONB
|
||||||
|
)
|
||||||
|
)
|
||||||
|
AS form_json,
|
||||||
|
|
||||||
|
l."ListFormCode"
|
||||||
|
|
||||||
|
FROM list_form_source l
|
||||||
|
)
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
jsonb_build_object
|
||||||
|
(
|
||||||
|
'listForms',
|
||||||
|
|
||||||
|
COALESCE
|
||||||
|
(
|
||||||
|
jsonb_agg
|
||||||
|
(
|
||||||
|
form_json
|
||||||
|
|
||||||
|
ORDER BY
|
||||||
|
"ListFormCode"
|
||||||
|
),
|
||||||
|
|
||||||
|
'[]'::JSONB
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
INTO v_result
|
||||||
|
|
||||||
|
FROM list_forms_json;
|
||||||
|
|
||||||
|
|
||||||
|
RETURN COALESCE
|
||||||
|
(
|
||||||
|
v_result,
|
||||||
|
|
||||||
|
jsonb_build_object
|
||||||
|
(
|
||||||
|
'listForms',
|
||||||
|
'[]'::JSONB
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
@ -0,0 +1,239 @@
|
||||||
|
CREATE OR REPLACE FUNCTION dbo."Sas_H_ListFormFieldsDictionaryJson_SaveDbTableColumns"
|
||||||
|
(
|
||||||
|
p_tenant_name VARCHAR(128) DEFAULT 'Sozsoft',
|
||||||
|
p_definition_culture_name VARCHAR(10) DEFAULT 'en',
|
||||||
|
p_ui_culture_name VARCHAR(10) DEFAULT 'tr',
|
||||||
|
p_list_form_code VARCHAR(64) DEFAULT NULL,
|
||||||
|
p_only_base_definitions BOOLEAN DEFAULT TRUE,
|
||||||
|
p_resource_name VARCHAR(64) DEFAULT NULL,
|
||||||
|
p_max_forms INTEGER DEFAULT 500,
|
||||||
|
p_deactivate_previous BOOLEAN DEFAULT TRUE,
|
||||||
|
p_note VARCHAR(4000) DEFAULT NULL
|
||||||
|
)
|
||||||
|
RETURNS TABLE
|
||||||
|
(
|
||||||
|
"TenantName" VARCHAR,
|
||||||
|
"DictionaryType" VARCHAR,
|
||||||
|
"DefinitionCultureName" VARCHAR,
|
||||||
|
"UiCultureName" VARCHAR,
|
||||||
|
"ListFormCode" VARCHAR,
|
||||||
|
"OnlyBaseDefinitions" BOOLEAN,
|
||||||
|
"ResourceName" VARCHAR,
|
||||||
|
"MaxForms" INTEGER,
|
||||||
|
"CacheKey" TEXT,
|
||||||
|
"FormCount" INTEGER,
|
||||||
|
"FieldCount" INTEGER,
|
||||||
|
"JsonLength" INTEGER,
|
||||||
|
"IsActive" BOOLEAN,
|
||||||
|
"RefreshedAt" TIMESTAMP,
|
||||||
|
"SourceProcedure" VARCHAR,
|
||||||
|
"Note" VARCHAR
|
||||||
|
)
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
v_json_data JSONB;
|
||||||
|
v_cache_key TEXT;
|
||||||
|
v_form_count INTEGER := 0;
|
||||||
|
v_field_count INTEGER := 0;
|
||||||
|
v_json_length INTEGER := 0;
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
/*
|
||||||
|
SQL Server:
|
||||||
|
EXEC dbo.Sas_H_ListFormFieldsDictionaryJson
|
||||||
|
|
||||||
|
PostgreSQL tarafında bunun JSON / JSONB döndüren bir FUNCTION
|
||||||
|
olduğu varsayılmıştır.
|
||||||
|
*/
|
||||||
|
SELECT dbo."Sas_H_ListFormFieldsDictionaryJson"
|
||||||
|
(
|
||||||
|
p_definition_culture_name,
|
||||||
|
p_ui_culture_name,
|
||||||
|
p_list_form_code,
|
||||||
|
p_only_base_definitions,
|
||||||
|
p_resource_name
|
||||||
|
)
|
||||||
|
INTO v_json_data;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
JSON boş kontrolü
|
||||||
|
*/
|
||||||
|
IF v_json_data IS NULL THEN
|
||||||
|
RAISE EXCEPTION
|
||||||
|
'JSON veri sözlüğü boş döndü. dbo.Sas_H_ListFormFieldsDictionaryJson çıktısını kontrol edin.'
|
||||||
|
USING ERRCODE = 'P0001';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
CacheKey oluşturulması
|
||||||
|
*/
|
||||||
|
v_cache_key :=
|
||||||
|
'ListFormJson|'
|
||||||
|
|| COALESCE(p_tenant_name, '')
|
||||||
|
|| '|'
|
||||||
|
|| COALESCE(p_definition_culture_name, '')
|
||||||
|
|| '|'
|
||||||
|
|| COALESCE(p_ui_culture_name, '')
|
||||||
|
|| '|'
|
||||||
|
|| COALESCE(p_list_form_code, '')
|
||||||
|
|| '|'
|
||||||
|
|| CASE
|
||||||
|
WHEN COALESCE(p_only_base_definitions, TRUE)
|
||||||
|
THEN '1'
|
||||||
|
ELSE '0'
|
||||||
|
END
|
||||||
|
|| '|'
|
||||||
|
|| COALESCE(p_resource_name, '')
|
||||||
|
|| '|'
|
||||||
|
|| COALESCE(p_max_forms, 500)::TEXT;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Form sayısı
|
||||||
|
|
||||||
|
JSON:
|
||||||
|
{
|
||||||
|
"listForms": [...]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
IF jsonb_typeof(v_json_data -> 'listForms') = 'array' THEN
|
||||||
|
|
||||||
|
v_form_count :=
|
||||||
|
jsonb_array_length(v_json_data -> 'listForms');
|
||||||
|
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Toplam Field sayısı
|
||||||
|
|
||||||
|
Her listForms elemanının:
|
||||||
|
{
|
||||||
|
"fields": [...]
|
||||||
|
}
|
||||||
|
|
||||||
|
alanındaki kayıtlar sayılır.
|
||||||
|
*/
|
||||||
|
SELECT COUNT(*)::INTEGER
|
||||||
|
INTO v_field_count
|
||||||
|
FROM jsonb_array_elements(
|
||||||
|
COALESCE(
|
||||||
|
v_json_data -> 'listForms',
|
||||||
|
'[]'::JSONB
|
||||||
|
)
|
||||||
|
) AS lf
|
||||||
|
CROSS JOIN LATERAL jsonb_array_elements(
|
||||||
|
CASE
|
||||||
|
WHEN jsonb_typeof(lf -> 'fields') = 'array'
|
||||||
|
THEN lf -> 'fields'
|
||||||
|
ELSE '[]'::JSONB
|
||||||
|
END
|
||||||
|
) AS ff;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
JSON karakter uzunluğu
|
||||||
|
*/
|
||||||
|
v_json_length := LENGTH(v_json_data::TEXT);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
PostgreSQL function çağrısı kendi transaction'ı içerisinde
|
||||||
|
çalıştığı için SQL Server'daki BEGIN TRAN / COMMIT burada
|
||||||
|
ayrıca kullanılmaz.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Önceki aktif kaydı pasif yap
|
||||||
|
*/
|
||||||
|
IF p_deactivate_previous THEN
|
||||||
|
|
||||||
|
UPDATE dbo."Sas_H_DbTableColumn"
|
||||||
|
SET "IsActive" = FALSE
|
||||||
|
WHERE "DictionaryType" = 'ListFormJson'
|
||||||
|
AND "CacheKey" = v_cache_key
|
||||||
|
AND COALESCE("IsActive", FALSE) = TRUE;
|
||||||
|
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Yeni JSON kaydını ekle
|
||||||
|
*/
|
||||||
|
INSERT INTO dbo."Sas_H_DbTableColumn"
|
||||||
|
(
|
||||||
|
"TenantName",
|
||||||
|
"DictionaryType",
|
||||||
|
"DefinitionCultureName",
|
||||||
|
"UiCultureName",
|
||||||
|
"ListFormCode",
|
||||||
|
"OnlyBaseDefinitions",
|
||||||
|
"ResourceName",
|
||||||
|
"MaxForms",
|
||||||
|
"CacheKey",
|
||||||
|
"JsonData",
|
||||||
|
"FormCount",
|
||||||
|
"FieldCount",
|
||||||
|
"JsonLength",
|
||||||
|
"IsActive",
|
||||||
|
"RefreshedAt",
|
||||||
|
"SourceProcedure",
|
||||||
|
"Note"
|
||||||
|
)
|
||||||
|
VALUES
|
||||||
|
(
|
||||||
|
COALESCE(p_tenant_name, 'Sozsoft'),
|
||||||
|
'ListFormJson',
|
||||||
|
COALESCE(p_definition_culture_name, 'en'),
|
||||||
|
COALESCE(p_ui_culture_name, 'tr'),
|
||||||
|
p_list_form_code,
|
||||||
|
COALESCE(p_only_base_definitions, TRUE),
|
||||||
|
p_resource_name,
|
||||||
|
COALESCE(p_max_forms, 500),
|
||||||
|
v_cache_key,
|
||||||
|
v_json_data,
|
||||||
|
v_form_count,
|
||||||
|
v_field_count,
|
||||||
|
v_json_length,
|
||||||
|
TRUE,
|
||||||
|
CURRENT_TIMESTAMP,
|
||||||
|
'dbo.Sas_H_ListFormFieldsDictionaryJson',
|
||||||
|
p_note
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Eklenen aktif kaydı döndür
|
||||||
|
*/
|
||||||
|
RETURN QUERY
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
T."TenantName",
|
||||||
|
T."DictionaryType",
|
||||||
|
T."DefinitionCultureName",
|
||||||
|
T."UiCultureName",
|
||||||
|
T."ListFormCode",
|
||||||
|
T."OnlyBaseDefinitions",
|
||||||
|
T."ResourceName",
|
||||||
|
T."MaxForms",
|
||||||
|
T."CacheKey",
|
||||||
|
T."FormCount",
|
||||||
|
T."FieldCount",
|
||||||
|
T."JsonLength",
|
||||||
|
T."IsActive",
|
||||||
|
T."RefreshedAt",
|
||||||
|
T."SourceProcedure",
|
||||||
|
T."Note"
|
||||||
|
FROM dbo."Sas_H_DbTableColumn" T
|
||||||
|
WHERE T."DictionaryType" = 'ListFormJson'
|
||||||
|
AND T."CacheKey" = v_cache_key
|
||||||
|
AND T."IsActive" = TRUE
|
||||||
|
ORDER BY T."RefreshedAt" DESC
|
||||||
|
LIMIT 1;
|
||||||
|
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
CREATE OR REPLACE VIEW dbo."Sas_H_OrderItem_ByTenantId"
|
||||||
|
AS
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
oi."Id",
|
||||||
|
o."TenantId",
|
||||||
|
oi."ProductId",
|
||||||
|
oi."ProductName",
|
||||||
|
oi."BillingCycle",
|
||||||
|
oi."Period",
|
||||||
|
oi."Quantity",
|
||||||
|
oi."Price",
|
||||||
|
oi."VatRate",
|
||||||
|
oi."VatAmount",
|
||||||
|
oi."TotalPrice",
|
||||||
|
oi."OrderId",
|
||||||
|
o."IsActive"
|
||||||
|
|
||||||
|
FROM dbo."Sas_H_Order" o
|
||||||
|
|
||||||
|
INNER JOIN dbo."Sas_H_OrderItem" oi
|
||||||
|
ON o."Id" = oi."OrderId";
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
-- Create View
|
||||||
|
CREATE OR ALTER VIEW [dbo].[Sas_H_OrderItem_ByTenantId]
|
||||||
|
AS
|
||||||
|
|
||||||
|
SELECT dbo.Sas_H_OrderItem.Id, dbo.Sas_H_Order.TenantId, dbo.Sas_H_OrderItem.ProductId, dbo.Sas_H_OrderItem.ProductName, dbo.Sas_H_OrderItem.BillingCycle, dbo.Sas_H_OrderItem.Period, dbo.Sas_H_OrderItem.Quantity,
|
||||||
|
dbo.Sas_H_OrderItem.Price, dbo.Sas_H_OrderItem.VatRate, dbo.Sas_H_OrderItem.VatAmount, dbo.Sas_H_OrderItem.TotalPrice, dbo.Sas_H_OrderItem.OrderId, dbo.Sas_H_Order.IsActive
|
||||||
|
FROM dbo.Sas_H_Order INNER JOIN
|
||||||
|
dbo.Sas_H_OrderItem ON dbo.Sas_H_Order.Id = dbo.Sas_H_OrderItem.OrderId
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
IF OBJECT_ID(N'[dbo].[Pro_T_Approval]', 'U') IS NULL
|
||||||
|
BEGIN
|
||||||
|
CREATE TABLE [dbo].[Pro_T_Approval]
|
||||||
|
(
|
||||||
|
[Id] uniqueidentifier NOT NULL DEFAULT NEWID(),
|
||||||
|
[ApprovalUserName] nvarchar(256) NULL,
|
||||||
|
[ApprovalStatus] nvarchar(50) NULL,
|
||||||
|
[ApprovalDate] datetime NULL,
|
||||||
|
[ApprovalDescription] nvarchar(200) NULL,
|
||||||
|
[TenantId] uniqueidentifier NULL,
|
||||||
|
[Title] nvarchar(100) NULL,
|
||||||
|
CONSTRAINT [PK_Pro_T_Approval] PRIMARY KEY NONCLUSTERED
|
||||||
|
(
|
||||||
|
[Id] ASC
|
||||||
|
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
IF OBJECT_ID(N'[dbo].[Pro_T_Todo]', 'U') IS NULL
|
||||||
|
BEGIN
|
||||||
|
CREATE TABLE [dbo].[Pro_T_Todo]
|
||||||
|
(
|
||||||
|
[Id] uniqueidentifier NOT NULL DEFAULT NEWID(),
|
||||||
|
[Title] nvarchar(300) NOT NULL,
|
||||||
|
[Status] nvarchar(50) NOT NULL DEFAULT N'Inbox',
|
||||||
|
[Description] nvarchar(MAX) NULL,
|
||||||
|
[DueDate] datetime2 NULL,
|
||||||
|
[Tags] nvarchar(500) NULL,
|
||||||
|
[Assignees] nvarchar(500) NULL,
|
||||||
|
[Priority] nvarchar(50) NULL,
|
||||||
|
[Completed] bit NOT NULL DEFAULT 0,
|
||||||
|
[SortOrder] int NOT NULL DEFAULT 0,
|
||||||
|
[TenantId] uniqueidentifier NULL,
|
||||||
|
CONSTRAINT [PK_Table] PRIMARY KEY NONCLUSTERED
|
||||||
|
(
|
||||||
|
[Id] ASC
|
||||||
|
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
IF OBJECT_ID(N'[dbo].[Sal_T_Approval]', 'U') IS NULL
|
|
||||||
BEGIN
|
|
||||||
CREATE TABLE [dbo].[Sal_T_Approval]
|
|
||||||
(
|
|
||||||
[Id] uniqueidentifier NOT NULL DEFAULT NEWID(),
|
|
||||||
[CreationTime] datetime2 NOT NULL DEFAULT GETUTCDATE(),
|
|
||||||
[CreatorId] uniqueidentifier NULL,
|
|
||||||
[LastModificationTime] datetime2 NULL,
|
|
||||||
[LastModifierId] uniqueidentifier NULL,
|
|
||||||
[IsDeleted] bit NOT NULL DEFAULT 0,
|
|
||||||
[DeletionTime] datetime2 NULL,
|
|
||||||
[DeleterId] uniqueidentifier NULL,
|
|
||||||
[TenantId] uniqueidentifier NULL,
|
|
||||||
[ApprovalUserName] nvarchar(256) NULL,
|
|
||||||
[ApprovalStatus] nvarchar(50) NULL,
|
|
||||||
[ApprovalDate] datetime NULL,
|
|
||||||
[ApprovalDescription] nvarchar(200) NULL,
|
|
||||||
[Name] nvarchar(100) NULL,
|
|
||||||
CONSTRAINT [PK_Sal_T_Approval] PRIMARY KEY NONCLUSTERED
|
|
||||||
(
|
|
||||||
[Id] ASC
|
|
||||||
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
|
|
||||||
) ON [PRIMARY]
|
|
||||||
END
|
|
||||||
GO
|
|
||||||
|
|
@ -13,27 +13,30 @@
|
||||||
"ConfirmDelete": true,
|
"ConfirmDelete": true,
|
||||||
"DefaultLayout": "grid",
|
"DefaultLayout": "grid",
|
||||||
"Grid": true,
|
"Grid": true,
|
||||||
|
"Card": true,
|
||||||
"Pivot": true,
|
"Pivot": true,
|
||||||
"Tree": true,
|
"Tree": true,
|
||||||
"Chart": true,
|
"Chart": true,
|
||||||
"Gantt": true,
|
"Gantt": true,
|
||||||
"Scheduler": true,
|
"Scheduler": true,
|
||||||
|
"Todo": false,
|
||||||
"LanguageTextMenuEn": "Approval",
|
"LanguageTextMenuEn": "Approval",
|
||||||
"LanguageTextMenuTr": "Approval",
|
"LanguageTextMenuTr": "Onaylama",
|
||||||
"LanguageTextTitleEn": "Approval",
|
"LanguageTextTitleEn": "Approval",
|
||||||
"LanguageTextTitleTr": "Onaylama",
|
"LanguageTextTitleTr": "Onaylama",
|
||||||
"LanguageTextDescEn": "Approval",
|
"LanguageTextDescEn": "Approval",
|
||||||
"LanguageTextDescTr": "Onaylama",
|
"LanguageTextDescTr": "Onaylama",
|
||||||
"LanguageTextMenuParentEn": "Sales",
|
"LanguageTextMenuParentEn": "Project",
|
||||||
"LanguageTextMenuParentTr": "Sat\u0131\u015F",
|
"LanguageTextMenuParentTr": "Project",
|
||||||
"PermissionGroupName": "App.Wizard.Sales",
|
"PermissionGroupName": "App.Wizard.Project",
|
||||||
"MenuParentCode": "App.Wizard.Sales",
|
"MenuParentCode": "App.Wizard.Project",
|
||||||
"MenuParentIcon": "FcAssistant",
|
"MenuParentShortName": "Pro",
|
||||||
"MenuIcon": "FcAndroidOs",
|
"MenuParentIcon": "FcVideoProjector",
|
||||||
|
"MenuIcon": "FcApproval",
|
||||||
"DataSourceCode": "Default",
|
"DataSourceCode": "Default",
|
||||||
"DataSourceConnectionString": "",
|
"DataSourceConnectionString": "",
|
||||||
"SelectCommandType": 1,
|
"SelectCommandType": 1,
|
||||||
"SelectCommand": "Sal_T_Approval",
|
"SelectCommand": "Pro_T_Approval",
|
||||||
"KeyFieldName": "Id",
|
"KeyFieldName": "Id",
|
||||||
"KeyFieldDbSourceType": 9,
|
"KeyFieldDbSourceType": 9,
|
||||||
"TreeKeyExpr": "",
|
"TreeKeyExpr": "",
|
||||||
|
|
@ -49,13 +52,103 @@
|
||||||
"SchedulerTextExpr": "",
|
"SchedulerTextExpr": "",
|
||||||
"SchedulerStartDateExpr": "",
|
"SchedulerStartDateExpr": "",
|
||||||
"SchedulerEndDateExpr": "",
|
"SchedulerEndDateExpr": "",
|
||||||
|
"TodoTitleExpr": "",
|
||||||
|
"TodoStatusExpr": "",
|
||||||
|
"TodoDescriptionExpr": "",
|
||||||
|
"TodoDueDateExpr": "",
|
||||||
|
"TodoTagExpr": "",
|
||||||
|
"TodoAssigneeExpr": "",
|
||||||
|
"TodoPriorityExpr": "",
|
||||||
|
"TodoCompletedExpr": "",
|
||||||
|
"TodoOrderExpr": "",
|
||||||
|
"TodoStatusOrder": "Backlog, Ready to Start, In Progress, Code Review, Testing, Staging",
|
||||||
|
"TodoAllowDragging": true,
|
||||||
|
"ApprovalUserFieldName": "ApprovalUserName",
|
||||||
|
"ApprovalDateFieldName": "ApprovalDate",
|
||||||
|
"ApprovalStatusFieldName": "ApprovalStatus",
|
||||||
|
"ApprovalDescriptionFieldName": "ApprovalDescription",
|
||||||
|
"ApprovalIsFilterUserName": false,
|
||||||
|
"Criteria": [
|
||||||
|
{
|
||||||
|
"ListFormCode": "App.Wizard.Approval",
|
||||||
|
"Kind": "Start",
|
||||||
|
"Title": "\u0130\u015F Ak\u0131\u015F\u0131 Ba\u015Flat1",
|
||||||
|
"CompareColumn": "Price",
|
||||||
|
"CompareOperator": "\u003E",
|
||||||
|
"CompareValue": 5000,
|
||||||
|
"Approver": "",
|
||||||
|
"NextOnStart": "App.Wizard.Approval-N002",
|
||||||
|
"NextOnTrue": "",
|
||||||
|
"NextOnFalse": "",
|
||||||
|
"NextOnApprove": "",
|
||||||
|
"NextOnReject": "",
|
||||||
|
"PositionX": 46,
|
||||||
|
"PositionY": 46,
|
||||||
|
"CompareOutcomes": [],
|
||||||
|
"Id": "App.Wizard.Approval-N001"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ListFormCode": "App.Wizard.Approval",
|
||||||
|
"Kind": "Approval",
|
||||||
|
"Title": "Onay1",
|
||||||
|
"CompareColumn": "Price",
|
||||||
|
"CompareOperator": "\u003E",
|
||||||
|
"CompareValue": 5000,
|
||||||
|
"Approver": "system@sozsoft.com",
|
||||||
|
"NextOnStart": "",
|
||||||
|
"NextOnTrue": "",
|
||||||
|
"NextOnFalse": "",
|
||||||
|
"NextOnApprove": "App.Wizard.Approval-N003",
|
||||||
|
"NextOnReject": "App.Wizard.Approval-N004",
|
||||||
|
"PositionX": 337,
|
||||||
|
"PositionY": 39,
|
||||||
|
"CompareOutcomes": [],
|
||||||
|
"Id": "App.Wizard.Approval-N002"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ListFormCode": "App.Wizard.Approval",
|
||||||
|
"Kind": "Inform",
|
||||||
|
"Title": "Bilgilendirme1",
|
||||||
|
"CompareColumn": "Price",
|
||||||
|
"CompareOperator": "\u003E",
|
||||||
|
"CompareValue": 5000,
|
||||||
|
"Approver": "system@sozsoft.com",
|
||||||
|
"NextOnStart": "App.Wizard.Approval-N004",
|
||||||
|
"NextOnTrue": "",
|
||||||
|
"NextOnFalse": "",
|
||||||
|
"NextOnApprove": "",
|
||||||
|
"NextOnReject": "",
|
||||||
|
"PositionX": 538,
|
||||||
|
"PositionY": 324,
|
||||||
|
"CompareOutcomes": [],
|
||||||
|
"Id": "App.Wizard.Approval-N003"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ListFormCode": "App.Wizard.Approval",
|
||||||
|
"Kind": "End",
|
||||||
|
"Title": "\u0130\u015F Ak\u0131\u015F\u0131 Bitir1",
|
||||||
|
"CompareColumn": "Price",
|
||||||
|
"CompareOperator": "\u003E",
|
||||||
|
"CompareValue": 5000,
|
||||||
|
"Approver": "",
|
||||||
|
"NextOnStart": "",
|
||||||
|
"NextOnTrue": "",
|
||||||
|
"NextOnFalse": "",
|
||||||
|
"NextOnApprove": "",
|
||||||
|
"NextOnReject": "",
|
||||||
|
"PositionX": 852,
|
||||||
|
"PositionY": 26,
|
||||||
|
"CompareOutcomes": [],
|
||||||
|
"Id": "App.Wizard.Approval-N004"
|
||||||
|
}
|
||||||
|
],
|
||||||
"Groups": [
|
"Groups": [
|
||||||
{
|
{
|
||||||
"Caption": "",
|
"Caption": "",
|
||||||
"ColCount": 1,
|
"ColCount": 1,
|
||||||
"Items": [
|
"Items": [
|
||||||
{
|
{
|
||||||
"DataField": "Id",
|
"FieldName": "Id",
|
||||||
"CaptionName": "App.Listform.ListformField.Id",
|
"CaptionName": "App.Listform.ListformField.Id",
|
||||||
"EditorType": "dxTextBox",
|
"EditorType": "dxTextBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -72,24 +165,7 @@
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"DataField": "Name",
|
"FieldName": "ApprovalUserName",
|
||||||
"CaptionName": "App.Listform.ListformField.Name",
|
|
||||||
"EditorType": "dxTextBox",
|
|
||||||
"EditorOptions": "",
|
|
||||||
"EditorScript": "",
|
|
||||||
"ColSpan": 1,
|
|
||||||
"IsRequired": true,
|
|
||||||
"IncludeInEditingForm": true,
|
|
||||||
"DbSourceType": 16,
|
|
||||||
"TurkishCaption": "Name",
|
|
||||||
"EnglishCaption": "Name",
|
|
||||||
"LookupDataSourceType": 1,
|
|
||||||
"ValueExpr": "Key",
|
|
||||||
"DisplayExpr": "Name",
|
|
||||||
"LookupQuery": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"DataField": "ApprovalUserName",
|
|
||||||
"CaptionName": "App.Listform.ListformField.ApprovalUserName",
|
"CaptionName": "App.Listform.ListformField.ApprovalUserName",
|
||||||
"EditorType": "dxTextBox",
|
"EditorType": "dxTextBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -106,7 +182,7 @@
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"DataField": "ApprovalStatus",
|
"FieldName": "ApprovalStatus",
|
||||||
"CaptionName": "App.Listform.ListformField.ApprovalStatus",
|
"CaptionName": "App.Listform.ListformField.ApprovalStatus",
|
||||||
"EditorType": "dxTextBox",
|
"EditorType": "dxTextBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -123,7 +199,7 @@
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"DataField": "ApprovalDate",
|
"FieldName": "ApprovalDate",
|
||||||
"CaptionName": "App.Listform.ListformField.ApprovalDate",
|
"CaptionName": "App.Listform.ListformField.ApprovalDate",
|
||||||
"EditorType": "dxDateBox",
|
"EditorType": "dxDateBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -140,7 +216,7 @@
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"DataField": "ApprovalDescription",
|
"FieldName": "ApprovalDescription",
|
||||||
"CaptionName": "App.Listform.ListformField.ApprovalDescription",
|
"CaptionName": "App.Listform.ListformField.ApprovalDescription",
|
||||||
"EditorType": "dxTextBox",
|
"EditorType": "dxTextBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -155,219 +231,39 @@
|
||||||
"ValueExpr": "Key",
|
"ValueExpr": "Key",
|
||||||
"DisplayExpr": "Name",
|
"DisplayExpr": "Name",
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "Title",
|
||||||
|
"CaptionName": "App.Listform.ListformField.Title",
|
||||||
|
"EditorType": "dxTextBox",
|
||||||
|
"EditorOptions": "",
|
||||||
|
"EditorScript": "",
|
||||||
|
"ColSpan": 1,
|
||||||
|
"IsRequired": false,
|
||||||
|
"IncludeInEditingForm": true,
|
||||||
|
"DbSourceType": 16,
|
||||||
|
"TurkishCaption": "Title",
|
||||||
|
"EnglishCaption": "Title",
|
||||||
|
"LookupDataSourceType": 1,
|
||||||
|
"ValueExpr": "Key",
|
||||||
|
"DisplayExpr": "Name",
|
||||||
|
"LookupQuery": ""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"SubForms": [],
|
"SubForms": [],
|
||||||
"Widgets": [],
|
"Widgets": []
|
||||||
"Workflow": {
|
|
||||||
"ApprovalUserFieldName": "ApprovalUserName",
|
|
||||||
"IsFilterUserName": true,
|
|
||||||
"ApprovalDateFieldName": "ApprovalDate",
|
|
||||||
"ApprovalStatusFieldName": "ApprovalStatus",
|
|
||||||
"ApprovalDescriptionFieldName": "ApprovalDescription",
|
|
||||||
"Criteria": [
|
|
||||||
{
|
|
||||||
"ListFormCode": "App.Wizard.Approval",
|
|
||||||
"Kind": "Start",
|
|
||||||
"Title": "\u0130\u015F Ak\u0131\u015F\u0131 Ba\u015Flat1",
|
|
||||||
"CompareColumn": "Price",
|
|
||||||
"CompareOperator": "\u003E",
|
|
||||||
"CompareValue": 5000,
|
|
||||||
"Approver": "",
|
|
||||||
"NextOnStart": "N002",
|
|
||||||
"NextOnTrue": "",
|
|
||||||
"NextOnFalse": "",
|
|
||||||
"NextOnApprove": "",
|
|
||||||
"NextOnReject": "",
|
|
||||||
"PositionX": 34,
|
|
||||||
"PositionY": 104,
|
|
||||||
"CompareOutcomes": [],
|
|
||||||
"Id": "N001"
|
|
||||||
},
|
},
|
||||||
{
|
"IsDeletedField": false,
|
||||||
"ListFormCode": "App.Wizard.Approval",
|
"IsCreatedField": false,
|
||||||
"Kind": "Approval",
|
|
||||||
"Title": "Onay1",
|
|
||||||
"CompareColumn": "Price",
|
|
||||||
"CompareOperator": "\u003E",
|
|
||||||
"CompareValue": 5000,
|
|
||||||
"Approver": "admin@sozsoft.com",
|
|
||||||
"NextOnStart": "",
|
|
||||||
"NextOnTrue": "",
|
|
||||||
"NextOnFalse": "",
|
|
||||||
"NextOnApprove": "N003",
|
|
||||||
"NextOnReject": "N004",
|
|
||||||
"PositionX": 323,
|
|
||||||
"PositionY": 104,
|
|
||||||
"CompareOutcomes": [],
|
|
||||||
"Id": "N002"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ListFormCode": "App.Wizard.Approval",
|
|
||||||
"Kind": "Approval",
|
|
||||||
"Title": "Onay2",
|
|
||||||
"CompareColumn": "Price",
|
|
||||||
"CompareOperator": "\u003E",
|
|
||||||
"CompareValue": 5000,
|
|
||||||
"Approver": "demo@sozsoft.com",
|
|
||||||
"NextOnStart": "",
|
|
||||||
"NextOnTrue": "",
|
|
||||||
"NextOnFalse": "",
|
|
||||||
"NextOnApprove": "N004",
|
|
||||||
"NextOnReject": "N004",
|
|
||||||
"PositionX": 586,
|
|
||||||
"PositionY": 104,
|
|
||||||
"CompareOutcomes": [],
|
|
||||||
"Id": "N003"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ListFormCode": "App.Wizard.Approval",
|
|
||||||
"Kind": "Inform",
|
|
||||||
"Title": "Bilgilendirme1",
|
|
||||||
"CompareColumn": "Price",
|
|
||||||
"CompareOperator": "\u003E",
|
|
||||||
"CompareValue": 5000,
|
|
||||||
"Approver": "system@sozsoft.com",
|
|
||||||
"NextOnStart": "N005",
|
|
||||||
"NextOnTrue": "",
|
|
||||||
"NextOnFalse": "",
|
|
||||||
"NextOnApprove": "",
|
|
||||||
"NextOnReject": "",
|
|
||||||
"PositionX": 458,
|
|
||||||
"PositionY": 411,
|
|
||||||
"CompareOutcomes": [],
|
|
||||||
"Id": "N004"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ListFormCode": "App.Wizard.Approval",
|
|
||||||
"Kind": "End",
|
|
||||||
"Title": "\u0130\u015F Ak\u0131\u015F\u0131 Bitir1",
|
|
||||||
"CompareColumn": "Price",
|
|
||||||
"CompareOperator": "\u003E",
|
|
||||||
"CompareValue": 5000,
|
|
||||||
"Approver": "",
|
|
||||||
"NextOnStart": "",
|
|
||||||
"NextOnTrue": "",
|
|
||||||
"NextOnFalse": "",
|
|
||||||
"NextOnApprove": "",
|
|
||||||
"NextOnReject": "",
|
|
||||||
"PositionX": 792,
|
|
||||||
"PositionY": 412,
|
|
||||||
"CompareOutcomes": [],
|
|
||||||
"Id": "N005"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"WorkflowCriteria": [
|
|
||||||
{
|
|
||||||
"ListFormCode": "App.Wizard.Approval",
|
|
||||||
"Kind": "Start",
|
|
||||||
"Title": "\u0130\u015F Ak\u0131\u015F\u0131 Ba\u015Flat1",
|
|
||||||
"CompareColumn": "Price",
|
|
||||||
"CompareOperator": "\u003E",
|
|
||||||
"CompareValue": 5000,
|
|
||||||
"Approver": "",
|
|
||||||
"NextOnStart": "N002",
|
|
||||||
"NextOnTrue": "",
|
|
||||||
"NextOnFalse": "",
|
|
||||||
"NextOnApprove": "",
|
|
||||||
"NextOnReject": "",
|
|
||||||
"PositionX": 34,
|
|
||||||
"PositionY": 104,
|
|
||||||
"CompareOutcomes": [],
|
|
||||||
"Id": "N001"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ListFormCode": "App.Wizard.Approval",
|
|
||||||
"Kind": "Approval",
|
|
||||||
"Title": "Onay1",
|
|
||||||
"CompareColumn": "Price",
|
|
||||||
"CompareOperator": "\u003E",
|
|
||||||
"CompareValue": 5000,
|
|
||||||
"Approver": "admin@sozsoft.com",
|
|
||||||
"NextOnStart": "",
|
|
||||||
"NextOnTrue": "",
|
|
||||||
"NextOnFalse": "",
|
|
||||||
"NextOnApprove": "N003",
|
|
||||||
"NextOnReject": "N004",
|
|
||||||
"PositionX": 323,
|
|
||||||
"PositionY": 104,
|
|
||||||
"CompareOutcomes": [],
|
|
||||||
"Id": "N002"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ListFormCode": "App.Wizard.Approval",
|
|
||||||
"Kind": "Approval",
|
|
||||||
"Title": "Onay2",
|
|
||||||
"CompareColumn": "Price",
|
|
||||||
"CompareOperator": "\u003E",
|
|
||||||
"CompareValue": 5000,
|
|
||||||
"Approver": "demo@sozsoft.com",
|
|
||||||
"NextOnStart": "",
|
|
||||||
"NextOnTrue": "",
|
|
||||||
"NextOnFalse": "",
|
|
||||||
"NextOnApprove": "N004",
|
|
||||||
"NextOnReject": "N004",
|
|
||||||
"PositionX": 586,
|
|
||||||
"PositionY": 104,
|
|
||||||
"CompareOutcomes": [],
|
|
||||||
"Id": "N003"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ListFormCode": "App.Wizard.Approval",
|
|
||||||
"Kind": "Inform",
|
|
||||||
"Title": "Bilgilendirme1",
|
|
||||||
"CompareColumn": "Price",
|
|
||||||
"CompareOperator": "\u003E",
|
|
||||||
"CompareValue": 5000,
|
|
||||||
"Approver": "system@sozsoft.com",
|
|
||||||
"NextOnStart": "N005",
|
|
||||||
"NextOnTrue": "",
|
|
||||||
"NextOnFalse": "",
|
|
||||||
"NextOnApprove": "",
|
|
||||||
"NextOnReject": "",
|
|
||||||
"PositionX": 458,
|
|
||||||
"PositionY": 411,
|
|
||||||
"CompareOutcomes": [],
|
|
||||||
"Id": "N004"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ListFormCode": "App.Wizard.Approval",
|
|
||||||
"Kind": "End",
|
|
||||||
"Title": "\u0130\u015F Ak\u0131\u015F\u0131 Bitir1",
|
|
||||||
"CompareColumn": "Price",
|
|
||||||
"CompareOperator": "\u003E",
|
|
||||||
"CompareValue": 5000,
|
|
||||||
"Approver": "",
|
|
||||||
"NextOnStart": "",
|
|
||||||
"NextOnTrue": "",
|
|
||||||
"NextOnFalse": "",
|
|
||||||
"NextOnApprove": "",
|
|
||||||
"NextOnReject": "",
|
|
||||||
"PositionX": 792,
|
|
||||||
"PositionY": 412,
|
|
||||||
"CompareOutcomes": [],
|
|
||||||
"Id": "N005"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"IsDeletedField": true,
|
|
||||||
"IsCreatedField": true,
|
|
||||||
"InsertedRecords": {
|
"InsertedRecords": {
|
||||||
"LanguageKeys": [
|
"LanguageKeys": [
|
||||||
"App.Wizard.Approval",
|
"App.Wizard.Approval",
|
||||||
"App.Wizard.Approval.Title",
|
"App.Wizard.Approval.Title",
|
||||||
"App.Wizard.Approval.Desc",
|
"App.Wizard.Approval.Desc"
|
||||||
"App.Listform.ListformField.ApprovalUserName",
|
|
||||||
"App.Listform.ListformField.ApprovalStatus",
|
|
||||||
"App.Listform.ListformField.ApprovalDate",
|
|
||||||
"App.Listform.ListformField.ApprovalDescription"
|
|
||||||
],
|
|
||||||
"PermissionGroupNames": [
|
|
||||||
"App.Wizard.Sales"
|
|
||||||
],
|
],
|
||||||
|
"PermissionGroupNames": [],
|
||||||
"PermissionNames": [
|
"PermissionNames": [
|
||||||
"App.Wizard.Approval",
|
"App.Wizard.Approval",
|
||||||
"App.Wizard.Approval.Create",
|
"App.Wizard.Approval.Create",
|
||||||
|
|
@ -0,0 +1,281 @@
|
||||||
|
{
|
||||||
|
"Wizard": {
|
||||||
|
"WizardName": "Todo",
|
||||||
|
"ListFormCode": "App.Wizard.Todo",
|
||||||
|
"MenuCode": "App.Wizard.Todo",
|
||||||
|
"IsTenant": true,
|
||||||
|
"IsBranch": false,
|
||||||
|
"IsOrganizationUnit": false,
|
||||||
|
"AllowAdding": true,
|
||||||
|
"AllowUpdating": true,
|
||||||
|
"AllowDeleting": true,
|
||||||
|
"AllowDetail": false,
|
||||||
|
"ConfirmDelete": true,
|
||||||
|
"DefaultLayout": "todo",
|
||||||
|
"Grid": true,
|
||||||
|
"Card": true,
|
||||||
|
"Pivot": true,
|
||||||
|
"Tree": true,
|
||||||
|
"Chart": true,
|
||||||
|
"Gantt": true,
|
||||||
|
"Scheduler": true,
|
||||||
|
"Todo": true,
|
||||||
|
"LanguageTextMenuEn": "Todo",
|
||||||
|
"LanguageTextMenuTr": "\u0130\u015Fler",
|
||||||
|
"LanguageTextTitleEn": "Todo",
|
||||||
|
"LanguageTextTitleTr": "\u0130\u015Fler",
|
||||||
|
"LanguageTextDescEn": "Todo",
|
||||||
|
"LanguageTextDescTr": "\u0130\u015Fler",
|
||||||
|
"LanguageTextMenuParentEn": "Project",
|
||||||
|
"LanguageTextMenuParentTr": "Project",
|
||||||
|
"PermissionGroupName": "App.Wizard.Project",
|
||||||
|
"MenuParentCode": "App.Wizard.Project",
|
||||||
|
"MenuParentShortName": "Pro",
|
||||||
|
"MenuParentIcon": "FcVideoProjector",
|
||||||
|
"MenuIcon": "FcTodoList",
|
||||||
|
"DataSourceCode": "Default",
|
||||||
|
"DataSourceConnectionString": "",
|
||||||
|
"SelectCommandType": 1,
|
||||||
|
"SelectCommand": "Pro_T_Todo",
|
||||||
|
"KeyFieldName": "Id",
|
||||||
|
"KeyFieldDbSourceType": 9,
|
||||||
|
"TreeKeyExpr": "",
|
||||||
|
"TreeParentIdExpr": "",
|
||||||
|
"TreeAutoExpandAll": false,
|
||||||
|
"GanttKeyExpr": "",
|
||||||
|
"GanttParentIdExpr": "",
|
||||||
|
"GanttAutoExpandAll": false,
|
||||||
|
"GanttTitleExpr": "",
|
||||||
|
"GanttStartExpr": "",
|
||||||
|
"GanttEndExpr": "",
|
||||||
|
"GanttProgressExpr": "",
|
||||||
|
"SchedulerTextExpr": "",
|
||||||
|
"SchedulerStartDateExpr": "",
|
||||||
|
"SchedulerEndDateExpr": "",
|
||||||
|
"TodoTitleExpr": "Title",
|
||||||
|
"TodoStatusExpr": "Status",
|
||||||
|
"TodoDescriptionExpr": "Description",
|
||||||
|
"TodoDueDateExpr": "DueDate",
|
||||||
|
"TodoTagExpr": "Tags",
|
||||||
|
"TodoAssigneeExpr": "Assignees",
|
||||||
|
"TodoPriorityExpr": "Priority",
|
||||||
|
"TodoCompletedExpr": "Completed",
|
||||||
|
"TodoOrderExpr": "SortOrder",
|
||||||
|
"TodoStatusOrder": "Backlog, Ready to Start, In Progress, Code Review, Testing, Staging",
|
||||||
|
"TodoAllowDragging": true,
|
||||||
|
"ApprovalUserFieldName": "",
|
||||||
|
"ApprovalDateFieldName": "",
|
||||||
|
"ApprovalStatusFieldName": "",
|
||||||
|
"ApprovalDescriptionFieldName": "",
|
||||||
|
"ApprovalIsFilterUserName": false,
|
||||||
|
"Criteria": [],
|
||||||
|
"Groups": [
|
||||||
|
{
|
||||||
|
"Caption": "",
|
||||||
|
"ColCount": 1,
|
||||||
|
"Items": [
|
||||||
|
{
|
||||||
|
"FieldName": "Id",
|
||||||
|
"CaptionName": "App.Listform.ListformField.Id",
|
||||||
|
"EditorType": "dxTextBox",
|
||||||
|
"EditorOptions": "",
|
||||||
|
"EditorScript": "",
|
||||||
|
"ColSpan": 1,
|
||||||
|
"IsRequired": true,
|
||||||
|
"IncludeInEditingForm": true,
|
||||||
|
"DbSourceType": 9,
|
||||||
|
"TurkishCaption": "Id",
|
||||||
|
"EnglishCaption": "Id",
|
||||||
|
"LookupDataSourceType": 1,
|
||||||
|
"ValueExpr": "Key",
|
||||||
|
"DisplayExpr": "Name",
|
||||||
|
"LookupQuery": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "Title",
|
||||||
|
"CaptionName": "App.Listform.ListformField.Title",
|
||||||
|
"EditorType": "dxTextBox",
|
||||||
|
"EditorOptions": "",
|
||||||
|
"EditorScript": "",
|
||||||
|
"ColSpan": 1,
|
||||||
|
"IsRequired": true,
|
||||||
|
"IncludeInEditingForm": true,
|
||||||
|
"DbSourceType": 16,
|
||||||
|
"TurkishCaption": "Title",
|
||||||
|
"EnglishCaption": "Title",
|
||||||
|
"LookupDataSourceType": 1,
|
||||||
|
"ValueExpr": "Key",
|
||||||
|
"DisplayExpr": "Name",
|
||||||
|
"LookupQuery": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "Status",
|
||||||
|
"CaptionName": "App.Listform.ListformField.Status",
|
||||||
|
"EditorType": "dxTextBox",
|
||||||
|
"EditorOptions": "",
|
||||||
|
"EditorScript": "",
|
||||||
|
"ColSpan": 1,
|
||||||
|
"IsRequired": true,
|
||||||
|
"IncludeInEditingForm": false,
|
||||||
|
"DbSourceType": 16,
|
||||||
|
"TurkishCaption": "Status",
|
||||||
|
"EnglishCaption": "Status",
|
||||||
|
"LookupDataSourceType": 1,
|
||||||
|
"ValueExpr": "Key",
|
||||||
|
"DisplayExpr": "Name",
|
||||||
|
"LookupQuery": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "Description",
|
||||||
|
"CaptionName": "App.Listform.ListformField.Description",
|
||||||
|
"EditorType": "dxHtmlEditor",
|
||||||
|
"EditorOptions": "{\u0022mediaResizing\u0022:{\u0022enabled\u0022:true},\u0022imageUpload\u0022:{\u0022tabs\u0022:[\u0022file\u0022,\u0022url\u0022],\u0022fileUploadMode\u0022:\u0022base64\u0022},\u0022toolbar\u0022:{\u0022multiline\u0022:true,\u0022items\u0022:[{\u0022name\u0022:\u0022undo\u0022},{\u0022name\u0022:\u0022redo\u0022},{\u0022name\u0022:\u0022separator\u0022},{\u0022name\u0022:\u0022size\u0022,\u0022acceptedValues\u0022:[\u00228pt\u0022,\u002210pt\u0022,\u002212pt\u0022,\u002214pt\u0022,\u002218pt\u0022,\u002224pt\u0022,\u002236pt\u0022],\u0022options\u0022:{\u0022inputAttr\u0022:{\u0022aria-label\u0022:\u0022Font size\u0022}}},{\u0022name\u0022:\u0022font\u0022,\u0022acceptedValues\u0022:[\u0022Arial\u0022,\u0022Courier New\u0022,\u0022Georgia\u0022,\u0022Impact\u0022,\u0022Lucida Console\u0022,\u0022Tahoma\u0022,\u0022Times New Roman\u0022,\u0022Verdana\u0022],\u0022options\u0022:{\u0022inputAttr\u0022:{\u0022aria-label\u0022:\u0022Font family\u0022}}},{\u0022name\u0022:\u0022separator\u0022},{\u0022name\u0022:\u0022bold\u0022},{\u0022name\u0022:\u0022italic\u0022},{\u0022name\u0022:\u0022strike\u0022},{\u0022name\u0022:\u0022underline\u0022},{\u0022name\u0022:\u0022separator\u0022},{\u0022name\u0022:\u0022alignLeft\u0022},{\u0022name\u0022:\u0022alignCenter\u0022},{\u0022name\u0022:\u0022alignRight\u0022},{\u0022name\u0022:\u0022alignJustify\u0022},{\u0022name\u0022:\u0022separator\u0022},{\u0022name\u0022:\u0022orderedList\u0022},{\u0022name\u0022:\u0022bulletList\u0022},{\u0022name\u0022:\u0022separator\u0022},{\u0022name\u0022:\u0022header\u0022,\u0022acceptedValues\u0022:[false,1,2,3,4,5]},{\u0022name\u0022:\u0022separator\u0022},{\u0022name\u0022:\u0022color\u0022},{\u0022name\u0022:\u0022background\u0022},{\u0022name\u0022:\u0022separator\u0022},{\u0022name\u0022:\u0022link\u0022},{\u0022name\u0022:\u0022image\u0022},{\u0022name\u0022:\u0022separator\u0022},{\u0022name\u0022:\u0022clear\u0022},{\u0022name\u0022:\u0022codeBlock\u0022},{\u0022name\u0022:\u0022blockquote\u0022},{\u0022name\u0022:\u0022separator\u0022},{\u0022name\u0022:\u0022insertTable\u0022},{\u0022name\u0022:\u0022deleteTable\u0022},{\u0022name\u0022:\u0022insertRowAbove\u0022},{\u0022name\u0022:\u0022insertRowBelow\u0022},{\u0022name\u0022:\u0022deleteRow\u0022},{\u0022name\u0022:\u0022insertColumnLeft\u0022},{\u0022name\u0022:\u0022insertColumnRight\u0022},{\u0022name\u0022:\u0022deleteColumn\u0022},{\u0022name\u0022:\u0022cellProperties\u0022},{\u0022name\u0022:\u0022tableProperties\u0022}]}}",
|
||||||
|
"EditorScript": "",
|
||||||
|
"ColSpan": 1,
|
||||||
|
"IsRequired": false,
|
||||||
|
"IncludeInEditingForm": false,
|
||||||
|
"DbSourceType": 16,
|
||||||
|
"TurkishCaption": "Description",
|
||||||
|
"EnglishCaption": "Description",
|
||||||
|
"LookupDataSourceType": 1,
|
||||||
|
"ValueExpr": "Key",
|
||||||
|
"DisplayExpr": "Name",
|
||||||
|
"LookupQuery": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "DueDate",
|
||||||
|
"CaptionName": "App.Listform.ListformField.DueDate",
|
||||||
|
"EditorType": "dxDateBox",
|
||||||
|
"EditorOptions": "",
|
||||||
|
"EditorScript": "",
|
||||||
|
"ColSpan": 1,
|
||||||
|
"IsRequired": false,
|
||||||
|
"IncludeInEditingForm": false,
|
||||||
|
"DbSourceType": 6,
|
||||||
|
"TurkishCaption": "Due Date",
|
||||||
|
"EnglishCaption": "Due Date",
|
||||||
|
"LookupDataSourceType": 1,
|
||||||
|
"ValueExpr": "Key",
|
||||||
|
"DisplayExpr": "Name",
|
||||||
|
"LookupQuery": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "Tags",
|
||||||
|
"CaptionName": "App.Listform.ListformField.Tags",
|
||||||
|
"EditorType": "dxTextBox",
|
||||||
|
"EditorOptions": "",
|
||||||
|
"EditorScript": "",
|
||||||
|
"ColSpan": 1,
|
||||||
|
"IsRequired": false,
|
||||||
|
"IncludeInEditingForm": false,
|
||||||
|
"DbSourceType": 16,
|
||||||
|
"TurkishCaption": "Tags",
|
||||||
|
"EnglishCaption": "Tags",
|
||||||
|
"LookupDataSourceType": 1,
|
||||||
|
"ValueExpr": "Key",
|
||||||
|
"DisplayExpr": "Name",
|
||||||
|
"LookupQuery": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "Assignees",
|
||||||
|
"CaptionName": "App.Listform.ListformField.Assignees",
|
||||||
|
"EditorType": "dxTextBox",
|
||||||
|
"EditorOptions": "",
|
||||||
|
"EditorScript": "",
|
||||||
|
"ColSpan": 1,
|
||||||
|
"IsRequired": false,
|
||||||
|
"IncludeInEditingForm": false,
|
||||||
|
"DbSourceType": 16,
|
||||||
|
"TurkishCaption": "Assignees",
|
||||||
|
"EnglishCaption": "Assignees",
|
||||||
|
"LookupDataSourceType": 1,
|
||||||
|
"ValueExpr": "Key",
|
||||||
|
"DisplayExpr": "Name",
|
||||||
|
"LookupQuery": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "Priority",
|
||||||
|
"CaptionName": "App.Listform.ListformField.Priority",
|
||||||
|
"EditorType": "dxTextBox",
|
||||||
|
"EditorOptions": "",
|
||||||
|
"EditorScript": "",
|
||||||
|
"ColSpan": 1,
|
||||||
|
"IsRequired": false,
|
||||||
|
"IncludeInEditingForm": false,
|
||||||
|
"DbSourceType": 16,
|
||||||
|
"TurkishCaption": "Priority",
|
||||||
|
"EnglishCaption": "Priority",
|
||||||
|
"LookupDataSourceType": 1,
|
||||||
|
"ValueExpr": "Key",
|
||||||
|
"DisplayExpr": "Name",
|
||||||
|
"LookupQuery": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "Completed",
|
||||||
|
"CaptionName": "App.Listform.ListformField.Completed",
|
||||||
|
"EditorType": "dxCheckBox",
|
||||||
|
"EditorOptions": "",
|
||||||
|
"EditorScript": "",
|
||||||
|
"ColSpan": 1,
|
||||||
|
"IsRequired": true,
|
||||||
|
"IncludeInEditingForm": false,
|
||||||
|
"DbSourceType": 3,
|
||||||
|
"TurkishCaption": "Completed",
|
||||||
|
"EnglishCaption": "Completed",
|
||||||
|
"LookupDataSourceType": 1,
|
||||||
|
"ValueExpr": "Key",
|
||||||
|
"DisplayExpr": "Name",
|
||||||
|
"LookupQuery": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FieldName": "SortOrder",
|
||||||
|
"CaptionName": "App.Listform.ListformField.SortOrder",
|
||||||
|
"EditorType": "dxNumberBox",
|
||||||
|
"EditorOptions": "",
|
||||||
|
"EditorScript": "",
|
||||||
|
"ColSpan": 1,
|
||||||
|
"IsRequired": true,
|
||||||
|
"IncludeInEditingForm": false,
|
||||||
|
"DbSourceType": 11,
|
||||||
|
"TurkishCaption": "Sort Order",
|
||||||
|
"EnglishCaption": "Sort Order",
|
||||||
|
"LookupDataSourceType": 1,
|
||||||
|
"ValueExpr": "Key",
|
||||||
|
"DisplayExpr": "Name",
|
||||||
|
"LookupQuery": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"SubForms": [],
|
||||||
|
"Widgets": []
|
||||||
|
},
|
||||||
|
"IsDeletedField": false,
|
||||||
|
"IsCreatedField": false,
|
||||||
|
"InsertedRecords": {
|
||||||
|
"LanguageKeys": [
|
||||||
|
"App.Wizard.Todo",
|
||||||
|
"App.Wizard.Todo.Title",
|
||||||
|
"App.Wizard.Todo.Desc",
|
||||||
|
"App.Listform.ListformField.Assignees",
|
||||||
|
"App.Listform.ListformField.Completed",
|
||||||
|
"App.Listform.ListformField.SortOrder"
|
||||||
|
],
|
||||||
|
"PermissionGroupNames": [
|
||||||
|
"App.Wizard.Project"
|
||||||
|
],
|
||||||
|
"PermissionNames": [
|
||||||
|
"App.Wizard.Todo",
|
||||||
|
"App.Wizard.Todo.Create",
|
||||||
|
"App.Wizard.Todo.Update",
|
||||||
|
"App.Wizard.Todo.Delete",
|
||||||
|
"App.Wizard.Todo.Export",
|
||||||
|
"App.Wizard.Todo.Import",
|
||||||
|
"App.Wizard.Todo.Note"
|
||||||
|
],
|
||||||
|
"MenuCodes": [
|
||||||
|
"App.Wizard.Todo"
|
||||||
|
],
|
||||||
|
"DataSourceCodes": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -107,6 +107,8 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
|
|
||||||
var fileName = Path.GetFileName(filePath);
|
var fileName = Path.GetFileName(filePath);
|
||||||
|
|
||||||
|
await BackfillMenuParentShortNameAsync(seedFile.Wizard);
|
||||||
|
|
||||||
// Zaten seeded mi kontrol et (ListForm var mı?)
|
// Zaten seeded mi kontrol et (ListForm var mı?)
|
||||||
if (await _repoListForm.AnyAsync(a => a.ListFormCode == seedFile.Wizard.ListFormCode))
|
if (await _repoListForm.AnyAsync(a => a.ListFormCode == seedFile.Wizard.ListFormCode))
|
||||||
{
|
{
|
||||||
|
|
@ -132,14 +134,17 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
var isCreated = seedFile.IsCreatedField;
|
var isCreated = seedFile.IsCreatedField;
|
||||||
input.SubForms ??= new List<SubFormDto>();
|
input.SubForms ??= new List<SubFormDto>();
|
||||||
input.Widgets ??= new List<WidgetEditDto>();
|
input.Widgets ??= new List<WidgetEditDto>();
|
||||||
input.Workflow ??= new WorkflowDto();
|
input.Criteria ??= [];
|
||||||
input.WorkflowCriteria ??= new List<ListFormWorkflowCriteriaDto>();
|
EnsureUniqueWorkflowCriteriaTitles(input.Criteria);
|
||||||
if (input.WorkflowCriteria.Count == 0 && input.Workflow.Criteria?.Count > 0)
|
var workflow = new WorkflowDto
|
||||||
{
|
{
|
||||||
input.WorkflowCriteria = input.Workflow.Criteria;
|
ApprovalUserFieldName = input.ApprovalUserFieldName,
|
||||||
}
|
ApprovalIsFilterUserName = input.ApprovalIsFilterUserName,
|
||||||
input.Workflow.Criteria = input.WorkflowCriteria;
|
ApprovalDateFieldName = input.ApprovalDateFieldName,
|
||||||
EnsureUniqueWorkflowCriteriaTitles(input.WorkflowCriteria);
|
ApprovalStatusFieldName = input.ApprovalStatusFieldName,
|
||||||
|
ApprovalDescriptionFieldName = input.ApprovalDescriptionFieldName,
|
||||||
|
Criteria = input.Criteria,
|
||||||
|
};
|
||||||
|
|
||||||
var wizardName = input.WizardName.Trim();
|
var wizardName = input.WizardName.Trim();
|
||||||
var code = string.IsNullOrWhiteSpace(input.MenuCode)
|
var code = string.IsNullOrWhiteSpace(input.MenuCode)
|
||||||
|
|
@ -148,7 +153,7 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
var listFormCode = string.IsNullOrWhiteSpace(input.ListFormCode)
|
var listFormCode = string.IsNullOrWhiteSpace(input.ListFormCode)
|
||||||
? code
|
? code
|
||||||
: input.ListFormCode.Trim();
|
: input.ListFormCode.Trim();
|
||||||
NormalizeWorkflowCriteriaIds(listFormCode, input.WorkflowCriteria);
|
NormalizeWorkflowCriteriaIds(listFormCode, input.Criteria);
|
||||||
var titleLangKey = $"{listFormCode}.Title";
|
var titleLangKey = $"{listFormCode}.Title";
|
||||||
var nameLangKey = code;
|
var nameLangKey = code;
|
||||||
var descLangKey = $"{listFormCode}.Desc";
|
var descLangKey = $"{listFormCode}.Desc";
|
||||||
|
|
@ -250,6 +255,7 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
Code = input.MenuParentCode,
|
Code = input.MenuParentCode,
|
||||||
DisplayName = input.MenuParentCode,
|
DisplayName = input.MenuParentCode,
|
||||||
IsDisabled = false,
|
IsDisabled = false,
|
||||||
|
ShortName = input.MenuParentShortName,
|
||||||
Icon = menuParentIcon,
|
Icon = menuParentIcon,
|
||||||
Order = maxRootOrder + 1,
|
Order = maxRootOrder + 1,
|
||||||
}, autoSave: true);
|
}, autoSave: true);
|
||||||
|
|
@ -299,21 +305,9 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
Caption = g.Caption,
|
Caption = g.Caption,
|
||||||
ColCount = g.ColCount,
|
ColCount = g.ColCount,
|
||||||
ColSpan = g.ColCount,
|
ColSpan = g.ColCount,
|
||||||
ItemType = "group",
|
ItemType = "group"
|
||||||
Items = g.Items
|
|
||||||
.Where(i => i.IncludeInEditingForm && i.DataField != input.KeyFieldName)
|
|
||||||
.Select((it, ii) => new EditingFormItemDto
|
|
||||||
{
|
|
||||||
Order = ii + 1,
|
|
||||||
DataField = it.DataField,
|
|
||||||
EditorType2 = it.EditorType,
|
|
||||||
ColSpan = it.ColSpan,
|
|
||||||
EditorOptions = string.IsNullOrWhiteSpace(it.EditorOptions) ? null : it.EditorOptions,
|
|
||||||
EditorScript = string.IsNullOrWhiteSpace(it.EditorScript) ? null : it.EditorScript,
|
|
||||||
})
|
})
|
||||||
.ToArray()
|
.Where((_, index) => input.Groups[index].Items.Any(i => i.IncludeInEditingForm && i.FieldName != input.KeyFieldName))
|
||||||
})
|
|
||||||
.Where(g => g.Items.Length > 0)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// ListForm - varsa sil, yeniden ekle
|
// ListForm - varsa sil, yeniden ekle
|
||||||
|
|
@ -338,8 +332,8 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
// EditingForm'da required olan alanları tespit et, ValidationRuleJson eklemek için
|
// EditingForm'da required olan alanları tespit et, ValidationRuleJson eklemek için
|
||||||
var editingFormFieldNames = input.Groups
|
var editingFormFieldNames = input.Groups
|
||||||
.SelectMany(g => g.Items)
|
.SelectMany(g => g.Items)
|
||||||
.Where(i => i.IncludeInEditingForm && i.DataField != input.KeyFieldName)
|
.Where(i => i.IncludeInEditingForm && i.FieldName != input.KeyFieldName)
|
||||||
.Select(i => new { FieldName = i.DataField, Isrequired = i.IsRequired })
|
.Select(i => new { FieldName = i.FieldName, Isrequired = i.IsRequired })
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// Heigth ve Width hesaplama
|
// Heigth ve Width hesaplama
|
||||||
|
|
@ -347,7 +341,7 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
.Select(g =>
|
.Select(g =>
|
||||||
{
|
{
|
||||||
var items = g.Items
|
var items = g.Items
|
||||||
.Where(i => i.IncludeInEditingForm && i.DataField != input.KeyFieldName)
|
.Where(i => i.IncludeInEditingForm && i.FieldName != input.KeyFieldName)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var columnCount = g.ColCount;
|
var columnCount = g.ColCount;
|
||||||
|
|
@ -392,8 +386,8 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
PageSize = 10,
|
PageSize = 10,
|
||||||
ExportJson = WizardConsts.DefaultExportJson,
|
ExportJson = WizardConsts.DefaultExportJson,
|
||||||
IsSubForm = false,
|
IsSubForm = false,
|
||||||
ShowNote = input.SubForms.Count > 0 || input.WorkflowCriteria.Count > 0,
|
ShowNote = input.SubForms.Count > 0 || input.Criteria.Count > 0,
|
||||||
LayoutJson = WizardConsts.DefaultLayoutJson(input.DefaultLayout, input.Grid, input.Pivot, input.Tree, input.Chart, input.Gantt, input.Scheduler),
|
LayoutJson = WizardConsts.DefaultLayoutJson(input.DefaultLayout, input.Grid, input.Card, input.Pivot, input.Tree, input.Chart, input.Gantt, input.Scheduler, input.Todo),
|
||||||
CultureName = LanguageCodes.En,
|
CultureName = LanguageCodes.En,
|
||||||
ListFormCode = input.ListFormCode,
|
ListFormCode = input.ListFormCode,
|
||||||
Name = nameLangKey,
|
Name = nameLangKey,
|
||||||
|
|
@ -413,41 +407,74 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
HeaderFilterJson = WizardConsts.DefaultHeaderFilterJson(),
|
HeaderFilterJson = WizardConsts.DefaultHeaderFilterJson(),
|
||||||
SearchPanelJson = WizardConsts.DefaultSearchPanelJson(),
|
SearchPanelJson = WizardConsts.DefaultSearchPanelJson(),
|
||||||
GroupPanelJson = WizardConsts.DefaultGroupPanelJson(),
|
GroupPanelJson = WizardConsts.DefaultGroupPanelJson(),
|
||||||
SelectionJson = WizardConsts.DefaultSelectionSingleJson(input.WorkflowCriteria.Count > 0 ? GridOptions.SelectionModeSingle : GridOptions.SelectionModeNone),
|
SelectionJson = WizardConsts.DefaultSelectionSingleJson(input.Criteria.Count > 0 ? GridOptions.SelectionModeSingle : GridOptions.SelectionModeNone),
|
||||||
ColumnOptionJson = WizardConsts.DefaultColumnOptionJson(),
|
ColumnOptionJson = WizardConsts.DefaultColumnOptionJson(),
|
||||||
PermissionJson = WizardConsts.DefaultPermissionJson(code),
|
PermissionJson = WizardConsts.DefaultPermissionJson(code),
|
||||||
DeleteCommand = isDeleted ? WizardConsts.DefaultDeleteCommand(input.SelectCommand) : null,
|
DeleteCommand = isDeleted ? WizardConsts.DefaultDeleteCommand(input.SelectCommand) : null,
|
||||||
DeleteFieldsDefaultValueJson = isDeleted
|
DeleteFieldsDefaultValueJson = isDeleted
|
||||||
? WizardConsts.DefaultDeleteFieldsDefaultValueJson(input.KeyFieldDbSourceType)
|
? WizardConsts.DefaultDeleteFieldsDefaultValueJson(input.KeyFieldDbSourceType)
|
||||||
: WizardConsts.DefaultFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
: WizardConsts.DefaultDeleteFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
||||||
InsertFieldsDefaultValueJson = isCreated
|
InsertFieldsDefaultValueJson = isCreated
|
||||||
? WizardConsts.DefaultInsertFieldsDefaultValueJson(input.KeyFieldDbSourceType)
|
? WizardConsts.DefaultInsertFieldsDefaultValueJson(input.KeyFieldDbSourceType)
|
||||||
: WizardConsts.DefaultFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
: WizardConsts.DefaultInsertFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
||||||
PagerOptionJson = WizardConsts.DefaultPagerOptionJson,
|
PagerOptionJson = WizardConsts.DefaultPagerOptionJson,
|
||||||
EditingOptionJson = WizardConsts.DefaultEditingOptionJson(titleLangKey, formWidth, formHeight, input.AllowDeleting, input.AllowAdding, input.AllowUpdating, input.ConfirmDelete, false, input.AllowDetail),
|
EditingOptionJson = WizardConsts.DefaultEditingOptionJson(titleLangKey, formWidth, formHeight, input.AllowDeleting, input.AllowAdding, input.AllowUpdating, input.ConfirmDelete, false, input.AllowDetail),
|
||||||
EditingFormJson = editingFormDtos.Count > 0 ? JsonSerializer.Serialize(editingFormDtos) : null,
|
EditingFormJson = editingFormDtos.Count > 0 ? JsonSerializer.Serialize(editingFormDtos) : null,
|
||||||
SubFormsJson = input.SubForms.Count > 0 ? JsonSerializer.Serialize(input.SubForms) : null,
|
SubFormsJson = input.SubForms.Count > 0 ? JsonSerializer.Serialize(input.SubForms) : null,
|
||||||
WidgetsJson = input.Widgets.Count > 0 ? JsonSerializer.Serialize(input.Widgets) : null,
|
WidgetsJson = input.Widgets.Count > 0 ? JsonSerializer.Serialize(input.Widgets) : null,
|
||||||
WorkflowJson = HasWorkflow(input.Workflow, input.WorkflowCriteria) ? JsonSerializer.Serialize(input.Workflow) : null,
|
WorkflowJson = HasWorkflow(workflow, input.Criteria) ? JsonSerializer.Serialize(workflow) : null,
|
||||||
|
TodoOptionJson = (input.Todo || input.DefaultLayout == "todo") &&
|
||||||
|
!string.IsNullOrEmpty(input.TodoTitleExpr) &&
|
||||||
|
!string.IsNullOrEmpty(input.TodoStatusExpr)
|
||||||
|
? JsonSerializer.Serialize(new TodoOptionDto
|
||||||
|
{
|
||||||
|
TitleExpr = input.TodoTitleExpr,
|
||||||
|
StatusExpr = input.TodoStatusExpr,
|
||||||
|
DescriptionExpr = input.TodoDescriptionExpr,
|
||||||
|
DueDateExpr = input.TodoDueDateExpr,
|
||||||
|
TagExpr = input.TodoTagExpr,
|
||||||
|
AssigneeExpr = input.TodoAssigneeExpr,
|
||||||
|
PriorityExpr = input.TodoPriorityExpr,
|
||||||
|
CompletedExpr = input.TodoCompletedExpr,
|
||||||
|
OrderExpr = input.TodoOrderExpr,
|
||||||
|
StatusOrder = input.TodoStatusOrder,
|
||||||
|
AllowDragging = input.TodoAllowDragging,
|
||||||
|
})
|
||||||
|
: null,
|
||||||
}, autoSave: true);
|
}, autoSave: true);
|
||||||
|
|
||||||
// ListFormFields
|
// ListFormFields
|
||||||
var fieldOrder = 0;
|
var fieldOrder = 0;
|
||||||
|
var editGroupOrder = 0;
|
||||||
foreach (var group in input.Groups)
|
foreach (var group in input.Groups)
|
||||||
{
|
{
|
||||||
|
editGroupOrder++;
|
||||||
|
var editOrder = 0;
|
||||||
foreach (var item in group.Items)
|
foreach (var item in group.Items)
|
||||||
{
|
{
|
||||||
fieldOrder++;
|
fieldOrder++;
|
||||||
|
if (item.IncludeInEditingForm && item.FieldName != input.KeyFieldName)
|
||||||
|
{
|
||||||
|
editOrder++;
|
||||||
|
}
|
||||||
await _repoListFormField.InsertAsync(new ListFormField
|
await _repoListFormField.InsertAsync(new ListFormField
|
||||||
{
|
{
|
||||||
ListFormCode = input.ListFormCode,
|
ListFormCode = input.ListFormCode,
|
||||||
FieldName = item.DataField,
|
FieldName = item.FieldName,
|
||||||
CaptionName = item.CaptionName,
|
CaptionName = item.CaptionName,
|
||||||
Visible = item.DataField != input.KeyFieldName,
|
Visible = item.FieldName != input.KeyFieldName,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
Width = 0, //Fit columns için hepsine sıfır veriyorum.
|
Width = 0, //Fit columns için hepsine sıfır veriyorum.
|
||||||
AllowSearch = true,
|
AllowSearch = true,
|
||||||
ListOrderNo = fieldOrder,
|
ListOrderNo = fieldOrder,
|
||||||
|
EditGroupOrderNo = item.IncludeInEditingForm ? editGroupOrder : null,
|
||||||
|
EditOrderNo = item.IncludeInEditingForm && item.FieldName != input.KeyFieldName
|
||||||
|
? editOrder
|
||||||
|
: null,
|
||||||
|
EditorType2 = item.EditorType,
|
||||||
|
ColSpan = item.ColSpan,
|
||||||
|
EditorOptions = string.IsNullOrWhiteSpace(item.EditorOptions) ? null : item.EditorOptions,
|
||||||
|
EditorScript = string.IsNullOrWhiteSpace(item.EditorScript) ? null : item.EditorScript,
|
||||||
SourceDbType = item.DbSourceType,
|
SourceDbType = item.DbSourceType,
|
||||||
CultureName = PlatformConsts.DefaultLanguage,
|
CultureName = PlatformConsts.DefaultLanguage,
|
||||||
PermissionJson = WizardConsts.DefaultFieldPermissionJson(code),
|
PermissionJson = WizardConsts.DefaultFieldPermissionJson(code),
|
||||||
|
|
@ -457,7 +484,7 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
LookupJson = !string.IsNullOrWhiteSpace(item.LookupQuery)
|
LookupJson = !string.IsNullOrWhiteSpace(item.LookupQuery)
|
||||||
? WizardConsts.DefaultLookupJson(item.LookupDataSourceType, item.DisplayExpr, item.ValueExpr, item.LookupQuery)
|
? WizardConsts.DefaultLookupJson(item.LookupDataSourceType, item.DisplayExpr, item.ValueExpr, item.LookupQuery)
|
||||||
: null,
|
: null,
|
||||||
ValidationRuleJson = editingFormFieldNames.Any(f => f.FieldName == item.DataField && f.Isrequired)
|
ValidationRuleJson = editingFormFieldNames.Any(f => f.FieldName == item.FieldName && f.Isrequired)
|
||||||
? WizardConsts.DefaultValidationRuleRequiredJson
|
? WizardConsts.DefaultValidationRuleRequiredJson
|
||||||
: null
|
: null
|
||||||
}, autoSave: true);
|
}, autoSave: true);
|
||||||
|
|
@ -466,7 +493,7 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var criteria in input.WorkflowCriteria)
|
foreach (var criteria in input.Criteria)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(criteria.Id))
|
if (string.IsNullOrWhiteSpace(criteria.Id))
|
||||||
{
|
{
|
||||||
|
|
@ -495,6 +522,24 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task BackfillMenuParentShortNameAsync(ListFormWizardDto input)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(input.MenuParentCode) ||
|
||||||
|
string.IsNullOrWhiteSpace(input.MenuParentShortName))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var menuParent = await _repoMenu.FirstOrDefaultAsync(a => a.Code == input.MenuParentCode);
|
||||||
|
if (menuParent == null || !string.IsNullOrWhiteSpace(menuParent.ShortName))
|
||||||
|
return;
|
||||||
|
|
||||||
|
menuParent.ShortName = input.MenuParentShortName.Trim();
|
||||||
|
await _repoMenu.UpdateAsync(menuParent, autoSave: true);
|
||||||
|
_logger.LogInformation(
|
||||||
|
"Menu parent '{MenuParentCode}' ShortName backfilled as '{ShortName}'.",
|
||||||
|
input.MenuParentCode,
|
||||||
|
menuParent.ShortName);
|
||||||
|
}
|
||||||
|
|
||||||
private static bool HasWorkflow(WorkflowDto workflow, List<ListFormWorkflowCriteriaDto> criteria)
|
private static bool HasWorkflow(WorkflowDto workflow, List<ListFormWorkflowCriteriaDto> criteria)
|
||||||
{
|
{
|
||||||
return workflow != null && (
|
return workflow != null && (
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ public enum TableNameEnum
|
||||||
InstallmentOption,
|
InstallmentOption,
|
||||||
Order,
|
Order,
|
||||||
OrderItem,
|
OrderItem,
|
||||||
|
OrderItem_ByTenantId,
|
||||||
BlogCategory,
|
BlogCategory,
|
||||||
BlogPost,
|
BlogPost,
|
||||||
Demo,
|
Demo,
|
||||||
|
|
@ -94,5 +95,5 @@ public enum TableNameEnum
|
||||||
VideoroomAttandance,
|
VideoroomAttandance,
|
||||||
VideoroomChat,
|
VideoroomChat,
|
||||||
Sequence,
|
Sequence,
|
||||||
DbTableColumn
|
DbTableColumn,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -758,6 +758,7 @@ public static class PlatformConsts
|
||||||
public const string dxDateBox = "dxDateBox";
|
public const string dxDateBox = "dxDateBox";
|
||||||
public const string dxDateRangeBox = "dxDateRangeBox";
|
public const string dxDateRangeBox = "dxDateRangeBox";
|
||||||
public const string dxDropDownBox = "dxDropDownBox";
|
public const string dxDropDownBox = "dxDropDownBox";
|
||||||
|
public const string dxGridBox = "dxGridBox";
|
||||||
public const string dxHtmlEditor = "dxHtmlEditor";
|
public const string dxHtmlEditor = "dxHtmlEditor";
|
||||||
public const string dxLookup = "dxHtmlEdidxLookuptor";
|
public const string dxLookup = "dxHtmlEdidxLookuptor";
|
||||||
public const string dxNumberBox = "dxNumberBox";
|
public const string dxNumberBox = "dxNumberBox";
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ public static class TableNameResolver
|
||||||
{ nameof(TableNameEnum.InstallmentOption), (TablePrefix.PlatformByName, MenuPrefix.Saas) },
|
{ nameof(TableNameEnum.InstallmentOption), (TablePrefix.PlatformByName, MenuPrefix.Saas) },
|
||||||
{ nameof(TableNameEnum.Order), (TablePrefix.PlatformByName, MenuPrefix.Saas) },
|
{ nameof(TableNameEnum.Order), (TablePrefix.PlatformByName, MenuPrefix.Saas) },
|
||||||
{ nameof(TableNameEnum.OrderItem), (TablePrefix.PlatformByName, MenuPrefix.Saas) },
|
{ nameof(TableNameEnum.OrderItem), (TablePrefix.PlatformByName, MenuPrefix.Saas) },
|
||||||
|
{ nameof(TableNameEnum.OrderItem_ByTenantId), (TablePrefix.PlatformByName, MenuPrefix.Saas) },
|
||||||
{ nameof(TableNameEnum.BlogCategory), (TablePrefix.PlatformByName, MenuPrefix.Saas) },
|
{ nameof(TableNameEnum.BlogCategory), (TablePrefix.PlatformByName, MenuPrefix.Saas) },
|
||||||
{ nameof(TableNameEnum.BlogPost), (TablePrefix.PlatformByName, MenuPrefix.Saas) },
|
{ nameof(TableNameEnum.BlogPost), (TablePrefix.PlatformByName, MenuPrefix.Saas) },
|
||||||
{ nameof(TableNameEnum.Demo), (TablePrefix.PlatformByName, MenuPrefix.Saas) },
|
{ nameof(TableNameEnum.Demo), (TablePrefix.PlatformByName, MenuPrefix.Saas) },
|
||||||
|
|
|
||||||
|
|
@ -84,14 +84,16 @@ public static class WizardConsts
|
||||||
Margin = 10
|
Margin = 10
|
||||||
});
|
});
|
||||||
|
|
||||||
public static string DefaultLayoutJson(string DefaultLayout = "grid", bool Grid = true, bool Pivot = true, bool Chart = true, bool Tree = true, bool Gantt = true, bool Scheduler = true) => JsonSerializer.Serialize(new
|
public static string DefaultLayoutJson(string DefaultLayout = "grid", bool Grid = true, bool Card = true, bool Pivot = true, bool Chart = true, bool Tree = true, bool Gantt = true, bool Scheduler = true, bool Todo = true) => JsonSerializer.Serialize(new
|
||||||
{
|
{
|
||||||
Grid = Grid,
|
Grid = Grid,
|
||||||
|
Card = Card,
|
||||||
Pivot = Pivot,
|
Pivot = Pivot,
|
||||||
Chart = Chart,
|
Chart = Chart,
|
||||||
Tree = Tree,
|
Tree = Tree,
|
||||||
Gantt = Gantt,
|
Gantt = Gantt,
|
||||||
Scheduler = Scheduler,
|
Scheduler = Scheduler,
|
||||||
|
Todo = Todo,
|
||||||
DefaultLayout = DefaultLayout,
|
DefaultLayout = DefaultLayout,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -196,6 +198,14 @@ public static class WizardConsts
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string DefaultInsertFieldsJsonOnlyId(DbType dbType = DbType.Guid)
|
||||||
|
{
|
||||||
|
return JsonSerializer.Serialize(new[]
|
||||||
|
{
|
||||||
|
new { FieldName = "Id", FieldDbType = dbType, Value = "@NEWID", CustomValueType = FieldCustomValueTypeEnum.CustomKey }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static string DefaultDeleteFieldsDefaultValueJson(DbType dbType = DbType.Guid)
|
public static string DefaultDeleteFieldsDefaultValueJson(DbType dbType = DbType.Guid)
|
||||||
{
|
{
|
||||||
return JsonSerializer.Serialize(new[]
|
return JsonSerializer.Serialize(new[]
|
||||||
|
|
@ -205,11 +215,11 @@ public static class WizardConsts
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string DefaultFieldsJsonOnlyId(DbType dbType = DbType.Guid)
|
public static string DefaultDeleteFieldsJsonOnlyId(DbType dbType = DbType.Guid)
|
||||||
{
|
{
|
||||||
return JsonSerializer.Serialize(new[]
|
return JsonSerializer.Serialize(new[]
|
||||||
{
|
{
|
||||||
new { FieldName = "Id", FieldDbType = dbType, Value = "@NEWID", CustomValueType = FieldCustomValueTypeEnum.CustomKey }
|
new { FieldName = "Id", FieldDbType = dbType, Value = "@ID", CustomValueType = FieldCustomValueTypeEnum.CustomKey }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -416,6 +416,8 @@ public static class SeedConsts
|
||||||
public const string RecurringJobs = Default + ".RecurringJobs";
|
public const string RecurringJobs = Default + ".RecurringJobs";
|
||||||
public const string Jobs = Default + ".Jobs";
|
public const string Jobs = Default + ".Jobs";
|
||||||
}
|
}
|
||||||
|
public const string Licence = Prefix.App + ".Licence";
|
||||||
|
public const string LicenceItem = Prefix.App + ".LicenceItem";
|
||||||
|
|
||||||
//Web Site
|
//Web Site
|
||||||
public const string Home = Prefix.App + ".Home";
|
public const string Home = Prefix.App + ".Home";
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ using Volo.Abp.MultiTenancy;
|
||||||
|
|
||||||
namespace Sozsoft.Platform.Entities
|
namespace Sozsoft.Platform.Entities
|
||||||
{
|
{
|
||||||
public class ReportCategory : FullAuditedEntity<string>, IMultiTenant
|
public class ReportCategory : FullAuditedEntity<Guid>, IMultiTenant
|
||||||
{
|
{
|
||||||
public Guid? TenantId { get; set; }
|
public Guid? TenantId { get; set; }
|
||||||
|
|
||||||
|
|
@ -15,9 +15,12 @@ namespace Sozsoft.Platform.Entities
|
||||||
|
|
||||||
public ICollection<ReportTemplate> ReportTemplates { get; set; }
|
public ICollection<ReportTemplate> ReportTemplates { get; set; }
|
||||||
|
|
||||||
public ReportCategory(string id)
|
protected ReportCategory()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReportCategory(Guid id) : base(id)
|
||||||
{
|
{
|
||||||
Id = id;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ namespace Sozsoft.Platform.Entities
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
public string HtmlContent { get; set; }
|
public string HtmlContent { get; set; }
|
||||||
|
|
||||||
public string CategoryId { get; set; }
|
public Guid CategoryId { get; set; }
|
||||||
public ReportCategory ReportCategory { get; set; }
|
public ReportCategory ReportCategory { get; set; }
|
||||||
|
|
||||||
public string Status { get; set; }
|
public string Status { get; set; }
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Sozsoft.Platform.Entities
|
||||||
string name,
|
string name,
|
||||||
string description,
|
string description,
|
||||||
string htmlContent,
|
string htmlContent,
|
||||||
string categoryId,
|
Guid categoryId,
|
||||||
string status
|
string status
|
||||||
) : base(id)
|
) : base(id)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ public class ListForm : Entity<Guid>
|
||||||
public string TreeOptionJson { get; set; } // Tree yapisi ile ilgili ayarlar
|
public string TreeOptionJson { get; set; } // Tree yapisi ile ilgili ayarlar
|
||||||
public string GanttOptionJson { get; set; } // Gantt yapisi ile ilgili ayarlar
|
public string GanttOptionJson { get; set; } // Gantt yapisi ile ilgili ayarlar
|
||||||
public string SchedulerOptionJson { get; set; } // Scheduler yapisi ile ilgili ayarlar
|
public string SchedulerOptionJson { get; set; } // Scheduler yapisi ile ilgili ayarlar
|
||||||
|
public string TodoOptionJson { get; set; } // Todo board alan esleme ayarlari
|
||||||
public string FilterRowJson { get; set; } // Filtre ayarlari, Json olarak tutulur, donus sinifi FilterRowDto
|
public string FilterRowJson { get; set; } // Filtre ayarlari, Json olarak tutulur, donus sinifi FilterRowDto
|
||||||
public string RowJson { get; set; } // Row ayarları, Json olarak tutulur, donus sinifi FilterRowDto
|
public string RowJson { get; set; } // Row ayarları, Json olarak tutulur, donus sinifi FilterRowDto
|
||||||
public string HeaderFilterJson { get; set; } // Header filtreleme ayarlari, Json olarak tutulur
|
public string HeaderFilterJson { get; set; } // Header filtreleme ayarlari, Json olarak tutulur
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,12 @@ public class ListFormField : Entity<Guid>
|
||||||
|
|
||||||
public string Alignment { get; set; } = "left"; // Sütunun Sağa, sola veya ortalama gösterimi
|
public string Alignment { get; set; } = "left"; // Sütunun Sağa, sola veya ortalama gösterimi
|
||||||
public string Format { get; set; } // Cell bazında sütunun formatlanması
|
public string Format { get; set; } // Cell bazında sütunun formatlanması
|
||||||
|
|
||||||
|
public int? EditOrderNo { get; set; }
|
||||||
|
public int? EditGroupOrderNo { get; set; }
|
||||||
|
public string EditorType2 { get; set; }
|
||||||
|
public int? ColSpan { get; set; }
|
||||||
|
public string EditorScript { get; set; } //Sütunun ekstra javascript ile yönetilmesi
|
||||||
public string EditorOptions { get; set; } //Sütunun ekstra özellikleri yönetilmesi
|
public string EditorOptions { get; set; } //Sütunun ekstra özellikleri yönetilmesi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using Volo.Abp.Domain.Values;
|
|
||||||
|
|
||||||
namespace Sozsoft.Platform.Queries;
|
|
||||||
|
|
||||||
// public class EditingForm : ValueObject
|
|
||||||
// {
|
|
||||||
// public int Order { get; set; }
|
|
||||||
// public string ItemType { get; set; }
|
|
||||||
// public string Caption { get; set; }
|
|
||||||
// public int ColCount { get; set; }
|
|
||||||
// public int ColSpan { get; set; }
|
|
||||||
// /// <summary> Type: Array<Simple Form Item | Group Form Item | Tabbed Form Item | Empty Form Item | Button Form Item>
|
|
||||||
// /// Bu kisma suan sadece string olarak doldurulacak
|
|
||||||
// /// items: ['FirstName', 'LastName',
|
|
||||||
// /// { dataField: 'Notes', editorType: 'dxTextArea', colSpan: 2, editorOptions: { height: 100, }, }
|
|
||||||
// /// ],
|
|
||||||
// /// </summary>
|
|
||||||
// //[TextArea]
|
|
||||||
// //public string[] Items { get; set; }
|
|
||||||
// public EditingFormItem[] Items { get; set; }
|
|
||||||
|
|
||||||
// protected override IEnumerable<object> GetAtomicValues()
|
|
||||||
// {
|
|
||||||
// yield return ItemType;
|
|
||||||
// yield return Caption;
|
|
||||||
// yield return ColCount;
|
|
||||||
// yield return ColSpan;
|
|
||||||
// yield return Items;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public class EditingFormItem : ValueObject
|
|
||||||
// {
|
|
||||||
// [JsonPropertyName("order")]
|
|
||||||
// public int Order { get; set; }
|
|
||||||
// [JsonPropertyName("dataField")]
|
|
||||||
// public string DataField { get; set; }
|
|
||||||
// [JsonPropertyName("editorType2")]
|
|
||||||
// public string EditorType2 { get; set; }
|
|
||||||
// [JsonPropertyName("colSpan")]
|
|
||||||
// public int ColSpan { get; set; }
|
|
||||||
// [JsonPropertyName("editorOptions")]
|
|
||||||
// public string EditorOptions { get; set; }
|
|
||||||
// [JsonPropertyName("isRequired")]
|
|
||||||
// public bool IsRequired { get; set; }
|
|
||||||
|
|
||||||
// protected override IEnumerable<object> GetAtomicValues()
|
|
||||||
// {
|
|
||||||
// yield return DataField;
|
|
||||||
// yield return EditorType2;
|
|
||||||
// yield return ColSpan;
|
|
||||||
// yield return EditorOptions;
|
|
||||||
// yield return IsRequired;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
@ -52,7 +52,9 @@ public class QueryHelper
|
||||||
case DbType.String:
|
case DbType.String:
|
||||||
case DbType.AnsiString:
|
case DbType.AnsiString:
|
||||||
var strValues = values.Select(a => a?.ToString()).ToArray();
|
var strValues = values.Select(a => a?.ToString()).ToArray();
|
||||||
value = string.Join(PlatformConsts.MultiValueDelimiter, strValues);
|
value = isArray
|
||||||
|
? string.Join(PlatformConsts.MultiValueDelimiter, strValues)
|
||||||
|
: strValues[0];
|
||||||
break;
|
break;
|
||||||
case DbType.Date:
|
case DbType.Date:
|
||||||
case DbType.DateTime:
|
case DbType.DateTime:
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,8 @@ 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 = NormalizeCollectionParameterCommand(command, parameters, dataSourceType);
|
// sql = NormalizeCollectionParameterCommand(command, parameters, dataSourceType);
|
||||||
|
sql = command;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -188,12 +189,6 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
}
|
}
|
||||||
else if (op == OperationEnum.Update)
|
else if (op == OperationEnum.Update)
|
||||||
{
|
{
|
||||||
var where = dataSourceType switch
|
|
||||||
{
|
|
||||||
DataSourceTypeEnum.Mssql => $"\"{listForm.KeyFieldName}\" IN @{listForm.KeyFieldName}",
|
|
||||||
DataSourceTypeEnum.Postgresql => $"\"{listForm.KeyFieldName}\" = ANY(@{listForm.KeyFieldName})",
|
|
||||||
_ => string.Empty,
|
|
||||||
};
|
|
||||||
var updateFields = parameters.Select(a => $"\"{a.Key}\" = @{a.Key}").ToList();
|
var updateFields = parameters.Select(a => $"\"{a.Key}\" = @{a.Key}").ToList();
|
||||||
var val = QueryHelper.GetFormattedValue(listForm.KeyFieldDbSourceType, keys);
|
var val = QueryHelper.GetFormattedValue(listForm.KeyFieldDbSourceType, keys);
|
||||||
if (!parameters.ContainsKey(listForm.KeyFieldName))
|
if (!parameters.ContainsKey(listForm.KeyFieldName))
|
||||||
|
|
@ -202,6 +197,18 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
listForm.KeyFieldName,
|
listForm.KeyFieldName,
|
||||||
val.GetType().IsArray ? val : new object[] { val });
|
val.GetType().IsArray ? val : new object[] { val });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var where = BuildWhereCondition(
|
||||||
|
listForm.KeyFieldName,
|
||||||
|
parameters[listForm.KeyFieldName],
|
||||||
|
dataSourceType);
|
||||||
|
|
||||||
|
if (parameters.TryGetValue("TenantId", out var tenantId)
|
||||||
|
&& !string.Equals(listForm.KeyFieldName, "TenantId", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
where += $" AND {BuildWhereCondition("TenantId", tenantId, dataSourceType)}";
|
||||||
|
}
|
||||||
|
|
||||||
sql = $"UPDATE \"{listForm.SelectCommand}\" SET {string.Join(',', updateFields)} WHERE {where}";
|
sql = $"UPDATE \"{listForm.SelectCommand}\" SET {string.Join(',', updateFields)} WHERE {where}";
|
||||||
}
|
}
|
||||||
else if (op == OperationEnum.Delete)
|
else if (op == OperationEnum.Delete)
|
||||||
|
|
@ -212,12 +219,7 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
{
|
{
|
||||||
where = string.Join(
|
where = string.Join(
|
||||||
" AND ",
|
" AND ",
|
||||||
parameters.Select(a => dataSourceType switch
|
parameters.Select(a => BuildWhereCondition(a.Key, a.Value, dataSourceType)).ToList());
|
||||||
{
|
|
||||||
DataSourceTypeEnum.Mssql => $"\"{a.Key}\" IN @{a.Key}",
|
|
||||||
DataSourceTypeEnum.Postgresql => $"\"{a.Key}\" = ANY(@{a.Key})",
|
|
||||||
_ => "1 = 0",
|
|
||||||
}).ToList());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -240,77 +242,101 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string NormalizeCollectionParameterCommand(
|
private static bool IsCollectionValue(object value)
|
||||||
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
|
return value is System.Collections.IEnumerable
|
||||||
&& value is not string
|
&& value is not string
|
||||||
&& value is not byte[];
|
&& value is not byte[];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string NormalizeMssqlCollectionParameter(
|
private static string BuildWhereCondition(
|
||||||
string sql,
|
string fieldName,
|
||||||
string escapedParameterName,
|
object value,
|
||||||
string parameterName)
|
DataSourceTypeEnum dataSourceType)
|
||||||
{
|
{
|
||||||
sql = Regex.Replace(
|
return dataSourceType switch
|
||||||
sql,
|
{
|
||||||
$@"IN\s*\(\s*@{escapedParameterName}\s*\)",
|
DataSourceTypeEnum.Mssql when value is null or DBNull => $"\"{fieldName}\" IS NULL",
|
||||||
$"IN @{parameterName}",
|
DataSourceTypeEnum.Postgresql when value is null or DBNull => $"\"{fieldName}\" IS NULL",
|
||||||
RegexOptions.IgnoreCase);
|
DataSourceTypeEnum.Mssql when IsCollectionValue(value) => $"\"{fieldName}\" IN @{fieldName}",
|
||||||
|
DataSourceTypeEnum.Postgresql when IsCollectionValue(value) => $"\"{fieldName}\" = ANY(@{fieldName})",
|
||||||
return Regex.Replace(
|
DataSourceTypeEnum.Mssql => $"\"{fieldName}\" = @{fieldName}",
|
||||||
sql,
|
DataSourceTypeEnum.Postgresql => $"\"{fieldName}\" = @{fieldName}",
|
||||||
$@"(?<column>(""[^""]+""|\[[^\]]+\]|`[^`]+`|\w+))\s*=\s*@{escapedParameterName}\b",
|
_ => "1 = 0",
|
||||||
match => $"{match.Groups["column"].Value} IN @{parameterName}",
|
};
|
||||||
RegexOptions.IgnoreCase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string NormalizePostgresqlCollectionParameter(
|
// private static string NormalizeCollectionParameterCommand(
|
||||||
string sql,
|
// string command,
|
||||||
string escapedParameterName,
|
// Dictionary<string, object> parameters,
|
||||||
string parameterName)
|
// DataSourceTypeEnum dataSourceType)
|
||||||
{
|
// {
|
||||||
sql = Regex.Replace(
|
// if (string.IsNullOrWhiteSpace(command) || parameters == null || parameters.Count == 0)
|
||||||
sql,
|
// {
|
||||||
$@"IN\s*\(\s*@{escapedParameterName}\s*\)",
|
// return command;
|
||||||
$"= ANY(@{parameterName})",
|
// }
|
||||||
RegexOptions.IgnoreCase);
|
|
||||||
|
|
||||||
return Regex.Replace(
|
// var sql = command;
|
||||||
sql,
|
// foreach (var parameter in parameters)
|
||||||
$@"(?<column>(""[^""]+""|\[[^\]]+\]|`[^`]+`|\w+))\s*=\s*@{escapedParameterName}\b",
|
// {
|
||||||
match => $"{match.Groups["column"].Value} = ANY(@{parameterName})",
|
// if (!IsCollectionParameter(parameter.Value))
|
||||||
RegexOptions.IgnoreCase);
|
// {
|
||||||
}
|
// 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);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -469,7 +469,7 @@ public class SelectQueryManager : PlatformDomainService, ISelectQueryManager
|
||||||
if (listform.WorkflowJson.IsNullOrWhiteSpace() == false)
|
if (listform.WorkflowJson.IsNullOrWhiteSpace() == false)
|
||||||
{
|
{
|
||||||
var workflow = JsonSerializer.Deserialize<Workflow>(listform.WorkflowJson);
|
var workflow = JsonSerializer.Deserialize<Workflow>(listform.WorkflowJson);
|
||||||
if (workflow != null && workflow.IsFilterUserName)
|
if (workflow != null && workflow.ApprovalIsFilterUserName)
|
||||||
{
|
{
|
||||||
if (whereParts.Any())
|
if (whereParts.Any())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,18 @@ namespace Sozsoft.Platform.Queries;
|
||||||
public class Workflow : ValueObject
|
public class Workflow : ValueObject
|
||||||
{
|
{
|
||||||
public string ApprovalUserFieldName { get; set; }
|
public string ApprovalUserFieldName { get; set; }
|
||||||
public bool IsFilterUserName { get; set; }
|
|
||||||
public string ApprovalDateFieldName { get; set; }
|
public string ApprovalDateFieldName { get; set; }
|
||||||
public string ApprovalStatusFieldName { get; set; }
|
public string ApprovalStatusFieldName { get; set; }
|
||||||
public string ApprovalDescriptionFieldName { get; set; }
|
public string ApprovalDescriptionFieldName { get; set; }
|
||||||
|
public bool ApprovalIsFilterUserName { get; set; }
|
||||||
|
|
||||||
protected override IEnumerable<object> GetAtomicValues()
|
protected override IEnumerable<object> GetAtomicValues()
|
||||||
{
|
{
|
||||||
yield return ApprovalUserFieldName;
|
yield return ApprovalUserFieldName;
|
||||||
yield return IsFilterUserName;
|
|
||||||
yield return ApprovalDateFieldName;
|
yield return ApprovalDateFieldName;
|
||||||
yield return ApprovalStatusFieldName;
|
yield return ApprovalStatusFieldName;
|
||||||
yield return ApprovalDescriptionFieldName;
|
yield return ApprovalDescriptionFieldName;
|
||||||
|
yield return ApprovalIsFilterUserName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -378,6 +378,7 @@ public class PlatformDbContext :
|
||||||
b.Property(a => a.WorkflowJson).HasColumnType("text");
|
b.Property(a => a.WorkflowJson).HasColumnType("text");
|
||||||
b.Property(a => a.ExtraFilterJson).HasColumnType("text");
|
b.Property(a => a.ExtraFilterJson).HasColumnType("text");
|
||||||
b.Property(a => a.LayoutJson).HasColumnType("text");
|
b.Property(a => a.LayoutJson).HasColumnType("text");
|
||||||
|
b.Property(a => a.TodoOptionJson).HasColumnType("text");
|
||||||
b.Property(a => a.CommonJson).HasColumnType("text");
|
b.Property(a => a.CommonJson).HasColumnType("text");
|
||||||
b.Property(a => a.DataSourceJson).HasColumnType("text");
|
b.Property(a => a.DataSourceJson).HasColumnType("text");
|
||||||
b.Property(a => a.AdaptiveLayoutJson).HasColumnType("text");
|
b.Property(a => a.AdaptiveLayoutJson).HasColumnType("text");
|
||||||
|
|
@ -454,6 +455,8 @@ public class PlatformDbContext :
|
||||||
b.Property(a => a.Alignment).HasMaxLength(20).HasDefaultValue("left");
|
b.Property(a => a.Alignment).HasMaxLength(20).HasDefaultValue("left");
|
||||||
b.Property(a => a.Format).HasMaxLength(128);
|
b.Property(a => a.Format).HasMaxLength(128);
|
||||||
b.Property(a => a.EditorOptions).HasColumnType("text");
|
b.Property(a => a.EditorOptions).HasColumnType("text");
|
||||||
|
b.Property(a => a.EditorType2).HasMaxLength(64);
|
||||||
|
b.Property(a => a.EditorScript).HasColumnType("text");
|
||||||
|
|
||||||
b.HasIndex(x => new { x.ListFormCode, x.UserId, x.RoleId, x.CultureName, x.FieldName }).IsUnique().HasFilter(null);
|
b.HasIndex(x => new { x.ListFormCode, x.UserId, x.RoleId, x.CultureName, x.FieldName }).IsUnique().HasFilter(null);
|
||||||
});
|
});
|
||||||
|
|
@ -660,7 +663,6 @@ public class PlatformDbContext :
|
||||||
b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.ReportCategory)), Prefix.DbSchema);
|
b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.ReportCategory)), Prefix.DbSchema);
|
||||||
b.ConfigureByConvention();
|
b.ConfigureByConvention();
|
||||||
|
|
||||||
b.Property(x => x.Id).HasMaxLength(256);
|
|
||||||
b.Property(x => x.Name).IsRequired().HasMaxLength(256);
|
b.Property(x => x.Name).IsRequired().HasMaxLength(256);
|
||||||
b.Property(x => x.Description).HasMaxLength(4096); // JSON string
|
b.Property(x => x.Description).HasMaxLength(4096); // JSON string
|
||||||
b.Property(x => x.Icon).HasMaxLength(64);
|
b.Property(x => x.Icon).HasMaxLength(64);
|
||||||
|
|
@ -674,7 +676,6 @@ public class PlatformDbContext :
|
||||||
b.ConfigureByConvention();
|
b.ConfigureByConvention();
|
||||||
|
|
||||||
b.Property(x => x.Name).IsRequired().HasMaxLength(256);
|
b.Property(x => x.Name).IsRequired().HasMaxLength(256);
|
||||||
b.Property(x => x.CategoryId).HasMaxLength(256);
|
|
||||||
b.Property(x => x.Description).HasMaxLength(1024);
|
b.Property(x => x.Description).HasMaxLength(1024);
|
||||||
b.Property(x => x.HtmlContent).IsRequired();
|
b.Property(x => x.HtmlContent).IsRequired();
|
||||||
b.Property(x => x.Status).HasMaxLength(20);
|
b.Property(x => x.Status).HasMaxLength(20);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
|
||||||
namespace Sozsoft.Platform.Migrations
|
namespace Sozsoft.Platform.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(PlatformDbContext))]
|
[DbContext(typeof(PlatformDbContext))]
|
||||||
[Migration("20260713103339_Initial")]
|
[Migration("20260717065637_Initial")]
|
||||||
partial class Initial
|
partial class Initial
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -3264,6 +3264,9 @@ namespace Sozsoft.Platform.Migrations
|
||||||
b.Property<string>("TitleJson")
|
b.Property<string>("TitleJson")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("TodoOptionJson")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<string>("TooltipJson")
|
b.Property<string>("TooltipJson")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
|
@ -3412,6 +3415,9 @@ namespace Sozsoft.Platform.Migrations
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.Property<int?>("ColSpan")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("ColumnCssClass")
|
b.Property<string>("ColumnCssClass")
|
||||||
.HasMaxLength(128)
|
.HasMaxLength(128)
|
||||||
.HasColumnType("nvarchar(128)");
|
.HasColumnType("nvarchar(128)");
|
||||||
|
|
@ -3437,9 +3443,22 @@ namespace Sozsoft.Platform.Migrations
|
||||||
.HasMaxLength(10)
|
.HasMaxLength(10)
|
||||||
.HasColumnType("nvarchar(10)");
|
.HasColumnType("nvarchar(10)");
|
||||||
|
|
||||||
|
b.Property<int?>("EditGroupOrderNo")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int?>("EditOrderNo")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("EditorOptions")
|
b.Property<string>("EditorOptions")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("EditorScript")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("EditorType2")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("nvarchar(64)");
|
||||||
|
|
||||||
b.Property<string>("FieldName")
|
b.Property<string>("FieldName")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(128)
|
.HasMaxLength(128)
|
||||||
|
|
@ -4482,9 +4501,8 @@ namespace Sozsoft.Platform.Migrations
|
||||||
|
|
||||||
modelBuilder.Entity("Sozsoft.Platform.Entities.ReportCategory", b =>
|
modelBuilder.Entity("Sozsoft.Platform.Entities.ReportCategory", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("Id")
|
b.Property<Guid>("Id")
|
||||||
.HasMaxLength(256)
|
.HasColumnType("uniqueidentifier");
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreationTime")
|
b.Property<DateTime>("CreationTime")
|
||||||
.HasColumnType("datetime2")
|
.HasColumnType("datetime2")
|
||||||
|
|
@ -4547,9 +4565,8 @@ namespace Sozsoft.Platform.Migrations
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
b.Property<string>("CategoryId")
|
b.Property<Guid>("CategoryId")
|
||||||
.HasMaxLength(256)
|
.HasColumnType("uniqueidentifier");
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreationTime")
|
b.Property<DateTime>("CreationTime")
|
||||||
.HasColumnType("datetime2")
|
.HasColumnType("datetime2")
|
||||||
|
|
@ -8820,7 +8837,8 @@ namespace Sozsoft.Platform.Migrations
|
||||||
b.HasOne("Sozsoft.Platform.Entities.ReportCategory", "ReportCategory")
|
b.HasOne("Sozsoft.Platform.Entities.ReportCategory", "ReportCategory")
|
||||||
.WithMany("ReportTemplates")
|
.WithMany("ReportTemplates")
|
||||||
.HasForeignKey("CategoryId")
|
.HasForeignKey("CategoryId")
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
b.Navigation("ReportCategory");
|
b.Navigation("ReportCategory");
|
||||||
});
|
});
|
||||||
|
|
@ -650,7 +650,7 @@ namespace Sozsoft.Platform.Migrations
|
||||||
name: "Adm_T_ReportCategory",
|
name: "Adm_T_ReportCategory",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
Id = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||||
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
||||||
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
|
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
|
||||||
Description = table.Column<string>(type: "nvarchar(max)", maxLength: 4096, nullable: true),
|
Description = table.Column<string>(type: "nvarchar(max)", maxLength: 4096, nullable: true),
|
||||||
|
|
@ -1392,6 +1392,7 @@ namespace Sozsoft.Platform.Migrations
|
||||||
TreeOptionJson = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
TreeOptionJson = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||||
GanttOptionJson = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
GanttOptionJson = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||||
SchedulerOptionJson = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
SchedulerOptionJson = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||||
|
TodoOptionJson = table.Column<string>(type: "text", nullable: true),
|
||||||
FilterRowJson = table.Column<string>(type: "text", nullable: true),
|
FilterRowJson = table.Column<string>(type: "text", nullable: true),
|
||||||
RowJson = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
RowJson = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||||
HeaderFilterJson = table.Column<string>(type: "text", nullable: true),
|
HeaderFilterJson = table.Column<string>(type: "text", nullable: true),
|
||||||
|
|
@ -2259,7 +2260,7 @@ namespace Sozsoft.Platform.Migrations
|
||||||
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
|
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false),
|
||||||
Description = table.Column<string>(type: "nvarchar(1024)", maxLength: 1024, nullable: true),
|
Description = table.Column<string>(type: "nvarchar(1024)", maxLength: 1024, nullable: true),
|
||||||
HtmlContent = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
HtmlContent = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||||
CategoryId = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
CategoryId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||||
Status = table.Column<string>(type: "nvarchar(20)", maxLength: 20, nullable: true),
|
Status = table.Column<string>(type: "nvarchar(20)", maxLength: 20, nullable: true),
|
||||||
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
|
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||||
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
||||||
|
|
@ -2790,6 +2791,11 @@ namespace Sozsoft.Platform.Migrations
|
||||||
PivotSettingsJson = table.Column<string>(type: "text", nullable: true),
|
PivotSettingsJson = table.Column<string>(type: "text", nullable: true),
|
||||||
Alignment = table.Column<string>(type: "nvarchar(20)", maxLength: 20, nullable: true, defaultValue: "left"),
|
Alignment = table.Column<string>(type: "nvarchar(20)", maxLength: 20, nullable: true, defaultValue: "left"),
|
||||||
Format = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
|
Format = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),
|
||||||
|
EditOrderNo = table.Column<int>(type: "int", nullable: true),
|
||||||
|
EditGroupOrderNo = table.Column<int>(type: "int", nullable: true),
|
||||||
|
EditorType2 = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
|
||||||
|
ColSpan = table.Column<int>(type: "int", nullable: true),
|
||||||
|
EditorScript = table.Column<string>(type: "text", nullable: true),
|
||||||
EditorOptions = table.Column<string>(type: "text", nullable: true)
|
EditorOptions = table.Column<string>(type: "text", nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
|
|
@ -3261,6 +3261,9 @@ namespace Sozsoft.Platform.Migrations
|
||||||
b.Property<string>("TitleJson")
|
b.Property<string>("TitleJson")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("TodoOptionJson")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<string>("TooltipJson")
|
b.Property<string>("TooltipJson")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
|
@ -3409,6 +3412,9 @@ namespace Sozsoft.Platform.Migrations
|
||||||
.HasMaxLength(256)
|
.HasMaxLength(256)
|
||||||
.HasColumnType("nvarchar(256)");
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.Property<int?>("ColSpan")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("ColumnCssClass")
|
b.Property<string>("ColumnCssClass")
|
||||||
.HasMaxLength(128)
|
.HasMaxLength(128)
|
||||||
.HasColumnType("nvarchar(128)");
|
.HasColumnType("nvarchar(128)");
|
||||||
|
|
@ -3434,9 +3440,22 @@ namespace Sozsoft.Platform.Migrations
|
||||||
.HasMaxLength(10)
|
.HasMaxLength(10)
|
||||||
.HasColumnType("nvarchar(10)");
|
.HasColumnType("nvarchar(10)");
|
||||||
|
|
||||||
|
b.Property<int?>("EditGroupOrderNo")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int?>("EditOrderNo")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
b.Property<string>("EditorOptions")
|
b.Property<string>("EditorOptions")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("EditorScript")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("EditorType2")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("nvarchar(64)");
|
||||||
|
|
||||||
b.Property<string>("FieldName")
|
b.Property<string>("FieldName")
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasMaxLength(128)
|
.HasMaxLength(128)
|
||||||
|
|
@ -4479,9 +4498,8 @@ namespace Sozsoft.Platform.Migrations
|
||||||
|
|
||||||
modelBuilder.Entity("Sozsoft.Platform.Entities.ReportCategory", b =>
|
modelBuilder.Entity("Sozsoft.Platform.Entities.ReportCategory", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("Id")
|
b.Property<Guid>("Id")
|
||||||
.HasMaxLength(256)
|
.HasColumnType("uniqueidentifier");
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreationTime")
|
b.Property<DateTime>("CreationTime")
|
||||||
.HasColumnType("datetime2")
|
.HasColumnType("datetime2")
|
||||||
|
|
@ -4544,9 +4562,8 @@ namespace Sozsoft.Platform.Migrations
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
.HasColumnType("uniqueidentifier");
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
b.Property<string>("CategoryId")
|
b.Property<Guid>("CategoryId")
|
||||||
.HasMaxLength(256)
|
.HasColumnType("uniqueidentifier");
|
||||||
.HasColumnType("nvarchar(256)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("CreationTime")
|
b.Property<DateTime>("CreationTime")
|
||||||
.HasColumnType("datetime2")
|
.HasColumnType("datetime2")
|
||||||
|
|
@ -8817,7 +8834,8 @@ namespace Sozsoft.Platform.Migrations
|
||||||
b.HasOne("Sozsoft.Platform.Entities.ReportCategory", "ReportCategory")
|
b.HasOne("Sozsoft.Platform.Entities.ReportCategory", "ReportCategory")
|
||||||
.WithMany("ReportTemplates")
|
.WithMany("ReportTemplates")
|
||||||
.HasForeignKey("CategoryId")
|
.HasForeignKey("CategoryId")
|
||||||
.OnDelete(DeleteBehavior.Restrict);
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
b.Navigation("ReportCategory");
|
b.Navigation("ReportCategory");
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -491,7 +491,7 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
private readonly IRepository<GlobalSearch, int> _globalSearch;
|
private readonly IRepository<GlobalSearch, int> _globalSearch;
|
||||||
private readonly IRepository<CustomEndpoint, Guid> _customEndpointRepository;
|
private readonly IRepository<CustomEndpoint, Guid> _customEndpointRepository;
|
||||||
private readonly IRepository<CustomComponent, Guid> _customComponentRepository;
|
private readonly IRepository<CustomComponent, Guid> _customComponentRepository;
|
||||||
private readonly IRepository<ReportCategory, string> _reportCategoriesRepository;
|
private readonly IRepository<ReportCategory, Guid> _reportCategoriesRepository;
|
||||||
private readonly IRepository<ReportTemplate, Guid> _reportTemplatesRepository;
|
private readonly IRepository<ReportTemplate, Guid> _reportTemplatesRepository;
|
||||||
private readonly IRepository<Home, Guid> _homeRepository;
|
private readonly IRepository<Home, Guid> _homeRepository;
|
||||||
private readonly IRepository<About, Guid> _aboutRepository;
|
private readonly IRepository<About, Guid> _aboutRepository;
|
||||||
|
|
@ -548,7 +548,7 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
IRepository<SkillLevel, string> skillLevelRepository,
|
IRepository<SkillLevel, string> skillLevelRepository,
|
||||||
IRepository<CustomEndpoint, Guid> customEndpointRepository,
|
IRepository<CustomEndpoint, Guid> customEndpointRepository,
|
||||||
IRepository<CustomComponent, Guid> customComponentRepository,
|
IRepository<CustomComponent, Guid> customComponentRepository,
|
||||||
IRepository<ReportCategory, string> reportCategoriesRepository,
|
IRepository<ReportCategory, Guid> reportCategoriesRepository,
|
||||||
IRepository<ReportTemplate, Guid> reportTemplatesRepository,
|
IRepository<ReportTemplate, Guid> reportTemplatesRepository,
|
||||||
IRepository<Home, Guid> homeRepository,
|
IRepository<Home, Guid> homeRepository,
|
||||||
IRepository<About, Guid> aboutRepository,
|
IRepository<About, Guid> aboutRepository,
|
||||||
|
|
@ -867,7 +867,7 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
|
|
||||||
if (!exists)
|
if (!exists)
|
||||||
{
|
{
|
||||||
await _reportCategoriesRepository.InsertAsync(new ReportCategory(item.Name)
|
await _reportCategoriesRepository.InsertAsync(new ReportCategory(Guid.NewGuid())
|
||||||
{
|
{
|
||||||
Name = item.Name,
|
Name = item.Name,
|
||||||
Description = item.Description,
|
Description = item.Description,
|
||||||
|
|
|
||||||
|
|
@ -542,14 +542,16 @@ public class DynamicFormReport : XtraReport
|
||||||
.Where(x => x.IsActive != false)
|
.Where(x => x.IsActive != false)
|
||||||
.ToDictionary(x => x.FieldName, StringComparer.OrdinalIgnoreCase);
|
.ToDictionary(x => x.FieldName, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
var formItems = GetEditingFormItems(listForm)
|
var editFields = fields
|
||||||
.Where(x => !string.IsNullOrWhiteSpace(x.DataField))
|
.Where(x => x.EditOrderNo.HasValue)
|
||||||
|
.OrderBy(x => x.EditGroupOrderNo ?? 1)
|
||||||
|
.ThenBy(x => x.EditOrderNo)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var orderedFields = formItems.Count > 0
|
var orderedFields = editFields.Count > 0
|
||||||
? formItems
|
? editFields
|
||||||
.Where(x => fieldsByName.ContainsKey(x.DataField))
|
.Where(x => fieldsByName.ContainsKey(x.FieldName))
|
||||||
.Select(x => new FieldWithEditor(fieldsByName[x.DataField], x.EditorType2, x.ColSpan))
|
.Select(x => new FieldWithEditor(x, x.EditorType2, x.ColSpan ?? 1))
|
||||||
.ToList()
|
.ToList()
|
||||||
: fields
|
: fields
|
||||||
.Where(x => !string.IsNullOrWhiteSpace(x.FieldName) && x.FieldName != "undefined")
|
.Where(x => !string.IsNullOrWhiteSpace(x.FieldName) && x.FieldName != "undefined")
|
||||||
|
|
@ -582,10 +584,9 @@ public class DynamicFormReport : XtraReport
|
||||||
var usedFields = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
var usedFields = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
foreach (var group in groups)
|
foreach (var group in groups)
|
||||||
{
|
{
|
||||||
var groupFields = (group.Items ?? [])
|
var groupFields = fields
|
||||||
.OrderBy(x => x.Order)
|
.Where(x => (x.Field.EditGroupOrderNo ?? 1) == group.Order)
|
||||||
.Where(x => !string.IsNullOrWhiteSpace(x.DataField) && fieldsByName.ContainsKey(x.DataField))
|
.OrderBy(x => x.Field.EditOrderNo ?? int.MaxValue)
|
||||||
.Select(x => fieldsByName[x.DataField])
|
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
foreach (var field in groupFields)
|
foreach (var field in groupFields)
|
||||||
|
|
@ -625,13 +626,6 @@ public class DynamicFormReport : XtraReport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<EditingFormItemDto> GetEditingFormItems(ListForm listForm)
|
|
||||||
{
|
|
||||||
return GetEditingFormGroups(listForm)
|
|
||||||
.OrderBy(x => x.Order)
|
|
||||||
.SelectMany(x => (x.Items ?? []).OrderBy(i => i.Order));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<(SubFormDto Form, string Filter)> GetListSubForms(
|
private static IEnumerable<(SubFormDto Form, string Filter)> GetListSubForms(
|
||||||
ListForm listForm,
|
ListForm listForm,
|
||||||
IDictionary<string, object> row)
|
IDictionary<string, object> row)
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ public class DynamicGridReport : XtraReport
|
||||||
|
|
||||||
await selectQueryManager.PrepareQueriesAsync(listForm, fields, dataSourceType, customizations, queryParams);
|
await selectQueryManager.PrepareQueriesAsync(listForm, fields, dataSourceType, customizations, queryParams);
|
||||||
var selectFieldsByName = DynamicReportImageHelper.CreateSelectFieldMap(selectQueryManager.SelectFields);
|
var selectFieldsByName = DynamicReportImageHelper.CreateSelectFieldMap(selectQueryManager.SelectFields);
|
||||||
var editorTypesByField = DynamicReportImageHelper.CreateEditorTypeMap(listForm);
|
var editorTypesByField = DynamicReportImageHelper.CreateEditorTypeMap(fields);
|
||||||
|
|
||||||
var availableFields = fields
|
var availableFields = fields
|
||||||
.Where(x => !string.IsNullOrWhiteSpace(x.FieldName) && x.FieldName != "undefined")
|
.Where(x => !string.IsNullOrWhiteSpace(x.FieldName) && x.FieldName != "undefined")
|
||||||
|
|
|
||||||
|
|
@ -73,27 +73,15 @@ internal static class DynamicReportImageHelper
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string, string> CreateEditorTypeMap(ListForm listForm)
|
public static Dictionary<string, string> CreateEditorTypeMap(IEnumerable<ListFormField> fields)
|
||||||
{
|
{
|
||||||
var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
if (string.IsNullOrWhiteSpace(listForm?.EditingFormJson))
|
foreach (var field in fields ?? [])
|
||||||
{
|
{
|
||||||
return map;
|
if (!string.IsNullOrWhiteSpace(field.FieldName) && !string.IsNullOrWhiteSpace(field.EditorType2))
|
||||||
|
{
|
||||||
|
map[field.FieldName] = field.EditorType2;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var groups = JsonSerializer.Deserialize<List<EditingFormDto>>(listForm.EditingFormJson) ?? [];
|
|
||||||
foreach (var item in groups.SelectMany(x => x.Items ?? []))
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(item.DataField))
|
|
||||||
{
|
|
||||||
map[item.DataField] = item.EditorType2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (JsonException)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
|
|
@ -452,26 +440,17 @@ internal static class DynamicReportImageHelper
|
||||||
return editorType is PlatformConsts.EditorTypes.dxImageUpload or PlatformConsts.EditorTypes.dxImageViewer;
|
return editorType is PlatformConsts.EditorTypes.dxImageUpload or PlatformConsts.EditorTypes.dxImageViewer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool HasImageEditor(ListForm listForm, string fieldName)
|
public static bool HasImageEditor(IEnumerable<ListFormField> fields, string fieldName)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(listForm?.EditingFormJson) || string.IsNullOrWhiteSpace(fieldName))
|
if (string.IsNullOrWhiteSpace(fieldName))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
return (fields ?? []).Any(x =>
|
||||||
{
|
string.Equals(x.FieldName, fieldName, StringComparison.OrdinalIgnoreCase) &&
|
||||||
var groups = JsonSerializer.Deserialize<List<EditingFormDto>>(listForm.EditingFormJson) ?? [];
|
|
||||||
return groups
|
|
||||||
.SelectMany(x => x.Items ?? [])
|
|
||||||
.Any(x => string.Equals(x.DataField, fieldName, StringComparison.OrdinalIgnoreCase) &&
|
|
||||||
IsImageEditor(x.EditorType2));
|
IsImageEditor(x.EditorType2));
|
||||||
}
|
}
|
||||||
catch (JsonException)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float GetGridImageHeight() => DefaultGridImageHeight;
|
public static float GetGridImageHeight() => DefaultGridImageHeight;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ public class DynamicTreeReport : XtraReport
|
||||||
|
|
||||||
await selectQueryManager.PrepareQueriesAsync(listForm, fields, dataSourceType, customizations, queryParams);
|
await selectQueryManager.PrepareQueriesAsync(listForm, fields, dataSourceType, customizations, queryParams);
|
||||||
var selectFieldsByName = DynamicReportImageHelper.CreateSelectFieldMap(selectQueryManager.SelectFields);
|
var selectFieldsByName = DynamicReportImageHelper.CreateSelectFieldMap(selectQueryManager.SelectFields);
|
||||||
var editorTypesByField = DynamicReportImageHelper.CreateEditorTypeMap(listForm);
|
var editorTypesByField = DynamicReportImageHelper.CreateEditorTypeMap(fields);
|
||||||
|
|
||||||
var availableFields = fields
|
var availableFields = fields
|
||||||
.Where(x => !string.IsNullOrWhiteSpace(x.FieldName) && x.FieldName != "undefined")
|
.Where(x => !string.IsNullOrWhiteSpace(x.FieldName) && x.FieldName != "undefined")
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,29 @@
|
||||||
{
|
{
|
||||||
"commit": "e7be51a",
|
"commit": "8146adf",
|
||||||
"releases": [
|
"releases": [
|
||||||
|
{
|
||||||
|
"version": "1.1.08",
|
||||||
|
"buildDate": "2026-07-16",
|
||||||
|
"commit": "24e92fcb82eef0ee26ca5d65e08c5404f132a09e",
|
||||||
|
"changeLog": [
|
||||||
|
"- CardView komponenti geliştirildi.",
|
||||||
|
"- Todo / Kanban komponenti geliştirildi.",
|
||||||
|
"- Licence information",
|
||||||
|
"- Check New Versiyon komponenti."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "1.1.07",
|
||||||
|
"buildDate": "2026-07-13",
|
||||||
|
"commit": "50cb3eaf979eb5027172a92a4e941ed64aa3671e",
|
||||||
|
"changeLog": [
|
||||||
|
"- localStorage tüm bilgiler easy-peasy içerisinde birleştirildi.",
|
||||||
|
"- Codex 5.6 sol optimizasyon yapıldı. Bir çok komponent Lazy load ile yüklendi.",
|
||||||
|
"- Workflow komponentinden birden fazla kişi onay verebilir.",
|
||||||
|
"- Posta Kodu eklendi.",
|
||||||
|
"- Sales Order kısmında Yeni ve Eski müşteri sipariş ayrımı yapıldı"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "1.1.06",
|
"version": "1.1.06",
|
||||||
"buildDate": "2026-07-06",
|
"buildDate": "2026-07-06",
|
||||||
|
|
|
||||||
|
|
@ -193,12 +193,8 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
const [foundTenantName, setFoundTenantName] = useState('')
|
const [foundTenantName, setFoundTenantName] = useState('')
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
const { tenantData, tenantFormDraft } = useStoreState(
|
const { tenantData, tenantFormDraft } = useStoreState((state) => state.client.order)
|
||||||
(state) => state.client.order,
|
const { setTenantFormDraft, clearTenant } = useStoreActions((actions) => actions.client.order)
|
||||||
)
|
|
||||||
const { setTenantFormDraft, clearTenant } = useStoreActions(
|
|
||||||
(actions) => actions.client.order,
|
|
||||||
)
|
|
||||||
const hasRestoredTenantData = useRef(false)
|
const hasRestoredTenantData = useRef(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -681,7 +677,9 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<FaPhone className="w-4 h-4 text-gray-500" />
|
<FaPhone className="w-4 h-4 text-gray-500" />
|
||||||
<span className="font-medium">{translate('::Abp.Identity.User.UserInformation.PhoneNumber')}:</span>
|
<span className="font-medium">
|
||||||
|
{translate('::Abp.Identity.User.UserInformation.PhoneNumber')}:
|
||||||
|
</span>
|
||||||
<span>{formData.phoneNumber}</span>
|
<span>{formData.phoneNumber}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -999,41 +997,6 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
|
||||||
{translate('::Public.contact.taxOffice')}
|
|
||||||
</label>
|
|
||||||
<div className="relative">
|
|
||||||
<FaBuilding className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
required
|
|
||||||
placeholder="Sarıgazi"
|
|
||||||
value={formData.taxOffice}
|
|
||||||
onChange={(e) => handleInputChange('taxOffice', e.target.value)}
|
|
||||||
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
|
||||||
{translate('::Public.contact.taxNumber')}
|
|
||||||
</label>
|
|
||||||
<div className="relative">
|
|
||||||
<FaDollarSign className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
required
|
|
||||||
placeholder="1234567890"
|
|
||||||
value={formData.vknTckn}
|
|
||||||
onChange={(e) => handleInputChange('vknTckn', e.target.value)}
|
|
||||||
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||||
|
|
@ -1094,6 +1057,41 @@ export const TenantForm: React.FC<TenantFormProps> = ({ onSubmit }) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||||
|
{translate('::Public.contact.taxOffice')}
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<FaBuilding className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
placeholder="Sarıgazi"
|
||||||
|
value={formData.taxOffice}
|
||||||
|
onChange={(e) => handleInputChange('taxOffice', e.target.value)}
|
||||||
|
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||||
|
{translate('::Public.contact.taxNumber')}
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<FaDollarSign className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-5 h-5" />
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
required
|
||||||
|
placeholder="1234567890"
|
||||||
|
value={formData.vknTckn}
|
||||||
|
onChange={(e) => handleInputChange('vknTckn', e.target.value)}
|
||||||
|
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-500 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import Drawer from '@/components/ui/Drawer'
|
||||||
import SidePanelContent, { SidePanelContentProps } from './SidePanelContent'
|
import SidePanelContent, { SidePanelContentProps } from './SidePanelContent'
|
||||||
import CopyButton from '../ThemeConfigurator/CopyButton'
|
import CopyButton from '../ThemeConfigurator/CopyButton'
|
||||||
import withHeaderItem from '@/utils/hoc/withHeaderItem'
|
import withHeaderItem from '@/utils/hoc/withHeaderItem'
|
||||||
import { useStoreState, useStoreActions } from '@/store'
|
import { useStoreActions, useStoreState } from '@/store'
|
||||||
import type { CommonProps } from '@/proxy/common'
|
import type { CommonProps } from '@/proxy/common'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { FcEngineering } from 'react-icons/fc'
|
import { FcEngineering } from 'react-icons/fc'
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,7 @@ import {
|
||||||
import { useStoreState } from '@/store'
|
import { useStoreState } from '@/store'
|
||||||
import useMenuActive from '@/utils/hooks/useMenuActive'
|
import useMenuActive from '@/utils/hooks/useMenuActive'
|
||||||
import isEmpty from 'lodash/isEmpty'
|
import isEmpty from 'lodash/isEmpty'
|
||||||
import React from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import { useEffect } from 'react'
|
|
||||||
import { FaQuestionCircle } from 'react-icons/fa'
|
import { FaQuestionCircle } from 'react-icons/fa'
|
||||||
import { Link, useLocation } from 'react-router-dom'
|
import { Link, useLocation } from 'react-router-dom'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,22 +6,31 @@ import withHeaderItem from '@/utils/hoc/withHeaderItem'
|
||||||
import useAuth from '@/utils/hooks/useAuth'
|
import useAuth from '@/utils/hooks/useAuth'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
import type { ReactElement } from 'react'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import { Avatar } from '../ui'
|
import { Avatar } from '../ui'
|
||||||
import { FcEngineering, FcNext, FcNfcSign, FcVoicePresentation } from 'react-icons/fc'
|
import {
|
||||||
|
FcEngineering,
|
||||||
|
FcNext,
|
||||||
|
FcNfcSign,
|
||||||
|
FcSynchronize,
|
||||||
|
FcVoicePresentation,
|
||||||
|
} from 'react-icons/fc'
|
||||||
|
import { useManualUpdateCheck } from '@/views/version/ChangeLog'
|
||||||
|
|
||||||
type DropdownList = {
|
type DropdownList = {
|
||||||
label: string
|
label: string
|
||||||
path: string
|
path: string
|
||||||
icon: JSX.Element
|
icon: ReactElement
|
||||||
}
|
}
|
||||||
|
|
||||||
const _UserDropdown = ({ className }: CommonProps) => {
|
const UserDropdownBase = ({ className }: CommonProps) => {
|
||||||
const { setPanelExpand } = useStoreActions((actions) => actions.theme)
|
const { setPanelExpand } = useStoreActions((actions) => actions.theme)
|
||||||
const { userName, name, email, avatar } = useStoreState((state) => state.auth.user)
|
const { userName, name, email, avatar } = useStoreState((state) => state.auth.user)
|
||||||
const tenant = useStoreState((state) => state.abpConfig.config?.currentTenant)
|
const tenant = useStoreState((state) => state.abpConfig.config?.currentTenant)
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
const { signOut } = useAuth()
|
const { signOut } = useAuth()
|
||||||
|
const { isCheckingUpdate, checkForUpdate } = useManualUpdateCheck()
|
||||||
const displayName = name || userName
|
const displayName = name || userName
|
||||||
const tenantName = tenant?.name
|
const tenantName = tenant?.name
|
||||||
|
|
||||||
|
|
@ -113,6 +122,23 @@ const _UserDropdown = ({ className }: CommonProps) => {
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
<Dropdown.Item
|
||||||
|
eventKey="Check New Version"
|
||||||
|
className="mb-1 px-0"
|
||||||
|
onClick={checkForUpdate}
|
||||||
|
>
|
||||||
|
<span className="flex h-full w-full items-center gap-2 px-2">
|
||||||
|
<span className={classNames('text-xl opacity-50', isCheckingUpdate && 'animate-spin')}>
|
||||||
|
<FcSynchronize />
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
{isCheckingUpdate
|
||||||
|
? translate('::App.CheckUpdate')
|
||||||
|
: translate('::App.CheckForUpdates')}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</Dropdown.Item>
|
||||||
|
|
||||||
{/* <Dropdown.Item variant="divider" /> */}
|
{/* <Dropdown.Item variant="divider" /> */}
|
||||||
<Dropdown.Item eventKey="Sign Out" className="mb-1 px-2" onClick={signOut}>
|
<Dropdown.Item eventKey="Sign Out" className="mb-1 px-2" onClick={signOut}>
|
||||||
<span className="text-xl opacity-50">
|
<span className="text-xl opacity-50">
|
||||||
|
|
@ -124,6 +150,6 @@ const _UserDropdown = ({ className }: CommonProps) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const UserDropdown = withHeaderItem(_UserDropdown)
|
const UserDropdown = withHeaderItem(UserDropdownBase)
|
||||||
|
|
||||||
export default UserDropdown
|
export default UserDropdown
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import {
|
import React, {
|
||||||
Children,
|
Children,
|
||||||
cloneElement,
|
cloneElement,
|
||||||
forwardRef,
|
forwardRef,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { createContext } from 'react'
|
import React, { createContext } from 'react'
|
||||||
|
|
||||||
export type CheckboxValue = string | number
|
export type CheckboxValue = string | number
|
||||||
export type CheckboxGroupValue = CheckboxValue[]
|
export type CheckboxGroupValue = CheckboxValue[]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import {
|
import React, {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useState,
|
useState,
|
||||||
useRef,
|
useRef,
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import type { CommonProps } from '../../@types/common'
|
||||||
import type { MonthBaseProps } from './components/Month'
|
import type { MonthBaseProps } from './components/Month'
|
||||||
import type { DayKeydownPayload } from './components/types'
|
import type { DayKeydownPayload } from './components/types'
|
||||||
import type { RefObject } from 'react'
|
import type { RefObject } from 'react'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
export interface DateTableProps extends CommonProps, MonthBaseProps {
|
export interface DateTableProps extends CommonProps, MonthBaseProps {
|
||||||
dateViewCount: number
|
dateViewCount: number
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import {
|
import React, {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useState,
|
useState,
|
||||||
useRef,
|
useRef,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import {
|
import React, {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useState, useEffect, useCallback, useMemo } from 'react'
|
import React, { useState, useEffect, useCallback, useMemo } from 'react'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import { FaChevronCircleLeft, FaEllipsisH, FaChevronCircleRight } from 'react-icons/fa';
|
import { FaChevronCircleLeft, FaEllipsisH, FaChevronCircleRight } from 'react-icons/fa';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import {
|
import React, {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useState,
|
useState,
|
||||||
useCallback,
|
useCallback,
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { FaCheckCircle, FaInfoCircle, FaExclamation, FaTimesCircle } from 'react-icons/fa';
|
import { FaCheckCircle, FaInfoCircle, FaExclamation, FaTimesCircle } from 'react-icons/fa';
|
||||||
import type { TypeAttributes, CommonProps } from '../@types/common'
|
import type { TypeAttributes, CommonProps } from '../@types/common'
|
||||||
import type { ReactNode } from 'react'
|
import type { ReactElement, ReactNode } from 'react'
|
||||||
|
|
||||||
export interface StatusIconProps extends CommonProps {
|
export interface StatusIconProps extends CommonProps {
|
||||||
type: TypeAttributes.Status
|
type: TypeAttributes.Status
|
||||||
custom?: ReactNode | JSX.Element
|
custom?: ReactNode | ReactElement
|
||||||
iconColor?: string
|
iconColor?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -12,7 +12,7 @@ const ICONS: Record<
|
||||||
TypeAttributes.Status,
|
TypeAttributes.Status,
|
||||||
{
|
{
|
||||||
color: string
|
color: string
|
||||||
icon: JSX.Element
|
icon: ReactElement
|
||||||
}
|
}
|
||||||
> = {
|
> = {
|
||||||
success: {
|
success: {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useState, useCallback, useRef, useEffect } from 'react'
|
import React, { useState, useCallback, useRef, useEffect } from 'react'
|
||||||
import useCallbackRef from './useCallbackRef'
|
import useCallbackRef from './useCallbackRef'
|
||||||
|
|
||||||
type UseControllableStateParams<T> = {
|
type UseControllableStateParams<T> = {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,22 @@ body {
|
||||||
font-size: 14px; /* body’ye font-size uygulanmaz */
|
font-size: 14px; /* body’ye font-size uygulanmaz */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-card-view.dx-cardview {
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-card-view .dx-cardview-card,
|
||||||
|
.list-card-view .dx-cardview-card-header .dx-toolbar,
|
||||||
|
.list-card-view .dx-cardview-card-footer {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-card-view .dx-toolbar .dx-button-text {
|
||||||
|
text-transform: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.dx-form-group-with-caption > .dx-form-group-content {
|
.dx-form-group-with-caption > .dx-form-group-content {
|
||||||
padding-top: 2px !important;
|
padding-top: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,4 +33,5 @@ export interface ListFormJsonRowDto {
|
||||||
export interface ListState {
|
export interface ListState {
|
||||||
listFormCode: string
|
listFormCode: string
|
||||||
layout: ListViewLayoutType
|
layout: ListViewLayoutType
|
||||||
|
cardColumnCount?: number
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ export const ListFormEditTabs = {
|
||||||
TreeForm: 'tree',
|
TreeForm: 'tree',
|
||||||
GanttForm: 'gantt',
|
GanttForm: 'gantt',
|
||||||
SchedulerForm: 'scheduler',
|
SchedulerForm: 'scheduler',
|
||||||
|
TodoForm: 'todo',
|
||||||
PagerForm: 'pager',
|
PagerForm: 'pager',
|
||||||
StateForm: 'state',
|
StateForm: 'state',
|
||||||
SubForm: 'subForm',
|
SubForm: 'subForm',
|
||||||
|
|
@ -93,6 +94,7 @@ export const tabVisibilityConfig: Record<string, string[]> = {
|
||||||
'tree',
|
'tree',
|
||||||
'gantt',
|
'gantt',
|
||||||
'scheduler',
|
'scheduler',
|
||||||
|
'todo',
|
||||||
'pager',
|
'pager',
|
||||||
'state',
|
'state',
|
||||||
'extrafilter',
|
'extrafilter',
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
import { SelectCommandTypeEnum } from '@/proxy/form/models'
|
|
||||||
import {
|
import {
|
||||||
ListFormWorkflowCriteriaDto,
|
ListFormWorkflowCriteriaDto,
|
||||||
SubFormDto,
|
SubFormDto,
|
||||||
WidgetEditDto,
|
WidgetEditDto,
|
||||||
WorkflowDto,
|
SelectCommandTypeEnum,
|
||||||
} from '@/proxy/form/models'
|
} from '@/proxy/form/models'
|
||||||
import { ListViewLayoutType } from '@/views/admin/listForm/edit/types'
|
import { ListViewLayoutType } from '@/views/admin/listForm/edit/types'
|
||||||
|
|
||||||
export interface ListFormWizardColumnItemDto {
|
export interface ListFormWizardColumnItemDto {
|
||||||
dataField: string
|
fieldName: string
|
||||||
editorType: string
|
editorType: string
|
||||||
editorOptions: string
|
editorOptions: string
|
||||||
editorScript: string
|
editorScript: string
|
||||||
|
|
@ -39,11 +38,13 @@ export interface ListFormWizardDto {
|
||||||
|
|
||||||
defaultLayout: ListViewLayoutType
|
defaultLayout: ListViewLayoutType
|
||||||
grid: boolean
|
grid: boolean
|
||||||
|
card: boolean
|
||||||
pivot: boolean
|
pivot: boolean
|
||||||
tree: boolean
|
tree: boolean
|
||||||
chart: boolean
|
chart: boolean
|
||||||
gantt: boolean
|
gantt: boolean
|
||||||
scheduler: boolean
|
scheduler: boolean
|
||||||
|
todo: boolean
|
||||||
|
|
||||||
languageTextMenuEn: string
|
languageTextMenuEn: string
|
||||||
languageTextMenuTr: string
|
languageTextMenuTr: string
|
||||||
|
|
@ -55,6 +56,7 @@ export interface ListFormWizardDto {
|
||||||
languageTextMenuParentTr: string
|
languageTextMenuParentTr: string
|
||||||
permissionGroupName: string
|
permissionGroupName: string
|
||||||
menuParentCode: string
|
menuParentCode: string
|
||||||
|
menuParentShortName?: string
|
||||||
menuParentIcon?: string
|
menuParentIcon?: string
|
||||||
menuIcon: string
|
menuIcon: string
|
||||||
dataSourceCode: string
|
dataSourceCode: string
|
||||||
|
|
@ -83,11 +85,30 @@ export interface ListFormWizardDto {
|
||||||
schedulerStartDateExpr?: string
|
schedulerStartDateExpr?: string
|
||||||
schedulerEndDateExpr?: string
|
schedulerEndDateExpr?: string
|
||||||
|
|
||||||
|
// Todo options (required when defaultLayout = 'todo')
|
||||||
|
todoTitleExpr: string
|
||||||
|
todoStatusExpr: string
|
||||||
|
todoDescriptionExpr: string
|
||||||
|
todoDueDateExpr: string
|
||||||
|
todoTagExpr: string
|
||||||
|
todoAssigneeExpr: string
|
||||||
|
todoPriorityExpr: string
|
||||||
|
todoCompletedExpr: string
|
||||||
|
todoOrderExpr: string
|
||||||
|
todoStatusOrder: string
|
||||||
|
todoAllowDragging: boolean
|
||||||
|
|
||||||
|
// Workflow options (required when defaultLayout = 'workflow')
|
||||||
|
approvalUserFieldName: string
|
||||||
|
approvalDateFieldName: string
|
||||||
|
approvalStatusFieldName: string
|
||||||
|
approvalDescriptionFieldName: string
|
||||||
|
approvalIsFilterUserName: boolean
|
||||||
|
criteria: ListFormWorkflowCriteriaDto[]
|
||||||
|
|
||||||
groups?: ListFormWizardColumnGroupDto[]
|
groups?: ListFormWizardColumnGroupDto[]
|
||||||
subForms?: SubFormDto[]
|
subForms?: SubFormDto[]
|
||||||
widgets?: WidgetEditDto[]
|
widgets?: WidgetEditDto[]
|
||||||
workflow?: WorkflowDto
|
|
||||||
workflowCriteria?: ListFormWorkflowCriteriaDto[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WizardFileInfoDto {
|
export interface WizardFileInfoDto {
|
||||||
|
|
@ -109,7 +130,7 @@ export interface WizardInsertedRecordsDto {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WizardSeedFileItemDto {
|
export interface WizardSeedFileItemDto {
|
||||||
dataField: string
|
fieldName: string
|
||||||
editorType: string
|
editorType: string
|
||||||
editorOptions: string
|
editorOptions: string
|
||||||
editorScript: string
|
editorScript: string
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import type {
|
||||||
StartEditAction,
|
StartEditAction,
|
||||||
StateStoreType,
|
StateStoreType,
|
||||||
} from 'devextreme/ui/data_grid_types'
|
} from 'devextreme/ui/data_grid_types'
|
||||||
import type { FormItemComponent } from 'devextreme/ui/form'
|
|
||||||
import { AuditedEntityDto } from '../abp'
|
import { AuditedEntityDto } from '../abp'
|
||||||
import { EditorType2, RowMode } from '../../views/form/types'
|
import { EditorType2, RowMode } from '../../views/form/types'
|
||||||
import {
|
import {
|
||||||
|
|
@ -195,7 +194,7 @@ export interface ColumnFilterDto {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ColumnFormatDto extends AuditedEntityDto<string> {
|
export interface ColumnFormatDto extends AuditedEntityDto<string> {
|
||||||
fieldName?: string
|
fieldName: string
|
||||||
captionName?: string
|
captionName?: string
|
||||||
placeHolder?: string
|
placeHolder?: string
|
||||||
readOnly: boolean
|
readOnly: boolean
|
||||||
|
|
@ -245,6 +244,14 @@ export interface ColumnFormatDto extends AuditedEntityDto<string> {
|
||||||
alignment?: HorizontalAlignment
|
alignment?: HorizontalAlignment
|
||||||
format?: string
|
format?: string
|
||||||
editorOptions?: string
|
editorOptions?: string
|
||||||
|
editOrderNo?: number
|
||||||
|
editGroupOrderNo?: number
|
||||||
|
editorType2: EditorType2
|
||||||
|
colSpan?: number
|
||||||
|
gridBoxOptions?: GridBoxOptionsDto
|
||||||
|
tagBoxOptions?: TagBoxOptionsDto
|
||||||
|
imageUploadOptions?: ImageUploadOptionsDto
|
||||||
|
editorScript?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum AuthorizationTypeEnum {
|
export enum AuthorizationTypeEnum {
|
||||||
|
|
@ -442,6 +449,20 @@ export interface SchedulerOptionDto {
|
||||||
resources?: SchedulerResourceDto[]
|
resources?: SchedulerResourceDto[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TodoOptionDto {
|
||||||
|
titleExpr?: string
|
||||||
|
statusExpr?: string
|
||||||
|
descriptionExpr?: string
|
||||||
|
dueDateExpr?: string
|
||||||
|
tagExpr?: string
|
||||||
|
assigneeExpr?: string
|
||||||
|
priorityExpr?: string
|
||||||
|
completedExpr?: string
|
||||||
|
orderExpr?: string
|
||||||
|
statusOrder?: string
|
||||||
|
allowDragging?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export interface SchedulerResourceDto {
|
export interface SchedulerResourceDto {
|
||||||
fieldExpr?: string
|
fieldExpr?: string
|
||||||
dataSource?: any[]
|
dataSource?: any[]
|
||||||
|
|
@ -478,20 +499,6 @@ export interface EditingFormDto {
|
||||||
caption?: string
|
caption?: string
|
||||||
colCount: number
|
colCount: number
|
||||||
colSpan: number
|
colSpan: number
|
||||||
items?: EditingFormItemDto[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EditingFormItemDto {
|
|
||||||
order: number
|
|
||||||
dataField: string
|
|
||||||
editorType: FormItemComponent
|
|
||||||
editorType2: EditorType2
|
|
||||||
colSpan?: number
|
|
||||||
editorOptions?: string
|
|
||||||
gridBoxOptions?: GridBoxOptionsDto
|
|
||||||
tagBoxOptions?: TagBoxOptionsDto
|
|
||||||
imageUploadOptions?: ImageUploadOptionsDto
|
|
||||||
editorScript?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GridEditingPopupDto {
|
export interface GridEditingPopupDto {
|
||||||
|
|
@ -557,6 +564,8 @@ export interface GridOptionsDto extends AuditedEntityDto<string> {
|
||||||
ganttOptionDto: GanttOptionDto
|
ganttOptionDto: GanttOptionDto
|
||||||
schedulerOptionJson?: string
|
schedulerOptionJson?: string
|
||||||
schedulerOptionDto: SchedulerOptionDto
|
schedulerOptionDto: SchedulerOptionDto
|
||||||
|
todoOptionJson?: string
|
||||||
|
todoOptionDto: TodoOptionDto
|
||||||
pagerOptionJson?: string
|
pagerOptionJson?: string
|
||||||
pagerOptionDto: GridPagerOptionDto
|
pagerOptionDto: GridPagerOptionDto
|
||||||
editingOptionJson?: string
|
editingOptionJson?: string
|
||||||
|
|
@ -911,10 +920,10 @@ export interface WidgetEditDto {
|
||||||
|
|
||||||
export interface WorkflowDto {
|
export interface WorkflowDto {
|
||||||
approvalUserFieldName: string
|
approvalUserFieldName: string
|
||||||
isFilterUserName: boolean
|
|
||||||
approvalDateFieldName: string
|
approvalDateFieldName: string
|
||||||
approvalStatusFieldName: string
|
approvalStatusFieldName: string
|
||||||
approvalDescriptionFieldName: string
|
approvalDescriptionFieldName: string
|
||||||
|
approvalIsFilterUserName: boolean
|
||||||
criteria: ListFormWorkflowCriteriaDto[]
|
criteria: ListFormWorkflowCriteriaDto[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -951,11 +960,13 @@ export interface ListFormWorkflowCriteriaDto {
|
||||||
|
|
||||||
export interface LayoutDto {
|
export interface LayoutDto {
|
||||||
grid: boolean
|
grid: boolean
|
||||||
|
card: boolean
|
||||||
pivot: boolean
|
pivot: boolean
|
||||||
tree: boolean
|
tree: boolean
|
||||||
chart: boolean
|
chart: boolean
|
||||||
gantt: boolean
|
gantt: boolean
|
||||||
scheduler: boolean
|
scheduler: boolean
|
||||||
|
todo: boolean
|
||||||
defaultLayout: ListViewLayoutType
|
defaultLayout: ListViewLayoutType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import { LayoutType } from '../theme/models'
|
import { LayoutType } from '../theme/models'
|
||||||
import type { LazyExoticComponent, ReactNode } from 'react'
|
import type { LazyExoticComponent, ReactElement, ReactNode } from 'react'
|
||||||
|
|
||||||
export interface Meta {
|
export interface Meta {
|
||||||
pageContainerType?: 'default' | 'gutterless' | 'contained'
|
pageContainerType?: 'default' | 'gutterless' | 'contained'
|
||||||
header?: string | ReactNode
|
header?: string | ReactNode
|
||||||
headerContainer?: boolean
|
headerContainer?: boolean
|
||||||
extraHeader?: LazyExoticComponent<() => JSX.Element>
|
extraHeader?: LazyExoticComponent<() => ReactElement>
|
||||||
footer?: boolean
|
footer?: boolean
|
||||||
layout?: LayoutType
|
layout?: LayoutType
|
||||||
}
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ export interface Meta {
|
||||||
export type Route = {
|
export type Route = {
|
||||||
key: string
|
key: string
|
||||||
path: string
|
path: string
|
||||||
component: LazyExoticComponent<<T extends Meta>(props: T) => JSX.Element>
|
component: LazyExoticComponent<<T extends Meta>(props: T) => ReactElement>
|
||||||
authority: string[]
|
authority: string[]
|
||||||
meta?: Meta
|
meta?: Meta
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ export const adminModel: AdminModel = {
|
||||||
setStates: action((state, payload) => {
|
setStates: action((state, payload) => {
|
||||||
const stateId = state.states.findIndex((s) => s.listFormCode === payload.listFormCode)
|
const stateId = state.states.findIndex((s) => s.listFormCode === payload.listFormCode)
|
||||||
if (stateId !== -1) {
|
if (stateId !== -1) {
|
||||||
state.states[stateId] = payload
|
state.states[stateId] = { ...state.states[stateId], ...payload }
|
||||||
} else {
|
} else {
|
||||||
state.states = [...state.states, payload]
|
state.states = [...state.states, payload]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ export const store = createStore<StoreModel>(
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
allow: ['auth', 'theme', 'locale', 'client', 'admin'],
|
allow: ['auth', 'theme', 'locale', 'client', 'admin'],
|
||||||
|
storage: 'localStorage',
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { useLocation } from 'react-router-dom'
|
||||||
import { FaUser } from 'react-icons/fa'
|
import { FaUser } from 'react-icons/fa'
|
||||||
import navigationIcon from '@/proxy/menus/navigation-icon.config'
|
import navigationIcon from '@/proxy/menus/navigation-icon.config'
|
||||||
import { navigationTreeToFlat } from '@/utils/navigation'
|
import { navigationTreeToFlat } from '@/utils/navigation'
|
||||||
|
import { ReactElement } from 'react'
|
||||||
|
|
||||||
const extractListFormCode = (path: string): string | null => {
|
const extractListFormCode = (path: string): string | null => {
|
||||||
const p = (path ?? '').toLowerCase()
|
const p = (path ?? '').toLowerCase()
|
||||||
|
|
@ -14,7 +15,7 @@ const extractListFormCode = (path: string): string | null => {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useCurrentMenuIcon(className = 'w-6 h-6'): JSX.Element {
|
export function useCurrentMenuIcon(className = 'w-6 h-6'): ReactElement {
|
||||||
const mainMenu = useStoreState((state) => state.abpConfig.menu.mainMenu)
|
const mainMenu = useStoreState((state) => state.abpConfig.menu.mainMenu)
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const menus = navigationTreeToFlat(mainMenu)
|
const menus = navigationTreeToFlat(mainMenu)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
|
|
||||||
function useTimeOutMessage(
|
function useTimeOutMessage(
|
||||||
interval = 3000,
|
interval = 3000,
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,11 @@ import FormTabSubForm from './FormTabSubForm'
|
||||||
import FormFields from './form-fields/FormFields'
|
import FormFields from './form-fields/FormFields'
|
||||||
import { putListForms } from '@/services/admin/list-form.service'
|
import { putListForms } from '@/services/admin/list-form.service'
|
||||||
import { getRoles, getUsers } from '@/services/identity.service'
|
import { getRoles, getUsers } from '@/services/identity.service'
|
||||||
import { SelectCommandTypeEnum, GridOptionsEditDto, ListFormCustomizationDto } from '@/proxy/form/models'
|
import {
|
||||||
|
SelectCommandTypeEnum,
|
||||||
|
GridOptionsEditDto,
|
||||||
|
ListFormCustomizationDto,
|
||||||
|
} from '@/proxy/form/models'
|
||||||
import { IdentityRoleDto, IdentityUserDto } from '@/proxy/admin/models'
|
import { IdentityRoleDto, IdentityUserDto } from '@/proxy/admin/models'
|
||||||
import { getListFormCustomizations } from '@/services/admin/list-form-customization.service'
|
import { getListFormCustomizations } from '@/services/admin/list-form-customization.service'
|
||||||
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
|
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
|
||||||
|
|
@ -54,6 +58,7 @@ import FormTabSorting from './FormTabSorting'
|
||||||
import FormTabRow from './FormTabRow'
|
import FormTabRow from './FormTabRow'
|
||||||
import FormTabGantt from './FormTabGantt'
|
import FormTabGantt from './FormTabGantt'
|
||||||
import FormTabScheduler from './FormTabScheduler'
|
import FormTabScheduler from './FormTabScheduler'
|
||||||
|
import FormTabTodo from './FormTabTodo'
|
||||||
import { APP_NAME } from '@/constants/app.constant'
|
import { APP_NAME } from '@/constants/app.constant'
|
||||||
import { FormTabWorkflow } from './FormTabWorkflow'
|
import { FormTabWorkflow } from './FormTabWorkflow'
|
||||||
|
|
||||||
|
|
@ -295,6 +300,9 @@ const FormEdit = () => {
|
||||||
{translate('::ListForms.ListFormEdit.ExtraFilters')}
|
{translate('::ListForms.ListFormEdit.ExtraFilters')}
|
||||||
</TabNav>
|
</TabNav>
|
||||||
)}
|
)}
|
||||||
|
{visibleTabs.includes('editForm') && (
|
||||||
|
<TabNav value="editForm">{translate('::ListForms.ListFormEdit.EditingForm')}</TabNav>
|
||||||
|
)}
|
||||||
{visibleTabs.includes('fields') && (
|
{visibleTabs.includes('fields') && (
|
||||||
<TabNav value="fields">{translate('::ListForms.ListFormEdit.TabFields')}</TabNav>
|
<TabNav value="fields">{translate('::ListForms.ListFormEdit.TabFields')}</TabNav>
|
||||||
)}
|
)}
|
||||||
|
|
@ -303,9 +311,6 @@ const FormEdit = () => {
|
||||||
{translate('::ListForms.ListFormEdit.TabCustomization')}
|
{translate('::ListForms.ListFormEdit.TabCustomization')}
|
||||||
</TabNav>
|
</TabNav>
|
||||||
)}
|
)}
|
||||||
{visibleTabs.includes('editForm') && (
|
|
||||||
<TabNav value="editForm">{translate('::ListForms.ListFormEdit.EditingForm')}</TabNav>
|
|
||||||
)}
|
|
||||||
{visibleTabs.includes('pivots') && (
|
{visibleTabs.includes('pivots') && (
|
||||||
<TabNav value="pivots">{translate('::ListForms.ListFormEdit.TabPivot')}</TabNav>
|
<TabNav value="pivots">{translate('::ListForms.ListFormEdit.TabPivot')}</TabNav>
|
||||||
)}
|
)}
|
||||||
|
|
@ -318,6 +323,7 @@ const FormEdit = () => {
|
||||||
{visibleTabs.includes('scheduler') && (
|
{visibleTabs.includes('scheduler') && (
|
||||||
<TabNav value="scheduler">{translate('::ListForms.ListFormEdit.TabScheduler')}</TabNav>
|
<TabNav value="scheduler">{translate('::ListForms.ListFormEdit.TabScheduler')}</TabNav>
|
||||||
)}
|
)}
|
||||||
|
{visibleTabs.includes('todo') && <TabNav value="todo">Todo</TabNav>}
|
||||||
{visibleTabs.includes('subForms') && (
|
{visibleTabs.includes('subForms') && (
|
||||||
<TabNav value="subForms">{translate('::ListForms.ListFormEdit.SubForms')}</TabNav>
|
<TabNav value="subForms">{translate('::ListForms.ListFormEdit.SubForms')}</TabNav>
|
||||||
)}
|
)}
|
||||||
|
|
@ -431,6 +437,9 @@ const FormEdit = () => {
|
||||||
<TabContent value="scheduler" className="px-2">
|
<TabContent value="scheduler" className="px-2">
|
||||||
<FormTabScheduler onSubmit={onSubmit} />
|
<FormTabScheduler onSubmit={onSubmit} />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
|
<TabContent value="todo" className="px-2">
|
||||||
|
<FormTabTodo onSubmit={onSubmit} />
|
||||||
|
</TabContent>
|
||||||
<TabContent value="pager" className="px-2">
|
<TabContent value="pager" className="px-2">
|
||||||
<FormTabPager onSubmit={onSubmit} />
|
<FormTabPager onSubmit={onSubmit} />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
|
|
@ -455,6 +464,7 @@ const FormEdit = () => {
|
||||||
<TabContent value="fields" className="px-2">
|
<TabContent value="fields" className="px-2">
|
||||||
<FormFields
|
<FormFields
|
||||||
listFormCode={listFormCode}
|
listFormCode={listFormCode}
|
||||||
|
editingFormGroups={listFormValues.editingFormDto ?? []}
|
||||||
langOptions={langOptions}
|
langOptions={langOptions}
|
||||||
roleList={roleList}
|
roleList={roleList}
|
||||||
userList={userList}
|
userList={userList}
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,13 @@ const schema = Yup.object().shape({
|
||||||
defaultLayout: Yup.string(),
|
defaultLayout: Yup.string(),
|
||||||
layoutDto: Yup.object().shape({
|
layoutDto: Yup.object().shape({
|
||||||
grid: Yup.boolean(),
|
grid: Yup.boolean(),
|
||||||
|
card: Yup.boolean(),
|
||||||
pivot: Yup.boolean(),
|
pivot: Yup.boolean(),
|
||||||
chart: Yup.boolean(),
|
chart: Yup.boolean(),
|
||||||
tree: Yup.boolean(),
|
tree: Yup.boolean(),
|
||||||
gantt: Yup.boolean(),
|
gantt: Yup.boolean(),
|
||||||
|
scheduler: Yup.boolean(),
|
||||||
|
todo: Yup.boolean(),
|
||||||
defaultLayout: Yup.string(),
|
defaultLayout: Yup.string(),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
@ -312,6 +315,22 @@ function FormTabDetails(
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.DetailsLayoutDto.CardLayout')}
|
||||||
|
invalid={errors.layoutDto?.card && touched.layoutDto?.card}
|
||||||
|
errorMessage={errors.layoutDto?.card}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
className="w-20"
|
||||||
|
autoComplete="off"
|
||||||
|
name="layoutDto.card"
|
||||||
|
placeholder={translate(
|
||||||
|
'::ListForms.ListFormEdit.DetailsLayoutDto.CardLayout',
|
||||||
|
)}
|
||||||
|
component={Checkbox}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
label={translate('::ListForms.ListFormEdit.DetailsLayoutDto.PivotLayout')}
|
label={translate('::ListForms.ListFormEdit.DetailsLayoutDto.PivotLayout')}
|
||||||
invalid={errors.layoutDto?.pivot && touched.layoutDto?.pivot}
|
invalid={errors.layoutDto?.pivot && touched.layoutDto?.pivot}
|
||||||
|
|
@ -393,6 +412,19 @@ function FormTabDetails(
|
||||||
component={Checkbox}
|
component={Checkbox}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.DetailsLayoutDto.TodoLayout')}
|
||||||
|
invalid={errors.layoutDto?.todo && touched.layoutDto?.todo}
|
||||||
|
errorMessage={errors.layoutDto?.todo}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
className="w-20"
|
||||||
|
autoComplete="off"
|
||||||
|
name="layoutDto.todo"
|
||||||
|
component={Checkbox}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@ function FormTabEditForm(props: { listFormCode: string }) {
|
||||||
<Th>{translate('::ListForms.ListFormEdit.DetailsTitle')}</Th>
|
<Th>{translate('::ListForms.ListFormEdit.DetailsTitle')}</Th>
|
||||||
<Th>{translate('::ListForms.ListFormEdit.EditingFormColumnCount')}</Th>
|
<Th>{translate('::ListForms.ListFormEdit.EditingFormColumnCount')}</Th>
|
||||||
<Th>{translate('::ListForms.ListFormEdit.EditingFormColumnSpan')}</Th>
|
<Th>{translate('::ListForms.ListFormEdit.EditingFormColumnSpan')}</Th>
|
||||||
<Th>{translate('::ListForms.ListFormEdit.EditingFormItems')}</Th>
|
|
||||||
</Tr>
|
</Tr>
|
||||||
</THead>
|
</THead>
|
||||||
<TBody>
|
<TBody>
|
||||||
|
|
@ -109,13 +108,6 @@ function FormTabEditForm(props: { listFormCode: string }) {
|
||||||
<Td>{row.caption}</Td>
|
<Td>{row.caption}</Td>
|
||||||
<Td>{row.colCount}</Td>
|
<Td>{row.colCount}</Td>
|
||||||
<Td>{row.colSpan}</Td>
|
<Td>{row.colSpan}</Td>
|
||||||
<Td>
|
|
||||||
<ul className="list-disc">
|
|
||||||
{row.items?.map((i, idx) => (
|
|
||||||
<li key={`items-${i.dataField}-${idx}`}>{i.dataField}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</Td>
|
|
||||||
</Tr>
|
</Tr>
|
||||||
))}
|
))}
|
||||||
</TBody>
|
</TBody>
|
||||||
|
|
|
||||||
137
ui/src/views/admin/listForm/edit/FormTabTodo.tsx
Normal file
137
ui/src/views/admin/listForm/edit/FormTabTodo.tsx
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Checkbox,
|
||||||
|
FormContainer,
|
||||||
|
FormItem,
|
||||||
|
Input,
|
||||||
|
Notification,
|
||||||
|
Select,
|
||||||
|
toast,
|
||||||
|
} from '@/components/ui'
|
||||||
|
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
||||||
|
import type { GridOptionsEditDto } from '@/proxy/form/models'
|
||||||
|
import { getListFormFields } from '@/services/admin/list-form-field.service'
|
||||||
|
import { useStoreState } from '@/store'
|
||||||
|
import type { SelectBoxOption } from '@/types/shared'
|
||||||
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
|
import groupBy from 'lodash/groupBy'
|
||||||
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
|
import { useParams } from 'react-router-dom'
|
||||||
|
import type { FormEditProps } from './FormEdit'
|
||||||
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
|
||||||
|
const mappings: Array<{
|
||||||
|
name: keyof GridOptionsEditDto['todoOptionDto']
|
||||||
|
labelKey: string
|
||||||
|
required?: boolean
|
||||||
|
}> = [
|
||||||
|
{ name: 'titleExpr', labelKey: 'TodoTitleExpr', required: true },
|
||||||
|
{ name: 'statusExpr', labelKey: 'TodoStatusExpr', required: true },
|
||||||
|
{ name: 'descriptionExpr', labelKey: 'TodoDescriptionExpr' },
|
||||||
|
{ name: 'dueDateExpr', labelKey: 'TodoDueDateExpr' },
|
||||||
|
{ name: 'tagExpr', labelKey: 'TodoTagExpr' },
|
||||||
|
{ name: 'assigneeExpr', labelKey: 'TodoAssigneeExpr' },
|
||||||
|
{ name: 'priorityExpr', labelKey: 'TodoPriorityExpr' },
|
||||||
|
{ name: 'completedExpr', labelKey: 'TodoCompletedExpr' },
|
||||||
|
{ name: 'orderExpr', labelKey: 'TodoOrderExpr' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const FormTabTodo = ({ onSubmit }: FormEditProps) => {
|
||||||
|
const { listFormCode } = useParams()
|
||||||
|
const values = useStoreState((state) => state.admin.lists.values)
|
||||||
|
const [fields, setFields] = useState<SelectBoxOption[]>([])
|
||||||
|
const { translate } = useLocalization()
|
||||||
|
const translateRef = useRef(translate)
|
||||||
|
translateRef.current = translate
|
||||||
|
|
||||||
|
const loadFields = useCallback(async () => {
|
||||||
|
if (!listFormCode) return
|
||||||
|
try {
|
||||||
|
const response = await getListFormFields({
|
||||||
|
listFormCode,
|
||||||
|
sorting: 'ListOrderNo',
|
||||||
|
maxResultCount: 1000,
|
||||||
|
})
|
||||||
|
const names = groupBy(response.data?.items ?? [], 'fieldName')
|
||||||
|
setFields(Object.keys(names).map((name) => ({ value: name, label: name })))
|
||||||
|
} catch (error: any) {
|
||||||
|
toast.push(
|
||||||
|
<Notification type="danger">
|
||||||
|
{translateRef.current('::ListForms.ListFormFieldEdit.TodoFieldsLoadFailed', {
|
||||||
|
0: error.toString(),
|
||||||
|
})}
|
||||||
|
</Notification>,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}, [listFormCode])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadFields()
|
||||||
|
}, [loadFields])
|
||||||
|
if (!values) return null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Formik
|
||||||
|
initialValues={values}
|
||||||
|
onSubmit={(formValues, helpers) => onSubmit(ListFormEditTabs.TodoForm, formValues, helpers)}
|
||||||
|
>
|
||||||
|
{({ isSubmitting, values: formValues }) => (
|
||||||
|
<Form>
|
||||||
|
<FormContainer size="sm">
|
||||||
|
<div className="grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-4">
|
||||||
|
{mappings.map((mapping) => (
|
||||||
|
<FormItem
|
||||||
|
key={mapping.name}
|
||||||
|
label={`${translate(
|
||||||
|
`::ListForms.ListFormFieldEdit.${mapping.labelKey}`,
|
||||||
|
)}${mapping.required ? ' *' : ''}`}
|
||||||
|
>
|
||||||
|
<Field name={`todoOptionDto.${mapping.name}`}>
|
||||||
|
{({ field, form }: FieldProps) => (
|
||||||
|
<Select
|
||||||
|
field={field}
|
||||||
|
form={form}
|
||||||
|
isClearable={!mapping.required}
|
||||||
|
options={fields}
|
||||||
|
value={fields.find(
|
||||||
|
(option) => option.value === formValues.todoOptionDto?.[mapping.name],
|
||||||
|
)}
|
||||||
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</FormItem>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="mt-3 grid grid-cols-1 gap-3 md:grid-cols-2">
|
||||||
|
<FormItem label={translate('::ListForms.ListFormFieldEdit.TodoStatusOrder')}>
|
||||||
|
<Field
|
||||||
|
name="todoOptionDto.statusOrder"
|
||||||
|
component={Input}
|
||||||
|
placeholder={translate(
|
||||||
|
'::ListForms.ListFormFieldEdit.TodoStatusOrderPlaceholder',
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label={translate('::ListForms.ListFormFieldEdit.TodoAllowDragging')}>
|
||||||
|
<Field name="todoOptionDto.allowDragging" component={Checkbox} />
|
||||||
|
</FormItem>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
block
|
||||||
|
size="sm"
|
||||||
|
variant="solid"
|
||||||
|
loading={isSubmitting}
|
||||||
|
type="submit"
|
||||||
|
className="my-3"
|
||||||
|
>
|
||||||
|
{translate('::Save')}
|
||||||
|
</Button>
|
||||||
|
</FormContainer>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FormTabTodo
|
||||||
|
|
@ -314,10 +314,10 @@ export function FormTabWorkflow(
|
||||||
const schema = object().shape({
|
const schema = object().shape({
|
||||||
workflowDto: object().shape({
|
workflowDto: object().shape({
|
||||||
approvalUserFieldName: string().required(),
|
approvalUserFieldName: string().required(),
|
||||||
isFilterUserName: bool(),
|
|
||||||
approvalStatusFieldName: string().required(),
|
approvalStatusFieldName: string().required(),
|
||||||
approvalDateFieldName: string(),
|
approvalDateFieldName: string(),
|
||||||
approvalDescriptionFieldName: string(),
|
approvalDescriptionFieldName: string(),
|
||||||
|
approvalIsFilterUserName: bool(),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -442,16 +442,16 @@ export function FormTabWorkflow(
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
label={translate('::ListForms.ListFormEdit.Workflow.IsFilterUserName')}
|
label={translate('::ListForms.ListFormEdit.Workflow.ApprovalIsFilterUserName')}
|
||||||
invalid={
|
invalid={
|
||||||
!!(
|
!!(
|
||||||
errors.workflowDto?.isFilterUserName &&
|
errors.workflowDto?.approvalIsFilterUserName &&
|
||||||
touched.workflowDto?.isFilterUserName
|
touched.workflowDto?.approvalIsFilterUserName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
errorMessage={errors.workflowDto?.isFilterUserName as string}
|
errorMessage={errors.workflowDto?.approvalIsFilterUserName as string}
|
||||||
>
|
>
|
||||||
<Field name="workflowDto.isFilterUserName" component={Checkbox} />
|
<Field name="workflowDto.approvalIsFilterUserName" component={Checkbox} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,17 @@ import FormFieldTabTotalSummary from './FormFieldTabTotalSummary'
|
||||||
import FormFieldTabValidationRules from './FormFieldTabValidationRules'
|
import FormFieldTabValidationRules from './FormFieldTabValidationRules'
|
||||||
import { FormFieldEditProps } from './FormFields'
|
import { FormFieldEditProps } from './FormFields'
|
||||||
import FormFieldTabPivotSetting from './FormFieldTabPivotSetting'
|
import FormFieldTabPivotSetting from './FormFieldTabPivotSetting'
|
||||||
|
import type { EditingFormDto } from '@/proxy/form/models'
|
||||||
|
|
||||||
function FormFieldEdit({
|
function FormFieldEdit({
|
||||||
item,
|
item,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
fields,
|
fields,
|
||||||
|
editingFormGroups,
|
||||||
}: {
|
}: {
|
||||||
item: ColumnFormatEditDto | null
|
item: ColumnFormatEditDto | null
|
||||||
fields: ColumnFormatEditDto[]
|
fields: ColumnFormatEditDto[]
|
||||||
|
editingFormGroups: EditingFormDto[]
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
||||||
|
|
@ -78,7 +81,12 @@ function FormFieldEdit({
|
||||||
<FormFieldTabDetails initialValues={item} onSubmit={onSubmit} />
|
<FormFieldTabDetails initialValues={item} onSubmit={onSubmit} />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="options">
|
<TabContent value="options">
|
||||||
<FormFieldTabOptions initialValues={item} onSubmit={onSubmit} />
|
<FormFieldTabOptions
|
||||||
|
initialValues={item}
|
||||||
|
editingFormGroups={editingFormGroups}
|
||||||
|
fields={fields}
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
/>
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="permissions">
|
<TabContent value="permissions">
|
||||||
<FormFieldTabPermissions initialValues={item} onSubmit={onSubmit} />
|
<FormFieldTabPermissions initialValues={item} onSubmit={onSubmit} />
|
||||||
|
|
@ -96,18 +104,10 @@ function FormFieldEdit({
|
||||||
<FormFieldTabGrouping initialValues={item} onSubmit={onSubmit} />
|
<FormFieldTabGrouping initialValues={item} onSubmit={onSubmit} />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="groupSummary">
|
<TabContent value="groupSummary">
|
||||||
<FormFieldTabGroupSummary
|
<FormFieldTabGroupSummary initialValues={item} fields={fields} onSubmit={onSubmit} />
|
||||||
initialValues={item}
|
|
||||||
fields={fields}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="totalSummary">
|
<TabContent value="totalSummary">
|
||||||
<FormFieldTabTotalSummary
|
<FormFieldTabTotalSummary initialValues={item} fields={fields} onSubmit={onSubmit} />
|
||||||
initialValues={item}
|
|
||||||
fields={fields}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="joinOptions">
|
<TabContent value="joinOptions">
|
||||||
<FormFieldTabJoinOptions initialValues={item} onSubmit={onSubmit} />
|
<FormFieldTabJoinOptions initialValues={item} onSubmit={onSubmit} />
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import { Button, Card, FormItem, Input, Select } from '@/components/ui'
|
import { Button, Card, Checkbox, FormItem, Input, Select } from '@/components/ui'
|
||||||
import { ColumnFormatEditDto, ListFormFieldEditTabs } from '@/proxy/admin/list-form-field/models'
|
import { ColumnFormatEditDto, ListFormFieldEditTabs } from '@/proxy/admin/list-form-field/models'
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
import { SelectBoxOption } from '@/types/shared'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { FaSlidersH } from 'react-icons/fa'
|
import { FaSlidersH } from 'react-icons/fa'
|
||||||
import { number, object, string } from 'yup'
|
import { bool, number, object, string } from 'yup'
|
||||||
import { dbSourceTypeOptions, listFormAlignmentOptions } from '../options'
|
import { dbSourceTypeOptions, listFormAlignmentOptions } from '../options'
|
||||||
import EditorOptionsBuilderDialog from '../json-row-operations/EditorOptionsBuilderDialog'
|
import EditorOptionsBuilderDialog from '../json-row-operations/EditorOptionsBuilderDialog'
|
||||||
import { FormFieldEditProps } from './FormFields'
|
import { FormFieldEditProps } from './FormFields'
|
||||||
|
|
@ -16,10 +16,13 @@ const schema = object().shape({
|
||||||
captionName: string(),
|
captionName: string(),
|
||||||
placeHolder: string(),
|
placeHolder: string(),
|
||||||
bandName: string(),
|
bandName: string(),
|
||||||
|
isActive: bool().required(),
|
||||||
|
visible: bool().required(),
|
||||||
|
allowSearch: bool().required(),
|
||||||
sourceDbType: number().required(),
|
sourceDbType: number().required(),
|
||||||
alignment: string(),
|
alignment: string(),
|
||||||
format: string(),
|
format: string(),
|
||||||
editorOptions: string().max(1000),
|
editorOptions: string(),
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabDetails({
|
function FormFieldTabDetails({
|
||||||
|
|
@ -72,6 +75,32 @@ function FormFieldTabDetails({
|
||||||
>
|
>
|
||||||
<Field type="text" name="bandName" component={Input} />
|
<Field type="text" name="bandName" component={Input} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
<div className="flex w-full gap-4">
|
||||||
|
<FormItem
|
||||||
|
className="flex-1"
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.HeaderingAllowSearch')}
|
||||||
|
>
|
||||||
|
<Field name="allowSearch" component={Checkbox} />
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
className="flex-1"
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.OptionsIsActive')}
|
||||||
|
invalid={errors.isActive && touched.isActive}
|
||||||
|
errorMessage={errors.isActive}
|
||||||
|
>
|
||||||
|
<Field name="isActive" component={Checkbox} />
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
className="flex-1"
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.OptionsVisible')}
|
||||||
|
invalid={errors.visible && touched.visible}
|
||||||
|
errorMessage={errors.visible}
|
||||||
|
>
|
||||||
|
<Field name="visible" component={Checkbox} />
|
||||||
|
</FormItem>
|
||||||
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
<Card>
|
<Card>
|
||||||
<FormItem label={translate('::ListForms.ListFormEdit.CustomValueType')}>
|
<FormItem label={translate('::ListForms.ListFormEdit.CustomValueType')}>
|
||||||
|
|
@ -132,7 +161,7 @@ function FormFieldTabDetails({
|
||||||
type="text"
|
type="text"
|
||||||
name="editorOptions"
|
name="editorOptions"
|
||||||
component={Input}
|
component={Input}
|
||||||
rows={4}
|
rows={3}
|
||||||
textArea={true}
|
textArea={true}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -154,7 +183,14 @@ function FormFieldTabDetails({
|
||||||
onClose={() => setIsEditorOptionsDialogOpen(false)}
|
onClose={() => setIsEditorOptionsDialogOpen(false)}
|
||||||
onApply={(val) => setFieldValue('editorOptions', val)}
|
onApply={(val) => setFieldValue('editorOptions', val)}
|
||||||
/>
|
/>
|
||||||
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
<Button
|
||||||
|
block
|
||||||
|
size="sm"
|
||||||
|
className="mt-1"
|
||||||
|
variant="solid"
|
||||||
|
loading={isSubmitting}
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -4,29 +4,50 @@ import { SelectBoxOption } from '@/types/shared'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
import { bool, number, object, string } from 'yup'
|
import { bool, number, object, string } from 'yup'
|
||||||
import { sortDirectionOptions } from '../options'
|
import { columnEditorTypeListOptions, sortDirectionOptions } from '../options'
|
||||||
import { FormFieldEditProps } from './FormFields'
|
import { FormFieldEditProps } from './FormFields'
|
||||||
import { SortDirectionEnum } from '@/proxy/form/models'
|
import { EditingFormDto, SortDirectionEnum } from '@/proxy/form/models'
|
||||||
|
import { FaCode } from 'react-icons/fa'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import EditorScriptBuilderDialog from '../json-row-operations/EditorScriptBuilderDialog'
|
||||||
|
|
||||||
const schema = object().shape({
|
const schema = object().shape({
|
||||||
listOrderNo: number(),
|
listOrderNo: number(),
|
||||||
width: number(),
|
width: number(),
|
||||||
sortDirection: string().oneOf(Object.values(SortDirectionEnum) as string[]),
|
sortDirection: string().oneOf(Object.values(SortDirectionEnum) as string[]),
|
||||||
sortIndex: number(),
|
sortIndex: number(),
|
||||||
isActive: bool().required(),
|
editGroupOrderNo: number().nullable(),
|
||||||
visible: bool().required(),
|
editOrderNo: number().nullable(),
|
||||||
allowSearch: bool().required(),
|
colSpan: number().nullable(),
|
||||||
allowEditing: bool().required(),
|
allowEditing: bool().required(),
|
||||||
allowAdding: bool().required(),
|
allowAdding: bool().required(),
|
||||||
|
editorScript: string(),
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabOptions({
|
function FormFieldTabOptions({
|
||||||
initialValues,
|
initialValues,
|
||||||
|
editingFormGroups,
|
||||||
|
fields,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
}: {
|
}: {
|
||||||
initialValues: ColumnFormatEditDto
|
initialValues: ColumnFormatEditDto
|
||||||
|
editingFormGroups: EditingFormDto[]
|
||||||
|
fields: ColumnFormatEditDto[]
|
||||||
} & FormFieldEditProps) {
|
} & FormFieldEditProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
const [isEditorScriptDialogOpen, setIsEditorScriptDialogOpen] = useState(false)
|
||||||
|
const editingFormGroupOptions: SelectBoxOption[] = [...editingFormGroups]
|
||||||
|
.sort((left, right) => left.order - right.order)
|
||||||
|
.map((group) => ({
|
||||||
|
value: String(group.order),
|
||||||
|
label: `${group.order} - ${group.caption || translate('::ListForms.ListFormFieldEdit.EditFormGroup')}`,
|
||||||
|
}))
|
||||||
|
const editorScriptFields: SelectBoxOption[] = fields
|
||||||
|
.filter((field) => field.fieldName)
|
||||||
|
.map((field) => ({
|
||||||
|
value: field.fieldName,
|
||||||
|
label: field.captionName || field.fieldName,
|
||||||
|
}))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik
|
<Formik
|
||||||
|
|
@ -37,7 +58,7 @@ function FormFieldTabOptions({
|
||||||
await onSubmit(ListFormFieldEditTabs.OptionsForm, values, formikHelpers)
|
await onSubmit(ListFormFieldEditTabs.OptionsForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting, values, setFieldValue }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||||
<Card>
|
<Card>
|
||||||
|
|
@ -82,25 +103,7 @@ function FormFieldTabOptions({
|
||||||
>
|
>
|
||||||
<Field type="number" name="sortIndex" component={Input} />
|
<Field type="number" name="sortIndex" component={Input} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Card>
|
|
||||||
<Card>
|
|
||||||
<FormItem
|
|
||||||
label={translate('::ListForms.ListFormFieldEdit.OptionsIsActive')}
|
|
||||||
invalid={errors.isActive && touched.isActive}
|
|
||||||
errorMessage={errors.isActive}
|
|
||||||
>
|
|
||||||
<Field name="isActive" component={Checkbox} />
|
|
||||||
</FormItem>
|
|
||||||
<FormItem
|
|
||||||
label={translate('::ListForms.ListFormFieldEdit.OptionsVisible')}
|
|
||||||
invalid={errors.visible && touched.visible}
|
|
||||||
errorMessage={errors.visible}
|
|
||||||
>
|
|
||||||
<Field name="visible" component={Checkbox} />
|
|
||||||
</FormItem>
|
|
||||||
<FormItem label={translate('::ListForms.ListFormFieldEdit.HeaderingAllowSearch')}>
|
|
||||||
<Field name="allowSearch" component={Checkbox} />
|
|
||||||
</FormItem>
|
|
||||||
<FormItem label={translate('::ListForms.ListFormEdit.AllowEditing')}>
|
<FormItem label={translate('::ListForms.ListFormEdit.AllowEditing')}>
|
||||||
<Field name="allowEditing" component={Checkbox} />
|
<Field name="allowEditing" component={Checkbox} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
@ -108,9 +111,100 @@ function FormFieldTabOptions({
|
||||||
<Field name="allowAdding" component={Checkbox} />
|
<Field name="allowAdding" component={Checkbox} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Card>
|
</Card>
|
||||||
|
<Card>
|
||||||
|
<FormItem
|
||||||
|
invalid={errors.editorType2 && touched.editorType2}
|
||||||
|
errorMessage={errors.editorType2}
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.EditorType')}
|
||||||
|
>
|
||||||
|
<Field name="editorType2">
|
||||||
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
||||||
|
<Select
|
||||||
|
isClearable
|
||||||
|
options={columnEditorTypeListOptions}
|
||||||
|
value={columnEditorTypeListOptions.find(
|
||||||
|
(option) => option.value === field.value,
|
||||||
|
)}
|
||||||
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
invalid={errors.editGroupOrderNo && touched.editGroupOrderNo}
|
||||||
|
errorMessage={errors.editGroupOrderNo}
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.EditFormGroup')}
|
||||||
|
>
|
||||||
|
<Field name="editGroupOrderNo">
|
||||||
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
||||||
|
<Select
|
||||||
|
isClearable
|
||||||
|
options={editingFormGroupOptions}
|
||||||
|
value={editingFormGroupOptions.find(
|
||||||
|
(option) => Number(option.value) === Number(field.value),
|
||||||
|
)}
|
||||||
|
onChange={(option) =>
|
||||||
|
form.setFieldValue(
|
||||||
|
field.name,
|
||||||
|
option?.value == null ? null : Number(option.value),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
invalid={errors.editOrderNo && touched.editOrderNo}
|
||||||
|
errorMessage={errors.editOrderNo}
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.EditFormOrderNo')}
|
||||||
|
>
|
||||||
|
<Field type="number" name="editOrderNo" component={Input} />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem
|
||||||
|
invalid={errors.colSpan && touched.colSpan}
|
||||||
|
errorMessage={errors.colSpan}
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.EditFormColSpan')}
|
||||||
|
>
|
||||||
|
<Field type="number" name="colSpan" component={Input} />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label={translate('::ListForms.Wizard.Step3.EditorScript')}>
|
||||||
|
<div className="flex gap-2 items-start">
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
name="editorScript"
|
||||||
|
component={Input}
|
||||||
|
rows={3}
|
||||||
|
textArea={true}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
shape="circle"
|
||||||
|
variant="plain"
|
||||||
|
type="button"
|
||||||
|
size="sm"
|
||||||
|
title="Build editor script"
|
||||||
|
icon={<FaCode />}
|
||||||
|
onClick={() => setIsEditorScriptDialogOpen(true)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</FormItem>
|
||||||
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
</Card>
|
||||||
|
</div>
|
||||||
|
<EditorScriptBuilderDialog
|
||||||
|
isOpen={isEditorScriptDialogOpen}
|
||||||
|
value={values.editorScript}
|
||||||
|
currentField={values.fieldName}
|
||||||
|
fields={editorScriptFields}
|
||||||
|
onClose={() => setIsEditorScriptDialogOpen(false)}
|
||||||
|
onApply={(val) => setFieldValue('editorScript', val)}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
block
|
||||||
|
size="sm"
|
||||||
|
className="mt-1"
|
||||||
|
variant="solid"
|
||||||
|
loading={isSubmitting}
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
{isSubmitting ? translate('::Saving') : translate('::Save')}
|
||||||
</Button>
|
</Button>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ import { dbSourceTypeOptions, sqlDataTypeToDbType } from '../options'
|
||||||
import { IdentityRoleDto, IdentityUserDto } from '@/proxy/admin/models'
|
import { IdentityRoleDto, IdentityUserDto } from '@/proxy/admin/models'
|
||||||
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
|
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
|
||||||
import type { DatabaseColumnDto } from '@/proxy/sql-query-manager/models'
|
import type { DatabaseColumnDto } from '@/proxy/sql-query-manager/models'
|
||||||
|
import type { EditingFormDto } from '@/proxy/form/models'
|
||||||
|
|
||||||
export interface FormFieldEditProps {
|
export interface FormFieldEditProps {
|
||||||
onSubmit: (
|
onSubmit: (
|
||||||
|
|
@ -71,12 +72,14 @@ const copyFieldSchema = object().shape({
|
||||||
|
|
||||||
function FormFields({
|
function FormFields({
|
||||||
listFormCode,
|
listFormCode,
|
||||||
|
editingFormGroups,
|
||||||
langOptions,
|
langOptions,
|
||||||
roleList,
|
roleList,
|
||||||
userList,
|
userList,
|
||||||
columns,
|
columns,
|
||||||
}: {
|
}: {
|
||||||
listFormCode: string
|
listFormCode: string
|
||||||
|
editingFormGroups: EditingFormDto[]
|
||||||
langOptions: SelectBoxOption[]
|
langOptions: SelectBoxOption[]
|
||||||
roleList: SelectBoxOption[]
|
roleList: SelectBoxOption[]
|
||||||
userList: SelectBoxOption[]
|
userList: SelectBoxOption[]
|
||||||
|
|
@ -219,7 +222,8 @@ function FormFields({
|
||||||
await getFields()
|
await getFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFields = useCallback(async (cultureName?: string, roleId?: string, userId?: string) => {
|
const getFields = useCallback(
|
||||||
|
async (cultureName?: string, roleId?: string, userId?: string) => {
|
||||||
if (!listFormCode) {
|
if (!listFormCode) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -254,7 +258,9 @@ function FormFields({
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, [listFormCode])
|
},
|
||||||
|
[listFormCode],
|
||||||
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getFields()
|
getFields()
|
||||||
|
|
@ -405,7 +411,7 @@ function FormFields({
|
||||||
<Table compact>
|
<Table compact>
|
||||||
<THead>
|
<THead>
|
||||||
<Tr>
|
<Tr>
|
||||||
<Th className='w-3/12'>
|
<Th className="w-3/12">
|
||||||
<div>
|
<div>
|
||||||
<Button
|
<Button
|
||||||
shape="circle"
|
shape="circle"
|
||||||
|
|
@ -478,12 +484,19 @@ function FormFields({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<span>{field.listOrderNo}</span>
|
<span style={{ visibility: !field?.visible ? 'visible' : 'hidden' }}>
|
||||||
<span>{!field?.visible && <FaEyeSlash />}</span>
|
<FaEyeSlash />
|
||||||
<span>{!field?.isActive && <FaTimes />}</span>
|
</span>
|
||||||
|
<span style={{ visibility: !field?.isActive ? 'visible' : 'hidden' }}>
|
||||||
|
<FaTimes />
|
||||||
|
</span>
|
||||||
|
<span className="ml-5">
|
||||||
|
{field.listOrderNo}
|
||||||
|
{field.editOrderNo ? ` (${field.editOrderNo})` : ''}
|
||||||
|
</span>
|
||||||
</Td>
|
</Td>
|
||||||
<Td className='!p-0'>{field.fieldName}</Td>
|
<Td className="!p-0">{field.fieldName}</Td>
|
||||||
<Td className='align-middle text-center !p-0'>
|
<Td className="align-middle text-center !p-0">
|
||||||
<Avatar
|
<Avatar
|
||||||
size={18}
|
size={18}
|
||||||
shape="circle"
|
shape="circle"
|
||||||
|
|
@ -505,7 +518,12 @@ function FormFields({
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
<div className="2xl:col-span-3 lg:col-span-3 xl:col-span-2">
|
<div className="2xl:col-span-3 lg:col-span-3 xl:col-span-2">
|
||||||
<FormFieldEdit item={row} fields={fields} onSubmit={onSubmit} />
|
<FormFieldEdit
|
||||||
|
item={row}
|
||||||
|
fields={fields}
|
||||||
|
editingFormGroups={editingFormGroups}
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</AdaptableCard>
|
</AdaptableCard>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -224,11 +224,13 @@ export const listFormTypeOptions = [
|
||||||
|
|
||||||
export const listFormDefaultLayoutOptions = [
|
export const listFormDefaultLayoutOptions = [
|
||||||
{ value: 'grid', label: 'Grid' },
|
{ value: 'grid', label: 'Grid' },
|
||||||
|
{ value: 'card', label: 'Card' },
|
||||||
{ value: 'pivot', label: 'Pivot' },
|
{ value: 'pivot', label: 'Pivot' },
|
||||||
{ value: 'chart', label: 'Chart' },
|
{ value: 'chart', label: 'Chart' },
|
||||||
{ value: 'tree', label: 'Tree' },
|
{ value: 'tree', label: 'Tree' },
|
||||||
{ value: 'gantt', label: 'Gantt' },
|
{ value: 'gantt', label: 'Gantt' },
|
||||||
{ value: 'scheduler', label: 'Scheduler' },
|
{ value: 'scheduler', label: 'Scheduler' },
|
||||||
|
{ value: 'todo', label: 'Todo' },
|
||||||
]
|
]
|
||||||
|
|
||||||
export const listFormAlignmentOptions = [
|
export const listFormAlignmentOptions = [
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,22 @@
|
||||||
export type ChartOperation = '' | 'select' | 'insert' | 'update' | 'delete'
|
export type ChartOperation = '' | 'select' | 'insert' | 'update' | 'delete'
|
||||||
export type ChartDialogType = '' | 'pane' | 'serie' | 'annotation' | 'axis'
|
export type ChartDialogType = '' | 'pane' | 'serie' | 'annotation' | 'axis'
|
||||||
export type ListViewLayoutType = 'grid' | 'pivot' | 'tree' | 'chart' | 'gantt' | 'scheduler'
|
export type ListViewLayoutType =
|
||||||
|
| 'grid'
|
||||||
|
| 'card'
|
||||||
|
| 'pivot'
|
||||||
|
| 'tree'
|
||||||
|
| 'chart'
|
||||||
|
| 'gantt'
|
||||||
|
| 'scheduler'
|
||||||
|
| 'todo'
|
||||||
|
|
||||||
export const layoutTypes = {
|
export const layoutTypes = {
|
||||||
grid: 'Grid',
|
grid: 'Grid',
|
||||||
|
card: 'Card',
|
||||||
pivot: 'Pivot',
|
pivot: 'Pivot',
|
||||||
tree: 'Tree',
|
tree: 'Tree',
|
||||||
chart: 'Chart',
|
chart: 'Chart',
|
||||||
gantt: 'Gantt',
|
gantt: 'Gantt',
|
||||||
scheduler: 'Scheduler',
|
scheduler: 'Scheduler',
|
||||||
|
todo: 'Todo',
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import WizardStep1, {
|
||||||
import WizardStep2 from './WizardStep2'
|
import WizardStep2 from './WizardStep2'
|
||||||
import WizardStep3, { WizardGroup, WizardGroupItem } from './WizardStep3'
|
import WizardStep3, { WizardGroup, WizardGroupItem } from './WizardStep3'
|
||||||
import WizardStep7 from './WizardStep7'
|
import WizardStep7 from './WizardStep7'
|
||||||
|
import WizardStep8 from './WizardStep8'
|
||||||
import WizardStep4 from './WizardStep4'
|
import WizardStep4 from './WizardStep4'
|
||||||
import WizardStep5 from './WizardStep5'
|
import WizardStep5 from './WizardStep5'
|
||||||
import WizardStep6 from './WizardStep6'
|
import WizardStep6 from './WizardStep6'
|
||||||
|
|
@ -57,11 +58,24 @@ const initialValues: ListFormWizardDto = {
|
||||||
allowDetail: false,
|
allowDetail: false,
|
||||||
defaultLayout: 'grid',
|
defaultLayout: 'grid',
|
||||||
grid: true,
|
grid: true,
|
||||||
|
card: true,
|
||||||
pivot: true,
|
pivot: true,
|
||||||
tree: true,
|
tree: true,
|
||||||
chart: true,
|
chart: true,
|
||||||
gantt: true,
|
gantt: true,
|
||||||
scheduler: true,
|
scheduler: true,
|
||||||
|
todo: false,
|
||||||
|
todoTitleExpr: '',
|
||||||
|
todoStatusExpr: '',
|
||||||
|
todoDescriptionExpr: '',
|
||||||
|
todoDueDateExpr: '',
|
||||||
|
todoTagExpr: '',
|
||||||
|
todoAssigneeExpr: '',
|
||||||
|
todoPriorityExpr: '',
|
||||||
|
todoCompletedExpr: '',
|
||||||
|
todoOrderExpr: '',
|
||||||
|
todoStatusOrder: 'Backlog, Ready to Start, In Progress, Code Review, Testing, Staging',
|
||||||
|
todoAllowDragging: true,
|
||||||
languageTextMenuEn: '',
|
languageTextMenuEn: '',
|
||||||
languageTextMenuTr: '',
|
languageTextMenuTr: '',
|
||||||
languageTextTitleEn: '',
|
languageTextTitleEn: '',
|
||||||
|
|
@ -72,6 +86,7 @@ const initialValues: ListFormWizardDto = {
|
||||||
languageTextMenuParentTr: '',
|
languageTextMenuParentTr: '',
|
||||||
permissionGroupName: '',
|
permissionGroupName: '',
|
||||||
menuParentCode: '',
|
menuParentCode: '',
|
||||||
|
menuParentShortName: '',
|
||||||
menuParentIcon: '',
|
menuParentIcon: '',
|
||||||
menuIcon: '',
|
menuIcon: '',
|
||||||
dataSourceCode: '',
|
dataSourceCode: '',
|
||||||
|
|
@ -95,15 +110,12 @@ const initialValues: ListFormWizardDto = {
|
||||||
schedulerEndDateExpr: '',
|
schedulerEndDateExpr: '',
|
||||||
subForms: [],
|
subForms: [],
|
||||||
widgets: [],
|
widgets: [],
|
||||||
workflow: {
|
|
||||||
approvalUserFieldName: '',
|
approvalUserFieldName: '',
|
||||||
isFilterUserName: false,
|
|
||||||
approvalDateFieldName: '',
|
approvalDateFieldName: '',
|
||||||
approvalStatusFieldName: '',
|
approvalStatusFieldName: '',
|
||||||
approvalDescriptionFieldName: '',
|
approvalDescriptionFieldName: '',
|
||||||
|
approvalIsFilterUserName: false,
|
||||||
criteria: [],
|
criteria: [],
|
||||||
},
|
|
||||||
workflowCriteria: [],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const step1ValidationSchema = Yup.object().shape({
|
const step1ValidationSchema = Yup.object().shape({
|
||||||
|
|
@ -135,7 +147,26 @@ const step2ValidationSchema = Yup.object().shape({
|
||||||
confirmDelete: Yup.boolean(),
|
confirmDelete: Yup.boolean(),
|
||||||
})
|
})
|
||||||
|
|
||||||
const listFormValidationSchema = step1ValidationSchema.concat(step2ValidationSchema)
|
const todoValidationSchema = Yup.object().shape({
|
||||||
|
todoTitleExpr: Yup.string()
|
||||||
|
.trim()
|
||||||
|
.when('todo', {
|
||||||
|
is: true,
|
||||||
|
then: (schema) => schema.required(),
|
||||||
|
otherwise: (schema) => schema.notRequired(),
|
||||||
|
}),
|
||||||
|
todoStatusExpr: Yup.string()
|
||||||
|
.trim()
|
||||||
|
.when('todo', {
|
||||||
|
is: true,
|
||||||
|
then: (schema) => schema.required(),
|
||||||
|
otherwise: (schema) => schema.notRequired(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
const listFormValidationSchema = step1ValidationSchema
|
||||||
|
.concat(step2ValidationSchema)
|
||||||
|
.concat(todoValidationSchema)
|
||||||
|
|
||||||
// ─── Wizard ───────────────────────────────────────────────────────────────────
|
// ─── Wizard ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -225,13 +256,13 @@ const Wizard = () => {
|
||||||
const [widgets, setWidgets] = useState<WidgetEditDto[]>([])
|
const [widgets, setWidgets] = useState<WidgetEditDto[]>([])
|
||||||
const [workflow, setWorkflow] = useState<WorkflowDto>({
|
const [workflow, setWorkflow] = useState<WorkflowDto>({
|
||||||
approvalUserFieldName: '',
|
approvalUserFieldName: '',
|
||||||
isFilterUserName: false,
|
|
||||||
approvalDateFieldName: '',
|
approvalDateFieldName: '',
|
||||||
approvalStatusFieldName: '',
|
approvalStatusFieldName: '',
|
||||||
approvalDescriptionFieldName: '',
|
approvalDescriptionFieldName: '',
|
||||||
|
approvalIsFilterUserName: false,
|
||||||
criteria: [],
|
criteria: [],
|
||||||
})
|
})
|
||||||
const [workflowCriteria, setWorkflowCriteria] = useState<ListFormWorkflowCriteriaDto[]>([])
|
const [criteria, setCriteria] = useState<ListFormWorkflowCriteriaDto[]>([])
|
||||||
|
|
||||||
// Audit columns that should not be selected by default
|
// Audit columns that should not be selected by default
|
||||||
const AUDIT_COLUMNS = new Set([
|
const AUDIT_COLUMNS = new Set([
|
||||||
|
|
@ -255,7 +286,7 @@ const Wizard = () => {
|
||||||
const removeTenantGroupItems = (groups: WizardGroup[]) =>
|
const removeTenantGroupItems = (groups: WizardGroup[]) =>
|
||||||
groups.map((group) => ({
|
groups.map((group) => ({
|
||||||
...group,
|
...group,
|
||||||
items: group.items.filter((item) => !isTenantColumn(item.dataField)),
|
items: group.items.filter((item) => !isTenantColumn(item.fieldName)),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const loadColumns = async (dsCode: string, schema: string, name: string) => {
|
const loadColumns = async (dsCode: string, schema: string, name: string) => {
|
||||||
|
|
@ -406,11 +437,26 @@ const Wizard = () => {
|
||||||
allowDetail: w.allowDetail ?? false,
|
allowDetail: w.allowDetail ?? false,
|
||||||
defaultLayout: w.defaultLayout ?? 'grid',
|
defaultLayout: w.defaultLayout ?? 'grid',
|
||||||
grid: w.grid ?? true,
|
grid: w.grid ?? true,
|
||||||
|
card: w.card ?? true,
|
||||||
pivot: w.pivot ?? true,
|
pivot: w.pivot ?? true,
|
||||||
tree: w.tree ?? true,
|
tree: w.tree ?? true,
|
||||||
chart: w.chart ?? true,
|
chart: w.chart ?? true,
|
||||||
gantt: w.gantt ?? true,
|
gantt: w.gantt ?? true,
|
||||||
scheduler: w.scheduler ?? true,
|
scheduler: w.scheduler ?? true,
|
||||||
|
todo: w.todo ?? true,
|
||||||
|
todoTitleExpr: w.todoTitleExpr ?? '',
|
||||||
|
todoStatusExpr: w.todoStatusExpr ?? '',
|
||||||
|
todoDescriptionExpr: w.todoDescriptionExpr ?? '',
|
||||||
|
todoDueDateExpr: w.todoDueDateExpr ?? '',
|
||||||
|
todoTagExpr: w.todoTagExpr ?? '',
|
||||||
|
todoAssigneeExpr: w.todoAssigneeExpr ?? '',
|
||||||
|
todoPriorityExpr: w.todoPriorityExpr ?? '',
|
||||||
|
todoCompletedExpr: w.todoCompletedExpr ?? '',
|
||||||
|
todoOrderExpr: w.todoOrderExpr ?? '',
|
||||||
|
todoStatusOrder:
|
||||||
|
w.todoStatusOrder ??
|
||||||
|
'Backlog, Ready to Start, In Progress, Code Review, Testing, Staging',
|
||||||
|
todoAllowDragging: w.todoAllowDragging ?? true,
|
||||||
languageTextMenuEn: w.languageTextMenuEn ?? '',
|
languageTextMenuEn: w.languageTextMenuEn ?? '',
|
||||||
languageTextMenuTr: w.languageTextMenuTr ?? '',
|
languageTextMenuTr: w.languageTextMenuTr ?? '',
|
||||||
languageTextTitleEn: w.languageTextTitleEn ?? '',
|
languageTextTitleEn: w.languageTextTitleEn ?? '',
|
||||||
|
|
@ -421,6 +467,7 @@ const Wizard = () => {
|
||||||
languageTextMenuParentTr: w.languageTextMenuParentTr ?? '',
|
languageTextMenuParentTr: w.languageTextMenuParentTr ?? '',
|
||||||
permissionGroupName: w.permissionGroupName ?? '',
|
permissionGroupName: w.permissionGroupName ?? '',
|
||||||
menuParentCode: w.menuParentCode ?? '',
|
menuParentCode: w.menuParentCode ?? '',
|
||||||
|
menuParentShortName: w.menuParentShortName ?? '',
|
||||||
menuParentIcon: w.menuParentIcon ?? '',
|
menuParentIcon: w.menuParentIcon ?? '',
|
||||||
menuIcon: w.menuIcon ?? '',
|
menuIcon: w.menuIcon ?? '',
|
||||||
dataSourceCode: w.dataSourceCode ?? '',
|
dataSourceCode: w.dataSourceCode ?? '',
|
||||||
|
|
@ -444,15 +491,12 @@ const Wizard = () => {
|
||||||
schedulerEndDateExpr: w.schedulerEndDateExpr ?? '',
|
schedulerEndDateExpr: w.schedulerEndDateExpr ?? '',
|
||||||
subForms: w.subForms ?? [],
|
subForms: w.subForms ?? [],
|
||||||
widgets: w.widgets ?? [],
|
widgets: w.widgets ?? [],
|
||||||
workflow: w.workflow ?? {
|
approvalUserFieldName: w.approvalUserFieldName ?? '',
|
||||||
approvalUserFieldName: '',
|
approvalDateFieldName: w.approvalDateFieldName ?? '',
|
||||||
isFilterUserName: false,
|
approvalStatusFieldName: w.approvalStatusFieldName ?? '',
|
||||||
approvalDateFieldName: '',
|
approvalDescriptionFieldName: w.approvalDescriptionFieldName ?? '',
|
||||||
approvalStatusFieldName: '',
|
approvalIsFilterUserName: w.approvalIsFilterUserName ?? false,
|
||||||
approvalDescriptionFieldName: '',
|
criteria: w.criteria ?? [],
|
||||||
criteria: [],
|
|
||||||
},
|
|
||||||
workflowCriteria: w.workflowCriteria ?? w.workflow?.criteria ?? [],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Queue column load to run once dbObjects is available
|
// Queue column load to run once dbObjects is available
|
||||||
|
|
@ -476,19 +520,19 @@ const Wizard = () => {
|
||||||
caption: g.caption ?? '',
|
caption: g.caption ?? '',
|
||||||
colCount: g.colCount ?? 2,
|
colCount: g.colCount ?? 2,
|
||||||
items: (g.items ?? []).map(
|
items: (g.items ?? []).map(
|
||||||
(it: any, ii: number) =>
|
(it: WizardGroupItem, ii: number) =>
|
||||||
({
|
({
|
||||||
id: `${it.dataField}_edit_${ii}_${Date.now()}`,
|
id: `${it.fieldName}_edit_${ii}_${Date.now()}`,
|
||||||
dataField: it.dataField ?? '',
|
fieldName: it.fieldName ?? '',
|
||||||
editorType: it.editorType ?? 'dxTextBox',
|
editorType: it.editorType ?? 'dxTextBox',
|
||||||
editorOptions: it.editorOptions ?? '',
|
editorOptions: it.editorOptions ?? '',
|
||||||
editorScript: it.editorScript ?? '',
|
editorScript: it.editorScript ?? '',
|
||||||
colSpan: it.colSpan ?? 1,
|
colSpan: it.colSpan ?? 1,
|
||||||
isRequired: it.isRequired ?? false,
|
isRequired: it.isRequired ?? false,
|
||||||
includeInEditingForm: it.includeInEditingForm ?? true,
|
includeInEditingForm: it.includeInEditingForm ?? true,
|
||||||
turkishCaption: it.turkishCaption ?? it.dataField,
|
turkishCaption: it.turkishCaption ?? it.fieldName,
|
||||||
englishCaption: it.englishCaption ?? it.dataField,
|
englishCaption: it.englishCaption ?? it.fieldName,
|
||||||
captionName: it.captionName ?? `App.Listform.ListformField.${it.dataField}`,
|
captionName: it.captionName ?? `App.Listform.ListformField.${it.fieldName}`,
|
||||||
lookupDataSourceType:
|
lookupDataSourceType:
|
||||||
(it.lookupDataSourceType as UiLookupDataSourceTypeEnum) ??
|
(it.lookupDataSourceType as UiLookupDataSourceTypeEnum) ??
|
||||||
UiLookupDataSourceTypeEnum.StaticData,
|
UiLookupDataSourceTypeEnum.StaticData,
|
||||||
|
|
@ -501,23 +545,21 @@ const Wizard = () => {
|
||||||
setEditingGroups(restoredGroups)
|
setEditingGroups(restoredGroups)
|
||||||
|
|
||||||
// Restore selectedColumns from all group items
|
// Restore selectedColumns from all group items
|
||||||
const allFields = new Set(restoredGroups.flatMap((g) => g.items.map((i) => i.dataField)))
|
const allFields = new Set(restoredGroups.flatMap((g) => g.items.map((i) => i.fieldName)))
|
||||||
setSelectedColumns(allFields)
|
setSelectedColumns(allFields)
|
||||||
}
|
}
|
||||||
|
|
||||||
setSubForms(w.subForms ?? [])
|
setSubForms(w.subForms ?? [])
|
||||||
setWidgets(w.widgets ?? [])
|
setWidgets(w.widgets ?? [])
|
||||||
setWorkflow(
|
setWorkflow({
|
||||||
w.workflow ?? {
|
approvalUserFieldName: w.approvalUserFieldName ?? '',
|
||||||
approvalUserFieldName: '',
|
approvalDateFieldName: w.approvalDateFieldName ?? '',
|
||||||
isFilterUserName: false,
|
approvalStatusFieldName: w.approvalStatusFieldName ?? '',
|
||||||
approvalDateFieldName: '',
|
approvalDescriptionFieldName: w.approvalDescriptionFieldName ?? '',
|
||||||
approvalStatusFieldName: '',
|
approvalIsFilterUserName: w.approvalIsFilterUserName ?? false,
|
||||||
approvalDescriptionFieldName: '',
|
criteria: w.criteria ?? [],
|
||||||
criteria: [],
|
})
|
||||||
},
|
setCriteria(w.criteria ?? [])
|
||||||
)
|
|
||||||
setWorkflowCriteria(w.workflowCriteria ?? w.workflow?.criteria ?? [])
|
|
||||||
} catch {
|
} catch {
|
||||||
toast.push(
|
toast.push(
|
||||||
<Notification type="danger">
|
<Notification type="danger">
|
||||||
|
|
@ -619,8 +661,16 @@ const Wizard = () => {
|
||||||
formikRef.current?.setFieldValue('menuParentCode', code)
|
formikRef.current?.setFieldValue('menuParentCode', code)
|
||||||
const selectedMenu = rawMenuItems.find((item) => item.code === code)
|
const selectedMenu = rawMenuItems.find((item) => item.code === code)
|
||||||
formikRef.current?.setFieldValue('menuParentIcon', selectedMenu?.icon ?? '')
|
formikRef.current?.setFieldValue('menuParentIcon', selectedMenu?.icon ?? '')
|
||||||
if (!code) return
|
formikRef.current?.setFieldValue('languageTextMenuParentEn', selectedMenu?.menuTextEn ?? '')
|
||||||
applyPermissionGroupFromRoot(findRootCode(rawMenuItems, code))
|
formikRef.current?.setFieldValue('languageTextMenuParentTr', selectedMenu?.menuTextTr ?? '')
|
||||||
|
if (!code) {
|
||||||
|
formikRef.current?.setFieldValue('menuParentShortName', '')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const rootCode = findRootCode(rawMenuItems, code)
|
||||||
|
const rootMenu = rawMenuItems.find((item) => item.code === rootCode)
|
||||||
|
formikRef.current?.setFieldValue('menuParentShortName', rootMenu?.shortName ?? '')
|
||||||
|
applyPermissionGroupFromRoot(rootCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleMenuCreated = async (menu: {
|
const handleMenuCreated = async (menu: {
|
||||||
|
|
@ -629,6 +679,7 @@ const Wizard = () => {
|
||||||
menuTextEn: string
|
menuTextEn: string
|
||||||
menuTextTr: string
|
menuTextTr: string
|
||||||
icon?: string
|
icon?: string
|
||||||
|
shortName?: string
|
||||||
}) => {
|
}) => {
|
||||||
formikRef.current?.setFieldValue('menuParentCode', menu.code)
|
formikRef.current?.setFieldValue('menuParentCode', menu.code)
|
||||||
formikRef.current?.setFieldValue('menuParentIcon', menu.icon ?? '')
|
formikRef.current?.setFieldValue('menuParentIcon', menu.icon ?? '')
|
||||||
|
|
@ -636,6 +687,11 @@ const Wizard = () => {
|
||||||
formikRef.current?.setFieldValue('languageTextMenuParentTr', menu.menuTextTr)
|
formikRef.current?.setFieldValue('languageTextMenuParentTr', menu.menuTextTr)
|
||||||
|
|
||||||
const rootCode = menu.parentCode ? findRootCode(rawMenuItems, menu.parentCode) : menu.code
|
const rootCode = menu.parentCode ? findRootCode(rawMenuItems, menu.parentCode) : menu.code
|
||||||
|
const existingRoot = rawMenuItems.find((item) => item.code === rootCode)
|
||||||
|
formikRef.current?.setFieldValue(
|
||||||
|
'menuParentShortName',
|
||||||
|
menu.parentCode ? (existingRoot?.shortName ?? '') : (menu.shortName ?? ''),
|
||||||
|
)
|
||||||
applyPermissionGroupFromRoot(rootCode)
|
applyPermissionGroupFromRoot(rootCode)
|
||||||
|
|
||||||
await getMenuList()
|
await getMenuList()
|
||||||
|
|
@ -707,10 +763,10 @@ const Wizard = () => {
|
||||||
caption: g.caption,
|
caption: g.caption,
|
||||||
colCount: g.colCount,
|
colCount: g.colCount,
|
||||||
items: g.items.map((item) => {
|
items: g.items.map((item) => {
|
||||||
const col = selectCommandColumns.find((c) => c.columnName === item.dataField)
|
const col = selectCommandColumns.find((c) => c.columnName === item.fieldName)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dataField: item.dataField,
|
fieldName: item.fieldName,
|
||||||
editorType: item.editorType,
|
editorType: item.editorType,
|
||||||
editorOptions: item.editorOptions ?? '',
|
editorOptions: item.editorOptions ?? '',
|
||||||
editorScript: item.editorScript ?? '',
|
editorScript: item.editorScript ?? '',
|
||||||
|
|
@ -730,11 +786,12 @@ const Wizard = () => {
|
||||||
})),
|
})),
|
||||||
subForms,
|
subForms,
|
||||||
widgets,
|
widgets,
|
||||||
workflow: {
|
approvalUserFieldName: workflow.approvalUserFieldName,
|
||||||
...workflow,
|
approvalDateFieldName: workflow.approvalDateFieldName,
|
||||||
criteria: workflowCriteria,
|
approvalStatusFieldName: workflow.approvalStatusFieldName,
|
||||||
},
|
approvalDescriptionFieldName: workflow.approvalDescriptionFieldName,
|
||||||
workflowCriteria,
|
approvalIsFilterUserName: workflow.approvalIsFilterUserName,
|
||||||
|
criteria,
|
||||||
})
|
})
|
||||||
|
|
||||||
// ✅ sonra config çek
|
// ✅ sonra config çek
|
||||||
|
|
@ -780,6 +837,7 @@ const Wizard = () => {
|
||||||
<Steps.Item title={translate('::ListForms.ListFormEdit.SubForms') || 'Sub Forms'} />
|
<Steps.Item title={translate('::ListForms.ListFormEdit.SubForms') || 'Sub Forms'} />
|
||||||
<Steps.Item title={translate('::ListForms.ListFormEdit.TabWidgets') || 'Widgets'} />
|
<Steps.Item title={translate('::ListForms.ListFormEdit.TabWidgets') || 'Widgets'} />
|
||||||
<Steps.Item title={translate('::ListForms.ListFormEdit.TabWorkflow') || 'Workflow'} />
|
<Steps.Item title={translate('::ListForms.ListFormEdit.TabWorkflow') || 'Workflow'} />
|
||||||
|
<Steps.Item title={translate('::ListForms.ListFormEdit.TabTodo') || 'Todo / Kanban'} />
|
||||||
<Steps.Item title={translate('::App.Platform.Deploy') || 'Deploy'} />
|
<Steps.Item title={translate('::App.Platform.Deploy') || 'Deploy'} />
|
||||||
</Steps>
|
</Steps>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -815,6 +873,7 @@ const Wizard = () => {
|
||||||
onMenuParentChange={handleMenuParentChange}
|
onMenuParentChange={handleMenuParentChange}
|
||||||
onClearMenuParent={() => {
|
onClearMenuParent={() => {
|
||||||
formikRef.current?.setFieldValue('menuParentCode', '')
|
formikRef.current?.setFieldValue('menuParentCode', '')
|
||||||
|
formikRef.current?.setFieldValue('menuParentShortName', '')
|
||||||
formikRef.current?.setFieldValue('menuParentIcon', '')
|
formikRef.current?.setFieldValue('menuParentIcon', '')
|
||||||
}}
|
}}
|
||||||
onMenuCreated={handleMenuCreated}
|
onMenuCreated={handleMenuCreated}
|
||||||
|
|
@ -900,19 +959,30 @@ const Wizard = () => {
|
||||||
<WizardStep6
|
<WizardStep6
|
||||||
listFormCode={values.listFormCode}
|
listFormCode={values.listFormCode}
|
||||||
workflow={workflow}
|
workflow={workflow}
|
||||||
criteria={workflowCriteria}
|
criteria={criteria}
|
||||||
selectCommandColumns={selectCommandColumns}
|
selectCommandColumns={selectCommandColumns}
|
||||||
translate={translate}
|
translate={translate}
|
||||||
onWorkflowChange={setWorkflow}
|
onWorkflowChange={setWorkflow}
|
||||||
onCriteriaChange={setWorkflowCriteria}
|
onCriteriaChange={setCriteria}
|
||||||
onBack={() => setCurrentStep(4)}
|
onBack={() => setCurrentStep(4)}
|
||||||
onNext={() => setCurrentStep(6)}
|
onNext={() => setCurrentStep(6)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* ─── Step 7: Deploy ───────────────────────────── */}
|
{/* ─── Step 7: Todo / Kanban ────────────────────── */}
|
||||||
{currentStep === 6 && (
|
{currentStep === 6 && (
|
||||||
<WizardStep7
|
<WizardStep7
|
||||||
|
selectedColumns={selectedColumns}
|
||||||
|
selectCommandColumns={selectCommandColumns}
|
||||||
|
translate={translate}
|
||||||
|
onBack={() => setCurrentStep(5)}
|
||||||
|
onNext={() => setCurrentStep(7)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* ─── Step 8: Deploy ───────────────────────────── */}
|
||||||
|
{currentStep === 7 && (
|
||||||
|
<WizardStep8
|
||||||
values={values}
|
values={values}
|
||||||
wizardName={values.wizardName}
|
wizardName={values.wizardName}
|
||||||
selectedColumns={selectedColumns}
|
selectedColumns={selectedColumns}
|
||||||
|
|
@ -921,9 +991,9 @@ const Wizard = () => {
|
||||||
subForms={subForms}
|
subForms={subForms}
|
||||||
widgets={widgets}
|
widgets={widgets}
|
||||||
workflow={workflow}
|
workflow={workflow}
|
||||||
workflowCriteria={workflowCriteria}
|
criteria={criteria}
|
||||||
translate={translate}
|
translate={translate}
|
||||||
onBack={() => setCurrentStep(5)}
|
onBack={() => setCurrentStep(6)}
|
||||||
onSubmit={handleDeploy}
|
onSubmit={handleDeploy}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import { ListFormWizardDto } from '@/proxy/admin/wizard/models'
|
||||||
export interface MenuTreeNode {
|
export interface MenuTreeNode {
|
||||||
code: string
|
code: string
|
||||||
displayName: string
|
displayName: string
|
||||||
|
shortName?: string
|
||||||
icon?: string
|
icon?: string
|
||||||
url?: string
|
url?: string
|
||||||
order?: number
|
order?: number
|
||||||
|
|
@ -41,6 +42,7 @@ export function buildMenuTree(items: MenuItem[]): MenuTreeNode[] {
|
||||||
map.set(item.code!, {
|
map.set(item.code!, {
|
||||||
code: item.code!,
|
code: item.code!,
|
||||||
displayName: item.displayName ?? item.code!,
|
displayName: item.displayName ?? item.code!,
|
||||||
|
shortName: item.shortName ?? undefined,
|
||||||
icon: item.icon ?? undefined,
|
icon: item.icon ?? undefined,
|
||||||
url: item.url ?? undefined,
|
url: item.url ?? undefined,
|
||||||
order: item.order ?? undefined,
|
order: item.order ?? undefined,
|
||||||
|
|
|
||||||
|
|
@ -516,6 +516,20 @@ const WizardStep2 = ({
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.DetailsLayoutDto.CardLayout')}
|
||||||
|
invalid={errors?.card && touched?.card}
|
||||||
|
errorMessage={errors?.card}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
className="w-20"
|
||||||
|
autoComplete="off"
|
||||||
|
name="card"
|
||||||
|
placeholder={translate('::ListForms.ListFormEdit.DetailsLayoutDto.CardLayout')}
|
||||||
|
component={Checkbox}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
<FormItem
|
<FormItem
|
||||||
label={translate('::ListForms.ListFormEdit.DetailsLayoutDto.PivotLayout')}
|
label={translate('::ListForms.ListFormEdit.DetailsLayoutDto.PivotLayout')}
|
||||||
invalid={errors?.pivot && touched?.pivot}
|
invalid={errors?.pivot && touched?.pivot}
|
||||||
|
|
@ -585,6 +599,20 @@ const WizardStep2 = ({
|
||||||
component={Checkbox}
|
component={Checkbox}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.DetailsLayoutDto.TodoLayout')}
|
||||||
|
invalid={errors?.todo && touched?.todo}
|
||||||
|
errorMessage={errors?.todo}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
className="w-20"
|
||||||
|
autoComplete="off"
|
||||||
|
name="todo"
|
||||||
|
placeholder={translate('::ListForms.ListFormEdit.DetailsLayoutDto.TodoLayout')}
|
||||||
|
component={Checkbox}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { Button, Dialog } from '@/components/ui'
|
import { Button, Dialog } from '@/components/ui'
|
||||||
|
import type { SelectBoxOption } from '@/types/shared'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import {
|
import {
|
||||||
columnEditorTypeListOptions,
|
columnEditorTypeListOptions,
|
||||||
|
|
@ -28,14 +29,17 @@ import {
|
||||||
FaTrash,
|
FaTrash,
|
||||||
FaArrowRight,
|
FaArrowRight,
|
||||||
FaCode,
|
FaCode,
|
||||||
|
FaSlidersH,
|
||||||
} from 'react-icons/fa'
|
} from 'react-icons/fa'
|
||||||
import { UiLookupDataSourceTypeEnum } from '@/proxy/form/models'
|
import { UiLookupDataSourceTypeEnum } from '@/proxy/form/models'
|
||||||
|
import EditorOptionsBuilderDialog from '../edit/json-row-operations/EditorOptionsBuilderDialog'
|
||||||
|
import EditorScriptBuilderDialog from '../edit/json-row-operations/EditorScriptBuilderDialog'
|
||||||
import { buildLookupQuery } from '../lookupQuery'
|
import { buildLookupQuery } from '../lookupQuery'
|
||||||
|
|
||||||
// ─── Types ────────────────────────────────────────────────────────────────────
|
// ─── Types ────────────────────────────────────────────────────────────────────
|
||||||
export interface WizardGroupItem {
|
export interface WizardGroupItem {
|
||||||
id: string
|
id: string
|
||||||
dataField: string
|
fieldName: string
|
||||||
editorType: string
|
editorType: string
|
||||||
editorOptions: string
|
editorOptions: string
|
||||||
editorScript: string
|
editorScript: string
|
||||||
|
|
@ -109,7 +113,7 @@ function newGroupItem(colName: string, meta?: DatabaseColumnDto): WizardGroupIte
|
||||||
const sqlType = meta?.dataType ?? ''
|
const sqlType = meta?.dataType ?? ''
|
||||||
return {
|
return {
|
||||||
id: `${colName}_${Date.now()}`,
|
id: `${colName}_${Date.now()}`,
|
||||||
dataField: colName,
|
fieldName: colName,
|
||||||
editorType: inferEditorType(sqlType),
|
editorType: inferEditorType(sqlType),
|
||||||
editorOptions: '',
|
editorOptions: '',
|
||||||
editorScript: '',
|
editorScript: '',
|
||||||
|
|
@ -169,6 +173,7 @@ interface SortableItemProps {
|
||||||
groupColCount: number
|
groupColCount: number
|
||||||
dbObjects: SqlObjectExplorerDto | null
|
dbObjects: SqlObjectExplorerDto | null
|
||||||
dsCode: string
|
dsCode: string
|
||||||
|
editorScriptFields: SelectBoxOption[]
|
||||||
onTurkishCaptionChange: (val: string) => void
|
onTurkishCaptionChange: (val: string) => void
|
||||||
onEnglishCaptionChange: (val: string) => void
|
onEnglishCaptionChange: (val: string) => void
|
||||||
onEditorTypeChange: (val: string) => void
|
onEditorTypeChange: (val: string) => void
|
||||||
|
|
@ -190,6 +195,7 @@ function SortableItem({
|
||||||
groupColCount,
|
groupColCount,
|
||||||
dbObjects,
|
dbObjects,
|
||||||
dsCode,
|
dsCode,
|
||||||
|
editorScriptFields,
|
||||||
onTurkishCaptionChange,
|
onTurkishCaptionChange,
|
||||||
onEnglishCaptionChange,
|
onEnglishCaptionChange,
|
||||||
onEditorTypeChange,
|
onEditorTypeChange,
|
||||||
|
|
@ -207,6 +213,8 @@ function SortableItem({
|
||||||
}: SortableItemProps) {
|
}: SortableItemProps) {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
const [isTablePickerOpen, setIsTablePickerOpen] = useState(false)
|
const [isTablePickerOpen, setIsTablePickerOpen] = useState(false)
|
||||||
|
const [isEditorOptionsDialogOpen, setIsEditorOptionsDialogOpen] = useState(false)
|
||||||
|
const [isEditorScriptDialogOpen, setIsEditorScriptDialogOpen] = useState(false)
|
||||||
const [tableSearch, setTableSearch] = useState('')
|
const [tableSearch, setTableSearch] = useState('')
|
||||||
const [pickerStep, setPickerStep] = useState<'table' | 'columns'>('table')
|
const [pickerStep, setPickerStep] = useState<'table' | 'columns'>('table')
|
||||||
const [pickerTable, setPickerTable] = useState<{ schemaName: string; tableName: string } | null>(
|
const [pickerTable, setPickerTable] = useState<{ schemaName: string; tableName: string } | null>(
|
||||||
|
|
@ -248,7 +256,7 @@ function SortableItem({
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
/>
|
/>
|
||||||
<span className="flex-1 text-xs font-semibold text-indigo-600 dark:text-indigo-400 truncate">
|
<span className="flex-1 text-xs font-semibold text-indigo-600 dark:text-indigo-400 truncate">
|
||||||
{item.dataField}
|
{item.fieldName}
|
||||||
</span>
|
</span>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
@ -564,12 +572,23 @@ function SortableItem({
|
||||||
<span className="text-[10px] text-gray-400 font-medium">
|
<span className="text-[10px] text-gray-400 font-medium">
|
||||||
{translate('::ListForms.Wizard.Step3.EditorOptions')}
|
{translate('::ListForms.Wizard.Step3.EditorOptions')}
|
||||||
</span>
|
</span>
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
<input
|
<input
|
||||||
value={item.editorOptions}
|
value={item.editorOptions}
|
||||||
onChange={(e) => onEditorOptionsChange(e.target.value)}
|
onChange={(e) => onEditorOptionsChange(e.target.value)}
|
||||||
placeholder='{"readOnly": false}'
|
placeholder='{"readOnly": false}'
|
||||||
className="w-full text-xs px-1.5 py-1 rounded border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-700 dark:text-gray-200 focus:outline-none focus:border-indigo-400 resize-none font-mono"
|
className="min-w-0 flex-1 text-xs px-1.5 py-1 rounded border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-700 dark:text-gray-200 focus:outline-none focus:border-indigo-400 resize-none font-mono"
|
||||||
/>
|
/>
|
||||||
|
<Button
|
||||||
|
shape="circle"
|
||||||
|
variant="plain"
|
||||||
|
type="button"
|
||||||
|
size="sm"
|
||||||
|
title="Build editor options"
|
||||||
|
icon={<FaSlidersH />}
|
||||||
|
onClick={() => setIsEditorOptionsDialogOpen(true)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Editor Script */}
|
{/* Editor Script */}
|
||||||
|
|
@ -577,13 +596,40 @@ function SortableItem({
|
||||||
<span className="text-[10px] text-gray-400 font-medium">
|
<span className="text-[10px] text-gray-400 font-medium">
|
||||||
{translate('::ListForms.Wizard.Step3.EditorScript')}
|
{translate('::ListForms.Wizard.Step3.EditorScript')}
|
||||||
</span>
|
</span>
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
<input
|
<input
|
||||||
value={item.editorScript}
|
value={item.editorScript}
|
||||||
onChange={(e) => onEditorScriptChange(e.target.value)}
|
onChange={(e) => onEditorScriptChange(e.target.value)}
|
||||||
placeholder="(e) => { /* e.component */ }"
|
placeholder="(e) => { /* e.component */ }"
|
||||||
className="w-full text-xs px-1.5 py-1 rounded border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-700 dark:text-gray-200 focus:outline-none focus:border-indigo-400 resize-none font-mono"
|
className="min-w-0 flex-1 text-xs px-1.5 py-1 rounded border border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700 text-gray-700 dark:text-gray-200 focus:outline-none focus:border-indigo-400 resize-none font-mono"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
shape="circle"
|
||||||
|
variant="plain"
|
||||||
|
type="button"
|
||||||
|
size="sm"
|
||||||
|
title="Build editor script"
|
||||||
|
icon={<FaCode />}
|
||||||
|
onClick={() => setIsEditorScriptDialogOpen(true)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<EditorOptionsBuilderDialog
|
||||||
|
isOpen={isEditorOptionsDialogOpen}
|
||||||
|
value={item.editorOptions}
|
||||||
|
editorType={item.editorType}
|
||||||
|
onClose={() => setIsEditorOptionsDialogOpen(false)}
|
||||||
|
onApply={onEditorOptionsChange}
|
||||||
|
/>
|
||||||
|
<EditorScriptBuilderDialog
|
||||||
|
isOpen={isEditorScriptDialogOpen}
|
||||||
|
value={item.editorScript}
|
||||||
|
currentField={item.fieldName}
|
||||||
|
fields={editorScriptFields}
|
||||||
|
onClose={() => setIsEditorScriptDialogOpen(false)}
|
||||||
|
onApply={onEditorScriptChange}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Bottom row: ColSpan + Editing Form + Required */}
|
{/* Bottom row: ColSpan + Editing Form + Required */}
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
|
|
@ -639,6 +685,7 @@ interface GroupCardProps {
|
||||||
hasAvailable: boolean
|
hasAvailable: boolean
|
||||||
dbObjects: SqlObjectExplorerDto | null
|
dbObjects: SqlObjectExplorerDto | null
|
||||||
dsCode: string
|
dsCode: string
|
||||||
|
editorScriptFields: SelectBoxOption[]
|
||||||
onCaptionChange: (val: string) => void
|
onCaptionChange: (val: string) => void
|
||||||
onColCountChange: (val: number) => void
|
onColCountChange: (val: number) => void
|
||||||
onItemChange: (itemId: string, patch: Partial<WizardGroupItem>) => void
|
onItemChange: (itemId: string, patch: Partial<WizardGroupItem>) => void
|
||||||
|
|
@ -653,6 +700,7 @@ function GroupCard({
|
||||||
hasAvailable,
|
hasAvailable,
|
||||||
dbObjects,
|
dbObjects,
|
||||||
dsCode,
|
dsCode,
|
||||||
|
editorScriptFields,
|
||||||
onCaptionChange,
|
onCaptionChange,
|
||||||
onColCountChange,
|
onColCountChange,
|
||||||
onItemChange,
|
onItemChange,
|
||||||
|
|
@ -759,6 +807,7 @@ function GroupCard({
|
||||||
groupColCount={group.colCount}
|
groupColCount={group.colCount}
|
||||||
dbObjects={dbObjects}
|
dbObjects={dbObjects}
|
||||||
dsCode={dsCode}
|
dsCode={dsCode}
|
||||||
|
editorScriptFields={editorScriptFields}
|
||||||
onCaptionNameChange={(val) => onItemChange(item.id, { captionName: val })}
|
onCaptionNameChange={(val) => onItemChange(item.id, { captionName: val })}
|
||||||
onTurkishCaptionChange={(val) => onItemChange(item.id, { turkishCaption: val })}
|
onTurkishCaptionChange={(val) => onItemChange(item.id, { turkishCaption: val })}
|
||||||
onEnglishCaptionChange={(val) => onItemChange(item.id, { englishCaption: val })}
|
onEnglishCaptionChange={(val) => onItemChange(item.id, { englishCaption: val })}
|
||||||
|
|
@ -809,7 +858,7 @@ const WizardStep3 = ({
|
||||||
// 1. Remove items that are no longer in selectedColumns
|
// 1. Remove items that are no longer in selectedColumns
|
||||||
const cleaned = groups.map((g) => ({
|
const cleaned = groups.map((g) => ({
|
||||||
...g,
|
...g,
|
||||||
items: g.items.filter((i) => selectedColumns.has(i.dataField)),
|
items: g.items.filter((i) => selectedColumns.has(i.fieldName)),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// 2. Ensure at least one empty group exists for the user to drag into
|
// 2. Ensure at least one empty group exists for the user to drag into
|
||||||
|
|
@ -835,8 +884,14 @@ const WizardStep3 = ({
|
||||||
}, [selectedColumns])
|
}, [selectedColumns])
|
||||||
|
|
||||||
// ── Available columns = selected but NOT yet placed ───────────────────────
|
// ── Available columns = selected but NOT yet placed ───────────────────────
|
||||||
const placedColumns = new Set(groups.flatMap((g) => g.items.map((i) => i.dataField)))
|
const placedColumns = new Set(groups.flatMap((g) => g.items.map((i) => i.fieldName)))
|
||||||
const availableColumns = [...selectedColumns].filter((c) => !placedColumns.has(c))
|
const availableColumns = [...selectedColumns].filter((c) => !placedColumns.has(c))
|
||||||
|
const editorScriptFields: SelectBoxOption[] = groups.flatMap((group) =>
|
||||||
|
group.items.map((item) => ({
|
||||||
|
value: item.fieldName,
|
||||||
|
label: item.captionName || item.fieldName,
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
|
||||||
// ── Helpers ───────────────────────────────────────────────────────────────
|
// ── Helpers ───────────────────────────────────────────────────────────────
|
||||||
const colMeta = (name: string) => selectCommandColumns.find((c) => c.columnName === name)
|
const colMeta = (name: string) => selectCommandColumns.find((c) => c.columnName === name)
|
||||||
|
|
@ -878,7 +933,7 @@ const WizardStep3 = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
const addAllToGroup = (groupId: string) => {
|
const addAllToGroup = (groupId: string) => {
|
||||||
const placed = new Set(groups.flatMap((g) => g.items.map((i) => i.dataField)))
|
const placed = new Set(groups.flatMap((g) => g.items.map((i) => i.fieldName)))
|
||||||
const toAdd = [...selectedColumns].filter((c) => !placed.has(c))
|
const toAdd = [...selectedColumns].filter((c) => !placed.has(c))
|
||||||
if (toAdd.length === 0) return
|
if (toAdd.length === 0) return
|
||||||
onGroupsChange(
|
onGroupsChange(
|
||||||
|
|
@ -1018,7 +1073,7 @@ const WizardStep3 = ({
|
||||||
<div className="flex items-center gap-2 px-3 py-2 rounded-lg border border-indigo-400 bg-indigo-50 text-sm shadow-lg cursor-grabbing">
|
<div className="flex items-center gap-2 px-3 py-2 rounded-lg border border-indigo-400 bg-indigo-50 text-sm shadow-lg cursor-grabbing">
|
||||||
<FaGripVertical className="text-indigo-300 text-xs" />
|
<FaGripVertical className="text-indigo-300 text-xs" />
|
||||||
<span className="text-xs font-semibold text-indigo-600 bg-indigo-100 px-2 py-0.5 rounded">
|
<span className="text-xs font-semibold text-indigo-600 bg-indigo-100 px-2 py-0.5 rounded">
|
||||||
{item.dataField}
|
{item.fieldName}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs text-gray-500">{item.editorType}</span>
|
<span className="text-xs text-gray-500">{item.editorType}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1087,6 +1142,7 @@ const WizardStep3 = ({
|
||||||
hasAvailable={availableColumns.length > 0}
|
hasAvailable={availableColumns.length > 0}
|
||||||
dbObjects={dbObjects}
|
dbObjects={dbObjects}
|
||||||
dsCode={dsCode}
|
dsCode={dsCode}
|
||||||
|
editorScriptFields={editorScriptFields}
|
||||||
onCaptionChange={(val) => updateGroup(group.id, { caption: val })}
|
onCaptionChange={(val) => updateGroup(group.id, { caption: val })}
|
||||||
onColCountChange={(val) => updateGroup(group.id, { colCount: val })}
|
onColCountChange={(val) => updateGroup(group.id, { colCount: val })}
|
||||||
onItemChange={(itemId, patch) => updateItem(group.id, itemId, patch)}
|
onItemChange={(itemId, patch) => updateItem(group.id, itemId, patch)}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ type PendingLink = {
|
||||||
outcome: string
|
outcome: string
|
||||||
} | null
|
} | null
|
||||||
|
|
||||||
|
type RequiredWorkflowField = 'approvalUserFieldName' | 'approvalStatusFieldName'
|
||||||
|
|
||||||
const toDesignerCriteria = (items: ListFormWorkflowCriteriaDto[]): WorkflowCriteriaDto[] =>
|
const toDesignerCriteria = (items: ListFormWorkflowCriteriaDto[]): WorkflowCriteriaDto[] =>
|
||||||
items.map((item) => ({
|
items.map((item) => ({
|
||||||
...item,
|
...item,
|
||||||
|
|
@ -67,6 +69,9 @@ function WizardStep6({
|
||||||
const [dragPreview, setDragPreview] = useState<any>(null)
|
const [dragPreview, setDragPreview] = useState<any>(null)
|
||||||
const [canvasZoom, setCanvasZoom] = useState(1)
|
const [canvasZoom, setCanvasZoom] = useState(1)
|
||||||
const [designerTab, setDesignerTab] = useState('flow')
|
const [designerTab, setDesignerTab] = useState('flow')
|
||||||
|
const [workflowErrors, setWorkflowErrors] = useState<
|
||||||
|
Partial<Record<RequiredWorkflowField, string>>
|
||||||
|
>({})
|
||||||
const canvasRef = useRef<HTMLDivElement | null>(null)
|
const canvasRef = useRef<HTMLDivElement | null>(null)
|
||||||
|
|
||||||
const currentCriteria = useMemo(() => toDesignerCriteria(criteria), [criteria])
|
const currentCriteria = useMemo(() => toDesignerCriteria(criteria), [criteria])
|
||||||
|
|
@ -91,6 +96,10 @@ function WizardStep6({
|
||||||
setCriteriaForm(selected ? toCriteriaForm(selected) : emptyCriteria('Start', listFormCode))
|
setCriteriaForm(selected ? toCriteriaForm(selected) : emptyCriteria('Start', listFormCode))
|
||||||
}, [currentCriteria, listFormCode, selectedId])
|
}, [currentCriteria, listFormCode, selectedId])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (criteria.length === 0) setWorkflowErrors({})
|
||||||
|
}, [criteria.length])
|
||||||
|
|
||||||
const updateCriteria = (next: WorkflowCriteriaDto[]) => onCriteriaChange(toWizardCriteria(next))
|
const updateCriteria = (next: WorkflowCriteriaDto[]) => onCriteriaChange(toWizardCriteria(next))
|
||||||
|
|
||||||
const saveCriteria = (event: FormEvent<HTMLFormElement>) => {
|
const saveCriteria = (event: FormEvent<HTMLFormElement>) => {
|
||||||
|
|
@ -250,6 +259,26 @@ function WizardStep6({
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const continueToTodo = () => {
|
||||||
|
if (criteria.length === 0) {
|
||||||
|
setWorkflowErrors({})
|
||||||
|
onNext()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const requiredMessage = translate('::ListForms.Wizard.Required')
|
||||||
|
const nextErrors: Partial<Record<RequiredWorkflowField, string>> = {}
|
||||||
|
if (!workflow.approvalUserFieldName?.trim()) {
|
||||||
|
nextErrors.approvalUserFieldName = requiredMessage
|
||||||
|
}
|
||||||
|
if (!workflow.approvalStatusFieldName?.trim()) {
|
||||||
|
nextErrors.approvalStatusFieldName = requiredMessage
|
||||||
|
}
|
||||||
|
|
||||||
|
setWorkflowErrors(nextErrors)
|
||||||
|
if (Object.keys(nextErrors).length === 0) onNext()
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-[calc(100vh-250px)] min-h-[500px] flex-col overflow-hidden">
|
<div className="flex h-[calc(100vh-250px)] min-h-[500px] flex-col overflow-hidden">
|
||||||
<div className="flex-1 overflow-y-auto pr-1">
|
<div className="flex-1 overflow-y-auto pr-1">
|
||||||
|
|
@ -280,8 +309,19 @@ function WizardStep6({
|
||||||
'approvalDescriptionFieldName',
|
'approvalDescriptionFieldName',
|
||||||
'::ListForms.ListFormEdit.Workflow.ApprovalDescriptionFieldName',
|
'::ListForms.ListFormEdit.Workflow.ApprovalDescriptionFieldName',
|
||||||
],
|
],
|
||||||
].map(([name, label]) => (
|
].map(([name, label]) => {
|
||||||
<FormItem key={name} label={translate(label)}>
|
const requiredForCriteria =
|
||||||
|
criteria.length > 0 &&
|
||||||
|
(name === 'approvalUserFieldName' || name === 'approvalStatusFieldName')
|
||||||
|
const error = workflowErrors[name as RequiredWorkflowField]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormItem
|
||||||
|
key={name}
|
||||||
|
errorMessage={error}
|
||||||
|
invalid={Boolean(error)}
|
||||||
|
label={`${translate(label)}${requiredForCriteria ? ' *' : ''}`}
|
||||||
|
>
|
||||||
<Field name={name}>
|
<Field name={name}>
|
||||||
{({ field, form }: FieldProps) => (
|
{({ field, form }: FieldProps) => (
|
||||||
<Select
|
<Select
|
||||||
|
|
@ -294,6 +334,10 @@ function WizardStep6({
|
||||||
)}
|
)}
|
||||||
onChange={(option: any) => {
|
onChange={(option: any) => {
|
||||||
form.setFieldValue(field.name, option?.value ?? '')
|
form.setFieldValue(field.name, option?.value ?? '')
|
||||||
|
setWorkflowErrors((current) => ({
|
||||||
|
...current,
|
||||||
|
[field.name]: undefined,
|
||||||
|
}))
|
||||||
onWorkflowChange({
|
onWorkflowChange({
|
||||||
...values,
|
...values,
|
||||||
[field.name]: option?.value ?? '',
|
[field.name]: option?.value ?? '',
|
||||||
|
|
@ -304,20 +348,23 @@ function WizardStep6({
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
))}
|
)
|
||||||
|
})}
|
||||||
<FormItem
|
<FormItem
|
||||||
label={translate('::ListForms.ListFormEdit.Workflow.IsFilterUserName')}
|
label={translate(
|
||||||
|
'::ListForms.ListFormEdit.Workflow.ApprovalIsFilterUserName',
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<Field name="isFilterUserName">
|
<Field name="approvalIsFilterUserName">
|
||||||
{({ field, form }: FieldProps<boolean>) => (
|
{({ field, form }: FieldProps<boolean>) => (
|
||||||
<Checkbox
|
<Checkbox
|
||||||
name={field.name}
|
name={field.name}
|
||||||
checked={Boolean(values.isFilterUserName)}
|
checked={Boolean(values.approvalIsFilterUserName)}
|
||||||
onChange={(checked) => {
|
onChange={(checked) => {
|
||||||
form.setFieldValue(field.name, checked)
|
form.setFieldValue(field.name, checked)
|
||||||
onWorkflowChange({
|
onWorkflowChange({
|
||||||
...values,
|
...values,
|
||||||
isFilterUserName: checked,
|
approvalIsFilterUserName: checked,
|
||||||
criteria,
|
criteria,
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
|
|
@ -402,7 +449,7 @@ function WizardStep6({
|
||||||
variant="solid"
|
variant="solid"
|
||||||
type="button"
|
type="button"
|
||||||
icon={<FaArrowRight />}
|
icon={<FaArrowRight />}
|
||||||
onClick={onNext}
|
onClick={continueToTodo}
|
||||||
>
|
>
|
||||||
{translate('::Next') || 'Next'}
|
{translate('::Next') || 'Next'}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -1,717 +1,172 @@
|
||||||
import { Button } from '@/components/ui'
|
import { Button, Checkbox, FormItem, Input, Select } from '@/components/ui'
|
||||||
|
import type { ListFormWizardDto } from '@/proxy/admin/wizard/models'
|
||||||
import type { DatabaseColumnDto } from '@/proxy/sql-query-manager/models'
|
import type { DatabaseColumnDto } from '@/proxy/sql-query-manager/models'
|
||||||
import React, { useState } from 'react'
|
import type { SelectBoxOption } from '@/types/shared'
|
||||||
import {
|
import { Field, type FieldProps, useFormikContext } from 'formik'
|
||||||
FaArrowLeft,
|
import { useMemo, useState } from 'react'
|
||||||
FaCheckCircle,
|
import { FaArrowLeft, FaArrowRight } from 'react-icons/fa'
|
||||||
FaChevronDown,
|
|
||||||
FaChevronRight,
|
|
||||||
FaCircle,
|
|
||||||
FaExclamationCircle,
|
|
||||||
FaRocket,
|
|
||||||
FaSpinner,
|
|
||||||
} from 'react-icons/fa'
|
|
||||||
import { WizardGroup } from './WizardStep3'
|
|
||||||
import { dbSourceTypeOptions, selectCommandTypeOptions } from '../edit/options'
|
|
||||||
import { ListFormWizardDto } from '@/proxy/admin/wizard/models'
|
|
||||||
import {
|
|
||||||
ListFormWorkflowCriteriaDto,
|
|
||||||
SubFormDto,
|
|
||||||
WidgetEditDto,
|
|
||||||
WorkflowDto,
|
|
||||||
} from '@/proxy/form/models'
|
|
||||||
import { formatWorkflowApprovers } from '@/utils/workflow/workflowHelpers'
|
|
||||||
|
|
||||||
// ─── Types ────────────────────────────────────────────────────────────────────
|
interface WizardStep7Props {
|
||||||
|
|
||||||
export interface WizardStep7Props {
|
|
||||||
values: ListFormWizardDto
|
|
||||||
wizardName: string
|
|
||||||
selectedColumns: Set<string>
|
selectedColumns: Set<string>
|
||||||
selectCommandColumns: DatabaseColumnDto[]
|
selectCommandColumns: DatabaseColumnDto[]
|
||||||
groups: WizardGroup[]
|
|
||||||
subForms: SubFormDto[]
|
|
||||||
widgets: WidgetEditDto[]
|
|
||||||
workflow: WorkflowDto
|
|
||||||
workflowCriteria: ListFormWorkflowCriteriaDto[]
|
|
||||||
translate: (key: string) => string
|
translate: (key: string) => string
|
||||||
onBack: () => void
|
onBack: () => void
|
||||||
onSubmit: () => Promise<void>
|
onNext: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogStatus = 'pending' | 'running' | 'success' | 'error'
|
const mappings: Array<{
|
||||||
|
name:
|
||||||
interface LogEntry {
|
| 'todoTitleExpr'
|
||||||
id: number
|
| 'todoStatusExpr'
|
||||||
label: string
|
| 'todoDescriptionExpr'
|
||||||
status: LogStatus
|
| 'todoDueDateExpr'
|
||||||
detail?: string
|
| 'todoTagExpr'
|
||||||
}
|
| 'todoAssigneeExpr'
|
||||||
|
| 'todoPriorityExpr'
|
||||||
// ─── Deploy log steps ─────────────────────────────────────────────────────────
|
| 'todoCompletedExpr'
|
||||||
|
| 'todoOrderExpr'
|
||||||
function buildLogSteps(
|
translationKey: string
|
||||||
values: ListFormWizardDto,
|
required?: boolean
|
||||||
groups: WizardGroup[],
|
}> = [
|
||||||
translate: (key: string, params?: Record<string, string | number>) => string,
|
|
||||||
): Omit<LogEntry, 'status'>[] {
|
|
||||||
const totalFields = groups.reduce((acc, g) => acc + g.items.length, 0)
|
|
||||||
return [
|
|
||||||
{ id: 1, label: translate('::ListForms.Wizard.Step4.Log.ValidatingConfig') },
|
|
||||||
{
|
{
|
||||||
id: 2,
|
name: 'todoTitleExpr',
|
||||||
label: translate('::ListForms.Wizard.Step4.Log.CreatingMenu', { 0: values.menuCode }),
|
translationKey: '::ListForms.ListFormFieldEdit.TodoTitleExpr',
|
||||||
detail: `Parent: ${values.menuParentCode}`,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
name: 'todoStatusExpr',
|
||||||
label: translate('::ListForms.Wizard.Step4.Log.SavingLanguageTexts'),
|
translationKey: '::ListForms.ListFormFieldEdit.TodoStatusExpr',
|
||||||
detail: `EN: ${values.languageTextMenuEn} / TR: ${values.languageTextMenuTr}`,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 4,
|
name: 'todoDescriptionExpr',
|
||||||
label: translate('::ListForms.Wizard.Step4.Log.ConfiguringPermission', {
|
translationKey: '::ListForms.ListFormFieldEdit.TodoDescriptionExpr',
|
||||||
0: values.permissionGroupName,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 5,
|
name: 'todoDueDateExpr',
|
||||||
label: translate('::ListForms.Wizard.Step4.Log.ConnectingDataSource', {
|
translationKey: '::ListForms.ListFormFieldEdit.TodoDueDateExpr',
|
||||||
0: values.dataSourceCode,
|
},
|
||||||
}),
|
{ name: 'todoTagExpr', translationKey: '::ListForms.ListFormFieldEdit.TodoTagExpr' },
|
||||||
|
{
|
||||||
|
name: 'todoAssigneeExpr',
|
||||||
|
translationKey: '::ListForms.ListFormFieldEdit.TodoAssigneeExpr',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 6,
|
name: 'todoPriorityExpr',
|
||||||
label: translate('::ListForms.Wizard.Step4.Log.CreatingListForm', { 0: values.listFormCode }),
|
translationKey: '::ListForms.ListFormFieldEdit.TodoPriorityExpr',
|
||||||
detail: `Key: ${values.keyFieldName}`,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 7,
|
name: 'todoCompletedExpr',
|
||||||
label: translate('::ListForms.Wizard.Step4.Log.SavingFormGroups', {
|
translationKey: '::ListForms.ListFormFieldEdit.TodoCompletedExpr',
|
||||||
0: groups.length,
|
|
||||||
1: totalFields,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
{ id: 8, label: translate('::ListForms.Wizard.Step4.Log.Deploying') },
|
{ name: 'todoOrderExpr', translationKey: '::ListForms.ListFormFieldEdit.TodoOrderExpr' },
|
||||||
{ id: 9, label: translate('::ListForms.Wizard.Step4.Log.Completed') },
|
]
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─── Mini-components ──────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function LogIcon({ status }: { status: LogStatus }) {
|
|
||||||
if (status === 'running') return <FaSpinner className="text-indigo-500 animate-spin shrink-0" />
|
|
||||||
if (status === 'success') return <FaCheckCircle className="text-emerald-500 shrink-0" />
|
|
||||||
if (status === 'error') return <FaExclamationCircle className="text-red-500 shrink-0" />
|
|
||||||
return <FaCircle className="text-gray-300 dark:text-gray-600 shrink-0 text-[8px] mt-1" />
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SectionProps {
|
|
||||||
title: string
|
|
||||||
badge?: string | number
|
|
||||||
children: React.ReactNode
|
|
||||||
defaultOpen?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
function Section({ title, badge, children, defaultOpen = true }: SectionProps) {
|
|
||||||
const [open, setOpen] = useState(defaultOpen)
|
|
||||||
return (
|
|
||||||
<div className="rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden">
|
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
onClick={() => setOpen((v) => !v)}
|
|
||||||
variant="plain"
|
|
||||||
shape="none"
|
|
||||||
className="w-full !h-auto !items-center !justify-between !rounded-none !bg-gray-50 !px-4 !py-2.5 transition-colors hover:!bg-gray-100 dark:!bg-gray-800 dark:hover:!bg-gray-700"
|
|
||||||
>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
{open ? (
|
|
||||||
<FaChevronDown className="text-gray-400 text-xs" />
|
|
||||||
) : (
|
|
||||||
<FaChevronRight className="text-gray-400 text-xs" />
|
|
||||||
)}
|
|
||||||
<span className="text-sm font-semibold text-gray-700 dark:text-gray-200">{title}</span>
|
|
||||||
</div>
|
|
||||||
{badge !== undefined && (
|
|
||||||
<span className="text-xs bg-indigo-100 dark:bg-indigo-900/40 text-indigo-600 dark:text-indigo-400 px-2 py-0.5 rounded-full font-medium">
|
|
||||||
{badge}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
{open && <div className="px-4 py-3 bg-white dark:bg-gray-900">{children}</div>}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function Row({ label, value }: { label: string; value?: string | number }) {
|
|
||||||
if (!value && value !== 0) return null
|
|
||||||
return (
|
|
||||||
<div className="flex gap-2 py-1 border-b border-gray-100 dark:border-gray-800 last:border-0">
|
|
||||||
<span className="text-xs text-gray-400 w-40 shrink-0">{label}</span>
|
|
||||||
<span className="text-xs text-gray-700 dark:text-gray-200 font-medium break-all">
|
|
||||||
{value}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─── WizardStep7 ──────────────────────────────────────────────────────────────
|
|
||||||
const WizardStep7 = ({
|
const WizardStep7 = ({
|
||||||
values,
|
|
||||||
wizardName,
|
|
||||||
selectedColumns,
|
selectedColumns,
|
||||||
selectCommandColumns,
|
selectCommandColumns,
|
||||||
groups,
|
|
||||||
subForms,
|
|
||||||
widgets,
|
|
||||||
workflow,
|
|
||||||
workflowCriteria,
|
|
||||||
translate,
|
translate,
|
||||||
onBack,
|
onBack,
|
||||||
onSubmit,
|
onNext,
|
||||||
}: WizardStep7Props) => {
|
}: WizardStep7Props) => {
|
||||||
const [logs, setLogs] = useState<LogEntry[]>([])
|
const { errors, touched, values, setFieldTouched, setFieldValue, validateForm } =
|
||||||
const [isDeploying, setIsDeploying] = useState(false)
|
useFormikContext<ListFormWizardDto>()
|
||||||
const [isDone, setIsDone] = useState(false)
|
const [validationError, setValidationError] = useState('')
|
||||||
const [hasError, setHasError] = useState(false)
|
const fieldOptions = useMemo<SelectBoxOption[]>(
|
||||||
|
() =>
|
||||||
|
selectCommandColumns
|
||||||
|
.filter((column) => selectedColumns.has(column.columnName))
|
||||||
|
.map((column) => ({ value: column.columnName, label: column.columnName })),
|
||||||
|
[selectCommandColumns, selectedColumns],
|
||||||
|
)
|
||||||
|
|
||||||
const steps = buildLogSteps(values, groups, translate)
|
const continueToDeploy = async () => {
|
||||||
|
await Promise.all([
|
||||||
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))
|
setFieldTouched('todoTitleExpr', true, false),
|
||||||
|
setFieldTouched('todoStatusExpr', true, false),
|
||||||
const runDeploy = async () => {
|
|
||||||
if (isDeploying) return
|
|
||||||
setIsDeploying(true)
|
|
||||||
setHasError(false)
|
|
||||||
setIsDone(false)
|
|
||||||
|
|
||||||
// Initialize all as pending
|
|
||||||
setLogs(steps.map((s) => ({ ...s, status: 'pending' })))
|
|
||||||
|
|
||||||
const setStatus = (id: number, status: LogStatus) =>
|
|
||||||
setLogs((prev) => prev.map((l) => (l.id === id ? { ...l, status } : l)))
|
|
||||||
|
|
||||||
// Steps 1-7: pre-deploy simulation (fast)
|
|
||||||
for (let i = 0; i < steps.length - 2; i++) {
|
|
||||||
const step = steps[i]
|
|
||||||
setStatus(step.id, 'running')
|
|
||||||
await sleep(300 + Math.random() * 200)
|
|
||||||
setStatus(step.id, 'success')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 8: actual API call
|
|
||||||
const deployStep = steps[steps.length - 2]
|
|
||||||
setStatus(deployStep.id, 'running')
|
|
||||||
try {
|
|
||||||
await onSubmit()
|
|
||||||
setStatus(deployStep.id, 'success')
|
|
||||||
await sleep(200)
|
|
||||||
// Step 9: done
|
|
||||||
const doneStep = steps[steps.length - 1]
|
|
||||||
setStatus(doneStep.id, 'running')
|
|
||||||
await sleep(300)
|
|
||||||
setStatus(doneStep.id, 'success')
|
|
||||||
setIsDone(true)
|
|
||||||
} catch (err: any) {
|
|
||||||
setStatus(deployStep.id, 'error')
|
|
||||||
setLogs((prev) => [
|
|
||||||
...prev,
|
|
||||||
{
|
|
||||||
id: 999,
|
|
||||||
label: `Hata: ${err?.message ?? 'Bilinmeyen hata'}`,
|
|
||||||
status: 'error',
|
|
||||||
},
|
|
||||||
])
|
])
|
||||||
setHasError(true)
|
const validationErrors = await validateForm()
|
||||||
} finally {
|
|
||||||
setIsDeploying(false)
|
if (validationErrors.todoTitleExpr || validationErrors.todoStatusExpr) {
|
||||||
|
setValidationError(translate('::ListForms.ListFormFieldEdit.TodoRequiredFields'))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
setValidationError('')
|
||||||
|
onNext()
|
||||||
}
|
}
|
||||||
|
|
||||||
const totalFields = groups.reduce((acc, g) => acc + g.items.length, 0)
|
return (
|
||||||
const editingFormFields = groups.flatMap((g) =>
|
<div className="pb-20">
|
||||||
g.items
|
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3">
|
||||||
.filter((item) => item.includeInEditingForm && item.dataField !== values.keyFieldName)
|
{mappings.map((mapping) => {
|
||||||
.map((item) => ({ ...item, groupCaption: g.caption })),
|
const isRequired = Boolean(mapping.required && values.todo)
|
||||||
)
|
|
||||||
const groupedFieldNames = new Set(groups.flatMap((g) => g.items.map((item) => item.dataField)))
|
|
||||||
const ungroupedSelectedColumns = [...selectedColumns].filter((col) => !groupedFieldNames.has(col))
|
|
||||||
const hasWorkflowFields = Boolean(
|
|
||||||
workflow.approvalUserFieldName ||
|
|
||||||
workflow.approvalDateFieldName ||
|
|
||||||
workflow.approvalStatusFieldName ||
|
|
||||||
workflow.approvalDescriptionFieldName,
|
|
||||||
)
|
|
||||||
const workflowItems = workflowCriteria.length > 0 ? workflowCriteria : (workflow.criteria ?? [])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-[3fr_2fr] gap-5 pb-24 items-start">
|
<FormItem
|
||||||
{/* ── Left: Summary ──────────────────────────────────────────── */}
|
key={mapping.name}
|
||||||
<div className="flex flex-col gap-3">
|
label={`${translate(mapping.translationKey)}${isRequired ? ' *' : ''}`}
|
||||||
<div className="grid grid-cols-2 gap-3 items-start">
|
invalid={Boolean(touched[mapping.name] && errors[mapping.name])}
|
||||||
<Section title={translate('::ListForms.Wizard.Step4.MenuInfo')}>
|
errorMessage={touched[mapping.name] ? errors[mapping.name] : undefined}
|
||||||
<Row label={translate('::ListForms.Wizard.Step4.WizardName')} value={wizardName} />
|
|
||||||
<Row label={translate('::ListForms.Wizard.Step4.MenuCode')} value={values.menuCode} />
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.MenuParent')}
|
|
||||||
value={values.menuParentCode}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.PermissionGroup')}
|
|
||||||
value={values.permissionGroupName}
|
|
||||||
/>
|
|
||||||
<Row label={translate('::App.Listform.ListformField.Icon')} value={values.menuIcon} />
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.MenuTr')}
|
|
||||||
value={values.languageTextMenuTr}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.MenuEn')}
|
|
||||||
value={values.languageTextMenuEn}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.MenuParentTr')}
|
|
||||||
value={values.languageTextMenuParentTr}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.MenuParentEn')}
|
|
||||||
value={values.languageTextMenuParentEn}
|
|
||||||
/>
|
|
||||||
</Section>
|
|
||||||
|
|
||||||
<Section title={translate('::ListForms.Wizard.Step4.ListFormSettings')}>
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.ListFormCode')}
|
|
||||||
value={values.listFormCode}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.TitleTr')}
|
|
||||||
value={values.languageTextTitleTr}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.TitleEn')}
|
|
||||||
value={values.languageTextTitleEn}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.DescTr')}
|
|
||||||
value={values.languageTextDescTr}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.DescEn')}
|
|
||||||
value={values.languageTextDescEn}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.DataSource')}
|
|
||||||
value={values.dataSourceCode}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={translate('::App.Listform.ListformField.ConnectionString')}
|
|
||||||
value={values.dataSourceConnectionString}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.SelectCommand')}
|
|
||||||
value={`${values.selectCommand} (${
|
|
||||||
selectCommandTypeOptions.find((o: any) => o.value === values.selectCommandType)
|
|
||||||
?.label ?? String(values.selectCommandType)
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
<Row
|
|
||||||
label={translate('::ListForms.Wizard.Step4.KeyField')}
|
|
||||||
value={`${values.keyFieldName} (${
|
|
||||||
dbSourceTypeOptions.find((o: any) => o.value === values.keyFieldDbSourceType)
|
|
||||||
?.label ?? String(values.keyFieldDbSourceType)
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Section>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Section
|
|
||||||
title={
|
|
||||||
translate('::ListForms.Wizard.Step4.ColumnsAndFormLayout') || 'Columns & Form Layout'
|
|
||||||
}
|
|
||||||
badge={`${selectedColumns.size} ${translate('::App.Listform.ListformField.Column')} / ${editingFormFields.length} ${translate('::ListForms.Wizard.Step4.EditingForm') || 'Popup Form'}`}
|
|
||||||
>
|
>
|
||||||
<div className="mb-3 grid grid-cols-3 gap-2">
|
<Field name={mapping.name}>
|
||||||
{[
|
{({ field, form }: FieldProps) => (
|
||||||
{
|
<Select
|
||||||
label: translate('::ListForms.Wizard.Step4.SelectedColumns'),
|
field={field}
|
||||||
value: selectedColumns.size,
|
form={form}
|
||||||
className: 'text-indigo-600 dark:text-indigo-400',
|
isClearable={!isRequired}
|
||||||
},
|
options={fieldOptions}
|
||||||
{
|
value={fieldOptions.find((option) => option.value === values[mapping.name])}
|
||||||
label: translate('::ListForms.Wizard.Step4.EditingForm') || 'Popup Form',
|
onChange={(option) => {
|
||||||
value: editingFormFields.length,
|
form.setFieldValue(field.name, option?.value ?? '')
|
||||||
className: 'text-emerald-600 dark:text-emerald-400',
|
setValidationError('')
|
||||||
},
|
}}
|
||||||
{
|
/>
|
||||||
label: translate('::ListForms.Wizard.Step4.FormGroups'),
|
|
||||||
value: groups.length,
|
|
||||||
className: 'text-gray-700 dark:text-gray-200',
|
|
||||||
},
|
|
||||||
].map((item) => (
|
|
||||||
<div
|
|
||||||
key={item.label}
|
|
||||||
className="rounded-lg border border-gray-100 dark:border-gray-800 bg-gray-50 dark:bg-gray-800 px-3 py-2"
|
|
||||||
>
|
|
||||||
<div className={`text-lg font-semibold leading-none ${item.className}`}>
|
|
||||||
{item.value}
|
|
||||||
</div>
|
|
||||||
<div className="mt-1 text-[11px] text-gray-400 truncate">{item.label}</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex flex-col gap-2">
|
|
||||||
{groups.map((g) => (
|
|
||||||
<div
|
|
||||||
key={g.id}
|
|
||||||
className="overflow-hidden rounded-lg border border-gray-100 dark:border-gray-800"
|
|
||||||
>
|
|
||||||
<div className="flex items-center justify-between gap-3 bg-gray-50 dark:bg-gray-800 px-3 py-2">
|
|
||||||
<span className="text-xs font-semibold text-gray-700 dark:text-gray-200 truncate">
|
|
||||||
{g.caption || `(${translate('::ListForms.Wizard.Step4.StatGroup')})`}
|
|
||||||
</span>
|
|
||||||
<div className="flex items-center gap-1.5 text-[10px] text-gray-400 shrink-0">
|
|
||||||
<span className="rounded bg-white dark:bg-gray-900 px-1.5 py-0.5">
|
|
||||||
{g.items.length} {translate('::ListForms.Wizard.Step4.StatField')}
|
|
||||||
</span>
|
|
||||||
<span className="rounded bg-white dark:bg-gray-900 px-1.5 py-0.5">
|
|
||||||
{g.colCount} {translate('::App.Listform.ListformField.Column')}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="divide-y divide-gray-100 dark:divide-gray-800">
|
|
||||||
{g.items.length === 0 ? (
|
|
||||||
<span className="block px-3 py-2 text-xs text-gray-300 italic">
|
|
||||||
{translate('::ListForms.Wizard.Step4.NoFields') || 'Alan yok'}
|
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
g.items.map((item) => {
|
|
||||||
const meta = selectCommandColumns.find((c) => c.columnName === item.dataField)
|
|
||||||
const isKeyField = item.dataField === values.keyFieldName
|
|
||||||
const isPopupField = item.includeInEditingForm && !isKeyField
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={item.id}
|
|
||||||
className="grid grid-cols-[minmax(150px,1fr)_auto] items-center gap-3 px-3 py-1.5"
|
|
||||||
>
|
|
||||||
<div className="flex min-w-0 items-center gap-2">
|
|
||||||
<span className="text-xs font-medium text-indigo-600 dark:text-indigo-400 truncate">
|
|
||||||
{item.dataField}
|
|
||||||
</span>
|
|
||||||
{meta?.dataType && (
|
|
||||||
<span className="text-[10px] text-gray-400 truncate">
|
|
||||||
{meta.dataType}
|
|
||||||
</span>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</Field>
|
||||||
<div className="flex flex-wrap justify-end gap-1">
|
</FormItem>
|
||||||
<span className="rounded bg-indigo-50 dark:bg-indigo-900/30 px-1.5 py-0.5 text-[10px] text-indigo-600 dark:text-indigo-300">
|
|
||||||
{translate('::ListForms.Wizard.Step4.SelectedColumns') || 'List'}
|
|
||||||
</span>
|
|
||||||
{isPopupField && (
|
|
||||||
<span className="rounded bg-emerald-50 dark:bg-emerald-900/30 px-1.5 py-0.5 text-[10px] text-emerald-600 dark:text-emerald-300">
|
|
||||||
{translate('::ListForms.Wizard.Step4.EditingForm') || 'Popup Form'}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{isKeyField && (
|
|
||||||
<span className="rounded bg-amber-50 dark:bg-amber-900/30 px-1.5 py-0.5 text-[10px] text-amber-600 dark:text-amber-300">
|
|
||||||
{translate('::ListForms.Wizard.Step4.KeyField')}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
<span className="rounded bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 text-[10px] text-gray-400">
|
|
||||||
{item.editorType}
|
|
||||||
</span>
|
|
||||||
<span className="rounded bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 text-[10px] text-gray-400">
|
|
||||||
span-{item.colSpan}
|
|
||||||
{item.isRequired && <span className="ml-1 text-red-400">*</span>}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
{ungroupedSelectedColumns.length > 0 && (
|
|
||||||
<div className="rounded-lg border border-amber-100 dark:border-amber-900/40 bg-amber-50/50 dark:bg-amber-900/10 px-3 py-2">
|
|
||||||
<div className="mb-1.5 text-xs font-semibold text-amber-700 dark:text-amber-300">
|
|
||||||
{translate('::ListForms.Wizard.Step4.UngroupedColumns') || 'Ungrouped columns'}
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-wrap gap-1.5">
|
|
||||||
{ungroupedSelectedColumns.map((col) => {
|
|
||||||
const meta = selectCommandColumns.find((c) => c.columnName === col)
|
|
||||||
return (
|
|
||||||
<span
|
|
||||||
key={col}
|
|
||||||
className="inline-flex items-center gap-1 rounded-full border border-amber-200 dark:border-amber-800 bg-white dark:bg-gray-900 px-2 py-0.5 text-xs text-amber-700 dark:text-amber-300"
|
|
||||||
>
|
|
||||||
{col}
|
|
||||||
{meta?.dataType && (
|
|
||||||
<span className="text-[10px] text-amber-500 opacity-70">
|
|
||||||
{meta.dataType}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Section>
|
|
||||||
|
|
||||||
{subForms.length > 0 && (
|
<div className="mt-5 grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
<Section
|
<FormItem label={translate('::ListForms.ListFormFieldEdit.TodoStatusOrder')}>
|
||||||
title={translate('::ListForms.ListFormEdit.SubForms') || 'Sub Forms'}
|
<Field
|
||||||
badge={subForms.length}
|
name="todoStatusOrder"
|
||||||
>
|
component={Input}
|
||||||
<div className="flex flex-col gap-3">
|
placeholder={translate('::ListForms.ListFormFieldEdit.TodoStatusOrderPlaceholder')}
|
||||||
{subForms.map((subForm, index) => (
|
/>
|
||||||
<div
|
</FormItem>
|
||||||
key={`${subForm.code}-${index}`}
|
<FormItem label={translate('::ListForms.ListFormFieldEdit.TodoAllowDragging')}>
|
||||||
className="rounded-lg border border-gray-100 dark:border-gray-800 px-3 py-2"
|
<Field name="todoAllowDragging">
|
||||||
>
|
{({ field }: FieldProps<boolean>) => (
|
||||||
<Row label="Tab Title" value={subForm.tabTitle} />
|
<Checkbox
|
||||||
<Row label="List Form Code" value={subForm.code} />
|
checked={Boolean(field.value)}
|
||||||
<Row label="Tab Type" value={subForm.tabType} />
|
onChange={(checked) => setFieldValue(field.name, checked)}
|
||||||
<Row label="Refresh" value={subForm.isRefresh ? 'Active' : 'Inactive'} />
|
|
||||||
{(subForm.relation || []).length > 0 && (
|
|
||||||
<div className="pt-2">
|
|
||||||
<span className="text-xs text-gray-400">Relations</span>
|
|
||||||
<div className="mt-1 flex flex-wrap gap-1.5">
|
|
||||||
{subForm.relation.map((relation, relationIndex) => (
|
|
||||||
<span
|
|
||||||
key={`${relation.parentFieldName}-${relation.childFieldName}-${relationIndex}`}
|
|
||||||
className="rounded bg-gray-100 dark:bg-gray-800 px-2 py-0.5 text-xs text-gray-600 dark:text-gray-300"
|
|
||||||
>
|
|
||||||
{relation.parentFieldName} : {relation.childFieldName}
|
|
||||||
</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</Section>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{widgets.length > 0 && (
|
|
||||||
<Section
|
|
||||||
title={translate('::ListForms.ListFormEdit.TabWidgets') || 'Widgets'}
|
|
||||||
badge={widgets.length}
|
|
||||||
>
|
|
||||||
<div className="flex flex-col gap-3">
|
|
||||||
{widgets.map((widget, index) => (
|
|
||||||
<div
|
|
||||||
key={`${widget.title}-${widget.value}-${index}`}
|
|
||||||
className="rounded-lg border border-gray-100 dark:border-gray-800 px-3 py-2"
|
|
||||||
>
|
|
||||||
<Row label="Title Field" value={widget.title} />
|
|
||||||
<Row label="Value Field" value={widget.value} />
|
|
||||||
<Row label="Color Field" value={widget.color} />
|
|
||||||
<Row label="Icon Field" value={widget.icon} />
|
|
||||||
<Row label="Column Gap" value={widget.colGap} />
|
|
||||||
<Row label="Column Span" value={widget.colSpan} />
|
|
||||||
<Row label="Class Name" value={widget.className} />
|
|
||||||
<Row label="Value Class Name" value={widget.valueClassName} />
|
|
||||||
<Row label="Status" value={widget.isActive ? 'Active' : 'Inactive'} />
|
|
||||||
<Row label="Sql Query" value={widget.sqlQuery} />
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</Section>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{(hasWorkflowFields || workflowItems.length > 0) && (
|
|
||||||
<Section
|
|
||||||
title={translate('::ListForms.ListFormEdit.TabWorkflow') || 'Workflow'}
|
|
||||||
badge={workflowItems.length}
|
|
||||||
>
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
|
||||||
<div>
|
|
||||||
<Row label="Approval User" value={workflow.approvalUserFieldName} />
|
|
||||||
<Row label="Approval Date" value={workflow.approvalDateFieldName} />
|
|
||||||
<Row label="Approval Status" value={workflow.approvalStatusFieldName} />
|
|
||||||
<Row label="Approval Description" value={workflow.approvalDescriptionFieldName} />
|
|
||||||
<Row
|
|
||||||
label="Is Filter User Name?"
|
|
||||||
value={workflow.isFilterUserName === true ? 'Yes' : 'No'}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
{workflowItems.length > 0 && (
|
|
||||||
<div className="flex flex-col gap-2">
|
|
||||||
{workflowItems.map((criteria, index) => (
|
|
||||||
<div
|
|
||||||
key={criteria.id || index}
|
|
||||||
className="rounded bg-gray-50 dark:bg-gray-800 px-3 py-2"
|
|
||||||
>
|
|
||||||
<div className="text-xs font-semibold text-gray-700 dark:text-gray-200">
|
|
||||||
{criteria.title || criteria.kind || `Criteria ${index + 1}`}
|
|
||||||
</div>
|
|
||||||
{criteria.kind === 'Compare' && (
|
|
||||||
<div className="mt-1 text-[11px] text-gray-500 dark:text-gray-400">
|
|
||||||
{criteria.compareColumn} {criteria.compareOperator}{' '}
|
|
||||||
{criteria.compareValue}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{(criteria.kind === 'Approval' || criteria.kind === 'Inform') &&
|
|
||||||
criteria.approver && (
|
|
||||||
<div className="text-[11px] text-gray-500 dark:text-gray-400">
|
|
||||||
Approver: {formatWorkflowApprovers(criteria.approver)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Section>
|
|
||||||
)}
|
)}
|
||||||
|
</Field>
|
||||||
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ── Right: Deploy ──────────────────────────────────────────── */}
|
{validationError && <p className="mt-4 text-sm text-red-500">{validationError}</p>}
|
||||||
<div className="sticky top-4 flex flex-col gap-3 max-h-[calc(100vh-200px)]">
|
|
||||||
{/* Stats */}
|
|
||||||
<div className="grid grid-cols-7 gap-2">
|
|
||||||
{[
|
|
||||||
{ label: translate('::ListForms.Wizard.Step4.StatGroup'), value: groups.length },
|
|
||||||
{ label: translate('::ListForms.Wizard.Step4.StatField'), value: totalFields },
|
|
||||||
{
|
|
||||||
label: translate('::ListForms.Wizard.Step4.EditingForm') || 'Popup Form',
|
|
||||||
value: editingFormFields.length,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: translate('::App.Listform.ListformField.Column'),
|
|
||||||
value: selectedColumns.size,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: translate('::ListForms.ListFormEdit.SubForms') || 'Sub Forms',
|
|
||||||
value: subForms.length,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: translate('::ListForms.ListFormEdit.TabWidgets') || 'Widgets',
|
|
||||||
value: widgets.length,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: translate('::ListForms.ListFormEdit.TabWorkflow') || 'Workflow',
|
|
||||||
value: workflowItems.length,
|
|
||||||
},
|
|
||||||
].map((s) => (
|
|
||||||
<div
|
|
||||||
key={s.label}
|
|
||||||
className="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 p-3 text-center shadow-sm"
|
|
||||||
>
|
|
||||||
<div className="text-2xl font-bold text-indigo-600 dark:text-indigo-400">
|
|
||||||
{s.value}
|
|
||||||
</div>
|
|
||||||
<div className="text-xs text-gray-400 mt-0.5">{s.label}</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Log panel — grows to fill remaining height */}
|
<div className="fixed bottom-0 left-0 right-0 z-10 flex h-16 items-center border-t border-gray-200 bg-white px-6 dark:border-gray-700 dark:bg-gray-900">
|
||||||
<div className="rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col flex-1 min-h-0">
|
<div className="flex w-full items-center justify-between gap-3">
|
||||||
<div className="px-4 py-2.5 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between shrink-0">
|
<Button size="sm" variant="default" type="button" icon={<FaArrowLeft />} onClick={onBack}>
|
||||||
<span className="text-sm font-semibold text-gray-700 dark:text-gray-200 flex items-center gap-2">
|
{translate('::Back')}
|
||||||
<FaRocket className="text-indigo-400 text-xs" />
|
|
||||||
{translate('::ListForms.Wizard.Step4.DeployLog') || 'Deploy Log'}
|
|
||||||
</span>
|
|
||||||
{isDone && (
|
|
||||||
<span className="text-xs text-emerald-500 font-semibold flex items-center gap-1">
|
|
||||||
<FaCheckCircle /> {translate('::ListForms.Wizard.Step4.Success') || 'Başarılı'}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{hasError && (
|
|
||||||
<span className="text-xs text-red-500 font-semibold flex items-center gap-1">
|
|
||||||
<FaExclamationCircle /> {translate('::ListForms.Wizard.Step4.Error') || 'Hata'}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex-1 overflow-y-auto p-4 bg-[#0d1117] dark:bg-black font-mono min-h-[360px]">
|
|
||||||
{logs.length === 0 ? (
|
|
||||||
<div className="flex flex-col items-center justify-center h-full gap-3 py-10 select-none">
|
|
||||||
<FaRocket className="text-gray-700 text-3xl" />
|
|
||||||
<span className="text-xs text-gray-600 italic text-center">
|
|
||||||
{translate('::ListForms.Wizard.Step4.AllInfoReady') || 'Tüm bilgiler hazır.'}
|
|
||||||
<br />
|
|
||||||
{translate('::ListForms.Wizard.Step4.DeployStartHint')}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="flex flex-col gap-2">
|
|
||||||
{logs.map((log) => (
|
|
||||||
<div key={log.id} className="flex items-start gap-2.5">
|
|
||||||
<span className="mt-0.5 shrink-0">
|
|
||||||
<LogIcon status={log.status} />
|
|
||||||
</span>
|
|
||||||
<div>
|
|
||||||
<span
|
|
||||||
className={`text-xs leading-relaxed ${
|
|
||||||
log.status === 'success'
|
|
||||||
? 'text-emerald-400'
|
|
||||||
: log.status === 'error'
|
|
||||||
? 'text-red-400'
|
|
||||||
: log.status === 'running'
|
|
||||||
? 'text-yellow-300'
|
|
||||||
: 'text-gray-600'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{log.label}
|
|
||||||
</span>
|
|
||||||
{log.detail && (
|
|
||||||
<div className="text-[10px] text-gray-600 mt-0.5">{log.detail}</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
{isDone && (
|
|
||||||
<div className="mt-4 rounded-lg border border-emerald-800 bg-emerald-950/40 px-4 py-2.5 text-xs text-emerald-400 text-center font-semibold">
|
|
||||||
🎉 {translate('::ListForms.Wizard.Step4.DeploySuccess')}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* ── Fixed Footer ─────────────────────────────────────────────── */}
|
|
||||||
<div className="fixed bottom-0 left-0 right-0 z-10 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-700 px-6 py-0 h-16 flex items-center">
|
|
||||||
<div className="flex items-center gap-3 w-full">
|
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
variant="default"
|
|
||||||
type="button"
|
|
||||||
icon={<FaArrowLeft />}
|
|
||||||
onClick={onBack}
|
|
||||||
disabled={isDeploying}
|
|
||||||
>
|
|
||||||
{translate('::Back') || 'Back'}
|
|
||||||
</Button>
|
</Button>
|
||||||
<div className="flex-1 flex items-center justify-end">
|
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
type="button"
|
type="button"
|
||||||
icon={<FaRocket />}
|
icon={<FaArrowRight />}
|
||||||
loading={isDeploying}
|
onClick={continueToDeploy}
|
||||||
disabled={isDeploying || isDone}
|
|
||||||
onClick={runDeploy}
|
|
||||||
>
|
>
|
||||||
{isDeploying
|
{translate('::Next')}
|
||||||
? translate('::ListForms.Wizard.Step4.Log.Deploying')
|
|
||||||
: isDone
|
|
||||||
? `✓ ${translate('::ListForms.Wizard.Step4.Log.Completed')}`
|
|
||||||
: translate('::ListForms.Wizard.Step4.DeployAndSave')}
|
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
777
ui/src/views/admin/listForm/wizard/WizardStep8.tsx
Normal file
777
ui/src/views/admin/listForm/wizard/WizardStep8.tsx
Normal file
|
|
@ -0,0 +1,777 @@
|
||||||
|
import { Button } from '@/components/ui'
|
||||||
|
import type { DatabaseColumnDto } from '@/proxy/sql-query-manager/models'
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import {
|
||||||
|
FaArrowLeft,
|
||||||
|
FaCheckCircle,
|
||||||
|
FaChevronDown,
|
||||||
|
FaChevronRight,
|
||||||
|
FaCircle,
|
||||||
|
FaExclamationCircle,
|
||||||
|
FaRocket,
|
||||||
|
FaSpinner,
|
||||||
|
} from 'react-icons/fa'
|
||||||
|
import { WizardGroup } from './WizardStep3'
|
||||||
|
import { dbSourceTypeOptions, selectCommandTypeOptions } from '../edit/options'
|
||||||
|
import { ListFormWizardDto } from '@/proxy/admin/wizard/models'
|
||||||
|
import {
|
||||||
|
ListFormWorkflowCriteriaDto,
|
||||||
|
SubFormDto,
|
||||||
|
WidgetEditDto,
|
||||||
|
WorkflowDto,
|
||||||
|
} from '@/proxy/form/models'
|
||||||
|
import { formatWorkflowApprovers } from '@/utils/workflow/workflowHelpers'
|
||||||
|
|
||||||
|
// ─── Types ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
export interface WizardStep8Props {
|
||||||
|
values: ListFormWizardDto
|
||||||
|
wizardName: string
|
||||||
|
selectedColumns: Set<string>
|
||||||
|
selectCommandColumns: DatabaseColumnDto[]
|
||||||
|
groups: WizardGroup[]
|
||||||
|
subForms: SubFormDto[]
|
||||||
|
widgets: WidgetEditDto[]
|
||||||
|
workflow: WorkflowDto
|
||||||
|
criteria: ListFormWorkflowCriteriaDto[]
|
||||||
|
translate: (key: string) => string
|
||||||
|
onBack: () => void
|
||||||
|
onSubmit: () => Promise<void>
|
||||||
|
}
|
||||||
|
|
||||||
|
type LogStatus = 'pending' | 'running' | 'success' | 'error'
|
||||||
|
|
||||||
|
interface LogEntry {
|
||||||
|
id: number
|
||||||
|
label: string
|
||||||
|
status: LogStatus
|
||||||
|
detail?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Deploy log steps ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function buildLogSteps(
|
||||||
|
values: ListFormWizardDto,
|
||||||
|
groups: WizardGroup[],
|
||||||
|
translate: (key: string, params?: Record<string, string | number>) => string,
|
||||||
|
): Omit<LogEntry, 'status'>[] {
|
||||||
|
const totalFields = groups.reduce((acc, g) => acc + g.items.length, 0)
|
||||||
|
return [
|
||||||
|
{ id: 1, label: translate('::ListForms.Wizard.Step4.Log.ValidatingConfig') },
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: translate('::ListForms.Wizard.Step4.Log.CreatingMenu', { 0: values.menuCode }),
|
||||||
|
detail: `Parent: ${values.menuParentCode}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
label: translate('::ListForms.Wizard.Step4.Log.SavingLanguageTexts'),
|
||||||
|
detail: `EN: ${values.languageTextMenuEn} / TR: ${values.languageTextMenuTr}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
label: translate('::ListForms.Wizard.Step4.Log.ConfiguringPermission', {
|
||||||
|
0: values.permissionGroupName,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
label: translate('::ListForms.Wizard.Step4.Log.ConnectingDataSource', {
|
||||||
|
0: values.dataSourceCode,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
label: translate('::ListForms.Wizard.Step4.Log.CreatingListForm', { 0: values.listFormCode }),
|
||||||
|
detail: `Key: ${values.keyFieldName}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
label: translate('::ListForms.Wizard.Step4.Log.SavingFormGroups', {
|
||||||
|
0: groups.length,
|
||||||
|
1: totalFields,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{ id: 8, label: translate('::ListForms.Wizard.Step4.Log.Deploying') },
|
||||||
|
{ id: 9, label: translate('::ListForms.Wizard.Step4.Log.Completed') },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Mini-components ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function LogIcon({ status }: { status: LogStatus }) {
|
||||||
|
if (status === 'running') return <FaSpinner className="text-indigo-500 animate-spin shrink-0" />
|
||||||
|
if (status === 'success') return <FaCheckCircle className="text-emerald-500 shrink-0" />
|
||||||
|
if (status === 'error') return <FaExclamationCircle className="text-red-500 shrink-0" />
|
||||||
|
return <FaCircle className="text-gray-300 dark:text-gray-600 shrink-0 text-[8px] mt-1" />
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SectionProps {
|
||||||
|
title: string
|
||||||
|
badge?: string | number
|
||||||
|
children: React.ReactNode
|
||||||
|
defaultOpen?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
function Section({ title, badge, children, defaultOpen = true }: SectionProps) {
|
||||||
|
const [open, setOpen] = useState(defaultOpen)
|
||||||
|
return (
|
||||||
|
<div className="rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="plain"
|
||||||
|
shape="none"
|
||||||
|
className="w-full !h-auto !items-center !justify-between !rounded-none !bg-gray-50 !px-4 !py-2.5 transition-colors hover:!bg-gray-100 dark:!bg-gray-800 dark:hover:!bg-gray-700"
|
||||||
|
onClick={() => setOpen((v) => !v)}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{open ? (
|
||||||
|
<FaChevronDown className="text-gray-400 text-xs" />
|
||||||
|
) : (
|
||||||
|
<FaChevronRight className="text-gray-400 text-xs" />
|
||||||
|
)}
|
||||||
|
<span className="text-sm font-semibold text-gray-700 dark:text-gray-200">{title}</span>
|
||||||
|
</div>
|
||||||
|
{badge !== undefined && (
|
||||||
|
<span className="text-xs bg-indigo-100 dark:bg-indigo-900/40 text-indigo-600 dark:text-indigo-400 px-2 py-0.5 rounded-full font-medium">
|
||||||
|
{badge}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
{open && <div className="px-4 py-3 bg-white dark:bg-gray-900">{children}</div>}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Row({ label, value }: { label: string; value?: string | number }) {
|
||||||
|
if (!value && value !== 0) return null
|
||||||
|
return (
|
||||||
|
<div className="flex gap-2 py-1 border-b border-gray-100 dark:border-gray-800 last:border-0">
|
||||||
|
<span className="text-xs text-gray-400 w-40 shrink-0">{label}</span>
|
||||||
|
<span className="text-xs text-gray-700 dark:text-gray-200 font-medium break-all">
|
||||||
|
{value}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── WizardStep8 ──────────────────────────────────────────────────────────────
|
||||||
|
const WizardStep8 = ({
|
||||||
|
values,
|
||||||
|
wizardName,
|
||||||
|
selectedColumns,
|
||||||
|
selectCommandColumns,
|
||||||
|
groups,
|
||||||
|
subForms,
|
||||||
|
widgets,
|
||||||
|
workflow,
|
||||||
|
criteria,
|
||||||
|
translate,
|
||||||
|
onBack,
|
||||||
|
onSubmit,
|
||||||
|
}: WizardStep8Props) => {
|
||||||
|
const [logs, setLogs] = useState<LogEntry[]>([])
|
||||||
|
const [isDeploying, setIsDeploying] = useState(false)
|
||||||
|
const [isDone, setIsDone] = useState(false)
|
||||||
|
const [hasError, setHasError] = useState(false)
|
||||||
|
|
||||||
|
const steps = buildLogSteps(values, groups, translate)
|
||||||
|
|
||||||
|
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))
|
||||||
|
|
||||||
|
const runDeploy = async () => {
|
||||||
|
if (isDeploying) return
|
||||||
|
setIsDeploying(true)
|
||||||
|
setHasError(false)
|
||||||
|
setIsDone(false)
|
||||||
|
|
||||||
|
// Initialize all as pending
|
||||||
|
setLogs(steps.map((s) => ({ ...s, status: 'pending' })))
|
||||||
|
|
||||||
|
const setStatus = (id: number, status: LogStatus) =>
|
||||||
|
setLogs((prev) => prev.map((l) => (l.id === id ? { ...l, status } : l)))
|
||||||
|
|
||||||
|
// Steps 1-7: pre-deploy simulation (fast)
|
||||||
|
for (let i = 0; i < steps.length - 2; i++) {
|
||||||
|
const step = steps[i]
|
||||||
|
setStatus(step.id, 'running')
|
||||||
|
await sleep(300 + Math.random() * 200)
|
||||||
|
setStatus(step.id, 'success')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 8: actual API call
|
||||||
|
const deployStep = steps[steps.length - 2]
|
||||||
|
setStatus(deployStep.id, 'running')
|
||||||
|
try {
|
||||||
|
await onSubmit()
|
||||||
|
setStatus(deployStep.id, 'success')
|
||||||
|
await sleep(200)
|
||||||
|
// Step 9: done
|
||||||
|
const doneStep = steps[steps.length - 1]
|
||||||
|
setStatus(doneStep.id, 'running')
|
||||||
|
await sleep(300)
|
||||||
|
setStatus(doneStep.id, 'success')
|
||||||
|
setIsDone(true)
|
||||||
|
} catch (err: any) {
|
||||||
|
setStatus(deployStep.id, 'error')
|
||||||
|
setLogs((prev) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
id: 999,
|
||||||
|
label: `${translate('::ListForms.Wizard.Step4.Error')}: ${
|
||||||
|
err?.message ?? translate('::App.Platform.Unknown')
|
||||||
|
}`,
|
||||||
|
status: 'error',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
setHasError(true)
|
||||||
|
} finally {
|
||||||
|
setIsDeploying(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalFields = groups.reduce((acc, g) => acc + g.items.length, 0)
|
||||||
|
const editingFormFields = groups.flatMap((g) =>
|
||||||
|
g.items
|
||||||
|
.filter((item) => item.includeInEditingForm && item.fieldName !== values.keyFieldName)
|
||||||
|
.map((item) => ({ ...item, groupCaption: g.caption })),
|
||||||
|
)
|
||||||
|
const groupedFieldNames = new Set(groups.flatMap((g) => g.items.map((item) => item.fieldName)))
|
||||||
|
const ungroupedSelectedColumns = [...selectedColumns].filter((col) => !groupedFieldNames.has(col))
|
||||||
|
const hasWorkflowFields = Boolean(
|
||||||
|
workflow.approvalUserFieldName ||
|
||||||
|
workflow.approvalDateFieldName ||
|
||||||
|
workflow.approvalStatusFieldName ||
|
||||||
|
workflow.approvalDescriptionFieldName,
|
||||||
|
)
|
||||||
|
const workflowItems = criteria.length > 0 ? criteria : (workflow.criteria ?? [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="grid grid-cols-[3fr_2fr] gap-5 pb-24 items-start">
|
||||||
|
{/* ── Left: Summary ──────────────────────────────────────────── */}
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
<div className="grid grid-cols-2 gap-3 items-start">
|
||||||
|
<Section title={translate('::ListForms.Wizard.Step4.MenuInfo')}>
|
||||||
|
<Row label={translate('::ListForms.Wizard.Step4.WizardName')} value={wizardName} />
|
||||||
|
<Row label={translate('::ListForms.Wizard.Step4.MenuCode')} value={values.menuCode} />
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.MenuParent')}
|
||||||
|
value={values.menuParentCode}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.PermissionGroup')}
|
||||||
|
value={values.permissionGroupName}
|
||||||
|
/>
|
||||||
|
<Row label={translate('::App.Listform.ListformField.Icon')} value={values.menuIcon} />
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.MenuTr')}
|
||||||
|
value={values.languageTextMenuTr}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.MenuEn')}
|
||||||
|
value={values.languageTextMenuEn}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.MenuParentTr')}
|
||||||
|
value={values.languageTextMenuParentTr}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.MenuParentEn')}
|
||||||
|
value={values.languageTextMenuParentEn}
|
||||||
|
/>
|
||||||
|
</Section>
|
||||||
|
|
||||||
|
<Section title={translate('::ListForms.Wizard.Step4.ListFormSettings')}>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.ListFormCode')}
|
||||||
|
value={values.listFormCode}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.TitleTr')}
|
||||||
|
value={values.languageTextTitleTr}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.TitleEn')}
|
||||||
|
value={values.languageTextTitleEn}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.DescTr')}
|
||||||
|
value={values.languageTextDescTr}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.DescEn')}
|
||||||
|
value={values.languageTextDescEn}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.DataSource')}
|
||||||
|
value={values.dataSourceCode}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::App.Listform.ListformField.ConnectionString')}
|
||||||
|
value={values.dataSourceConnectionString}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.SelectCommand')}
|
||||||
|
value={`${values.selectCommand} (${
|
||||||
|
selectCommandTypeOptions.find((o: any) => o.value === values.selectCommandType)
|
||||||
|
?.label ?? String(values.selectCommandType)
|
||||||
|
})`}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.Wizard.Step4.KeyField')}
|
||||||
|
value={`${values.keyFieldName} (${
|
||||||
|
dbSourceTypeOptions.find((o: any) => o.value === values.keyFieldDbSourceType)
|
||||||
|
?.label ?? String(values.keyFieldDbSourceType)
|
||||||
|
})`}
|
||||||
|
/>
|
||||||
|
</Section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Section
|
||||||
|
title={
|
||||||
|
translate('::ListForms.Wizard.Step4.ColumnsAndFormLayout') || 'Columns & Form Layout'
|
||||||
|
}
|
||||||
|
badge={`${selectedColumns.size} ${translate('::App.Listform.ListformField.Column')} / ${editingFormFields.length} ${translate('::ListForms.Wizard.Step4.EditingForm') || 'Popup Form'}`}
|
||||||
|
>
|
||||||
|
<div className="mb-3 grid grid-cols-3 gap-2">
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
label: translate('::ListForms.Wizard.Step4.SelectedColumns'),
|
||||||
|
value: selectedColumns.size,
|
||||||
|
className: 'text-indigo-600 dark:text-indigo-400',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: translate('::ListForms.Wizard.Step4.EditingForm') || 'Popup Form',
|
||||||
|
value: editingFormFields.length,
|
||||||
|
className: 'text-emerald-600 dark:text-emerald-400',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: translate('::ListForms.Wizard.Step4.FormGroups'),
|
||||||
|
value: groups.length,
|
||||||
|
className: 'text-gray-700 dark:text-gray-200',
|
||||||
|
},
|
||||||
|
].map((item) => (
|
||||||
|
<div
|
||||||
|
key={item.label}
|
||||||
|
className="rounded-lg border border-gray-100 dark:border-gray-800 bg-gray-50 dark:bg-gray-800 px-3 py-2"
|
||||||
|
>
|
||||||
|
<div className={`text-lg font-semibold leading-none ${item.className}`}>
|
||||||
|
{item.value}
|
||||||
|
</div>
|
||||||
|
<div className="mt-1 text-[11px] text-gray-400 truncate">{item.label}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
{groups.map((g) => (
|
||||||
|
<div
|
||||||
|
key={g.id}
|
||||||
|
className="overflow-hidden rounded-lg border border-gray-100 dark:border-gray-800"
|
||||||
|
>
|
||||||
|
<div className="flex items-center justify-between gap-3 bg-gray-50 dark:bg-gray-800 px-3 py-2">
|
||||||
|
<span className="text-xs font-semibold text-gray-700 dark:text-gray-200 truncate">
|
||||||
|
{g.caption || `(${translate('::ListForms.Wizard.Step4.StatGroup')})`}
|
||||||
|
</span>
|
||||||
|
<div className="flex items-center gap-1.5 text-[10px] text-gray-400 shrink-0">
|
||||||
|
<span className="rounded bg-white dark:bg-gray-900 px-1.5 py-0.5">
|
||||||
|
{g.items.length} {translate('::ListForms.Wizard.Step4.StatField')}
|
||||||
|
</span>
|
||||||
|
<span className="rounded bg-white dark:bg-gray-900 px-1.5 py-0.5">
|
||||||
|
{g.colCount} {translate('::App.Listform.ListformField.Column')}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="divide-y divide-gray-100 dark:divide-gray-800">
|
||||||
|
{g.items.length === 0 ? (
|
||||||
|
<span className="block px-3 py-2 text-xs text-gray-300 italic">
|
||||||
|
{translate('::ListForms.Wizard.Step4.NoFields') || 'Alan yok'}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
g.items.map((item) => {
|
||||||
|
const meta = selectCommandColumns.find((c) => c.columnName === item.fieldName)
|
||||||
|
const isKeyField = item.fieldName === values.keyFieldName
|
||||||
|
const isPopupField = item.includeInEditingForm && !isKeyField
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={item.id}
|
||||||
|
className="grid grid-cols-[minmax(150px,1fr)_auto] items-center gap-3 px-3 py-1.5"
|
||||||
|
>
|
||||||
|
<div className="flex min-w-0 items-center gap-2">
|
||||||
|
<span className="text-xs font-medium text-indigo-600 dark:text-indigo-400 truncate">
|
||||||
|
{item.fieldName}
|
||||||
|
</span>
|
||||||
|
{meta?.dataType && (
|
||||||
|
<span className="text-[10px] text-gray-400 truncate">
|
||||||
|
{meta.dataType}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-wrap justify-end gap-1">
|
||||||
|
<span className="rounded bg-indigo-50 dark:bg-indigo-900/30 px-1.5 py-0.5 text-[10px] text-indigo-600 dark:text-indigo-300">
|
||||||
|
{translate('::ListForms.Wizard.Step4.SelectedColumns') || 'List'}
|
||||||
|
</span>
|
||||||
|
{isPopupField && (
|
||||||
|
<span className="rounded bg-emerald-50 dark:bg-emerald-900/30 px-1.5 py-0.5 text-[10px] text-emerald-600 dark:text-emerald-300">
|
||||||
|
{translate('::ListForms.Wizard.Step4.EditingForm') || 'Popup Form'}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{isKeyField && (
|
||||||
|
<span className="rounded bg-amber-50 dark:bg-amber-900/30 px-1.5 py-0.5 text-[10px] text-amber-600 dark:text-amber-300">
|
||||||
|
{translate('::ListForms.Wizard.Step4.KeyField')}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
<span className="rounded bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 text-[10px] text-gray-400">
|
||||||
|
{item.editorType}
|
||||||
|
</span>
|
||||||
|
<span className="rounded bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 text-[10px] text-gray-400">
|
||||||
|
span-{item.colSpan}
|
||||||
|
{item.isRequired && <span className="ml-1 text-red-400">*</span>}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{ungroupedSelectedColumns.length > 0 && (
|
||||||
|
<div className="rounded-lg border border-amber-100 dark:border-amber-900/40 bg-amber-50/50 dark:bg-amber-900/10 px-3 py-2">
|
||||||
|
<div className="mb-1.5 text-xs font-semibold text-amber-700 dark:text-amber-300">
|
||||||
|
{translate('::ListForms.Wizard.Step4.UngroupedColumns') || 'Ungrouped columns'}
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-wrap gap-1.5">
|
||||||
|
{ungroupedSelectedColumns.map((col) => {
|
||||||
|
const meta = selectCommandColumns.find((c) => c.columnName === col)
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
key={col}
|
||||||
|
className="inline-flex items-center gap-1 rounded-full border border-amber-200 dark:border-amber-800 bg-white dark:bg-gray-900 px-2 py-0.5 text-xs text-amber-700 dark:text-amber-300"
|
||||||
|
>
|
||||||
|
{col}
|
||||||
|
{meta?.dataType && (
|
||||||
|
<span className="text-[10px] text-amber-500 opacity-70">
|
||||||
|
{meta.dataType}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
|
|
||||||
|
{subForms.length > 0 && (
|
||||||
|
<Section
|
||||||
|
title={translate('::ListForms.ListFormEdit.SubForms') || 'Sub Forms'}
|
||||||
|
badge={subForms.length}
|
||||||
|
>
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
{subForms.map((subForm, index) => (
|
||||||
|
<div
|
||||||
|
key={`${subForm.code}-${index}`}
|
||||||
|
className="rounded-lg border border-gray-100 dark:border-gray-800 px-3 py-2"
|
||||||
|
>
|
||||||
|
<Row label="Tab Title" value={subForm.tabTitle} />
|
||||||
|
<Row label="List Form Code" value={subForm.code} />
|
||||||
|
<Row label="Tab Type" value={subForm.tabType} />
|
||||||
|
<Row label="Refresh" value={subForm.isRefresh ? 'Active' : 'Inactive'} />
|
||||||
|
{(subForm.relation || []).length > 0 && (
|
||||||
|
<div className="pt-2">
|
||||||
|
<span className="text-xs text-gray-400">Relations</span>
|
||||||
|
<div className="mt-1 flex flex-wrap gap-1.5">
|
||||||
|
{subForm.relation.map((relation, relationIndex) => (
|
||||||
|
<span
|
||||||
|
key={`${relation.parentFieldName}-${relation.childFieldName}-${relationIndex}`}
|
||||||
|
className="rounded bg-gray-100 dark:bg-gray-800 px-2 py-0.5 text-xs text-gray-600 dark:text-gray-300"
|
||||||
|
>
|
||||||
|
{relation.parentFieldName} : {relation.childFieldName}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{widgets.length > 0 && (
|
||||||
|
<Section
|
||||||
|
title={translate('::ListForms.ListFormEdit.TabWidgets') || 'Widgets'}
|
||||||
|
badge={widgets.length}
|
||||||
|
>
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
{widgets.map((widget, index) => (
|
||||||
|
<div
|
||||||
|
key={`${widget.title}-${widget.value}-${index}`}
|
||||||
|
className="rounded-lg border border-gray-100 dark:border-gray-800 px-3 py-2"
|
||||||
|
>
|
||||||
|
<Row label="Title Field" value={widget.title} />
|
||||||
|
<Row label="Value Field" value={widget.value} />
|
||||||
|
<Row label="Color Field" value={widget.color} />
|
||||||
|
<Row label="Icon Field" value={widget.icon} />
|
||||||
|
<Row label="Column Gap" value={widget.colGap} />
|
||||||
|
<Row label="Column Span" value={widget.colSpan} />
|
||||||
|
<Row label="Class Name" value={widget.className} />
|
||||||
|
<Row label="Value Class Name" value={widget.valueClassName} />
|
||||||
|
<Row label="Status" value={widget.isActive ? 'Active' : 'Inactive'} />
|
||||||
|
<Row label="Sql Query" value={widget.sqlQuery} />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{(hasWorkflowFields || workflowItems.length > 0) && (
|
||||||
|
<Section
|
||||||
|
title={translate('::ListForms.ListFormEdit.TabWorkflow') || 'Workflow'}
|
||||||
|
badge={workflowItems.length}
|
||||||
|
>
|
||||||
|
<div className="grid grid-cols-2 gap-3">
|
||||||
|
<div>
|
||||||
|
<Row label="Approval User" value={workflow.approvalUserFieldName} />
|
||||||
|
<Row label="Approval Date" value={workflow.approvalDateFieldName} />
|
||||||
|
<Row label="Approval Status" value={workflow.approvalStatusFieldName} />
|
||||||
|
<Row label="Approval Description" value={workflow.approvalDescriptionFieldName} />
|
||||||
|
<Row
|
||||||
|
label="Is Filter User Name?"
|
||||||
|
value={workflow.approvalIsFilterUserName === true ? 'Yes' : 'No'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{workflowItems.length > 0 && (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
{workflowItems.map((criteria, index) => (
|
||||||
|
<div
|
||||||
|
key={criteria.id || index}
|
||||||
|
className="rounded bg-gray-50 dark:bg-gray-800 px-3 py-2"
|
||||||
|
>
|
||||||
|
<div className="text-xs font-semibold text-gray-700 dark:text-gray-200">
|
||||||
|
{criteria.title || criteria.kind || `Criteria ${index + 1}`}
|
||||||
|
</div>
|
||||||
|
{criteria.kind === 'Compare' && (
|
||||||
|
<div className="mt-1 text-[11px] text-gray-500 dark:text-gray-400">
|
||||||
|
{criteria.compareColumn} {criteria.compareOperator}{' '}
|
||||||
|
{criteria.compareValue}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{(criteria.kind === 'Approval' || criteria.kind === 'Inform') &&
|
||||||
|
criteria.approver && (
|
||||||
|
<div className="text-[11px] text-gray-500 dark:text-gray-400">
|
||||||
|
Approver: {formatWorkflowApprovers(criteria.approver)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{values.todo && (
|
||||||
|
<Section title={translate('::ListForms.ListFormEdit.TabTodo') || 'Todo / Kanban'}>
|
||||||
|
<div className="grid grid-cols-2 gap-x-4">
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.TodoTitleExpr')}
|
||||||
|
value={values.todoTitleExpr}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.TodoStatusExpr')}
|
||||||
|
value={values.todoStatusExpr}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.TodoDescriptionExpr')}
|
||||||
|
value={values.todoDescriptionExpr}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.TodoDueDateExpr')}
|
||||||
|
value={values.todoDueDateExpr}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.TodoTagExpr')}
|
||||||
|
value={values.todoTagExpr}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.TodoAssigneeExpr')}
|
||||||
|
value={values.todoAssigneeExpr}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.TodoPriorityExpr')}
|
||||||
|
value={values.todoPriorityExpr}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.TodoCompletedExpr')}
|
||||||
|
value={values.todoCompletedExpr}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.TodoOrderExpr')}
|
||||||
|
value={values.todoOrderExpr}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.TodoStatusOrder')}
|
||||||
|
value={values.todoStatusOrder}
|
||||||
|
/>
|
||||||
|
<Row
|
||||||
|
label={translate('::ListForms.ListFormFieldEdit.TodoAllowDragging')}
|
||||||
|
value={translate(
|
||||||
|
values.todoAllowDragging ? '::App.Status.Active' : '::App.Status.Inactive',
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ── Right: Deploy ──────────────────────────────────────────── */}
|
||||||
|
<div className="sticky top-4 flex flex-col gap-3 max-h-[calc(100vh-200px)]">
|
||||||
|
{/* Stats */}
|
||||||
|
<div className="grid grid-cols-8 gap-2">
|
||||||
|
{[
|
||||||
|
{ label: translate('::ListForms.Wizard.Step4.StatGroup'), value: groups.length },
|
||||||
|
{ label: translate('::ListForms.Wizard.Step4.StatField'), value: totalFields },
|
||||||
|
{
|
||||||
|
label: translate('::ListForms.Wizard.Step4.EditingForm') || 'Popup Form',
|
||||||
|
value: editingFormFields.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: translate('::App.Listform.ListformField.Column'),
|
||||||
|
value: selectedColumns.size,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: translate('::ListForms.ListFormEdit.SubForms') || 'Sub Forms',
|
||||||
|
value: subForms.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: translate('::ListForms.ListFormEdit.TabWidgets') || 'Widgets',
|
||||||
|
value: widgets.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: translate('::ListForms.ListFormEdit.TabWorkflow') || 'Workflow',
|
||||||
|
value: workflowItems.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: translate('::ListForms.ListFormEdit.TabTodo') || 'Todo',
|
||||||
|
value: values.todo ? 1 : 0,
|
||||||
|
},
|
||||||
|
].map((s) => (
|
||||||
|
<div
|
||||||
|
key={s.label}
|
||||||
|
className="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 p-3 text-center shadow-sm"
|
||||||
|
>
|
||||||
|
<div className="text-2xl font-bold text-indigo-600 dark:text-indigo-400">
|
||||||
|
{s.value}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-gray-400 mt-0.5">{s.label}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Log panel — grows to fill remaining height */}
|
||||||
|
<div className="rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col flex-1 min-h-0">
|
||||||
|
<div className="px-4 py-2.5 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between shrink-0">
|
||||||
|
<span className="text-sm font-semibold text-gray-700 dark:text-gray-200 flex items-center gap-2">
|
||||||
|
<FaRocket className="text-indigo-400 text-xs" />
|
||||||
|
{translate('::ListForms.Wizard.Step4.DeployLog') || 'Deploy Log'}
|
||||||
|
</span>
|
||||||
|
{isDone && (
|
||||||
|
<span className="text-xs text-emerald-500 font-semibold flex items-center gap-1">
|
||||||
|
<FaCheckCircle /> {translate('::ListForms.Wizard.Step4.Success')}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{hasError && (
|
||||||
|
<span className="text-xs text-red-500 font-semibold flex items-center gap-1">
|
||||||
|
<FaExclamationCircle /> {translate('::ListForms.Wizard.Step4.Error')}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex-1 overflow-y-auto p-4 bg-[#0d1117] dark:bg-black font-mono min-h-[360px]">
|
||||||
|
{logs.length === 0 ? (
|
||||||
|
<div className="flex flex-col items-center justify-center h-full gap-3 py-10 select-none">
|
||||||
|
<FaRocket className="text-gray-700 text-3xl" />
|
||||||
|
<span className="text-xs text-gray-600 italic text-center">
|
||||||
|
{translate('::ListForms.Wizard.Step4.AllInfoReady')}
|
||||||
|
<br />
|
||||||
|
{translate('::ListForms.Wizard.Step4.DeployStartHint')}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
{logs.map((log) => (
|
||||||
|
<div key={log.id} className="flex items-start gap-2.5">
|
||||||
|
<span className="mt-0.5 shrink-0">
|
||||||
|
<LogIcon status={log.status} />
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
className={`text-xs leading-relaxed ${
|
||||||
|
log.status === 'success'
|
||||||
|
? 'text-emerald-400'
|
||||||
|
: log.status === 'error'
|
||||||
|
? 'text-red-400'
|
||||||
|
: log.status === 'running'
|
||||||
|
? 'text-yellow-300'
|
||||||
|
: 'text-gray-600'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{log.label}
|
||||||
|
</span>
|
||||||
|
{log.detail && (
|
||||||
|
<div className="text-[10px] text-gray-600 mt-0.5">{log.detail}</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{isDone && (
|
||||||
|
<div className="mt-4 rounded-lg border border-emerald-800 bg-emerald-950/40 px-4 py-2.5 text-xs text-emerald-400 text-center font-semibold">
|
||||||
|
🎉 {translate('::ListForms.Wizard.Step4.DeploySuccess')}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ── Fixed Footer ─────────────────────────────────────────────── */}
|
||||||
|
<div className="fixed bottom-0 left-0 right-0 z-10 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-700 px-6 py-0 h-16 flex items-center">
|
||||||
|
<div className="flex items-center gap-3 w-full">
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
variant="default"
|
||||||
|
type="button"
|
||||||
|
icon={<FaArrowLeft />}
|
||||||
|
disabled={isDeploying}
|
||||||
|
onClick={onBack}
|
||||||
|
>
|
||||||
|
{translate('::Back') || 'Back'}
|
||||||
|
</Button>
|
||||||
|
<div className="flex-1 flex items-center justify-end">
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
variant="solid"
|
||||||
|
type="button"
|
||||||
|
icon={<FaRocket />}
|
||||||
|
loading={isDeploying}
|
||||||
|
disabled={isDeploying || isDone}
|
||||||
|
onClick={runDeploy}
|
||||||
|
>
|
||||||
|
{isDeploying
|
||||||
|
? translate('::ListForms.Wizard.Step4.Log.Deploying')
|
||||||
|
: isDone
|
||||||
|
? `✓ ${translate('::ListForms.Wizard.Step4.Log.Completed')}`
|
||||||
|
: translate('::ListForms.Wizard.Step4.DeployAndSave')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default WizardStep8
|
||||||
|
|
@ -383,7 +383,7 @@ const OrganizationUnits = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Node = memo(({ node, style, dragHandle }: NodeRendererProps<any>) => {
|
const Node = memo(function Node({ node, style, dragHandle }: NodeRendererProps<any>) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue