Compare commits
No commits in common. "main" and "1.1.08" have entirely different histories.
72 changed files with 2799 additions and 4010 deletions
|
|
@ -10,11 +10,6 @@ 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; }
|
||||||
|
|
@ -245,41 +240,6 @@ 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,5 +16,35 @@ 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; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
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; }
|
|
||||||
}
|
|
||||||
|
|
@ -41,7 +41,6 @@ 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; }
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ namespace Sozsoft.Platform.ListForms;
|
||||||
|
|
||||||
public class WizardColumnItemInputDto
|
public class WizardColumnItemInputDto
|
||||||
{
|
{
|
||||||
public string FieldName { get; set; }
|
public string DataField { 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; }
|
||||||
|
|
|
||||||
|
|
@ -47,33 +47,26 @@ 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.SourceDbType = updateInput.SourceDbType;
|
entity.AllowEditing = updateInput.AllowEditing;
|
||||||
entity.Alignment = updateInput.Alignment;
|
entity.AllowAdding = updateInput.AllowAdding;
|
||||||
entity.Format = updateInput.Format;
|
|
||||||
entity.EditorOptions = updateInput.EditorOptions;
|
|
||||||
entity.EditorScript = updateInput.EditorScript;
|
|
||||||
entity.ListOrderNo = updateInput.ListOrderNo;
|
entity.ListOrderNo = updateInput.ListOrderNo;
|
||||||
|
entity.SourceDbType = updateInput.SourceDbType;
|
||||||
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.EditOrderNo = updateInput.EditOrderNo;
|
entity.Format = updateInput.Format;
|
||||||
entity.EditGroupOrderNo = updateInput.EditGroupOrderNo;
|
entity.Alignment = updateInput.Alignment;
|
||||||
entity.ColSpan = updateInput.ColSpan;
|
entity.EditorOptions = updateInput.EditorOptions;
|
||||||
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);
|
||||||
|
|
@ -81,10 +74,12 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,9 +136,6 @@ 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)
|
||||||
{
|
{
|
||||||
|
|
@ -160,11 +152,6 @@ 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)
|
||||||
{
|
{
|
||||||
|
|
@ -270,9 +257,6 @@ 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)
|
||||||
{
|
{
|
||||||
|
|
@ -285,40 +269,35 @@ 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;
|
|
||||||
}
|
}
|
||||||
if (input.CopiedFields.All || input.CopiedFields.Permission)
|
else if (input.CopiedFields.All || input.CopiedFields.Permission)
|
||||||
{
|
{
|
||||||
field.PermissionJson = sourceField.PermissionJson;
|
field.PermissionJson = sourceField.PermissionJson;
|
||||||
}
|
}
|
||||||
if (input.CopiedFields.All || input.CopiedFields.Customization)
|
else if (input.CopiedFields.All || input.CopiedFields.Customization)
|
||||||
field.ColumnCustomizationJson = sourceField.ColumnCustomizationJson;
|
field.ColumnCustomizationJson = sourceField.ColumnCustomizationJson;
|
||||||
if (input.CopiedFields.All || input.CopiedFields.Filtering)
|
else if (input.CopiedFields.All || input.CopiedFields.Filtering)
|
||||||
field.ColumnFilterJson = sourceField.ColumnFilterJson;
|
field.ColumnFilterJson = sourceField.ColumnFilterJson;
|
||||||
if (input.CopiedFields.All || input.CopiedFields.Headering)
|
else if (input.CopiedFields.All || input.CopiedFields.Headering)
|
||||||
field.ColumnHeaderJson = sourceField.ColumnHeaderJson;
|
field.ColumnHeaderJson = sourceField.ColumnHeaderJson;
|
||||||
if (input.CopiedFields.All || input.CopiedFields.Grouping)
|
else if (input.CopiedFields.All || input.CopiedFields.Grouping)
|
||||||
field.GroupingJson = sourceField.GroupingJson;
|
field.GroupingJson = sourceField.GroupingJson;
|
||||||
if (input.CopiedFields.All || input.CopiedFields.GroupSummary)
|
else if (input.CopiedFields.All || input.CopiedFields.GroupSummary)
|
||||||
field.GroupSummaryJson = sourceField.GroupSummaryJson;
|
field.GroupSummaryJson = sourceField.GroupSummaryJson;
|
||||||
if (input.CopiedFields.All || input.CopiedFields.TotalSummary)
|
else if (input.CopiedFields.All || input.CopiedFields.TotalSummary)
|
||||||
field.TotalSummaryJson = sourceField.TotalSummaryJson;
|
field.TotalSummaryJson = sourceField.TotalSummaryJson;
|
||||||
if (input.CopiedFields.All || input.CopiedFields.JoinOptions)
|
else if (input.CopiedFields.All || input.CopiedFields.JoinOptions)
|
||||||
field.JoinTableJson = sourceField.JoinTableJson;
|
field.JoinTableJson = sourceField.JoinTableJson;
|
||||||
if (input.CopiedFields.All || input.CopiedFields.CssOptions)
|
else if (input.CopiedFields.All || input.CopiedFields.CssOptions)
|
||||||
{
|
{
|
||||||
field.ColumnCssClass = sourceField.ColumnCssClass;
|
field.ColumnCssClass = sourceField.ColumnCssClass;
|
||||||
field.ColumnCssValue = sourceField.ColumnCssValue;
|
field.ColumnCssValue = sourceField.ColumnCssValue;
|
||||||
}
|
}
|
||||||
if (input.CopiedFields.All || input.CopiedFields.ValidationRules)
|
else if (input.CopiedFields.All || input.CopiedFields.ValidationRules)
|
||||||
field.ValidationRuleJson = sourceField.ValidationRuleJson;
|
field.ValidationRuleJson = sourceField.ValidationRuleJson;
|
||||||
if (input.CopiedFields.All || input.CopiedFields.Formatting)
|
else if (input.CopiedFields.All || input.CopiedFields.Formatting)
|
||||||
field.ColumnStylingJson = sourceField.ColumnStylingJson;
|
field.ColumnStylingJson = sourceField.ColumnStylingJson;
|
||||||
if (input.CopiedFields.All || input.CopiedFields.PivotSetting)
|
else if (input.CopiedFields.All || input.CopiedFields.PivotSetting)
|
||||||
field.PivotSettingsJson = sourceField.PivotSettingsJson;
|
field.PivotSettingsJson = sourceField.PivotSettingsJson;
|
||||||
|
|
||||||
await Repository.InsertAsync(field);
|
await Repository.InsertAsync(field);
|
||||||
|
|
|
||||||
|
|
@ -180,18 +180,11 @@ 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;
|
||||||
|
|
@ -237,9 +230,21 @@ 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
|
||||||
|
|
@ -308,8 +313,8 @@ public class ListFormWizardAppService(
|
||||||
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.DefaultDeleteFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
DeleteFieldsDefaultValueJson = isDeleted ? WizardConsts.DefaultDeleteFieldsDefaultValueJson(input.KeyFieldDbSourceType) : WizardConsts.DefaultFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
||||||
InsertFieldsDefaultValueJson = isCreated ? WizardConsts.DefaultInsertFieldsDefaultValueJson(input.KeyFieldDbSourceType) : WizardConsts.DefaultInsertFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
InsertFieldsDefaultValueJson = isCreated ? WizardConsts.DefaultInsertFieldsDefaultValueJson(input.KeyFieldDbSourceType) : WizardConsts.DefaultFieldsJsonOnlyId(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,
|
||||||
|
|
@ -366,36 +371,21 @@ public class ListFormWizardAppService(
|
||||||
|
|
||||||
// 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.FieldName,
|
FieldName = item.DataField,
|
||||||
CaptionName = item.CaptionName,
|
CaptionName = item.CaptionName,
|
||||||
Visible = item.FieldName != input.KeyFieldName,
|
Visible = item.DataField != 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),
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ 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;
|
||||||
|
|
@ -132,30 +131,6 @@ 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": "Grid Report",
|
"en": "List Report",
|
||||||
"tr": "Tablo Raporu"
|
"tr": "Liste Raporu"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
|
|
@ -4440,24 +4440,6 @@
|
||||||
"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",
|
||||||
|
|
@ -4686,12 +4668,6 @@
|
||||||
"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",
|
||||||
|
|
@ -5192,15 +5168,15 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormEdit.EditingFormFormGroups",
|
"key": "ListForms.ListFormEdit.EditingFormFormFields",
|
||||||
"en": "Editing Form Groups",
|
"en": "Editing Form Fields",
|
||||||
"tr": "Düzenleme Form Grupları"
|
"tr": "Düzenleme Form Alanları"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormEdit.EditingFormFormGroupsDescription",
|
"key": "ListForms.ListFormEdit.EditingFormFormFieldsDescription",
|
||||||
"en": "Groups that will appear in Edit form",
|
"en": "Edit formunda çıkacak field'lar",
|
||||||
"tr": "Düzenleme formunda çıkacak gruplar"
|
"tr": "Form Sütunları"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
|
|
@ -5922,30 +5898,6 @@
|
||||||
"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",
|
||||||
|
|
@ -19467,7 +19419,7 @@
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormFieldEdit.TodoStatusOrderPlaceholder",
|
"key": "ListForms.ListFormFieldEdit.TodoStatusOrderPlaceholder",
|
||||||
"en": "Backlog, Ready to Start, In Progress, Code Review, Testing, Staging",
|
"en": "Inbox, Today, This Week, This Month, Later, Done",
|
||||||
"tr": "Gelen Kutusu, Bugün, Bu Hafta, Bu Ay, Daha Sonra, Tamamlandı"
|
"tr": "Gelen Kutusu, Bugün, Bu Hafta, Bu Ay, Daha Sonra, Tamamlandı"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -19476,18 +19428,6 @@
|
||||||
"en": "Allow cards to be dragged between columns",
|
"en": "Allow cards to be dragged between columns",
|
||||||
"tr": "Kartları kolonlar arasında sürüklemeye izin ver"
|
"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",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.TodoBoard.Uncategorized",
|
"key": "ListForms.TodoBoard.Uncategorized",
|
||||||
|
|
@ -19755,13 +19695,13 @@
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.TodoBoard.NewColumn",
|
"key": "ListForms.TodoBoard.NewColumn",
|
||||||
"en": "New Kanban",
|
"en": "New Kanban column",
|
||||||
"tr": "Yeni kanban"
|
"tr": "Yeni kanban"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.TodoBoard.AddNewColumn",
|
"key": "ListForms.TodoBoard.AddNewColumn",
|
||||||
"en": "Add a new Kanban",
|
"en": "Add a new Kanban column",
|
||||||
"tr": "Yeni kanban ekle"
|
"tr": "Yeni kanban ekle"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -984,22 +984,22 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ParentCode": "App.DeveloperKit",
|
"ParentCode": "App.DeveloperKit",
|
||||||
"Code": "App.DeveloperKit.DynamicServices",
|
"Code": "App.DeveloperKit.Components",
|
||||||
"DisplayName": "App.DeveloperKit.DynamicServices",
|
"DisplayName": "App.DeveloperKit.Components",
|
||||||
"Order": 4,
|
"Order": 4,
|
||||||
"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
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ParentCode": "App.DeveloperKit",
|
"ParentCode": "App.DeveloperKit",
|
||||||
"Code": "App.DeveloperKit.Components",
|
"Code": "App.DeveloperKit.DynamicServices",
|
||||||
"DisplayName": "App.DeveloperKit.Components",
|
"DisplayName": "App.DeveloperKit.DynamicServices",
|
||||||
"Order": 5,
|
"Order": 5,
|
||||||
"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
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
IF OBJECT_ID(N'[dbo].[Pro_T_Todo]', 'U') IS NULL
|
IF OBJECT_ID(N'[dbo].[Adm_D_Todos]', 'U') IS NULL
|
||||||
BEGIN
|
BEGIN
|
||||||
CREATE TABLE [dbo].[Pro_T_Todo]
|
CREATE TABLE [dbo].[Adm_D_Todos]
|
||||||
(
|
(
|
||||||
[Id] uniqueidentifier NOT NULL DEFAULT NEWID(),
|
[Id] uniqueidentifier NOT NULL DEFAULT NEWID(),
|
||||||
[Title] nvarchar(300) NOT NULL,
|
[Title] nvarchar(300) NOT NULL,
|
||||||
|
|
@ -12,7 +12,6 @@ BEGIN
|
||||||
[Priority] nvarchar(50) NULL,
|
[Priority] nvarchar(50) NULL,
|
||||||
[Completed] bit NOT NULL DEFAULT 0,
|
[Completed] bit NOT NULL DEFAULT 0,
|
||||||
[SortOrder] int NOT NULL DEFAULT 0,
|
[SortOrder] int NOT NULL DEFAULT 0,
|
||||||
[TenantId] uniqueidentifier NULL,
|
|
||||||
CONSTRAINT [PK_Table] PRIMARY KEY NONCLUSTERED
|
CONSTRAINT [PK_Table] PRIMARY KEY NONCLUSTERED
|
||||||
(
|
(
|
||||||
[Id] ASC
|
[Id] ASC
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
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
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"Wizard": {
|
"Wizard": {
|
||||||
"WizardName": "Todo",
|
"WizardName": "Todos",
|
||||||
"ListFormCode": "App.Wizard.Todo",
|
"ListFormCode": "App.Wizard.Todos",
|
||||||
"MenuCode": "App.Wizard.Todo",
|
"MenuCode": "App.Wizard.Todos",
|
||||||
"IsTenant": true,
|
"IsTenant": false,
|
||||||
"IsBranch": false,
|
"IsBranch": false,
|
||||||
"IsOrganizationUnit": false,
|
"IsOrganizationUnit": false,
|
||||||
"AllowAdding": true,
|
"AllowAdding": true,
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
"AllowDeleting": true,
|
"AllowDeleting": true,
|
||||||
"AllowDetail": false,
|
"AllowDetail": false,
|
||||||
"ConfirmDelete": true,
|
"ConfirmDelete": true,
|
||||||
"DefaultLayout": "todo",
|
"DefaultLayout": "grid",
|
||||||
"Grid": true,
|
"Grid": true,
|
||||||
"Card": true,
|
"Card": true,
|
||||||
"Pivot": true,
|
"Pivot": true,
|
||||||
|
|
@ -20,23 +20,22 @@
|
||||||
"Gantt": true,
|
"Gantt": true,
|
||||||
"Scheduler": true,
|
"Scheduler": true,
|
||||||
"Todo": true,
|
"Todo": true,
|
||||||
"LanguageTextMenuEn": "Todo",
|
"LanguageTextMenuEn": "Todos",
|
||||||
"LanguageTextMenuTr": "\u0130\u015Fler",
|
"LanguageTextMenuTr": "Todos",
|
||||||
"LanguageTextTitleEn": "Todo",
|
"LanguageTextTitleEn": "Todos",
|
||||||
"LanguageTextTitleTr": "\u0130\u015Fler",
|
"LanguageTextTitleTr": "Todos",
|
||||||
"LanguageTextDescEn": "Todo",
|
"LanguageTextDescEn": "Todos",
|
||||||
"LanguageTextDescTr": "\u0130\u015Fler",
|
"LanguageTextDescTr": "Todos",
|
||||||
"LanguageTextMenuParentEn": "Project",
|
"LanguageTextMenuParentEn": "",
|
||||||
"LanguageTextMenuParentTr": "Project",
|
"LanguageTextMenuParentTr": "",
|
||||||
"PermissionGroupName": "App.Wizard.Project",
|
"PermissionGroupName": "App.Administration",
|
||||||
"MenuParentCode": "App.Wizard.Project",
|
"MenuParentCode": "App.Administration",
|
||||||
"MenuParentShortName": "Pro",
|
"MenuParentIcon": "FcOrganization",
|
||||||
"MenuParentIcon": "FcVideoProjector",
|
"MenuIcon": "FcAndroidOs",
|
||||||
"MenuIcon": "FcTodoList",
|
|
||||||
"DataSourceCode": "Default",
|
"DataSourceCode": "Default",
|
||||||
"DataSourceConnectionString": "",
|
"DataSourceConnectionString": "",
|
||||||
"SelectCommandType": 1,
|
"SelectCommandType": 1,
|
||||||
"SelectCommand": "Pro_T_Todo",
|
"SelectCommand": "Adm_D_Todos",
|
||||||
"KeyFieldName": "Id",
|
"KeyFieldName": "Id",
|
||||||
"KeyFieldDbSourceType": 9,
|
"KeyFieldDbSourceType": 9,
|
||||||
"TreeKeyExpr": "",
|
"TreeKeyExpr": "",
|
||||||
|
|
@ -61,7 +60,7 @@
|
||||||
"TodoPriorityExpr": "Priority",
|
"TodoPriorityExpr": "Priority",
|
||||||
"TodoCompletedExpr": "Completed",
|
"TodoCompletedExpr": "Completed",
|
||||||
"TodoOrderExpr": "SortOrder",
|
"TodoOrderExpr": "SortOrder",
|
||||||
"TodoStatusOrder": "Backlog, Ready to Start, In Progress, Code Review, Testing, Staging",
|
"TodoStatusOrder": "Inbox, Today, This Week, This Month, Later, Done",
|
||||||
"TodoAllowDragging": true,
|
"TodoAllowDragging": true,
|
||||||
"ApprovalUserFieldName": "",
|
"ApprovalUserFieldName": "",
|
||||||
"ApprovalDateFieldName": "",
|
"ApprovalDateFieldName": "",
|
||||||
|
|
@ -75,7 +74,7 @@
|
||||||
"ColCount": 1,
|
"ColCount": 1,
|
||||||
"Items": [
|
"Items": [
|
||||||
{
|
{
|
||||||
"FieldName": "Id",
|
"DataField": "Id",
|
||||||
"CaptionName": "App.Listform.ListformField.Id",
|
"CaptionName": "App.Listform.ListformField.Id",
|
||||||
"EditorType": "dxTextBox",
|
"EditorType": "dxTextBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -92,7 +91,7 @@
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FieldName": "Title",
|
"DataField": "Title",
|
||||||
"CaptionName": "App.Listform.ListformField.Title",
|
"CaptionName": "App.Listform.ListformField.Title",
|
||||||
"EditorType": "dxTextBox",
|
"EditorType": "dxTextBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -109,7 +108,7 @@
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FieldName": "Status",
|
"DataField": "Status",
|
||||||
"CaptionName": "App.Listform.ListformField.Status",
|
"CaptionName": "App.Listform.ListformField.Status",
|
||||||
"EditorType": "dxTextBox",
|
"EditorType": "dxTextBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -126,10 +125,10 @@
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FieldName": "Description",
|
"DataField": "Description",
|
||||||
"CaptionName": "App.Listform.ListformField.Description",
|
"CaptionName": "App.Listform.ListformField.Description",
|
||||||
"EditorType": "dxHtmlEditor",
|
"EditorType": "dxTextBox",
|
||||||
"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}]}}",
|
"EditorOptions": "",
|
||||||
"EditorScript": "",
|
"EditorScript": "",
|
||||||
"ColSpan": 1,
|
"ColSpan": 1,
|
||||||
"IsRequired": false,
|
"IsRequired": false,
|
||||||
|
|
@ -143,7 +142,7 @@
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FieldName": "DueDate",
|
"DataField": "DueDate",
|
||||||
"CaptionName": "App.Listform.ListformField.DueDate",
|
"CaptionName": "App.Listform.ListformField.DueDate",
|
||||||
"EditorType": "dxDateBox",
|
"EditorType": "dxDateBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -160,7 +159,7 @@
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FieldName": "Tags",
|
"DataField": "Tags",
|
||||||
"CaptionName": "App.Listform.ListformField.Tags",
|
"CaptionName": "App.Listform.ListformField.Tags",
|
||||||
"EditorType": "dxTextBox",
|
"EditorType": "dxTextBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -177,7 +176,7 @@
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FieldName": "Assignees",
|
"DataField": "Assignees",
|
||||||
"CaptionName": "App.Listform.ListformField.Assignees",
|
"CaptionName": "App.Listform.ListformField.Assignees",
|
||||||
"EditorType": "dxTextBox",
|
"EditorType": "dxTextBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -194,7 +193,7 @@
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FieldName": "Priority",
|
"DataField": "Priority",
|
||||||
"CaptionName": "App.Listform.ListformField.Priority",
|
"CaptionName": "App.Listform.ListformField.Priority",
|
||||||
"EditorType": "dxTextBox",
|
"EditorType": "dxTextBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -211,7 +210,7 @@
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FieldName": "Completed",
|
"DataField": "Completed",
|
||||||
"CaptionName": "App.Listform.ListformField.Completed",
|
"CaptionName": "App.Listform.ListformField.Completed",
|
||||||
"EditorType": "dxCheckBox",
|
"EditorType": "dxCheckBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -228,7 +227,7 @@
|
||||||
"LookupQuery": ""
|
"LookupQuery": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"FieldName": "SortOrder",
|
"DataField": "SortOrder",
|
||||||
"CaptionName": "App.Listform.ListformField.SortOrder",
|
"CaptionName": "App.Listform.ListformField.SortOrder",
|
||||||
"EditorType": "dxNumberBox",
|
"EditorType": "dxNumberBox",
|
||||||
"EditorOptions": "",
|
"EditorOptions": "",
|
||||||
|
|
@ -254,27 +253,25 @@
|
||||||
"IsCreatedField": false,
|
"IsCreatedField": false,
|
||||||
"InsertedRecords": {
|
"InsertedRecords": {
|
||||||
"LanguageKeys": [
|
"LanguageKeys": [
|
||||||
"App.Wizard.Todo",
|
"App.Wizard.Todos",
|
||||||
"App.Wizard.Todo.Title",
|
"App.Wizard.Todos.Title",
|
||||||
"App.Wizard.Todo.Desc",
|
"App.Wizard.Todos.Desc",
|
||||||
"App.Listform.ListformField.Assignees",
|
"App.Listform.ListformField.Assignees",
|
||||||
"App.Listform.ListformField.Completed",
|
"App.Listform.ListformField.Completed",
|
||||||
"App.Listform.ListformField.SortOrder"
|
"App.Listform.ListformField.SortOrder"
|
||||||
],
|
],
|
||||||
"PermissionGroupNames": [
|
"PermissionGroupNames": [],
|
||||||
"App.Wizard.Project"
|
|
||||||
],
|
|
||||||
"PermissionNames": [
|
"PermissionNames": [
|
||||||
"App.Wizard.Todo",
|
"App.Wizard.Todos",
|
||||||
"App.Wizard.Todo.Create",
|
"App.Wizard.Todos.Create",
|
||||||
"App.Wizard.Todo.Update",
|
"App.Wizard.Todos.Update",
|
||||||
"App.Wizard.Todo.Delete",
|
"App.Wizard.Todos.Delete",
|
||||||
"App.Wizard.Todo.Export",
|
"App.Wizard.Todos.Export",
|
||||||
"App.Wizard.Todo.Import",
|
"App.Wizard.Todos.Import",
|
||||||
"App.Wizard.Todo.Note"
|
"App.Wizard.Todos.Note"
|
||||||
],
|
],
|
||||||
"MenuCodes": [
|
"MenuCodes": [
|
||||||
"App.Wizard.Todo"
|
"App.Wizard.Todos"
|
||||||
],
|
],
|
||||||
"DataSourceCodes": []
|
"DataSourceCodes": []
|
||||||
}
|
}
|
||||||
|
|
@ -1,281 +0,0 @@
|
||||||
{
|
|
||||||
"Wizard": {
|
|
||||||
"WizardName": "Approval",
|
|
||||||
"ListFormCode": "App.Wizard.Approval",
|
|
||||||
"MenuCode": "App.Wizard.Approval",
|
|
||||||
"IsTenant": true,
|
|
||||||
"IsBranch": false,
|
|
||||||
"IsOrganizationUnit": false,
|
|
||||||
"AllowAdding": true,
|
|
||||||
"AllowUpdating": true,
|
|
||||||
"AllowDeleting": true,
|
|
||||||
"AllowDetail": false,
|
|
||||||
"ConfirmDelete": true,
|
|
||||||
"DefaultLayout": "grid",
|
|
||||||
"Grid": true,
|
|
||||||
"Card": true,
|
|
||||||
"Pivot": true,
|
|
||||||
"Tree": true,
|
|
||||||
"Chart": true,
|
|
||||||
"Gantt": true,
|
|
||||||
"Scheduler": true,
|
|
||||||
"Todo": false,
|
|
||||||
"LanguageTextMenuEn": "Approval",
|
|
||||||
"LanguageTextMenuTr": "Onaylama",
|
|
||||||
"LanguageTextTitleEn": "Approval",
|
|
||||||
"LanguageTextTitleTr": "Onaylama",
|
|
||||||
"LanguageTextDescEn": "Approval",
|
|
||||||
"LanguageTextDescTr": "Onaylama",
|
|
||||||
"LanguageTextMenuParentEn": "Project",
|
|
||||||
"LanguageTextMenuParentTr": "Project",
|
|
||||||
"PermissionGroupName": "App.Wizard.Project",
|
|
||||||
"MenuParentCode": "App.Wizard.Project",
|
|
||||||
"MenuParentShortName": "Pro",
|
|
||||||
"MenuParentIcon": "FcVideoProjector",
|
|
||||||
"MenuIcon": "FcApproval",
|
|
||||||
"DataSourceCode": "Default",
|
|
||||||
"DataSourceConnectionString": "",
|
|
||||||
"SelectCommandType": 1,
|
|
||||||
"SelectCommand": "Pro_T_Approval",
|
|
||||||
"KeyFieldName": "Id",
|
|
||||||
"KeyFieldDbSourceType": 9,
|
|
||||||
"TreeKeyExpr": "",
|
|
||||||
"TreeParentIdExpr": "",
|
|
||||||
"TreeAutoExpandAll": false,
|
|
||||||
"GanttKeyExpr": "",
|
|
||||||
"GanttParentIdExpr": "",
|
|
||||||
"GanttAutoExpandAll": false,
|
|
||||||
"GanttTitleExpr": "",
|
|
||||||
"GanttStartExpr": "",
|
|
||||||
"GanttEndExpr": "",
|
|
||||||
"GanttProgressExpr": "",
|
|
||||||
"SchedulerTextExpr": "",
|
|
||||||
"SchedulerStartDateExpr": "",
|
|
||||||
"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": [
|
|
||||||
{
|
|
||||||
"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": "ApprovalUserName",
|
|
||||||
"CaptionName": "App.Listform.ListformField.ApprovalUserName",
|
|
||||||
"EditorType": "dxTextBox",
|
|
||||||
"EditorOptions": "",
|
|
||||||
"EditorScript": "",
|
|
||||||
"ColSpan": 1,
|
|
||||||
"IsRequired": false,
|
|
||||||
"IncludeInEditingForm": false,
|
|
||||||
"DbSourceType": 16,
|
|
||||||
"TurkishCaption": "Approval User Name",
|
|
||||||
"EnglishCaption": "Approval User Name",
|
|
||||||
"LookupDataSourceType": 1,
|
|
||||||
"ValueExpr": "Key",
|
|
||||||
"DisplayExpr": "Name",
|
|
||||||
"LookupQuery": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"FieldName": "ApprovalStatus",
|
|
||||||
"CaptionName": "App.Listform.ListformField.ApprovalStatus",
|
|
||||||
"EditorType": "dxTextBox",
|
|
||||||
"EditorOptions": "",
|
|
||||||
"EditorScript": "",
|
|
||||||
"ColSpan": 1,
|
|
||||||
"IsRequired": false,
|
|
||||||
"IncludeInEditingForm": false,
|
|
||||||
"DbSourceType": 16,
|
|
||||||
"TurkishCaption": "Approval Status",
|
|
||||||
"EnglishCaption": "Approval Status",
|
|
||||||
"LookupDataSourceType": 1,
|
|
||||||
"ValueExpr": "Key",
|
|
||||||
"DisplayExpr": "Name",
|
|
||||||
"LookupQuery": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"FieldName": "ApprovalDate",
|
|
||||||
"CaptionName": "App.Listform.ListformField.ApprovalDate",
|
|
||||||
"EditorType": "dxDateBox",
|
|
||||||
"EditorOptions": "",
|
|
||||||
"EditorScript": "",
|
|
||||||
"ColSpan": 1,
|
|
||||||
"IsRequired": false,
|
|
||||||
"IncludeInEditingForm": false,
|
|
||||||
"DbSourceType": 6,
|
|
||||||
"TurkishCaption": "Approval Date",
|
|
||||||
"EnglishCaption": "Approval Date",
|
|
||||||
"LookupDataSourceType": 1,
|
|
||||||
"ValueExpr": "Key",
|
|
||||||
"DisplayExpr": "Name",
|
|
||||||
"LookupQuery": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"FieldName": "ApprovalDescription",
|
|
||||||
"CaptionName": "App.Listform.ListformField.ApprovalDescription",
|
|
||||||
"EditorType": "dxTextBox",
|
|
||||||
"EditorOptions": "",
|
|
||||||
"EditorScript": "",
|
|
||||||
"ColSpan": 1,
|
|
||||||
"IsRequired": false,
|
|
||||||
"IncludeInEditingForm": false,
|
|
||||||
"DbSourceType": 16,
|
|
||||||
"TurkishCaption": "Approval Description",
|
|
||||||
"EnglishCaption": "Approval Description",
|
|
||||||
"LookupDataSourceType": 1,
|
|
||||||
"ValueExpr": "Key",
|
|
||||||
"DisplayExpr": "Name",
|
|
||||||
"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": [],
|
|
||||||
"Widgets": []
|
|
||||||
},
|
|
||||||
"IsDeletedField": false,
|
|
||||||
"IsCreatedField": false,
|
|
||||||
"InsertedRecords": {
|
|
||||||
"LanguageKeys": [
|
|
||||||
"App.Wizard.Approval",
|
|
||||||
"App.Wizard.Approval.Title",
|
|
||||||
"App.Wizard.Approval.Desc"
|
|
||||||
],
|
|
||||||
"PermissionGroupNames": [],
|
|
||||||
"PermissionNames": [
|
|
||||||
"App.Wizard.Approval",
|
|
||||||
"App.Wizard.Approval.Create",
|
|
||||||
"App.Wizard.Approval.Update",
|
|
||||||
"App.Wizard.Approval.Delete",
|
|
||||||
"App.Wizard.Approval.Export",
|
|
||||||
"App.Wizard.Approval.Import",
|
|
||||||
"App.Wizard.Approval.Note"
|
|
||||||
],
|
|
||||||
"MenuCodes": [
|
|
||||||
"App.Wizard.Approval"
|
|
||||||
],
|
|
||||||
"DataSourceCodes": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -107,8 +107,6 @@ 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))
|
||||||
{
|
{
|
||||||
|
|
@ -255,7 +253,6 @@ 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);
|
||||||
|
|
@ -305,9 +302,21 @@ 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
|
||||||
|
|
@ -332,8 +341,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.FieldName != input.KeyFieldName)
|
.Where(i => i.IncludeInEditingForm && i.DataField != input.KeyFieldName)
|
||||||
.Select(i => new { FieldName = i.FieldName, Isrequired = i.IsRequired })
|
.Select(i => new { FieldName = i.DataField, Isrequired = i.IsRequired })
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// Heigth ve Width hesaplama
|
// Heigth ve Width hesaplama
|
||||||
|
|
@ -341,7 +350,7 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
.Select(g =>
|
.Select(g =>
|
||||||
{
|
{
|
||||||
var items = g.Items
|
var items = g.Items
|
||||||
.Where(i => i.IncludeInEditingForm && i.FieldName != input.KeyFieldName)
|
.Where(i => i.IncludeInEditingForm && i.DataField != input.KeyFieldName)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var columnCount = g.ColCount;
|
var columnCount = g.ColCount;
|
||||||
|
|
@ -413,10 +422,10 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
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.DefaultDeleteFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
: WizardConsts.DefaultFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
||||||
InsertFieldsDefaultValueJson = isCreated
|
InsertFieldsDefaultValueJson = isCreated
|
||||||
? WizardConsts.DefaultInsertFieldsDefaultValueJson(input.KeyFieldDbSourceType)
|
? WizardConsts.DefaultInsertFieldsDefaultValueJson(input.KeyFieldDbSourceType)
|
||||||
: WizardConsts.DefaultInsertFieldsJsonOnlyId(input.KeyFieldDbSourceType),
|
: WizardConsts.DefaultFieldsJsonOnlyId(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,
|
||||||
|
|
@ -445,36 +454,21 @@ public class WizardDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
|
|
||||||
// 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.FieldName,
|
FieldName = item.DataField,
|
||||||
CaptionName = item.CaptionName,
|
CaptionName = item.CaptionName,
|
||||||
Visible = item.FieldName != input.KeyFieldName,
|
Visible = item.DataField != 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),
|
||||||
|
|
@ -484,7 +478,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.FieldName && f.Isrequired)
|
ValidationRuleJson = editingFormFieldNames.Any(f => f.FieldName == item.DataField && f.Isrequired)
|
||||||
? WizardConsts.DefaultValidationRuleRequiredJson
|
? WizardConsts.DefaultValidationRuleRequiredJson
|
||||||
: null
|
: null
|
||||||
}, autoSave: true);
|
}, autoSave: true);
|
||||||
|
|
@ -522,24 +516,6 @@ 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 && (
|
||||||
|
|
|
||||||
|
|
@ -758,7 +758,6 @@ 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";
|
||||||
|
|
|
||||||
|
|
@ -198,14 +198,6 @@ 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[]
|
||||||
|
|
@ -215,11 +207,11 @@ public static class WizardConsts
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string DefaultDeleteFieldsJsonOnlyId(DbType dbType = DbType.Guid)
|
public static string DefaultFieldsJsonOnlyId(DbType dbType = DbType.Guid)
|
||||||
{
|
{
|
||||||
return JsonSerializer.Serialize(new[]
|
return JsonSerializer.Serialize(new[]
|
||||||
{
|
{
|
||||||
new { FieldName = "Id", FieldDbType = dbType, Value = "@ID", CustomValueType = FieldCustomValueTypeEnum.CustomKey }
|
new { FieldName = "Id", FieldDbType = dbType, Value = "@NEWID", CustomValueType = FieldCustomValueTypeEnum.CustomKey }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,12 +53,6 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
58
api/src/Sozsoft.Platform.Domain/Queries/EditingForm.cs
Normal file
58
api/src/Sozsoft.Platform.Domain/Queries/EditingForm.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
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;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
@ -170,8 +170,7 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
// oncelik Command alanindadir, dolu ise silme islemi buradaki sorguya yonlendirilir
|
// oncelik Command alanindadir, dolu ise silme islemi buradaki sorguya yonlendirilir
|
||||||
if (!string.IsNullOrEmpty(command))
|
if (!string.IsNullOrEmpty(command))
|
||||||
{
|
{
|
||||||
// sql = NormalizeCollectionParameterCommand(command, parameters, dataSourceType);
|
sql = NormalizeCollectionParameterCommand(command, parameters, dataSourceType);
|
||||||
sql = command;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -189,6 +188,12 @@ 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))
|
||||||
|
|
@ -197,18 +202,6 @@ 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)
|
||||||
|
|
@ -219,7 +212,12 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
{
|
{
|
||||||
where = string.Join(
|
where = string.Join(
|
||||||
" AND ",
|
" AND ",
|
||||||
parameters.Select(a => BuildWhereCondition(a.Key, a.Value, dataSourceType)).ToList());
|
parameters.Select(a => dataSourceType switch
|
||||||
|
{
|
||||||
|
DataSourceTypeEnum.Mssql => $"\"{a.Key}\" IN @{a.Key}",
|
||||||
|
DataSourceTypeEnum.Postgresql => $"\"{a.Key}\" = ANY(@{a.Key})",
|
||||||
|
_ => "1 = 0",
|
||||||
|
}).ToList());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -242,101 +240,77 @@ public class QueryManager : PlatformDomainService, IQueryManager
|
||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsCollectionValue(object value)
|
private static string NormalizeCollectionParameterCommand(
|
||||||
|
string command,
|
||||||
|
Dictionary<string, object> parameters,
|
||||||
|
DataSourceTypeEnum dataSourceType)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(command) || parameters == null || parameters.Count == 0)
|
||||||
|
{
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sql = command;
|
||||||
|
foreach (var parameter in parameters)
|
||||||
|
{
|
||||||
|
if (!IsCollectionParameter(parameter.Value))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var escapedParameterName = Regex.Escape(parameter.Key);
|
||||||
|
sql = dataSourceType switch
|
||||||
|
{
|
||||||
|
DataSourceTypeEnum.Mssql => NormalizeMssqlCollectionParameter(sql, escapedParameterName, parameter.Key),
|
||||||
|
DataSourceTypeEnum.Postgresql => NormalizePostgresqlCollectionParameter(sql, escapedParameterName, parameter.Key),
|
||||||
|
_ => sql
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsCollectionParameter(object value)
|
||||||
{
|
{
|
||||||
return value is System.Collections.IEnumerable
|
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 BuildWhereCondition(
|
private static string NormalizeMssqlCollectionParameter(
|
||||||
string fieldName,
|
string sql,
|
||||||
object value,
|
string escapedParameterName,
|
||||||
DataSourceTypeEnum dataSourceType)
|
string parameterName)
|
||||||
{
|
{
|
||||||
return dataSourceType switch
|
sql = Regex.Replace(
|
||||||
{
|
sql,
|
||||||
DataSourceTypeEnum.Mssql when value is null or DBNull => $"\"{fieldName}\" IS NULL",
|
$@"IN\s*\(\s*@{escapedParameterName}\s*\)",
|
||||||
DataSourceTypeEnum.Postgresql when value is null or DBNull => $"\"{fieldName}\" IS NULL",
|
$"IN @{parameterName}",
|
||||||
DataSourceTypeEnum.Mssql when IsCollectionValue(value) => $"\"{fieldName}\" IN @{fieldName}",
|
RegexOptions.IgnoreCase);
|
||||||
DataSourceTypeEnum.Postgresql when IsCollectionValue(value) => $"\"{fieldName}\" = ANY(@{fieldName})",
|
|
||||||
DataSourceTypeEnum.Mssql => $"\"{fieldName}\" = @{fieldName}",
|
return Regex.Replace(
|
||||||
DataSourceTypeEnum.Postgresql => $"\"{fieldName}\" = @{fieldName}",
|
sql,
|
||||||
_ => "1 = 0",
|
$@"(?<column>(""[^""]+""|\[[^\]]+\]|`[^`]+`|\w+))\s*=\s*@{escapedParameterName}\b",
|
||||||
};
|
match => $"{match.Groups["column"].Value} IN @{parameterName}",
|
||||||
|
RegexOptions.IgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static string NormalizeCollectionParameterCommand(
|
private static string NormalizePostgresqlCollectionParameter(
|
||||||
// string command,
|
string sql,
|
||||||
// Dictionary<string, object> parameters,
|
string escapedParameterName,
|
||||||
// DataSourceTypeEnum dataSourceType)
|
string parameterName)
|
||||||
// {
|
{
|
||||||
// if (string.IsNullOrWhiteSpace(command) || parameters == null || parameters.Count == 0)
|
sql = Regex.Replace(
|
||||||
// {
|
sql,
|
||||||
// return command;
|
$@"IN\s*\(\s*@{escapedParameterName}\s*\)",
|
||||||
// }
|
$"= ANY(@{parameterName})",
|
||||||
|
RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
// var sql = command;
|
return Regex.Replace(
|
||||||
// foreach (var parameter in parameters)
|
sql,
|
||||||
// {
|
$@"(?<column>(""[^""]+""|\[[^\]]+\]|`[^`]+`|\w+))\s*=\s*@{escapedParameterName}\b",
|
||||||
// if (!IsCollectionParameter(parameter.Value))
|
match => $"{match.Groups["column"].Value} = ANY(@{parameterName})",
|
||||||
// {
|
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);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -455,8 +455,6 @@ 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);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
|
||||||
namespace Sozsoft.Platform.Migrations
|
namespace Sozsoft.Platform.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(PlatformDbContext))]
|
[DbContext(typeof(PlatformDbContext))]
|
||||||
[Migration("20260717065637_Initial")]
|
[Migration("20260716120523_Initial")]
|
||||||
partial class Initial
|
partial class Initial
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -3415,9 +3415,6 @@ 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)");
|
||||||
|
|
@ -3443,22 +3440,9 @@ 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)
|
||||||
|
|
@ -2791,11 +2791,6 @@ 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 =>
|
||||||
|
|
@ -3412,9 +3412,6 @@ 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)");
|
||||||
|
|
@ -3440,22 +3437,9 @@ 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)
|
||||||
|
|
|
||||||
|
|
@ -542,16 +542,14 @@ 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 editFields = fields
|
var formItems = GetEditingFormItems(listForm)
|
||||||
.Where(x => x.EditOrderNo.HasValue)
|
.Where(x => !string.IsNullOrWhiteSpace(x.DataField))
|
||||||
.OrderBy(x => x.EditGroupOrderNo ?? 1)
|
|
||||||
.ThenBy(x => x.EditOrderNo)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var orderedFields = editFields.Count > 0
|
var orderedFields = formItems.Count > 0
|
||||||
? editFields
|
? formItems
|
||||||
.Where(x => fieldsByName.ContainsKey(x.FieldName))
|
.Where(x => fieldsByName.ContainsKey(x.DataField))
|
||||||
.Select(x => new FieldWithEditor(x, x.EditorType2, x.ColSpan ?? 1))
|
.Select(x => new FieldWithEditor(fieldsByName[x.DataField], x.EditorType2, x.ColSpan))
|
||||||
.ToList()
|
.ToList()
|
||||||
: fields
|
: fields
|
||||||
.Where(x => !string.IsNullOrWhiteSpace(x.FieldName) && x.FieldName != "undefined")
|
.Where(x => !string.IsNullOrWhiteSpace(x.FieldName) && x.FieldName != "undefined")
|
||||||
|
|
@ -584,9 +582,10 @@ 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 = fields
|
var groupFields = (group.Items ?? [])
|
||||||
.Where(x => (x.Field.EditGroupOrderNo ?? 1) == group.Order)
|
.OrderBy(x => x.Order)
|
||||||
.OrderBy(x => x.Field.EditOrderNo ?? int.MaxValue)
|
.Where(x => !string.IsNullOrWhiteSpace(x.DataField) && fieldsByName.ContainsKey(x.DataField))
|
||||||
|
.Select(x => fieldsByName[x.DataField])
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
foreach (var field in groupFields)
|
foreach (var field in groupFields)
|
||||||
|
|
@ -626,6 +625,13 @@ 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(fields);
|
var editorTypesByField = DynamicReportImageHelper.CreateEditorTypeMap(listForm);
|
||||||
|
|
||||||
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,16 +73,28 @@ internal static class DynamicReportImageHelper
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string, string> CreateEditorTypeMap(IEnumerable<ListFormField> fields)
|
public static Dictionary<string, string> CreateEditorTypeMap(ListForm listForm)
|
||||||
{
|
{
|
||||||
var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
foreach (var field in fields ?? [])
|
if (string.IsNullOrWhiteSpace(listForm?.EditingFormJson))
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(field.FieldName) && !string.IsNullOrWhiteSpace(field.EditorType2))
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var groups = JsonSerializer.Deserialize<List<EditingFormDto>>(listForm.EditingFormJson) ?? [];
|
||||||
|
foreach (var item in groups.SelectMany(x => x.Items ?? []))
|
||||||
{
|
{
|
||||||
map[field.FieldName] = field.EditorType2;
|
if (!string.IsNullOrWhiteSpace(item.DataField))
|
||||||
|
{
|
||||||
|
map[item.DataField] = item.EditorType2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (JsonException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
@ -440,16 +452,25 @@ 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(IEnumerable<ListFormField> fields, string fieldName)
|
public static bool HasImageEditor(ListForm listForm, string fieldName)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(fieldName))
|
if (string.IsNullOrWhiteSpace(listForm?.EditingFormJson) || string.IsNullOrWhiteSpace(fieldName))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (fields ?? []).Any(x =>
|
try
|
||||||
string.Equals(x.FieldName, fieldName, StringComparison.OrdinalIgnoreCase) &&
|
{
|
||||||
IsImageEditor(x.EditorType2));
|
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));
|
||||||
|
}
|
||||||
|
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(fields);
|
var editorTypesByField = DynamicReportImageHelper.CreateEditorTypeMap(listForm);
|
||||||
|
|
||||||
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,17 +1,6 @@
|
||||||
{
|
{
|
||||||
"commit": "8146adf",
|
"commit": "1d05d24",
|
||||||
"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",
|
"version": "1.1.07",
|
||||||
"buildDate": "2026-07-13",
|
"buildDate": "2026-07-13",
|
||||||
|
|
|
||||||
|
|
@ -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 { useStoreActions, useStoreState } from '@/store'
|
import { useStoreState, useStoreActions } 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,7 +16,8 @@ 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, { useEffect } from 'react'
|
import React 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'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, {
|
import {
|
||||||
Children,
|
Children,
|
||||||
cloneElement,
|
cloneElement,
|
||||||
forwardRef,
|
forwardRef,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { createContext } from 'react'
|
import { 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 React, {
|
import {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useState,
|
useState,
|
||||||
useRef,
|
useRef,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ 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 React, {
|
import {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useState,
|
useState,
|
||||||
useRef,
|
useRef,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, {
|
import {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState, useEffect, useCallback, useMemo } from 'react'
|
import { 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 React, {
|
import {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useState,
|
useState,
|
||||||
useCallback,
|
useCallback,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState, useCallback, useRef, useEffect } from 'react'
|
import { useState, useCallback, useRef, useEffect } from 'react'
|
||||||
import useCallbackRef from './useCallbackRef'
|
import useCallbackRef from './useCallbackRef'
|
||||||
|
|
||||||
type UseControllableStateParams<T> = {
|
type UseControllableStateParams<T> = {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import {
|
||||||
import { ListViewLayoutType } from '@/views/admin/listForm/edit/types'
|
import { ListViewLayoutType } from '@/views/admin/listForm/edit/types'
|
||||||
|
|
||||||
export interface ListFormWizardColumnItemDto {
|
export interface ListFormWizardColumnItemDto {
|
||||||
fieldName: string
|
dataField: string
|
||||||
editorType: string
|
editorType: string
|
||||||
editorOptions: string
|
editorOptions: string
|
||||||
editorScript: string
|
editorScript: string
|
||||||
|
|
@ -56,7 +56,6 @@ 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
|
||||||
|
|
@ -130,7 +129,7 @@ export interface WizardInsertedRecordsDto {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WizardSeedFileItemDto {
|
export interface WizardSeedFileItemDto {
|
||||||
fieldName: string
|
dataField: string
|
||||||
editorType: string
|
editorType: string
|
||||||
editorOptions: string
|
editorOptions: string
|
||||||
editorScript: string
|
editorScript: string
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ 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 {
|
||||||
|
|
@ -194,7 +195,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
|
||||||
|
|
@ -244,14 +245,6 @@ 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 {
|
||||||
|
|
@ -499,6 +492,20 @@ 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 {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
|
|
||||||
function useTimeOutMessage(
|
function useTimeOutMessage(
|
||||||
interval = 3000,
|
interval = 3000,
|
||||||
|
|
|
||||||
|
|
@ -300,9 +300,6 @@ 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>
|
||||||
)}
|
)}
|
||||||
|
|
@ -311,6 +308,9 @@ 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>
|
||||||
)}
|
)}
|
||||||
|
|
@ -464,7 +464,6 @@ 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}
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,6 @@ const schema = Yup.object().shape({
|
||||||
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(),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
@ -413,11 +411,7 @@ function FormTabDetails(
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
<FormItem
|
<FormItem label="Todo Layout">
|
||||||
label={translate('::ListForms.ListFormEdit.DetailsLayoutDto.TodoLayout')}
|
|
||||||
invalid={errors.layoutDto?.todo && touched.layoutDto?.todo}
|
|
||||||
errorMessage={errors.layoutDto?.todo}
|
|
||||||
>
|
|
||||||
<Field
|
<Field
|
||||||
className="w-20"
|
className="w-20"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ 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>
|
||||||
|
|
@ -108,6 +109,13 @@ 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>
|
||||||
|
|
|
||||||
|
|
@ -20,17 +20,14 @@ 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()
|
||||||
|
|
||||||
|
|
@ -75,18 +72,13 @@ function FormFieldEdit({
|
||||||
<TabNav value="pivotSetting">
|
<TabNav value="pivotSetting">
|
||||||
{translate('::ListForms.ListFormFieldEdit.TabPivotSettings')}
|
{translate('::ListForms.ListFormFieldEdit.TabPivotSettings')}
|
||||||
</TabNav>
|
</TabNav>
|
||||||
</TabList>
|
</TabList>
|
||||||
<div className="pt-4">
|
<div className="pt-4">
|
||||||
<TabContent value="details">
|
<TabContent value="details">
|
||||||
<FormFieldTabDetails initialValues={item} onSubmit={onSubmit} />
|
<FormFieldTabDetails initialValues={item} onSubmit={onSubmit} />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="options">
|
<TabContent value="options">
|
||||||
<FormFieldTabOptions
|
<FormFieldTabOptions initialValues={item} onSubmit={onSubmit} />
|
||||||
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} />
|
||||||
|
|
@ -104,10 +96,18 @@ function FormFieldEdit({
|
||||||
<FormFieldTabGrouping initialValues={item} onSubmit={onSubmit} />
|
<FormFieldTabGrouping initialValues={item} onSubmit={onSubmit} />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="groupSummary">
|
<TabContent value="groupSummary">
|
||||||
<FormFieldTabGroupSummary initialValues={item} fields={fields} onSubmit={onSubmit} />
|
<FormFieldTabGroupSummary
|
||||||
|
initialValues={item}
|
||||||
|
fields={fields}
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
/>
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="totalSummary">
|
<TabContent value="totalSummary">
|
||||||
<FormFieldTabTotalSummary initialValues={item} fields={fields} onSubmit={onSubmit} />
|
<FormFieldTabTotalSummary
|
||||||
|
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, Checkbox, FormItem, Input, Select } from '@/components/ui'
|
import { Button, Card, 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 { bool, number, object, string } from 'yup'
|
import { 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,13 +16,10 @@ 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(),
|
editorOptions: string().max(1000),
|
||||||
})
|
})
|
||||||
|
|
||||||
function FormFieldTabDetails({
|
function FormFieldTabDetails({
|
||||||
|
|
@ -75,32 +72,6 @@ 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')}>
|
||||||
|
|
@ -161,7 +132,7 @@ function FormFieldTabDetails({
|
||||||
type="text"
|
type="text"
|
||||||
name="editorOptions"
|
name="editorOptions"
|
||||||
component={Input}
|
component={Input}
|
||||||
rows={3}
|
rows={4}
|
||||||
textArea={true}
|
textArea={true}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -183,14 +154,7 @@ function FormFieldTabDetails({
|
||||||
onClose={() => setIsEditorOptionsDialogOpen(false)}
|
onClose={() => setIsEditorOptionsDialogOpen(false)}
|
||||||
onApply={(val) => setFieldValue('editorOptions', val)}
|
onApply={(val) => setFieldValue('editorOptions', val)}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
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,50 +4,29 @@ 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 { columnEditorTypeListOptions, sortDirectionOptions } from '../options'
|
import { sortDirectionOptions } from '../options'
|
||||||
import { FormFieldEditProps } from './FormFields'
|
import { FormFieldEditProps } from './FormFields'
|
||||||
import { EditingFormDto, SortDirectionEnum } from '@/proxy/form/models'
|
import { 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(),
|
||||||
editGroupOrderNo: number().nullable(),
|
isActive: bool().required(),
|
||||||
editOrderNo: number().nullable(),
|
visible: bool().required(),
|
||||||
colSpan: number().nullable(),
|
allowSearch: bool().required(),
|
||||||
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
|
||||||
|
|
@ -58,7 +37,7 @@ function FormFieldTabOptions({
|
||||||
await onSubmit(ListFormFieldEditTabs.OptionsForm, values, formikHelpers)
|
await onSubmit(ListFormFieldEditTabs.OptionsForm, values, formikHelpers)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{({ touched, errors, isSubmitting, values, setFieldValue }) => (
|
{({ touched, errors, isSubmitting, values }) => (
|
||||||
<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>
|
||||||
|
|
@ -103,7 +82,25 @@ 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>
|
||||||
|
|
@ -111,100 +108,9 @@ 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>
|
|
||||||
</FormItem>
|
|
||||||
</Card>
|
|
||||||
</div>
|
</div>
|
||||||
<EditorScriptBuilderDialog
|
|
||||||
isOpen={isEditorScriptDialogOpen}
|
<Button block size="sm" className="mt-1" variant="solid" loading={isSubmitting} type="submit">
|
||||||
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,7 +43,6 @@ 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: (
|
||||||
|
|
@ -72,14 +71,12 @@ 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[]
|
||||||
|
|
@ -222,45 +219,42 @@ function FormFields({
|
||||||
await getFields()
|
await getFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFields = useCallback(
|
const getFields = useCallback(async (cultureName?: string, roleId?: string, userId?: string) => {
|
||||||
async (cultureName?: string, roleId?: string, userId?: string) => {
|
if (!listFormCode) {
|
||||||
if (!listFormCode) {
|
return
|
||||||
return
|
}
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await getListFormFields({
|
const resp = await getListFormFields({
|
||||||
listFormCode,
|
listFormCode,
|
||||||
cultureName,
|
cultureName,
|
||||||
roleId,
|
roleId,
|
||||||
userId,
|
userId,
|
||||||
sorting: 'ListOrderNo',
|
sorting: 'ListOrderNo',
|
||||||
maxResultCount: 1000,
|
maxResultCount: 1000,
|
||||||
})
|
})
|
||||||
setNull(resp?.data?.items)
|
setNull(resp?.data?.items)
|
||||||
setFields(resp?.data?.items)
|
setFields(resp?.data?.items)
|
||||||
if (resp.data?.items) {
|
if (resp.data?.items) {
|
||||||
setFieldList(
|
setFieldList(
|
||||||
resp?.data?.items.map((f: ColumnFormatEditDto) => ({
|
resp?.data?.items.map((f: ColumnFormatEditDto) => ({
|
||||||
value: f.fieldName,
|
value: f.fieldName,
|
||||||
label: f.fieldName,
|
label: f.fieldName,
|
||||||
})),
|
})),
|
||||||
)
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
toast.push(
|
|
||||||
<Notification type="danger" duration={2000}>
|
|
||||||
Alanlar getirilemedi
|
|
||||||
{error.toString()}
|
|
||||||
</Notification>,
|
|
||||||
{
|
|
||||||
placement: 'bottom-end',
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
} catch (error: any) {
|
||||||
[listFormCode],
|
toast.push(
|
||||||
)
|
<Notification type="danger" duration={2000}>
|
||||||
|
Alanlar getirilemedi
|
||||||
|
{error.toString()}
|
||||||
|
</Notification>,
|
||||||
|
{
|
||||||
|
placement: 'bottom-end',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}, [listFormCode])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getFields()
|
getFields()
|
||||||
|
|
@ -411,7 +405,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"
|
||||||
|
|
@ -484,19 +478,12 @@ function FormFields({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<span style={{ visibility: !field?.visible ? 'visible' : 'hidden' }}>
|
<span>{field.listOrderNo}</span>
|
||||||
<FaEyeSlash />
|
<span>{!field?.visible && <FaEyeSlash />}</span>
|
||||||
</span>
|
<span>{!field?.isActive && <FaTimes />}</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"
|
||||||
|
|
@ -518,12 +505,7 @@ 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
|
<FormFieldEdit item={row} fields={fields} onSubmit={onSubmit} />
|
||||||
item={row}
|
|
||||||
fields={fields}
|
|
||||||
editingFormGroups={editingFormGroups}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</AdaptableCard>
|
</AdaptableCard>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -64,7 +64,7 @@ const initialValues: ListFormWizardDto = {
|
||||||
chart: true,
|
chart: true,
|
||||||
gantt: true,
|
gantt: true,
|
||||||
scheduler: true,
|
scheduler: true,
|
||||||
todo: false,
|
todo: true,
|
||||||
todoTitleExpr: '',
|
todoTitleExpr: '',
|
||||||
todoStatusExpr: '',
|
todoStatusExpr: '',
|
||||||
todoDescriptionExpr: '',
|
todoDescriptionExpr: '',
|
||||||
|
|
@ -74,7 +74,7 @@ const initialValues: ListFormWizardDto = {
|
||||||
todoPriorityExpr: '',
|
todoPriorityExpr: '',
|
||||||
todoCompletedExpr: '',
|
todoCompletedExpr: '',
|
||||||
todoOrderExpr: '',
|
todoOrderExpr: '',
|
||||||
todoStatusOrder: 'Backlog, Ready to Start, In Progress, Code Review, Testing, Staging',
|
todoStatusOrder: 'Inbox, Today, This Week, This Month, Later, Done',
|
||||||
todoAllowDragging: true,
|
todoAllowDragging: true,
|
||||||
languageTextMenuEn: '',
|
languageTextMenuEn: '',
|
||||||
languageTextMenuTr: '',
|
languageTextMenuTr: '',
|
||||||
|
|
@ -86,7 +86,6 @@ const initialValues: ListFormWizardDto = {
|
||||||
languageTextMenuParentTr: '',
|
languageTextMenuParentTr: '',
|
||||||
permissionGroupName: '',
|
permissionGroupName: '',
|
||||||
menuParentCode: '',
|
menuParentCode: '',
|
||||||
menuParentShortName: '',
|
|
||||||
menuParentIcon: '',
|
menuParentIcon: '',
|
||||||
menuIcon: '',
|
menuIcon: '',
|
||||||
dataSourceCode: '',
|
dataSourceCode: '',
|
||||||
|
|
@ -147,26 +146,7 @@ const step2ValidationSchema = Yup.object().shape({
|
||||||
confirmDelete: Yup.boolean(),
|
confirmDelete: Yup.boolean(),
|
||||||
})
|
})
|
||||||
|
|
||||||
const todoValidationSchema = Yup.object().shape({
|
const listFormValidationSchema = step1ValidationSchema.concat(step2ValidationSchema)
|
||||||
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 ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -286,7 +266,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.fieldName)),
|
items: group.items.filter((item) => !isTenantColumn(item.dataField)),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const loadColumns = async (dsCode: string, schema: string, name: string) => {
|
const loadColumns = async (dsCode: string, schema: string, name: string) => {
|
||||||
|
|
@ -453,9 +433,7 @@ const Wizard = () => {
|
||||||
todoPriorityExpr: w.todoPriorityExpr ?? '',
|
todoPriorityExpr: w.todoPriorityExpr ?? '',
|
||||||
todoCompletedExpr: w.todoCompletedExpr ?? '',
|
todoCompletedExpr: w.todoCompletedExpr ?? '',
|
||||||
todoOrderExpr: w.todoOrderExpr ?? '',
|
todoOrderExpr: w.todoOrderExpr ?? '',
|
||||||
todoStatusOrder:
|
todoStatusOrder: w.todoStatusOrder ?? 'Inbox, Today, This Week, This Month, Later, Done',
|
||||||
w.todoStatusOrder ??
|
|
||||||
'Backlog, Ready to Start, In Progress, Code Review, Testing, Staging',
|
|
||||||
todoAllowDragging: w.todoAllowDragging ?? true,
|
todoAllowDragging: w.todoAllowDragging ?? true,
|
||||||
languageTextMenuEn: w.languageTextMenuEn ?? '',
|
languageTextMenuEn: w.languageTextMenuEn ?? '',
|
||||||
languageTextMenuTr: w.languageTextMenuTr ?? '',
|
languageTextMenuTr: w.languageTextMenuTr ?? '',
|
||||||
|
|
@ -467,7 +445,6 @@ 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 ?? '',
|
||||||
|
|
@ -520,19 +497,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: WizardGroupItem, ii: number) =>
|
(it: any, ii: number) =>
|
||||||
({
|
({
|
||||||
id: `${it.fieldName}_edit_${ii}_${Date.now()}`,
|
id: `${it.dataField}_edit_${ii}_${Date.now()}`,
|
||||||
fieldName: it.fieldName ?? '',
|
dataField: it.dataField ?? '',
|
||||||
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.fieldName,
|
turkishCaption: it.turkishCaption ?? it.dataField,
|
||||||
englishCaption: it.englishCaption ?? it.fieldName,
|
englishCaption: it.englishCaption ?? it.dataField,
|
||||||
captionName: it.captionName ?? `App.Listform.ListformField.${it.fieldName}`,
|
captionName: it.captionName ?? `App.Listform.ListformField.${it.dataField}`,
|
||||||
lookupDataSourceType:
|
lookupDataSourceType:
|
||||||
(it.lookupDataSourceType as UiLookupDataSourceTypeEnum) ??
|
(it.lookupDataSourceType as UiLookupDataSourceTypeEnum) ??
|
||||||
UiLookupDataSourceTypeEnum.StaticData,
|
UiLookupDataSourceTypeEnum.StaticData,
|
||||||
|
|
@ -545,7 +522,7 @@ 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.fieldName)))
|
const allFields = new Set(restoredGroups.flatMap((g) => g.items.map((i) => i.dataField)))
|
||||||
setSelectedColumns(allFields)
|
setSelectedColumns(allFields)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -661,16 +638,8 @@ 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 ?? '')
|
||||||
formikRef.current?.setFieldValue('languageTextMenuParentEn', selectedMenu?.menuTextEn ?? '')
|
if (!code) return
|
||||||
formikRef.current?.setFieldValue('languageTextMenuParentTr', selectedMenu?.menuTextTr ?? '')
|
applyPermissionGroupFromRoot(findRootCode(rawMenuItems, code))
|
||||||
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: {
|
||||||
|
|
@ -679,7 +648,6 @@ 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 ?? '')
|
||||||
|
|
@ -687,11 +655,6 @@ 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()
|
||||||
|
|
@ -763,10 +726,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.fieldName)
|
const col = selectCommandColumns.find((c) => c.columnName === item.dataField)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fieldName: item.fieldName,
|
dataField: item.dataField,
|
||||||
editorType: item.editorType,
|
editorType: item.editorType,
|
||||||
editorOptions: item.editorOptions ?? '',
|
editorOptions: item.editorOptions ?? '',
|
||||||
editorScript: item.editorScript ?? '',
|
editorScript: item.editorScript ?? '',
|
||||||
|
|
@ -873,7 +836,6 @@ 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}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ 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
|
||||||
|
|
@ -42,7 +41,6 @@ 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,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
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,
|
||||||
|
|
@ -29,17 +28,14 @@ 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
|
||||||
fieldName: string
|
dataField: string
|
||||||
editorType: string
|
editorType: string
|
||||||
editorOptions: string
|
editorOptions: string
|
||||||
editorScript: string
|
editorScript: string
|
||||||
|
|
@ -113,7 +109,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()}`,
|
||||||
fieldName: colName,
|
dataField: colName,
|
||||||
editorType: inferEditorType(sqlType),
|
editorType: inferEditorType(sqlType),
|
||||||
editorOptions: '',
|
editorOptions: '',
|
||||||
editorScript: '',
|
editorScript: '',
|
||||||
|
|
@ -173,7 +169,6 @@ 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
|
||||||
|
|
@ -195,7 +190,6 @@ function SortableItem({
|
||||||
groupColCount,
|
groupColCount,
|
||||||
dbObjects,
|
dbObjects,
|
||||||
dsCode,
|
dsCode,
|
||||||
editorScriptFields,
|
|
||||||
onTurkishCaptionChange,
|
onTurkishCaptionChange,
|
||||||
onEnglishCaptionChange,
|
onEnglishCaptionChange,
|
||||||
onEditorTypeChange,
|
onEditorTypeChange,
|
||||||
|
|
@ -213,8 +207,6 @@ 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>(
|
||||||
|
|
@ -256,7 +248,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.fieldName}
|
{item.dataField}
|
||||||
</span>
|
</span>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
@ -572,23 +564,12 @@ 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 */}
|
||||||
|
|
@ -596,41 +577,14 @@ 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">
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
|
|
@ -685,7 +639,6 @@ 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
|
||||||
|
|
@ -700,7 +653,6 @@ function GroupCard({
|
||||||
hasAvailable,
|
hasAvailable,
|
||||||
dbObjects,
|
dbObjects,
|
||||||
dsCode,
|
dsCode,
|
||||||
editorScriptFields,
|
|
||||||
onCaptionChange,
|
onCaptionChange,
|
||||||
onColCountChange,
|
onColCountChange,
|
||||||
onItemChange,
|
onItemChange,
|
||||||
|
|
@ -807,7 +759,6 @@ 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 })}
|
||||||
|
|
@ -858,7 +809,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.fieldName)),
|
items: g.items.filter((i) => selectedColumns.has(i.dataField)),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// 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
|
||||||
|
|
@ -884,14 +835,8 @@ 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.fieldName)))
|
const placedColumns = new Set(groups.flatMap((g) => g.items.map((i) => i.dataField)))
|
||||||
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)
|
||||||
|
|
@ -933,7 +878,7 @@ const WizardStep3 = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
const addAllToGroup = (groupId: string) => {
|
const addAllToGroup = (groupId: string) => {
|
||||||
const placed = new Set(groups.flatMap((g) => g.items.map((i) => i.fieldName)))
|
const placed = new Set(groups.flatMap((g) => g.items.map((i) => i.dataField)))
|
||||||
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(
|
||||||
|
|
@ -1073,7 +1018,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.fieldName}
|
{item.dataField}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs text-gray-500">{item.editorType}</span>
|
<span className="text-xs text-gray-500">{item.editorType}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1142,7 +1087,6 @@ 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,8 +37,6 @@ 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,
|
||||||
|
|
@ -69,9 +67,6 @@ 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])
|
||||||
|
|
@ -96,10 +91,6 @@ 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>) => {
|
||||||
|
|
@ -259,26 +250,6 @@ 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">
|
||||||
|
|
@ -309,51 +280,33 @@ function WizardStep6({
|
||||||
'approvalDescriptionFieldName',
|
'approvalDescriptionFieldName',
|
||||||
'::ListForms.ListFormEdit.Workflow.ApprovalDescriptionFieldName',
|
'::ListForms.ListFormEdit.Workflow.ApprovalDescriptionFieldName',
|
||||||
],
|
],
|
||||||
].map(([name, label]) => {
|
].map(([name, label]) => (
|
||||||
const requiredForCriteria =
|
<FormItem key={name} label={translate(label)}>
|
||||||
criteria.length > 0 &&
|
<Field name={name}>
|
||||||
(name === 'approvalUserFieldName' || name === 'approvalStatusFieldName')
|
{({ field, form }: FieldProps) => (
|
||||||
const error = workflowErrors[name as RequiredWorkflowField]
|
<Select
|
||||||
|
field={field}
|
||||||
return (
|
form={form}
|
||||||
<FormItem
|
isClearable
|
||||||
key={name}
|
options={columnOptions}
|
||||||
errorMessage={error}
|
value={columnOptions.find(
|
||||||
invalid={Boolean(error)}
|
(option) => option.value === (values as any)[name],
|
||||||
label={`${translate(label)}${requiredForCriteria ? ' *' : ''}`}
|
)}
|
||||||
>
|
onChange={(option: any) => {
|
||||||
<Field name={name}>
|
form.setFieldValue(field.name, option?.value ?? '')
|
||||||
{({ field, form }: FieldProps) => (
|
onWorkflowChange({
|
||||||
<Select
|
...values,
|
||||||
field={field}
|
[field.name]: option?.value ?? '',
|
||||||
form={form}
|
criteria,
|
||||||
isClearable
|
})
|
||||||
options={columnOptions}
|
}}
|
||||||
value={columnOptions.find(
|
/>
|
||||||
(option) => option.value === (values as any)[name],
|
)}
|
||||||
)}
|
</Field>
|
||||||
onChange={(option: any) => {
|
</FormItem>
|
||||||
form.setFieldValue(field.name, option?.value ?? '')
|
))}
|
||||||
setWorkflowErrors((current) => ({
|
|
||||||
...current,
|
|
||||||
[field.name]: undefined,
|
|
||||||
}))
|
|
||||||
onWorkflowChange({
|
|
||||||
...values,
|
|
||||||
[field.name]: option?.value ?? '',
|
|
||||||
criteria,
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Field>
|
|
||||||
</FormItem>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
<FormItem
|
<FormItem
|
||||||
label={translate(
|
label={translate('::ListForms.ListFormEdit.Workflow.ApprovalIsFilterUserName')}
|
||||||
'::ListForms.ListFormEdit.Workflow.ApprovalIsFilterUserName',
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<Field name="approvalIsFilterUserName">
|
<Field name="approvalIsFilterUserName">
|
||||||
{({ field, form }: FieldProps<boolean>) => (
|
{({ field, form }: FieldProps<boolean>) => (
|
||||||
|
|
@ -449,7 +402,7 @@ function WizardStep6({
|
||||||
variant="solid"
|
variant="solid"
|
||||||
type="button"
|
type="button"
|
||||||
icon={<FaArrowRight />}
|
icon={<FaArrowRight />}
|
||||||
onClick={continueToTodo}
|
onClick={onNext}
|
||||||
>
|
>
|
||||||
{translate('::Next') || 'Next'}
|
{translate('::Next') || 'Next'}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import type { DatabaseColumnDto } from '@/proxy/sql-query-manager/models'
|
||||||
import type { SelectBoxOption } from '@/types/shared'
|
import type { SelectBoxOption } from '@/types/shared'
|
||||||
import { Field, type FieldProps, useFormikContext } from 'formik'
|
import { Field, type FieldProps, useFormikContext } from 'formik'
|
||||||
import { useMemo, useState } from 'react'
|
import { useMemo, useState } from 'react'
|
||||||
import { FaArrowLeft, FaArrowRight } from 'react-icons/fa'
|
import { FaArrowLeft, FaArrowRight, FaColumns } from 'react-icons/fa'
|
||||||
|
|
||||||
interface WizardStep7Props {
|
interface WizardStep7Props {
|
||||||
selectedColumns: Set<string>
|
selectedColumns: Set<string>
|
||||||
|
|
@ -25,41 +25,18 @@ const mappings: Array<{
|
||||||
| 'todoPriorityExpr'
|
| 'todoPriorityExpr'
|
||||||
| 'todoCompletedExpr'
|
| 'todoCompletedExpr'
|
||||||
| 'todoOrderExpr'
|
| 'todoOrderExpr'
|
||||||
translationKey: string
|
label: string
|
||||||
required?: boolean
|
required?: boolean
|
||||||
}> = [
|
}> = [
|
||||||
{
|
{ name: 'todoTitleExpr', label: 'Başlık alanı', required: true },
|
||||||
name: 'todoTitleExpr',
|
{ name: 'todoStatusExpr', label: 'Kanban / durum alanı', required: true },
|
||||||
translationKey: '::ListForms.ListFormFieldEdit.TodoTitleExpr',
|
{ name: 'todoDescriptionExpr', label: 'Açıklama alanı' },
|
||||||
required: true,
|
{ name: 'todoDueDateExpr', label: 'Termin tarihi alanı' },
|
||||||
},
|
{ name: 'todoTagExpr', label: 'Etiket alanı' },
|
||||||
{
|
{ name: 'todoAssigneeExpr', label: 'Atanan kişi alanı' },
|
||||||
name: 'todoStatusExpr',
|
{ name: 'todoPriorityExpr', label: 'Öncelik alanı' },
|
||||||
translationKey: '::ListForms.ListFormFieldEdit.TodoStatusExpr',
|
{ name: 'todoCompletedExpr', label: 'Tamamlandı alanı' },
|
||||||
required: true,
|
{ name: 'todoOrderExpr', label: 'Kart sıra alanı' },
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'todoDescriptionExpr',
|
|
||||||
translationKey: '::ListForms.ListFormFieldEdit.TodoDescriptionExpr',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'todoDueDateExpr',
|
|
||||||
translationKey: '::ListForms.ListFormFieldEdit.TodoDueDateExpr',
|
|
||||||
},
|
|
||||||
{ name: 'todoTagExpr', translationKey: '::ListForms.ListFormFieldEdit.TodoTagExpr' },
|
|
||||||
{
|
|
||||||
name: 'todoAssigneeExpr',
|
|
||||||
translationKey: '::ListForms.ListFormFieldEdit.TodoAssigneeExpr',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'todoPriorityExpr',
|
|
||||||
translationKey: '::ListForms.ListFormFieldEdit.TodoPriorityExpr',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'todoCompletedExpr',
|
|
||||||
translationKey: '::ListForms.ListFormFieldEdit.TodoCompletedExpr',
|
|
||||||
},
|
|
||||||
{ name: 'todoOrderExpr', translationKey: '::ListForms.ListFormFieldEdit.TodoOrderExpr' },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const WizardStep7 = ({
|
const WizardStep7 = ({
|
||||||
|
|
@ -69,8 +46,7 @@ const WizardStep7 = ({
|
||||||
onBack,
|
onBack,
|
||||||
onNext,
|
onNext,
|
||||||
}: WizardStep7Props) => {
|
}: WizardStep7Props) => {
|
||||||
const { errors, touched, values, setFieldTouched, setFieldValue, validateForm } =
|
const { values, setFieldValue } = useFormikContext<ListFormWizardDto>()
|
||||||
useFormikContext<ListFormWizardDto>()
|
|
||||||
const [validationError, setValidationError] = useState('')
|
const [validationError, setValidationError] = useState('')
|
||||||
const fieldOptions = useMemo<SelectBoxOption[]>(
|
const fieldOptions = useMemo<SelectBoxOption[]>(
|
||||||
() =>
|
() =>
|
||||||
|
|
@ -80,15 +56,9 @@ const WizardStep7 = ({
|
||||||
[selectCommandColumns, selectedColumns],
|
[selectCommandColumns, selectedColumns],
|
||||||
)
|
)
|
||||||
|
|
||||||
const continueToDeploy = async () => {
|
const continueToDeploy = () => {
|
||||||
await Promise.all([
|
if (values.todo && (!values.todoTitleExpr || !values.todoStatusExpr)) {
|
||||||
setFieldTouched('todoTitleExpr', true, false),
|
setValidationError('Başlık alanı ve Kanban / durum alanı zorunludur.')
|
||||||
setFieldTouched('todoStatusExpr', true, false),
|
|
||||||
])
|
|
||||||
const validationErrors = await validateForm()
|
|
||||||
|
|
||||||
if (validationErrors.todoTitleExpr || validationErrors.todoStatusExpr) {
|
|
||||||
setValidationError(translate('::ListForms.ListFormFieldEdit.TodoRequiredFields'))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setValidationError('')
|
setValidationError('')
|
||||||
|
|
@ -97,63 +67,75 @@ const WizardStep7 = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="pb-20">
|
<div className="pb-20">
|
||||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3">
|
<div className="mb-5 rounded-xl border border-indigo-200 bg-indigo-50/60 p-4 dark:border-indigo-900 dark:bg-indigo-950/20">
|
||||||
{mappings.map((mapping) => {
|
<div className="flex items-center gap-2 font-semibold text-indigo-700 dark:text-indigo-300">
|
||||||
const isRequired = Boolean(mapping.required && values.todo)
|
<FaColumns /> Todo / Kanban ayrıntıları
|
||||||
|
</div>
|
||||||
|
<p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
|
Liste alanlarını Todo kartının başlık, durum ve diğer özellikleriyle eşleştirin.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
return (
|
{!values.todo ? (
|
||||||
<FormItem
|
<div className="rounded-xl border border-amber-200 bg-amber-50 p-4 text-sm text-amber-700 dark:border-amber-900 dark:bg-amber-950/30 dark:text-amber-200">
|
||||||
key={mapping.name}
|
Todo görünümü liste ayarlarında kapalı. Bu adımı atlayabilir veya önceki adımlardan Todo
|
||||||
label={`${translate(mapping.translationKey)}${isRequired ? ' *' : ''}`}
|
görünümünü etkinleştirebilirsiniz.
|
||||||
invalid={Boolean(touched[mapping.name] && errors[mapping.name])}
|
</div>
|
||||||
errorMessage={touched[mapping.name] ? errors[mapping.name] : undefined}
|
) : (
|
||||||
>
|
<>
|
||||||
<Field name={mapping.name}>
|
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3">
|
||||||
{({ field, form }: FieldProps) => (
|
{mappings.map((mapping) => (
|
||||||
<Select
|
<FormItem
|
||||||
field={field}
|
key={mapping.name}
|
||||||
form={form}
|
label={`${mapping.label}${mapping.required ? ' *' : ''}`}
|
||||||
isClearable={!isRequired}
|
>
|
||||||
options={fieldOptions}
|
<Field name={mapping.name}>
|
||||||
value={fieldOptions.find((option) => option.value === values[mapping.name])}
|
{({ field, form }: FieldProps) => (
|
||||||
onChange={(option) => {
|
<Select
|
||||||
form.setFieldValue(field.name, option?.value ?? '')
|
field={field}
|
||||||
setValidationError('')
|
form={form}
|
||||||
}}
|
isClearable={!mapping.required}
|
||||||
|
options={fieldOptions}
|
||||||
|
value={fieldOptions.find((option) => option.value === values[mapping.name])}
|
||||||
|
onChange={(option) => {
|
||||||
|
form.setFieldValue(field.name, option?.value ?? '')
|
||||||
|
setValidationError('')
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</FormItem>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-5 grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
|
<FormItem label="Durum sırası (virgülle ayırın)">
|
||||||
|
<Field
|
||||||
|
name="todoStatusOrder"
|
||||||
|
component={Input}
|
||||||
|
placeholder="Inbox, Today, This Week, This Month, Later, Done"
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Kartları kolonlar arasında sürüklemeye izin ver">
|
||||||
|
<Field name="todoAllowDragging">
|
||||||
|
{({ field }: FieldProps<boolean>) => (
|
||||||
|
<Checkbox
|
||||||
|
checked={Boolean(field.value)}
|
||||||
|
onChange={(checked) => setFieldValue(field.name, checked)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)
|
</div>
|
||||||
})}
|
</>
|
||||||
</div>
|
)}
|
||||||
|
|
||||||
<div className="mt-5 grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
||||||
<FormItem label={translate('::ListForms.ListFormFieldEdit.TodoStatusOrder')}>
|
|
||||||
<Field
|
|
||||||
name="todoStatusOrder"
|
|
||||||
component={Input}
|
|
||||||
placeholder={translate('::ListForms.ListFormFieldEdit.TodoStatusOrderPlaceholder')}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
<FormItem label={translate('::ListForms.ListFormFieldEdit.TodoAllowDragging')}>
|
|
||||||
<Field name="todoAllowDragging">
|
|
||||||
{({ field }: FieldProps<boolean>) => (
|
|
||||||
<Checkbox
|
|
||||||
checked={Boolean(field.value)}
|
|
||||||
onChange={(checked) => setFieldValue(field.name, checked)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Field>
|
|
||||||
</FormItem>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{validationError && <p className="mt-4 text-sm text-red-500">{validationError}</p>}
|
{validationError && <p className="mt-4 text-sm text-red-500">{validationError}</p>}
|
||||||
|
|
||||||
<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="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="flex w-full items-center justify-between gap-3">
|
<div className="flex w-full items-center justify-between gap-3">
|
||||||
<Button size="sm" variant="default" type="button" icon={<FaArrowLeft />} onClick={onBack}>
|
<Button size="sm" variant="default" type="button" icon={<FaArrowLeft />} onClick={onBack}>
|
||||||
{translate('::Back')}
|
{translate('::Back') || 'Geri'}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|
@ -162,7 +144,7 @@ const WizardStep7 = ({
|
||||||
icon={<FaArrowRight />}
|
icon={<FaArrowRight />}
|
||||||
onClick={continueToDeploy}
|
onClick={continueToDeploy}
|
||||||
>
|
>
|
||||||
{translate('::Next')}
|
{translate('::Next') || 'Deploy adımına geç'}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -218,9 +218,7 @@ const WizardStep8 = ({
|
||||||
...prev,
|
...prev,
|
||||||
{
|
{
|
||||||
id: 999,
|
id: 999,
|
||||||
label: `${translate('::ListForms.Wizard.Step4.Error')}: ${
|
label: `Hata: ${err?.message ?? 'Bilinmeyen hata'}`,
|
||||||
err?.message ?? translate('::App.Platform.Unknown')
|
|
||||||
}`,
|
|
||||||
status: 'error',
|
status: 'error',
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
@ -233,10 +231,10 @@ const WizardStep8 = ({
|
||||||
const totalFields = groups.reduce((acc, g) => acc + g.items.length, 0)
|
const totalFields = groups.reduce((acc, g) => acc + g.items.length, 0)
|
||||||
const editingFormFields = groups.flatMap((g) =>
|
const editingFormFields = groups.flatMap((g) =>
|
||||||
g.items
|
g.items
|
||||||
.filter((item) => item.includeInEditingForm && item.fieldName !== values.keyFieldName)
|
.filter((item) => item.includeInEditingForm && item.dataField !== values.keyFieldName)
|
||||||
.map((item) => ({ ...item, groupCaption: g.caption })),
|
.map((item) => ({ ...item, groupCaption: g.caption })),
|
||||||
)
|
)
|
||||||
const groupedFieldNames = new Set(groups.flatMap((g) => g.items.map((item) => item.fieldName)))
|
const groupedFieldNames = new Set(groups.flatMap((g) => g.items.map((item) => item.dataField)))
|
||||||
const ungroupedSelectedColumns = [...selectedColumns].filter((col) => !groupedFieldNames.has(col))
|
const ungroupedSelectedColumns = [...selectedColumns].filter((col) => !groupedFieldNames.has(col))
|
||||||
const hasWorkflowFields = Boolean(
|
const hasWorkflowFields = Boolean(
|
||||||
workflow.approvalUserFieldName ||
|
workflow.approvalUserFieldName ||
|
||||||
|
|
@ -389,8 +387,8 @@ const WizardStep8 = ({
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
g.items.map((item) => {
|
g.items.map((item) => {
|
||||||
const meta = selectCommandColumns.find((c) => c.columnName === item.fieldName)
|
const meta = selectCommandColumns.find((c) => c.columnName === item.dataField)
|
||||||
const isKeyField = item.fieldName === values.keyFieldName
|
const isKeyField = item.dataField === values.keyFieldName
|
||||||
const isPopupField = item.includeInEditingForm && !isKeyField
|
const isPopupField = item.includeInEditingForm && !isKeyField
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
@ -399,7 +397,7 @@ const WizardStep8 = ({
|
||||||
>
|
>
|
||||||
<div className="flex min-w-0 items-center gap-2">
|
<div className="flex min-w-0 items-center gap-2">
|
||||||
<span className="text-xs font-medium text-indigo-600 dark:text-indigo-400 truncate">
|
<span className="text-xs font-medium text-indigo-600 dark:text-indigo-400 truncate">
|
||||||
{item.fieldName}
|
{item.dataField}
|
||||||
</span>
|
</span>
|
||||||
{meta?.dataType && (
|
{meta?.dataType && (
|
||||||
<span className="text-[10px] text-gray-400 truncate">
|
<span className="text-[10px] text-gray-400 truncate">
|
||||||
|
|
@ -576,52 +574,17 @@ const WizardStep8 = ({
|
||||||
{values.todo && (
|
{values.todo && (
|
||||||
<Section title={translate('::ListForms.ListFormEdit.TabTodo') || 'Todo / Kanban'}>
|
<Section title={translate('::ListForms.ListFormEdit.TabTodo') || 'Todo / Kanban'}>
|
||||||
<div className="grid grid-cols-2 gap-x-4">
|
<div className="grid grid-cols-2 gap-x-4">
|
||||||
<Row
|
<Row label="Başlık alanı" value={values.todoTitleExpr} />
|
||||||
label={translate('::ListForms.ListFormFieldEdit.TodoTitleExpr')}
|
<Row label="Kanban / durum alanı" value={values.todoStatusExpr} />
|
||||||
value={values.todoTitleExpr}
|
<Row label="Açıklama alanı" value={values.todoDescriptionExpr} />
|
||||||
/>
|
<Row label="Termin tarihi alanı" value={values.todoDueDateExpr} />
|
||||||
<Row
|
<Row label="Etiket alanı" value={values.todoTagExpr} />
|
||||||
label={translate('::ListForms.ListFormFieldEdit.TodoStatusExpr')}
|
<Row label="Atanan kişi alanı" value={values.todoAssigneeExpr} />
|
||||||
value={values.todoStatusExpr}
|
<Row label="Öncelik alanı" value={values.todoPriorityExpr} />
|
||||||
/>
|
<Row label="Tamamlandı alanı" value={values.todoCompletedExpr} />
|
||||||
<Row
|
<Row label="Kart sıra alanı" value={values.todoOrderExpr} />
|
||||||
label={translate('::ListForms.ListFormFieldEdit.TodoDescriptionExpr')}
|
<Row label="Durum sırası" value={values.todoStatusOrder} />
|
||||||
value={values.todoDescriptionExpr}
|
<Row label="Sürükle-bırak" value={values.todoAllowDragging ? 'Aktif' : 'Pasif'} />
|
||||||
/>
|
|
||||||
<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>
|
</div>
|
||||||
</Section>
|
</Section>
|
||||||
)}
|
)}
|
||||||
|
|
@ -680,12 +643,12 @@ const WizardStep8 = ({
|
||||||
</span>
|
</span>
|
||||||
{isDone && (
|
{isDone && (
|
||||||
<span className="text-xs text-emerald-500 font-semibold flex items-center gap-1">
|
<span className="text-xs text-emerald-500 font-semibold flex items-center gap-1">
|
||||||
<FaCheckCircle /> {translate('::ListForms.Wizard.Step4.Success')}
|
<FaCheckCircle /> {translate('::ListForms.Wizard.Step4.Success') || 'Başarılı'}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{hasError && (
|
{hasError && (
|
||||||
<span className="text-xs text-red-500 font-semibold flex items-center gap-1">
|
<span className="text-xs text-red-500 font-semibold flex items-center gap-1">
|
||||||
<FaExclamationCircle /> {translate('::ListForms.Wizard.Step4.Error')}
|
<FaExclamationCircle /> {translate('::ListForms.Wizard.Step4.Error') || 'Hata'}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -695,7 +658,7 @@ const WizardStep8 = ({
|
||||||
<div className="flex flex-col items-center justify-center h-full gap-3 py-10 select-none">
|
<div className="flex flex-col items-center justify-center h-full gap-3 py-10 select-none">
|
||||||
<FaRocket className="text-gray-700 text-3xl" />
|
<FaRocket className="text-gray-700 text-3xl" />
|
||||||
<span className="text-xs text-gray-600 italic text-center">
|
<span className="text-xs text-gray-600 italic text-center">
|
||||||
{translate('::ListForms.Wizard.Step4.AllInfoReady')}
|
{translate('::ListForms.Wizard.Step4.AllInfoReady') || 'Tüm bilgiler hazır.'}
|
||||||
<br />
|
<br />
|
||||||
{translate('::ListForms.Wizard.Step4.DeployStartHint')}
|
{translate('::ListForms.Wizard.Step4.DeployStartHint')}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
|
|
@ -383,7 +383,7 @@ const OrganizationUnits = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Node = memo(function Node({ node, style, dragHandle }: NodeRendererProps<any>) {
|
const Node = memo(({ node, style, dragHandle }: NodeRendererProps<any>) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
|
|
|
||||||
|
|
@ -90,47 +90,6 @@ interface TableIndex {
|
||||||
|
|
||||||
// ─── Constants ────────────────────────────────────────────────────────────────
|
// ─── Constants ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
const REL_TYPES: { value: RelationshipType; label: string; desc: string }[] = [
|
|
||||||
{ value: 'OneToMany', label: '1 → N', desc: 'Bire-çok' },
|
|
||||||
{ value: 'OneToOne', label: '1 → 1', desc: 'Bire-bir' },
|
|
||||||
]
|
|
||||||
|
|
||||||
const CASCADE_OPTIONS: { value: CascadeBehavior; label: string }[] = [
|
|
||||||
{ value: 'NoAction', label: 'No Action' },
|
|
||||||
{ value: 'Cascade', label: 'Cascade' },
|
|
||||||
{ value: 'SetNull', label: 'Set Null' },
|
|
||||||
{ value: 'Restrict', label: 'Restrict' },
|
|
||||||
]
|
|
||||||
|
|
||||||
const EMPTY_FK: Omit<SqlTableRelation, 'id'> = {
|
|
||||||
relationshipType: 'OneToMany',
|
|
||||||
fkColumnName: '',
|
|
||||||
referencedTable: '',
|
|
||||||
referencedColumn: 'Id',
|
|
||||||
cascadeDelete: 'NoAction',
|
|
||||||
cascadeUpdate: 'Cascade',
|
|
||||||
isRequired: false,
|
|
||||||
description: '',
|
|
||||||
}
|
|
||||||
|
|
||||||
const EMPTY_INDEX: Omit<TableIndex, 'id'> = {
|
|
||||||
indexName: '',
|
|
||||||
indexType: 'Index',
|
|
||||||
isClustered: false,
|
|
||||||
columns: [],
|
|
||||||
description: '',
|
|
||||||
}
|
|
||||||
|
|
||||||
const INDEX_TYPES: { value: IndexType; label: string; desc: string }[] = [
|
|
||||||
{
|
|
||||||
value: 'PrimaryKey',
|
|
||||||
label: 'Primary Key',
|
|
||||||
desc: 'App.SqlQueryManager.IndexType_PrimaryKey_Desc',
|
|
||||||
},
|
|
||||||
{ value: 'UniqueKey', label: 'Unique Key', desc: 'App.SqlQueryManager.IndexType_UniqueKey_Desc' },
|
|
||||||
{ value: 'Index', label: 'Index', desc: 'App.SqlQueryManager.IndexType_Index_Desc' },
|
|
||||||
]
|
|
||||||
|
|
||||||
const DATA_TYPES: { value: SqlDataType; label: string }[] = [
|
const DATA_TYPES: { value: SqlDataType; label: string }[] = [
|
||||||
{ value: 'nvarchar', label: 'String (nvarchar)' },
|
{ value: 'nvarchar', label: 'String (nvarchar)' },
|
||||||
{ value: 'nvarchar(MAX)', label: 'Text (nvarchar MAX)' },
|
{ value: 'nvarchar(MAX)', label: 'Text (nvarchar MAX)' },
|
||||||
|
|
@ -221,6 +180,47 @@ const FULL_AUDIT_COLUMNS: ColumnDefinition[] = [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const REL_TYPES: { value: RelationshipType; label: string; desc: string }[] = [
|
||||||
|
{ value: 'OneToMany', label: '1 → N', desc: 'Bire-çok' },
|
||||||
|
{ value: 'OneToOne', label: '1 → 1', desc: 'Bire-bir' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const CASCADE_OPTIONS: { value: CascadeBehavior; label: string }[] = [
|
||||||
|
{ value: 'NoAction', label: 'No Action' },
|
||||||
|
{ value: 'Cascade', label: 'Cascade' },
|
||||||
|
{ value: 'SetNull', label: 'Set Null' },
|
||||||
|
{ value: 'Restrict', label: 'Restrict' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const EMPTY_FK: Omit<SqlTableRelation, 'id'> = {
|
||||||
|
relationshipType: 'OneToMany',
|
||||||
|
fkColumnName: '',
|
||||||
|
referencedTable: '',
|
||||||
|
referencedColumn: 'Id',
|
||||||
|
cascadeDelete: 'NoAction',
|
||||||
|
cascadeUpdate: 'Cascade',
|
||||||
|
isRequired: false,
|
||||||
|
description: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
const EMPTY_INDEX: Omit<TableIndex, 'id'> = {
|
||||||
|
indexName: '',
|
||||||
|
indexType: 'Index',
|
||||||
|
isClustered: false,
|
||||||
|
columns: [],
|
||||||
|
description: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
const INDEX_TYPES: { value: IndexType; label: string; desc: string }[] = [
|
||||||
|
{
|
||||||
|
value: 'PrimaryKey',
|
||||||
|
label: 'Primary Key',
|
||||||
|
desc: 'App.SqlQueryManager.IndexType_PrimaryKey_Desc',
|
||||||
|
},
|
||||||
|
{ value: 'UniqueKey', label: 'Unique Key', desc: 'App.SqlQueryManager.IndexType_UniqueKey_Desc' },
|
||||||
|
{ value: 'Index', label: 'Index', desc: 'App.SqlQueryManager.IndexType_Index_Desc' },
|
||||||
|
]
|
||||||
|
|
||||||
const TENANT_COLUMN: ColumnDefinition = {
|
const TENANT_COLUMN: ColumnDefinition = {
|
||||||
id: '__TenantId',
|
id: '__TenantId',
|
||||||
columnName: 'TenantId',
|
columnName: 'TenantId',
|
||||||
|
|
@ -232,15 +232,6 @@ const TENANT_COLUMN: ColumnDefinition = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const WORKFLOW_COLUMNS: ColumnDefinition[] = [
|
const WORKFLOW_COLUMNS: ColumnDefinition[] = [
|
||||||
{
|
|
||||||
id: '__WorkflowId',
|
|
||||||
columnName: 'Id',
|
|
||||||
dataType: 'uniqueidentifier',
|
|
||||||
maxLength: '',
|
|
||||||
isNullable: false,
|
|
||||||
defaultValue: 'NEWID()',
|
|
||||||
description: 'Workflow primary key',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: '__ApprovalUserId',
|
id: '__ApprovalUserId',
|
||||||
columnName: 'ApprovalUserName',
|
columnName: 'ApprovalUserName',
|
||||||
|
|
@ -1333,26 +1324,6 @@ const SqlTableDesignerDialog = ({
|
||||||
|
|
||||||
const clearAllColumns = () => setColumns([createEmptyColumn()])
|
const clearAllColumns = () => setColumns([createEmptyColumn()])
|
||||||
|
|
||||||
const addAutomaticPrimaryKey = (preset: string, description: string) => {
|
|
||||||
const tableName = settings.tableName || initialTableData?.tableName || 'Table'
|
|
||||||
|
|
||||||
setIndexes((prev) => {
|
|
||||||
if (prev.some((index) => index.indexType === 'PrimaryKey')) return prev
|
|
||||||
|
|
||||||
return [
|
|
||||||
...prev,
|
|
||||||
{
|
|
||||||
id: `auto-${preset}-${crypto.randomUUID()}`,
|
|
||||||
indexName: `PK_${tableName}`,
|
|
||||||
indexType: 'PrimaryKey',
|
|
||||||
isClustered: false,
|
|
||||||
columns: [{ columnName: 'Id', order: 'ASC' }],
|
|
||||||
description,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const addFullAuditedColumns = () => {
|
const addFullAuditedColumns = () => {
|
||||||
const existingNames = new Set(columns.map((c) => c.columnName.trim().toLowerCase()))
|
const existingNames = new Set(columns.map((c) => c.columnName.trim().toLowerCase()))
|
||||||
const toAdd = FULL_AUDIT_COLUMNS.filter((c) => !existingNames.has(c.columnName.toLowerCase()))
|
const toAdd = FULL_AUDIT_COLUMNS.filter((c) => !existingNames.has(c.columnName.toLowerCase()))
|
||||||
|
|
@ -1361,7 +1332,24 @@ const SqlTableDesignerDialog = ({
|
||||||
return [...nonEmpty, ...toAdd.map((c) => ({ ...c })), createEmptyColumn()]
|
return [...nonEmpty, ...toAdd.map((c) => ({ ...c })), createEmptyColumn()]
|
||||||
})
|
})
|
||||||
|
|
||||||
addAutomaticPrimaryKey('full-audit', 'Full audited primary key (auto)')
|
// FullAudited ile Id eklendiğinde PK tanımı Index/Key listesine otomatik düşsün.
|
||||||
|
setIndexes((prev) => {
|
||||||
|
const hasPk = prev.some((ix) => ix.indexType === 'PrimaryKey')
|
||||||
|
if (hasPk) return prev
|
||||||
|
|
||||||
|
const tableName = settings.tableName || initialTableData?.tableName || 'Table'
|
||||||
|
return [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
id: `auto-pk-${crypto.randomUUID()}`,
|
||||||
|
indexName: `PK_${tableName}`,
|
||||||
|
indexType: 'PrimaryKey',
|
||||||
|
isClustered: false,
|
||||||
|
columns: [{ columnName: 'Id', order: 'ASC' }],
|
||||||
|
description: 'Primary key (auto)',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const addMultiTenantColumns = () => {
|
const addMultiTenantColumns = () => {
|
||||||
|
|
@ -1384,8 +1372,6 @@ const SqlTableDesignerDialog = ({
|
||||||
return [...nonEmpty, ...toAdd.map((c) => ({ ...c })), createEmptyColumn()]
|
return [...nonEmpty, ...toAdd.map((c) => ({ ...c })), createEmptyColumn()]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
addAutomaticPrimaryKey('workflow', 'Workflow primary key (auto)')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const addTodoColumns = () => {
|
const addTodoColumns = () => {
|
||||||
|
|
@ -1399,7 +1385,22 @@ const SqlTableDesignerDialog = ({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
addAutomaticPrimaryKey('todo', 'Todo primary key (auto)')
|
setIndexes((prev) => {
|
||||||
|
if (prev.some((index) => index.indexType === 'PrimaryKey')) return prev
|
||||||
|
|
||||||
|
const tableName = settings.tableName || initialTableData?.tableName || 'Table'
|
||||||
|
return [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
id: `auto-todo-pk-${crypto.randomUUID()}`,
|
||||||
|
indexName: `PK_${tableName}`,
|
||||||
|
indexType: 'PrimaryKey',
|
||||||
|
isClustered: false,
|
||||||
|
columns: [{ columnName: 'Id', order: 'ASC' }],
|
||||||
|
description: 'Todo primary key (auto)',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const importColumnsFromRememberedCreateTable = async () => {
|
const importColumnsFromRememberedCreateTable = async () => {
|
||||||
|
|
@ -1510,10 +1511,11 @@ const SqlTableDesignerDialog = ({
|
||||||
const syncAutoPkName = (newTableName: string) => {
|
const syncAutoPkName = (newTableName: string) => {
|
||||||
if (!newTableName) return
|
if (!newTableName) return
|
||||||
setIndexes((prev) =>
|
setIndexes((prev) =>
|
||||||
prev.map((ix) => {
|
prev.map((ix) =>
|
||||||
if (!ix.id.startsWith('auto-') || ix.indexType !== 'PrimaryKey') return ix
|
ix.indexType === 'PrimaryKey' && ix.id.startsWith('auto-pk')
|
||||||
return { ...ix, indexName: `PK_${newTableName}` }
|
? { ...ix, indexName: `PK_${newTableName}` }
|
||||||
}),
|
: ix,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1860,12 +1862,12 @@ const SqlTableDesignerDialog = ({
|
||||||
<>
|
<>
|
||||||
<div className="flex items-center justify-between py-2">
|
<div className="flex items-center justify-between py-2">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button size="xs" variant="solid" color="green-600" onClick={addMultiTenantColumns}>
|
|
||||||
{translate('::App.SqlQueryManager.AddMultiTenantColumns')}
|
|
||||||
</Button>
|
|
||||||
<Button size="xs" variant="solid" color="blue-600" onClick={addFullAuditedColumns}>
|
<Button size="xs" variant="solid" color="blue-600" onClick={addFullAuditedColumns}>
|
||||||
{translate('::App.SqlQueryManager.AddFullAuditedColumns')}
|
{translate('::App.SqlQueryManager.AddFullAuditedColumns')}
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button size="xs" variant="solid" color="green-600" onClick={addMultiTenantColumns}>
|
||||||
|
{translate('::App.SqlQueryManager.AddMultiTenantColumns')}
|
||||||
|
</Button>
|
||||||
<Button size="xs" variant="solid" color="indigo-600" onClick={addWorkflowColumns}>
|
<Button size="xs" variant="solid" color="indigo-600" onClick={addWorkflowColumns}>
|
||||||
{translate('::App.SqlQueryManager.AddWorkflowColumns')}
|
{translate('::App.SqlQueryManager.AddWorkflowColumns')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,9 @@ import type { GroupItem } from 'devextreme/ui/form'
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
|
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
|
||||||
import { GridColumnData } from '../list/GridColumnData'
|
import { GridColumnData } from '../list/GridColumnData'
|
||||||
import { addCss, addJs, getEditingFormGroups } from '../list/Utils'
|
import { addCss, addJs } from '../list/Utils'
|
||||||
import { PermissionResults, RowMode, SimpleItemWithColData } from './types'
|
import { PermissionResults, RowMode, SimpleItemWithColData } from './types'
|
||||||
import { ColumnFormatDto, GridDto, PlatformEditorTypes } from '@/proxy/form/models'
|
import { EditingFormItemDto, GridDto, PlatformEditorTypes } from '@/proxy/form/models'
|
||||||
import { getAccessDeniedPath } from '@/utils/routing'
|
import { getAccessDeniedPath } from '@/utils/routing'
|
||||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||||
import { useLookupDataSource } from './useLookupDataSource'
|
import { useLookupDataSource } from './useLookupDataSource'
|
||||||
|
|
@ -218,7 +218,10 @@ const useGridData = (props: {
|
||||||
)
|
)
|
||||||
setDataSource(dataSource)
|
setDataSource(dataSource)
|
||||||
|
|
||||||
const items = getEditingFormGroups(gridDto)
|
const items = gridDto?.gridOptions.editingFormDto
|
||||||
|
?.sort((a: any, b: any) => {
|
||||||
|
return a.order >= b.order ? 1 : -1
|
||||||
|
})
|
||||||
.map((e: any) => {
|
.map((e: any) => {
|
||||||
return {
|
return {
|
||||||
itemType: e.itemType,
|
itemType: e.itemType,
|
||||||
|
|
@ -227,12 +230,12 @@ const useGridData = (props: {
|
||||||
caption: e.caption,
|
caption: e.caption,
|
||||||
items: e.items
|
items: e.items
|
||||||
?.sort((a: any, b: any) => {
|
?.sort((a: any, b: any) => {
|
||||||
return (a.editOrderNo ?? 0) >= (b.editOrderNo ?? 0) ? 1 : -1
|
return a.order >= b.order ? 1 : -1
|
||||||
})
|
})
|
||||||
.map((i: ColumnFormatDto) => {
|
.map((i: EditingFormItemDto) => {
|
||||||
let editorOptions: Record<string, any> = {}
|
let editorOptions: Record<string, any> = {}
|
||||||
let parsedEditorOptions: Record<string, any> = {}
|
let parsedEditorOptions: Record<string, any> = {}
|
||||||
const colData = i
|
const colData = gridDto.columnFormats.find((x) => x.fieldName === i.dataField)
|
||||||
|
|
||||||
parsedEditorOptions = i.editorOptions ? JSON.parse(i.editorOptions) : {}
|
parsedEditorOptions = i.editorOptions ? JSON.parse(i.editorOptions) : {}
|
||||||
const lookupEditorOptions = colData?.lookupDto?.dataSourceType
|
const lookupEditorOptions = colData?.lookupDto?.dataSourceType
|
||||||
|
|
@ -247,14 +250,26 @@ const useGridData = (props: {
|
||||||
...parsedEditorOptions,
|
...parsedEditorOptions,
|
||||||
}
|
}
|
||||||
const item: SimpleItemWithColData = {
|
const item: SimpleItemWithColData = {
|
||||||
canRead: i.canRead ?? false,
|
canRead:
|
||||||
canUpdate: i.canUpdate ?? false,
|
gridDto.columnFormats.find((x: any) => x.fieldName === i.dataField)?.canRead ??
|
||||||
canCreate: i.canCreate ?? false,
|
false,
|
||||||
canExport: i.canExport ?? false,
|
canUpdate:
|
||||||
allowEditing: i.allowEditing ?? true,
|
gridDto.columnFormats.find((x: any) => x.fieldName === i.dataField)?.canUpdate ??
|
||||||
allowAdding: i.allowAdding ?? true,
|
false,
|
||||||
dataField: i.fieldName,
|
canCreate:
|
||||||
name: i.fieldName,
|
gridDto.columnFormats.find((x: any) => x.fieldName === i.dataField)?.canCreate ??
|
||||||
|
false,
|
||||||
|
canExport:
|
||||||
|
gridDto.columnFormats.find((x: any) => x.fieldName === i.dataField)?.canExport ??
|
||||||
|
false,
|
||||||
|
allowEditing:
|
||||||
|
gridDto.columnFormats.find((x: any) => x.fieldName === i.dataField)
|
||||||
|
?.allowEditing ?? true,
|
||||||
|
allowAdding:
|
||||||
|
gridDto.columnFormats.find((x: any) => x.fieldName === i.dataField)
|
||||||
|
?.allowAdding ?? true,
|
||||||
|
dataField: i.dataField,
|
||||||
|
name: i.dataField,
|
||||||
editorType2: i.editorType2,
|
editorType2: i.editorType2,
|
||||||
editorType:
|
editorType:
|
||||||
i.editorType2 == PlatformEditorTypes.dxGridBox
|
i.editorType2 == PlatformEditorTypes.dxGridBox
|
||||||
|
|
@ -271,8 +286,8 @@ const useGridData = (props: {
|
||||||
imageUploadOptions: i.imageUploadOptions,
|
imageUploadOptions: i.imageUploadOptions,
|
||||||
editorScript: i.editorScript,
|
editorScript: i.editorScript,
|
||||||
}
|
}
|
||||||
if (i.fieldName?.indexOf(':') >= 0) {
|
if (i.dataField.indexOf(':') >= 0) {
|
||||||
item.label = { text: captionize(i.fieldName.split(':')[1]) }
|
item.label = { text: captionize(i.dataField.split(':')[1]) }
|
||||||
}
|
}
|
||||||
if ((mode == 'edit' && !item.canUpdate) || (mode == 'new' && !item.canCreate)) {
|
if ((mode == 'edit' && !item.canUpdate) || (mode == 'new' && !item.canCreate)) {
|
||||||
item.editorOptions = {
|
item.editorOptions = {
|
||||||
|
|
@ -333,7 +348,7 @@ const useGridData = (props: {
|
||||||
|
|
||||||
const updateItems = (items: any[] = []): any[] =>
|
const updateItems = (items: any[] = []): any[] =>
|
||||||
items.map((item) => {
|
items.map((item) => {
|
||||||
const colData = item.colData
|
const colData = gridDto.columnFormats.find((x) => x.fieldName === item.dataField)
|
||||||
if (colData?.lookupDto?.dataSourceType && shouldRefreshLookup(item)) {
|
if (colData?.lookupDto?.dataSourceType && shouldRefreshLookup(item)) {
|
||||||
const currentDataSource = item.editorOptions?.dataSource
|
const currentDataSource = item.editorOptions?.dataSource
|
||||||
const keepCustomDataSource =
|
const keepCustomDataSource =
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import { ImportDashboard } from '@/components/importManager/ImportDashboard'
|
||||||
import { Dialog, Notification, toast } from '@/components/ui'
|
import { Dialog, Notification, toast } from '@/components/ui'
|
||||||
import { APP_NAME, DX_CLASSNAMES } from '@/constants/app.constant'
|
import { APP_NAME, DX_CLASSNAMES } from '@/constants/app.constant'
|
||||||
import {
|
import {
|
||||||
ColumnFormatDto,
|
|
||||||
DbTypeEnum,
|
DbTypeEnum,
|
||||||
|
EditingFormItemDto,
|
||||||
GridDto,
|
GridDto,
|
||||||
PlatformEditorTypes,
|
PlatformEditorTypes,
|
||||||
SubFormTabTypeEnum,
|
SubFormTabTypeEnum,
|
||||||
|
|
@ -41,12 +41,7 @@ import GridFilterDialogs from './GridFilterDialogs'
|
||||||
import { GridExtraFilterToolbar } from './GridExtraFilterToolbar'
|
import { GridExtraFilterToolbar } from './GridExtraFilterToolbar'
|
||||||
import { ImageUploadEditorComponent } from './editors/ImageUploadEditorComponent'
|
import { ImageUploadEditorComponent } from './editors/ImageUploadEditorComponent'
|
||||||
import { ImageViewerEditorComponent } from './editors/ImageViewerEditorComponent'
|
import { ImageViewerEditorComponent } from './editors/ImageViewerEditorComponent'
|
||||||
import {
|
import { extractSearchParamsFields, GridExtraFilterState, safeJsonParse } from './Utils'
|
||||||
extractSearchParamsFields,
|
|
||||||
getEditingFormGroups,
|
|
||||||
GridExtraFilterState,
|
|
||||||
safeJsonParse,
|
|
||||||
} from './Utils'
|
|
||||||
import { useFilters } from './useFilters'
|
import { useFilters } from './useFilters'
|
||||||
import { useListFormColumns } from './useListFormColumns'
|
import { useListFormColumns } from './useListFormColumns'
|
||||||
import { useListFormCustomDataSource } from './useListFormCustomDataSource'
|
import { useListFormCustomDataSource } from './useListFormCustomDataSource'
|
||||||
|
|
@ -99,7 +94,6 @@ const toCardColumn = (
|
||||||
const isImageColumn =
|
const isImageColumn =
|
||||||
typeof column.cellTemplate === 'function' &&
|
typeof column.cellTemplate === 'function' &&
|
||||||
Object.prototype.hasOwnProperty.call(column.extras ?? {}, 'imageUploadOptions')
|
Object.prototype.hasOwnProperty.call(column.extras ?? {}, 'imageUploadOptions')
|
||||||
const isHtmlColumn = column.colData?.editorType2 === 'dxHtmlEditor'
|
|
||||||
|
|
||||||
return Object.fromEntries(
|
return Object.fromEntries(
|
||||||
Object.entries({
|
Object.entries({
|
||||||
|
|
@ -145,14 +139,7 @@ const toCardColumn = (
|
||||||
})
|
})
|
||||||
return container
|
return container
|
||||||
}
|
}
|
||||||
: isHtmlColumn
|
: undefined,
|
||||||
? (templateOptions: any) => {
|
|
||||||
const templateData = templateOptions?.model ?? templateOptions
|
|
||||||
const container = document.createElement('div')
|
|
||||||
container.innerHTML = String(templateData.field?.value ?? '')
|
|
||||||
return container
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
format: column.format,
|
format: column.format,
|
||||||
headerFilter: column.headerFilter,
|
headerFilter: column.headerFilter,
|
||||||
lookup: column.lookup,
|
lookup: column.lookup,
|
||||||
|
|
@ -801,9 +788,12 @@ const CardView = (props: CardViewProps) => {
|
||||||
}, [filterToolbarData, toolbarData])
|
}, [filterToolbarData, toolbarData])
|
||||||
|
|
||||||
const mapEditingFormItem = useCallback(
|
const mapEditingFormItem = useCallback(
|
||||||
(item: ColumnFormatDto) => {
|
(item: EditingFormItemDto) => {
|
||||||
const fieldName = item.fieldName!
|
const fieldName = item.dataField.split(':')[0]
|
||||||
const column = item
|
const column = gridDto?.columnFormats.find(
|
||||||
|
(candidate) => candidate.fieldName?.toLowerCase() === fieldName.toLowerCase(),
|
||||||
|
)
|
||||||
|
if (!column) return undefined
|
||||||
if (
|
if (
|
||||||
mode === 'new' &&
|
mode === 'new' &&
|
||||||
fieldName.toLowerCase() === gridDto?.gridOptions.keyFieldName?.toLowerCase()
|
fieldName.toLowerCase() === gridDto?.gridOptions.keyFieldName?.toLowerCase()
|
||||||
|
|
@ -823,7 +813,7 @@ const CardView = (props: CardViewProps) => {
|
||||||
try {
|
try {
|
||||||
editorOptions = item.editorOptions ? JSON.parse(item.editorOptions) : {}
|
editorOptions = item.editorOptions ? JSON.parse(item.editorOptions) : {}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('EditorOptions parse error:', item.fieldName, error)
|
console.error('EditorOptions parse error:', item.dataField, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (column.sourceDbType === DbTypeEnum.Date) {
|
if (column.sourceDbType === DbTypeEnum.Date) {
|
||||||
|
|
@ -872,8 +862,8 @@ const CardView = (props: CardViewProps) => {
|
||||||
name: fieldName,
|
name: fieldName,
|
||||||
colSpan: item.colSpan,
|
colSpan: item.colSpan,
|
||||||
label: {
|
label: {
|
||||||
text: item.fieldName!.includes(':')
|
text: item.dataField.includes(':')
|
||||||
? item.fieldName!.split(':')[1]
|
? item.dataField.split(':')[1]
|
||||||
: translate('::' + (column.captionName || column.fieldName)),
|
: translate('::' + (column.captionName || column.fieldName)),
|
||||||
},
|
},
|
||||||
editorType:
|
editorType:
|
||||||
|
|
@ -898,7 +888,7 @@ const CardView = (props: CardViewProps) => {
|
||||||
const editingFormItems = useMemo(() => {
|
const editingFormItems = useMemo(() => {
|
||||||
if (!gridDto || mode === 'view') return []
|
if (!gridDto || mode === 'view') return []
|
||||||
|
|
||||||
const groups = [...(getEditingFormGroups(gridDto) ?? [])].sort(
|
const groups = [...(gridDto.gridOptions.editingFormDto ?? [])].sort(
|
||||||
(left, right) => left.order - right.order,
|
(left, right) => left.order - right.order,
|
||||||
)
|
)
|
||||||
const tabbedGroups = groups.filter((group) => group.itemType === 'tabbed')
|
const tabbedGroups = groups.filter((group) => group.itemType === 'tabbed')
|
||||||
|
|
@ -906,7 +896,7 @@ const CardView = (props: CardViewProps) => {
|
||||||
|
|
||||||
groups.forEach((group) => {
|
groups.forEach((group) => {
|
||||||
const items = [...(group.items ?? [])]
|
const items = [...(group.items ?? [])]
|
||||||
.sort((left, right) => (left.editOrderNo ?? 0) - (right.editOrderNo ?? 0))
|
.sort((left, right) => left.order - right.order)
|
||||||
.map(mapEditingFormItem)
|
.map(mapEditingFormItem)
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
|
|
||||||
|
|
@ -928,7 +918,7 @@ const CardView = (props: CardViewProps) => {
|
||||||
title: tab.caption,
|
title: tab.caption,
|
||||||
colCount: useMobileEditPopup ? 1 : tab.colCount || 1,
|
colCount: useMobileEditPopup ? 1 : tab.colCount || 1,
|
||||||
items: [...(tab.items ?? [])]
|
items: [...(tab.items ?? [])]
|
||||||
.sort((left, right) => (left.editOrderNo ?? 0) - (right.editOrderNo ?? 0))
|
.sort((left, right) => left.order - right.order)
|
||||||
.map(mapEditingFormItem)
|
.map(mapEditingFormItem)
|
||||||
.filter(Boolean),
|
.filter(Boolean),
|
||||||
}))
|
}))
|
||||||
|
|
@ -1247,6 +1237,7 @@ const CardView = (props: CardViewProps) => {
|
||||||
/>
|
/>
|
||||||
<FilterPanel
|
<FilterPanel
|
||||||
visible={gridDto.gridOptions.filterPanelDto.visible}
|
visible={gridDto.gridOptions.filterPanelDto.visible}
|
||||||
|
filterEnabled={gridDto.gridOptions.filterPanelDto.filterEnabled}
|
||||||
texts={gridDto.gridOptions.filterPanelDto.texts}
|
texts={gridDto.gridOptions.filterPanelDto.texts}
|
||||||
/>
|
/>
|
||||||
<HeaderFilter
|
<HeaderFilter
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ import '@/utils/registerDevExtremeEditors'
|
||||||
import { Dialog, Notification, toast } from '@/components/ui'
|
import { Dialog, Notification, toast } from '@/components/ui'
|
||||||
import { APP_NAME, DX_CLASSNAMES } from '@/constants/app.constant'
|
import { APP_NAME, DX_CLASSNAMES } from '@/constants/app.constant'
|
||||||
import {
|
import {
|
||||||
ColumnFormatDto,
|
|
||||||
DbTypeEnum,
|
DbTypeEnum,
|
||||||
|
EditingFormItemDto,
|
||||||
FieldCustomValueTypeEnum,
|
FieldCustomValueTypeEnum,
|
||||||
GridDto,
|
GridDto,
|
||||||
PlatformEditorTypes,
|
PlatformEditorTypes,
|
||||||
|
|
@ -53,8 +53,6 @@ import {
|
||||||
autoNumber,
|
autoNumber,
|
||||||
controlStyleCondition,
|
controlStyleCondition,
|
||||||
extractSearchParamsFields,
|
extractSearchParamsFields,
|
||||||
getEditingFormFields,
|
|
||||||
getEditingFormGroups,
|
|
||||||
GridExtraFilterState,
|
GridExtraFilterState,
|
||||||
safeJsonParse,
|
safeJsonParse,
|
||||||
setFormEditingExtraItemValues,
|
setFormEditingExtraItemValues,
|
||||||
|
|
@ -220,6 +218,13 @@ const getActiveEditingForm = (component: any) => {
|
||||||
return editForm?.getEditor || editForm?.itemOption ? editForm : undefined
|
return editForm?.getEditor || editForm?.itemOption ? editForm : undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const flattenEditingFormItems = (items: any[] = []): EditingFormItemDto[] =>
|
||||||
|
items.flatMap((item) => [
|
||||||
|
...(item?.dataField ? [item] : []),
|
||||||
|
...flattenEditingFormItems(item?.items || []),
|
||||||
|
...(item?.tabs || []).flatMap((tab: any) => flattenEditingFormItems(tab?.items || [])),
|
||||||
|
])
|
||||||
|
|
||||||
const getValueByField = (data: Record<string, any> = {}, field?: string) => {
|
const getValueByField = (data: Record<string, any> = {}, field?: string) => {
|
||||||
if (!field) return undefined
|
if (!field) return undefined
|
||||||
if (Object.prototype.hasOwnProperty.call(data, field)) return data[field]
|
if (Object.prototype.hasOwnProperty.call(data, field)) return data[field]
|
||||||
|
|
@ -604,7 +609,7 @@ const Grid = (props: GridProps) => {
|
||||||
.map((f) => f.fieldName)
|
.map((f) => f.fieldName)
|
||||||
const filteredData: any = {}
|
const filteredData: any = {}
|
||||||
for (const key of allowedFields) {
|
for (const key of allowedFields) {
|
||||||
if (key && Object.prototype.hasOwnProperty.call(e.data, key)) {
|
if (e.data.hasOwnProperty(key) && key) {
|
||||||
filteredData[key] = e.data[key]
|
filteredData[key] = e.data[key]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -720,10 +725,11 @@ const Grid = (props: GridProps) => {
|
||||||
const onEditorPreparing = useCallback(
|
const onEditorPreparing = useCallback(
|
||||||
(editor: DataGridTypes.EditorPreparingEvent<any, any>) => {
|
(editor: DataGridTypes.EditorPreparingEvent<any, any>) => {
|
||||||
if (editor.parentType === 'dataRow' && editor.dataField && gridDto) {
|
if (editor.parentType === 'dataRow' && editor.dataField && gridDto) {
|
||||||
const columnFormat = gridDto.columnFormats.find(
|
const formItem = gridDto.gridOptions.editingFormDto
|
||||||
(column) => column.fieldName === editor.dataField,
|
.flatMap((group) => flattenEditingFormItems([group]))
|
||||||
)
|
.find((i) => i.dataField === editor.dataField)
|
||||||
const formItem = columnFormat?.editOrderNo != null ? columnFormat : undefined
|
const fieldName = editor.dataField.split(':')[0]
|
||||||
|
const columnFormat = gridDto.columnFormats.find((column) => column.fieldName === fieldName)
|
||||||
const isNewRow = Boolean((editor as any).row?.isNewRow) || mode === 'new'
|
const isNewRow = Boolean((editor as any).row?.isNewRow) || mode === 'new'
|
||||||
|
|
||||||
const hasReadOnlyEditorOption = editor.editorOptions?.readOnly === true
|
const hasReadOnlyEditorOption = editor.editorOptions?.readOnly === true
|
||||||
|
|
@ -780,9 +786,9 @@ const Grid = (props: GridProps) => {
|
||||||
(pf: string) => !rowData[pf],
|
(pf: string) => !rowData[pf],
|
||||||
)
|
)
|
||||||
try {
|
try {
|
||||||
const childFormItem = gridDto.columnFormats.find(
|
const childFormItem = gridDto.gridOptions.editingFormDto
|
||||||
(column) => column.fieldName === childFieldName,
|
.flatMap((group) => flattenEditingFormItems([group]))
|
||||||
)
|
.find((i) => i.dataField === childFieldName)
|
||||||
const childEditorOptions = childFormItem?.editorOptions
|
const childEditorOptions = childFormItem?.editorOptions
|
||||||
? JSON.parse(childFormItem.editorOptions)
|
? JSON.parse(childFormItem.editorOptions)
|
||||||
: {}
|
: {}
|
||||||
|
|
@ -852,7 +858,7 @@ const Grid = (props: GridProps) => {
|
||||||
setFormData,
|
setFormData,
|
||||||
})
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Script exec error', formItem.fieldName, err)
|
console.error('Script exec error', formItem.dataField, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1130,7 +1136,7 @@ const Grid = (props: GridProps) => {
|
||||||
|
|
||||||
// Form items mapper'ı memoize et - popup açılışını hızlandırır
|
// Form items mapper'ı memoize et - popup açılışını hızlandırır
|
||||||
const mapFormItem = useCallback(
|
const mapFormItem = useCallback(
|
||||||
(i: ColumnFormatDto) => {
|
(i: EditingFormItemDto) => {
|
||||||
let editorOptions: EditorOptionsWithButtons = {}
|
let editorOptions: EditorOptionsWithButtons = {}
|
||||||
let parsedEditorOptions: EditorOptionsWithButtons = {}
|
let parsedEditorOptions: EditorOptionsWithButtons = {}
|
||||||
const forcedEditorOptions: EditorOptionsWithButtons = {}
|
const forcedEditorOptions: EditorOptionsWithButtons = {}
|
||||||
|
|
@ -1142,10 +1148,10 @@ const Grid = (props: GridProps) => {
|
||||||
const parsed = JSON.parse(rawFilter)
|
const parsed = JSON.parse(rawFilter)
|
||||||
const filters = extractSearchParamsFields(parsed)
|
const filters = extractSearchParamsFields(parsed)
|
||||||
|
|
||||||
const hasFilter = filters.some(([field]) => field === i.fieldName)
|
const hasFilter = filters.some(([field]) => field === i.dataField)
|
||||||
|
|
||||||
if (hasFilter) {
|
if (hasFilter) {
|
||||||
const existsInExtra = extraFilters.some((f) => f.fieldName === i.fieldName && !!f.value)
|
const existsInExtra = extraFilters.some((f) => f.fieldName === i.dataField && !!f.value)
|
||||||
|
|
||||||
if (!existsInExtra) {
|
if (!existsInExtra) {
|
||||||
forcedEditorOptions.readOnly = true
|
forcedEditorOptions.readOnly = true
|
||||||
|
|
@ -1153,11 +1159,11 @@ const Grid = (props: GridProps) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('EditorOptions parse error:', i.fieldName, err)
|
console.error('EditorOptions parse error:', i.dataField, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const fieldName = i.fieldName!
|
const fieldName = i.dataField.split(':')[0]
|
||||||
const listFormField = i
|
const listFormField = gridDto?.columnFormats.find((x: any) => x.fieldName === fieldName)
|
||||||
|
|
||||||
const defaultEditorOptions: EditorOptionsWithButtons = {}
|
const defaultEditorOptions: EditorOptionsWithButtons = {}
|
||||||
|
|
||||||
|
|
@ -1215,8 +1221,8 @@ const Grid = (props: GridProps) => {
|
||||||
canExport: listFormField?.canExport ?? false,
|
canExport: listFormField?.canExport ?? false,
|
||||||
allowEditing: listFormField?.allowEditing ?? true,
|
allowEditing: listFormField?.allowEditing ?? true,
|
||||||
allowAdding: listFormField?.allowAdding ?? true,
|
allowAdding: listFormField?.allowAdding ?? true,
|
||||||
dataField: i.fieldName,
|
dataField: i.dataField,
|
||||||
name: i.fieldName,
|
name: i.dataField,
|
||||||
editorType2: i.editorType2,
|
editorType2: i.editorType2,
|
||||||
editorType:
|
editorType:
|
||||||
i.editorType2 == PlatformEditorTypes.dxGridBox
|
i.editorType2 == PlatformEditorTypes.dxGridBox
|
||||||
|
|
@ -1234,12 +1240,12 @@ const Grid = (props: GridProps) => {
|
||||||
item.template = 'cellEditImageViewer'
|
item.template = 'cellEditImageViewer'
|
||||||
item.editorOptions = {
|
item.editorOptions = {
|
||||||
...item.editorOptions,
|
...item.editorOptions,
|
||||||
value: getValueByField(editingFormDataRef.current, i.fieldName),
|
value: getValueByField(editingFormDataRef.current, i.dataField),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.fieldName?.indexOf(':') >= 0) {
|
if (i.dataField.indexOf(':') >= 0) {
|
||||||
item.label = { text: captionize(i.fieldName.split(':')[1]) }
|
item.label = { text: captionize(i.dataField.split(':')[1]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mode == 'edit' && !item.canUpdate) || (mode == 'new' && !item.canCreate)) {
|
if ((mode == 'edit' && !item.canUpdate) || (mode == 'new' && !item.canCreate)) {
|
||||||
|
|
@ -1608,7 +1614,9 @@ const Grid = (props: GridProps) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const runReadOnlyScripts = () => {
|
const runReadOnlyScripts = () => {
|
||||||
const formItems = getEditingFormFields(gridDto)
|
const formItems = gridDto.gridOptions.editingFormDto.flatMap((group) =>
|
||||||
|
flattenEditingFormItems([group]),
|
||||||
|
)
|
||||||
const scriptItems = formItems.filter((formItem) =>
|
const scriptItems = formItems.filter((formItem) =>
|
||||||
shouldRunEditorScriptOnContentReady(formItem.editorScript),
|
shouldRunEditorScriptOnContentReady(formItem.editorScript),
|
||||||
)
|
)
|
||||||
|
|
@ -1619,9 +1627,9 @@ const Grid = (props: GridProps) => {
|
||||||
|
|
||||||
const editorValues = formItems.reduce<Record<string, any>>(
|
const editorValues = formItems.reduce<Record<string, any>>(
|
||||||
(values, formItem) => {
|
(values, formItem) => {
|
||||||
const editorInstance = form?.getEditor?.(formItem.fieldName)
|
const editorInstance = form?.getEditor?.(formItem.dataField)
|
||||||
if (editorInstance?.option) {
|
if (editorInstance?.option) {
|
||||||
values[formItem.fieldName!] = editorInstance.option('value')
|
values[formItem.dataField] = editorInstance.option('value')
|
||||||
}
|
}
|
||||||
return values
|
return values
|
||||||
},
|
},
|
||||||
|
|
@ -1636,17 +1644,17 @@ const Grid = (props: GridProps) => {
|
||||||
|
|
||||||
scriptItems.forEach((formItem) => {
|
scriptItems.forEach((formItem) => {
|
||||||
try {
|
try {
|
||||||
const editorInstance = form?.getEditor?.(formItem.fieldName)
|
const editorInstance = form?.getEditor?.(formItem.dataField)
|
||||||
const editorValue =
|
const editorValue =
|
||||||
editorInstance?.option?.('value') ??
|
editorInstance?.option?.('value') ??
|
||||||
getValueByField(formData, formItem.fieldName)
|
getValueByField(formData, formItem.dataField)
|
||||||
const editor = {
|
const editor = {
|
||||||
dataField: formItem.fieldName,
|
dataField: formItem.dataField,
|
||||||
component: grid,
|
component: grid,
|
||||||
}
|
}
|
||||||
const e = {
|
const e = {
|
||||||
component: form,
|
component: form,
|
||||||
dataField: formItem.fieldName,
|
dataField: formItem.dataField,
|
||||||
scriptEvent: 'contentReady',
|
scriptEvent: 'contentReady',
|
||||||
value: editorValue,
|
value: editorValue,
|
||||||
}
|
}
|
||||||
|
|
@ -1661,7 +1669,7 @@ const Grid = (props: GridProps) => {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(
|
console.error(
|
||||||
'Script exec error on contentReady',
|
'Script exec error on contentReady',
|
||||||
formItem.fieldName!,
|
formItem.dataField,
|
||||||
err,
|
err,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1677,10 +1685,11 @@ const Grid = (props: GridProps) => {
|
||||||
...(e.component?.option?.('formData') || {}),
|
...(e.component?.option?.('formData') || {}),
|
||||||
}
|
}
|
||||||
|
|
||||||
const formItem = getEditingFormFields(gridDto)
|
const formItem = gridDto.gridOptions.editingFormDto
|
||||||
|
.flatMap((group) => flattenEditingFormItems([group]))
|
||||||
.find(
|
.find(
|
||||||
(i) =>
|
(i) =>
|
||||||
String(i.fieldName || '').toLowerCase() ===
|
String(i.dataField || '').toLowerCase() ===
|
||||||
String(e.dataField || '').toLowerCase(),
|
String(e.dataField || '').toLowerCase(),
|
||||||
)
|
)
|
||||||
if (formItem?.editorScript) {
|
if (formItem?.editorScript) {
|
||||||
|
|
@ -1723,9 +1732,9 @@ const Grid = (props: GridProps) => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
items:
|
items:
|
||||||
getEditingFormGroups(gridDto)?.length > 0
|
gridDto.gridOptions.editingFormDto?.length > 0
|
||||||
? (() => {
|
? (() => {
|
||||||
const sortedFormDto = getEditingFormGroups(gridDto)
|
const sortedFormDto = gridDto.gridOptions.editingFormDto
|
||||||
.slice()
|
.slice()
|
||||||
.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
||||||
|
|
||||||
|
|
@ -1747,9 +1756,7 @@ const Grid = (props: GridProps) => {
|
||||||
colSpan: effectiveColSpan,
|
colSpan: effectiveColSpan,
|
||||||
caption: e.caption, // Group'larda caption olmalı
|
caption: e.caption, // Group'larda caption olmalı
|
||||||
items: e.items
|
items: e.items
|
||||||
?.sort((a: any, b: any) =>
|
?.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
||||||
(a.editOrderNo ?? 0) >= (b.editOrderNo ?? 0) ? 1 : -1,
|
|
||||||
)
|
|
||||||
.map(mapFormItem)
|
.map(mapFormItem)
|
||||||
.filter((a: any) => {
|
.filter((a: any) => {
|
||||||
if (mode === 'view') {
|
if (mode === 'view') {
|
||||||
|
|
@ -1778,9 +1785,7 @@ const Grid = (props: GridProps) => {
|
||||||
title: tabbedItem.caption, // Her tab'ın title'ı
|
title: tabbedItem.caption, // Her tab'ın title'ı
|
||||||
colCount: effectiveColCount,
|
colCount: effectiveColCount,
|
||||||
items: tabbedItem.items
|
items: tabbedItem.items
|
||||||
?.sort((a: any, b: any) =>
|
?.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
||||||
(a.editOrderNo ?? 0) >= (b.editOrderNo ?? 0) ? 1 : -1,
|
|
||||||
)
|
|
||||||
.map(mapFormItem)
|
.map(mapFormItem)
|
||||||
.filter((a: any) => {
|
.filter((a: any) => {
|
||||||
if (mode === 'view') {
|
if (mode === 'view') {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ interface IGridColumnData extends DataGridTypes.Column {
|
||||||
colData?: ColumnFormatDto
|
colData?: ColumnFormatDto
|
||||||
extras?: {
|
extras?: {
|
||||||
multiValue: boolean
|
multiValue: boolean
|
||||||
editorOptions?: Record<string, any>
|
editorOptions?: string
|
||||||
tagBoxOptions?: TagBoxOptionsDto
|
tagBoxOptions?: TagBoxOptionsDto
|
||||||
gridBoxOptions?: GridBoxOptionsDto
|
gridBoxOptions?: GridBoxOptionsDto
|
||||||
imageUploadOptions?: ImageUploadOptionsDto
|
imageUploadOptions?: ImageUploadOptionsDto
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { GridExtraFilterState } from './Utils'
|
import { GridExtraFilterState } from './Utils'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,6 @@ const List: React.FC = () => {
|
||||||
variant={viewMode === 'todo' ? 'solid' : 'default'}
|
variant={viewMode === 'todo' ? 'solid' : 'default'}
|
||||||
onClick={() => setLayout('todo')}
|
onClick={() => setLayout('todo')}
|
||||||
onMouseEnter={() => preload.todo()}
|
onMouseEnter={() => preload.todo()}
|
||||||
title={translate('::ListForms.ListFormEdit.TabTodo')}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{gridDto?.gridOptions?.layoutDto.scheduler &&
|
{gridDto?.gridOptions?.layoutDto.scheduler &&
|
||||||
|
|
@ -191,7 +190,6 @@ const List: React.FC = () => {
|
||||||
variant={viewMode === 'scheduler' ? 'solid' : 'default'}
|
variant={viewMode === 'scheduler' ? 'solid' : 'default'}
|
||||||
onClick={() => setLayout('scheduler')}
|
onClick={() => setLayout('scheduler')}
|
||||||
onMouseEnter={() => preload.scheduler()}
|
onMouseEnter={() => preload.scheduler()}
|
||||||
title={translate('::ListForms.ListFormEdit.TabScheduler')}
|
|
||||||
></Button>
|
></Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -204,7 +202,6 @@ const List: React.FC = () => {
|
||||||
variant={viewMode === 'gantt' ? 'solid' : 'default'}
|
variant={viewMode === 'gantt' ? 'solid' : 'default'}
|
||||||
onClick={() => setLayout('gantt')}
|
onClick={() => setLayout('gantt')}
|
||||||
onMouseEnter={() => preload.gantt()}
|
onMouseEnter={() => preload.gantt()}
|
||||||
title={translate('::ListForms.ListFormEdit.TabGantt')}
|
|
||||||
></Button>
|
></Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -216,7 +213,6 @@ const List: React.FC = () => {
|
||||||
variant={viewMode === 'tree' ? 'solid' : 'default'}
|
variant={viewMode === 'tree' ? 'solid' : 'default'}
|
||||||
onClick={() => setLayout('tree')}
|
onClick={() => setLayout('tree')}
|
||||||
onMouseEnter={() => preload.tree()}
|
onMouseEnter={() => preload.tree()}
|
||||||
title={translate('::ListForms.ListFormEdit.TabTree')}
|
|
||||||
></Button>
|
></Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -226,7 +222,6 @@ const List: React.FC = () => {
|
||||||
variant={viewMode === 'grid' ? 'solid' : 'default'}
|
variant={viewMode === 'grid' ? 'solid' : 'default'}
|
||||||
onClick={() => setLayout('grid')}
|
onClick={() => setLayout('grid')}
|
||||||
onMouseEnter={() => preload.grid()}
|
onMouseEnter={() => preload.grid()}
|
||||||
title={translate('::ListForms.ListFormEdit.TabGrid')}
|
|
||||||
></Button>
|
></Button>
|
||||||
|
|
||||||
{gridDto.gridOptions.layoutDto.card && (
|
{gridDto.gridOptions.layoutDto.card && (
|
||||||
|
|
@ -236,7 +231,6 @@ const List: React.FC = () => {
|
||||||
variant={viewMode === 'card' ? 'solid' : 'default'}
|
variant={viewMode === 'card' ? 'solid' : 'default'}
|
||||||
onClick={() => setLayout('card')}
|
onClick={() => setLayout('card')}
|
||||||
onMouseEnter={() => preload.card()}
|
onMouseEnter={() => preload.card()}
|
||||||
title={translate('::ListForms.ListFormEdit.TabCard')}
|
|
||||||
></Button>
|
></Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -247,7 +241,6 @@ const List: React.FC = () => {
|
||||||
variant={viewMode === 'pivot' ? 'solid' : 'default'}
|
variant={viewMode === 'pivot' ? 'solid' : 'default'}
|
||||||
onClick={() => setLayout('pivot')}
|
onClick={() => setLayout('pivot')}
|
||||||
onMouseEnter={() => preload.pivot()}
|
onMouseEnter={() => preload.pivot()}
|
||||||
title={translate('::ListForms.ListFormEdit.TabPivot')}
|
|
||||||
></Button>
|
></Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -258,7 +251,6 @@ const List: React.FC = () => {
|
||||||
variant={viewMode === 'chart' ? 'solid' : 'default'}
|
variant={viewMode === 'chart' ? 'solid' : 'default'}
|
||||||
onClick={() => setLayout('chart')}
|
onClick={() => setLayout('chart')}
|
||||||
onMouseEnter={() => preload.chart()}
|
onMouseEnter={() => preload.chart()}
|
||||||
title={translate('::ListForms.ListFormEdit.TabChart')}
|
|
||||||
></Button>
|
></Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ import Container from '@/components/shared/Container'
|
||||||
import '@/utils/registerDevExtremeEditors'
|
import '@/utils/registerDevExtremeEditors'
|
||||||
import { APP_NAME, DX_CLASSNAMES } from '@/constants/app.constant'
|
import { APP_NAME, DX_CLASSNAMES } from '@/constants/app.constant'
|
||||||
import {
|
import {
|
||||||
ColumnFormatDto,
|
|
||||||
DbTypeEnum,
|
DbTypeEnum,
|
||||||
GridDto,
|
GridDto,
|
||||||
PlatformEditorTypes,
|
PlatformEditorTypes,
|
||||||
UiLookupDataSourceTypeEnum,
|
UiLookupDataSourceTypeEnum,
|
||||||
|
EditingFormItemDto,
|
||||||
} from '@/proxy/form/models'
|
} from '@/proxy/form/models'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import Scheduler, {
|
import Scheduler, {
|
||||||
|
|
@ -21,12 +21,7 @@ import { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
import { getList } from '@/services/form.service'
|
import { getList } from '@/services/form.service'
|
||||||
import { useListFormCustomDataSource } from './useListFormCustomDataSource'
|
import { useListFormCustomDataSource } from './useListFormCustomDataSource'
|
||||||
import {
|
import { addCss, addJs, autoNumber } from './Utils'
|
||||||
addCss,
|
|
||||||
addJs,
|
|
||||||
autoNumber,
|
|
||||||
getEditingFormGroups,
|
|
||||||
} from './Utils'
|
|
||||||
import { layoutTypes } from '../admin/listForm/edit/types'
|
import { layoutTypes } from '../admin/listForm/edit/types'
|
||||||
import WidgetGroup from '@/components/ui/Widget/WidgetGroup'
|
import WidgetGroup from '@/components/ui/Widget/WidgetGroup'
|
||||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||||
|
|
@ -294,11 +289,11 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
// Grup düzenini EditingFormDto'dan, alanları ColumnFormatDto'dan oluştur.
|
// EditingFormDto'dan form items oluştur
|
||||||
const result: any[] = []
|
const result: any[] = []
|
||||||
|
|
||||||
if (getEditingFormGroups(gridDto)?.length > 0) {
|
if (gridDto.gridOptions.editingFormDto?.length > 0) {
|
||||||
const sortedFormDto = getEditingFormGroups(gridDto)
|
const sortedFormDto = gridDto.gridOptions.editingFormDto
|
||||||
.slice()
|
.slice()
|
||||||
.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
||||||
|
|
||||||
|
|
@ -306,7 +301,7 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
||||||
const tabbedItems = sortedFormDto.filter((e: any) => e.itemType === 'tabbed')
|
const tabbedItems = sortedFormDto.filter((e: any) => e.itemType === 'tabbed')
|
||||||
|
|
||||||
// Ortak item mapper fonksiyonu - hem group hem tab için kullanılır
|
// Ortak item mapper fonksiyonu - hem group hem tab için kullanılır
|
||||||
const mapFormItem = (i: ColumnFormatDto) => {
|
const mapFormItem = (i: EditingFormItemDto) => {
|
||||||
let editorOptions: any = {}
|
let editorOptions: any = {}
|
||||||
try {
|
try {
|
||||||
if (i.editorOptions) {
|
if (i.editorOptions) {
|
||||||
|
|
@ -316,8 +311,8 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const fieldName = i.fieldName!
|
const fieldName = i.dataField.split(':')[0]
|
||||||
const listFormField = i
|
const listFormField = gridDto.columnFormats.find((x: any) => x.fieldName === fieldName)
|
||||||
|
|
||||||
if (listFormField?.sourceDbType === DbTypeEnum.Date) {
|
if (listFormField?.sourceDbType === DbTypeEnum.Date) {
|
||||||
editorOptions = {
|
editorOptions = {
|
||||||
|
|
@ -356,7 +351,7 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditorType belirleme
|
// EditorType belirleme
|
||||||
let editorType: any = i.editorType2
|
let editorType: any = i.editorType2 || i.editorType
|
||||||
if (i.editorType2 === PlatformEditorTypes.dxGridBox) {
|
if (i.editorType2 === PlatformEditorTypes.dxGridBox) {
|
||||||
editorType = 'dxDropDownBox'
|
editorType = 'dxDropDownBox'
|
||||||
} else if (i.editorType2) {
|
} else if (i.editorType2) {
|
||||||
|
|
@ -414,8 +409,8 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
||||||
canExport: listFormField?.canExport ?? false,
|
canExport: listFormField?.canExport ?? false,
|
||||||
allowEditing: listFormField?.allowEditing ?? true,
|
allowEditing: listFormField?.allowEditing ?? true,
|
||||||
allowAdding: listFormField?.allowAdding ?? true,
|
allowAdding: listFormField?.allowAdding ?? true,
|
||||||
dataField: i.fieldName,
|
dataField: i.dataField,
|
||||||
name: i.fieldName,
|
name: i.dataField,
|
||||||
editorType2: i.editorType2,
|
editorType2: i.editorType2,
|
||||||
editorType:
|
editorType:
|
||||||
i.editorType2 == PlatformEditorTypes.dxGridBox
|
i.editorType2 == PlatformEditorTypes.dxGridBox
|
||||||
|
|
@ -429,8 +424,8 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
||||||
editorScript: i.editorScript,
|
editorScript: i.editorScript,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.fieldName?.indexOf(':') >= 0) {
|
if (i.dataField.indexOf(':') >= 0) {
|
||||||
item.label = { text: captionize(i.fieldName.split(':')[1]) }
|
item.label = { text: captionize(i.dataField.split(':')[1]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
@ -450,9 +445,7 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
||||||
// Items'ları da order'a göre sırala
|
// Items'ları da order'a göre sırala
|
||||||
const sortedItems = (e.items || [])
|
const sortedItems = (e.items || [])
|
||||||
.slice()
|
.slice()
|
||||||
.sort((a: any, b: any) =>
|
.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
||||||
(a.editOrderNo ?? 0) >= (b.editOrderNo ?? 0) ? 1 : -1,
|
|
||||||
)
|
|
||||||
|
|
||||||
const groupItems = sortedItems.map(mapFormItem)
|
const groupItems = sortedItems.map(mapFormItem)
|
||||||
|
|
||||||
|
|
@ -474,9 +467,7 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
||||||
title: tabbedItem.caption, // Her tab'ın title'ı
|
title: tabbedItem.caption, // Her tab'ın title'ı
|
||||||
colCount: effectiveColCount,
|
colCount: effectiveColCount,
|
||||||
items: tabbedItem.items
|
items: tabbedItem.items
|
||||||
?.sort((a: any, b: any) =>
|
?.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
||||||
(a.editOrderNo ?? 0) >= (b.editOrderNo ?? 0) ? 1 : -1,
|
|
||||||
)
|
|
||||||
.map(mapFormItem)
|
.map(mapFormItem)
|
||||||
.filter((a: any) => {
|
.filter((a: any) => {
|
||||||
if (currentMode === 'new') {
|
if (currentMode === 'new') {
|
||||||
|
|
@ -499,11 +490,11 @@ const SchedulerView = (props: SchedulerViewProps) => {
|
||||||
// Form'u tamamen yeniden baştan yapılandır
|
// Form'u tamamen yeniden baştan yapılandır
|
||||||
e.form.option(
|
e.form.option(
|
||||||
'colCount',
|
'colCount',
|
||||||
hasTabbedItems ? 1 : getEditingFormGroups(gridDto)?.[0]?.colCount || 2,
|
hasTabbedItems ? 1 : gridDto.gridOptions.editingFormDto?.[0]?.colCount || 2,
|
||||||
)
|
)
|
||||||
e.form.option(
|
e.form.option(
|
||||||
'colCount',
|
'colCount',
|
||||||
hasTabbedItems ? 1 : getEditingFormGroups(gridDto)?.[0]?.colCount || 2,
|
hasTabbedItems ? 1 : gridDto.gridOptions.editingFormDto?.[0]?.colCount || 2,
|
||||||
)
|
)
|
||||||
e.form.option('showValidationSummary', false)
|
e.form.option('showValidationSummary', false)
|
||||||
e.form.option('items', result)
|
e.form.option('items', result)
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,8 @@ import type { GridDto, TodoOptionDto } from '@/proxy/form/models'
|
||||||
import type { IdentityUserDto } from '@/proxy/admin/models'
|
import type { IdentityUserDto } from '@/proxy/admin/models'
|
||||||
import type { DataGridRef } from 'devextreme-react/data-grid'
|
import type { DataGridRef } from 'devextreme-react/data-grid'
|
||||||
import type CustomStore from 'devextreme/data/custom_store'
|
import type CustomStore from 'devextreme/data/custom_store'
|
||||||
import { HtmlEditor, ImageUpload, Item, MediaResizing, Toolbar } from 'devextreme-react/html-editor'
|
|
||||||
import TagBox from 'devextreme-react/tag-box'
|
import TagBox from 'devextreme-react/tag-box'
|
||||||
import { AVATAR_URL } from '@/constants/app.constant'
|
import { AVATAR_URL } from '@/constants/app.constant'
|
||||||
import {
|
|
||||||
fontFamilyOptions,
|
|
||||||
fontSizeOptions,
|
|
||||||
fontValues,
|
|
||||||
headerOptions,
|
|
||||||
headerValues,
|
|
||||||
sizeValues,
|
|
||||||
} from '@/proxy/reports/data'
|
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||||
import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
|
|
@ -69,16 +60,6 @@ interface UserOption {
|
||||||
|
|
||||||
const fieldValue = (row: TodoRow, field?: string) => (field ? row[field] : undefined)
|
const fieldValue = (row: TodoRow, field?: string) => (field ? row[field] : undefined)
|
||||||
|
|
||||||
const htmlToPlainText = (value: unknown) => {
|
|
||||||
const html = String(value ?? '')
|
|
||||||
if (!html) return ''
|
|
||||||
if (typeof document === 'undefined') return html.replace(/<[^>]*>/g, ' ')
|
|
||||||
|
|
||||||
const container = document.createElement('div')
|
|
||||||
container.innerHTML = html
|
|
||||||
return (container.textContent ?? '').replace(/\s+/g, ' ').trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
const textList = (value: unknown) =>
|
const textList = (value: unknown) =>
|
||||||
Array.isArray(value)
|
Array.isArray(value)
|
||||||
? value.map(String)
|
? value.map(String)
|
||||||
|
|
@ -701,51 +682,18 @@ const TodoBoard = ({ listFormCode, searchParams, gridDto }: TodoBoardProps) => {
|
||||||
<label className={labelClass}>
|
<label className={labelClass}>
|
||||||
{translate('::ListForms.TodoBoard.Description')}
|
{translate('::ListForms.TodoBoard.Description')}
|
||||||
</label>
|
</label>
|
||||||
<HtmlEditor
|
<textarea
|
||||||
height={220}
|
className={`${inputClass} min-h-36 resize-y`}
|
||||||
|
disabled={!canEdit}
|
||||||
placeholder={translate('::ListForms.TodoBoard.DescriptionPlaceholder')}
|
placeholder={translate('::ListForms.TodoBoard.DescriptionPlaceholder')}
|
||||||
readOnly={!canEdit}
|
|
||||||
value={String(draft[options.descriptionExpr] ?? '')}
|
value={String(draft[options.descriptionExpr] ?? '')}
|
||||||
onValueChanged={(event) =>
|
onChange={(event) =>
|
||||||
setDraft((current) => ({
|
setDraft((current) => ({
|
||||||
...current,
|
...current,
|
||||||
[options.descriptionExpr!]: event.value,
|
[options.descriptionExpr!]: event.target.value,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
>
|
/>
|
||||||
<MediaResizing enabled={true} />
|
|
||||||
<ImageUpload fileUploadMode="base64" />
|
|
||||||
<Toolbar multiline>
|
|
||||||
<Item name="undo" />
|
|
||||||
<Item name="redo" />
|
|
||||||
<Item name="separator" />
|
|
||||||
<Item name="size" acceptedValues={sizeValues} options={fontSizeOptions} />
|
|
||||||
<Item name="font" acceptedValues={fontValues} options={fontFamilyOptions} />
|
|
||||||
<Item name="separator" />
|
|
||||||
<Item name="bold" />
|
|
||||||
<Item name="italic" />
|
|
||||||
<Item name="underline" />
|
|
||||||
<Item name="strike" />
|
|
||||||
<Item name="separator" />
|
|
||||||
<Item name="orderedList" />
|
|
||||||
<Item name="bulletList" />
|
|
||||||
<Item name="separator" />
|
|
||||||
<Item name="header" acceptedValues={headerValues} options={headerOptions} />
|
|
||||||
<Item name="separator" />
|
|
||||||
<Item name="color" />
|
|
||||||
<Item name="background" />
|
|
||||||
<Item name="separator" />
|
|
||||||
<Item name="alignLeft" />
|
|
||||||
<Item name="alignCenter" />
|
|
||||||
<Item name="alignRight" />
|
|
||||||
<Item name="alignJustify" />
|
|
||||||
<Item name="separator" />
|
|
||||||
<Item name="link" />
|
|
||||||
<Item name="image" />
|
|
||||||
<Item name="separator" />
|
|
||||||
<Item name="clear" />
|
|
||||||
</Toolbar>
|
|
||||||
</HtmlEditor>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="grid gap-4 sm:grid-cols-2">
|
<div className="grid gap-4 sm:grid-cols-2">
|
||||||
|
|
@ -1024,9 +972,9 @@ const TodoBoard = ({ listFormCode, searchParams, gridDto }: TodoBoardProps) => {
|
||||||
</form>
|
</form>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<h4 className="min-w-0 truncate font-sm" title={status}>
|
<h3 className="min-w-0 truncate font-semibold" title={status}>
|
||||||
{status}
|
{status}
|
||||||
</h4>
|
</h3>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="rounded p-1 text-gray-400 opacity-0 transition hover:bg-gray-200 hover:text-blue-600 group-hover:opacity-100 dark:hover:bg-gray-700"
|
className="rounded p-1 text-gray-400 opacity-0 transition hover:bg-gray-200 hover:text-blue-600 group-hover:opacity-100 dark:hover:bg-gray-700"
|
||||||
|
|
@ -1204,7 +1152,7 @@ const TodoBoard = ({ listFormCode, searchParams, gridDto }: TodoBoardProps) => {
|
||||||
</div>
|
</div>
|
||||||
{fieldValue(row, options.descriptionExpr) && (
|
{fieldValue(row, options.descriptionExpr) && (
|
||||||
<p className="mt-1 line-clamp-2 text-xs leading-5 text-gray-500 dark:text-gray-400">
|
<p className="mt-1 line-clamp-2 text-xs leading-5 text-gray-500 dark:text-gray-400">
|
||||||
{htmlToPlainText(fieldValue(row, options.descriptionExpr))}
|
{String(fieldValue(row, options.descriptionExpr))}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{due && (
|
{due && (
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import { Dialog, Notification, toast } from '@/components/ui'
|
||||||
import { APP_NAME, DX_CLASSNAMES } from '@/constants/app.constant'
|
import { APP_NAME, DX_CLASSNAMES } from '@/constants/app.constant'
|
||||||
import { executeEditorScript } from '@/utils/editorScriptRuntime'
|
import { executeEditorScript } from '@/utils/editorScriptRuntime'
|
||||||
import {
|
import {
|
||||||
ColumnFormatDto,
|
|
||||||
DbTypeEnum,
|
DbTypeEnum,
|
||||||
|
EditingFormItemDto,
|
||||||
GridDto,
|
GridDto,
|
||||||
PlatformEditorTypes,
|
PlatformEditorTypes,
|
||||||
SubFormTabTypeEnum,
|
SubFormTabTypeEnum,
|
||||||
|
|
@ -44,8 +44,6 @@ import {
|
||||||
addJs,
|
addJs,
|
||||||
autoNumber,
|
autoNumber,
|
||||||
controlStyleCondition,
|
controlStyleCondition,
|
||||||
getEditingFormFields,
|
|
||||||
getEditingFormGroups,
|
|
||||||
GridExtraFilterState,
|
GridExtraFilterState,
|
||||||
safeJsonParse,
|
safeJsonParse,
|
||||||
setFormEditingExtraItemValues,
|
setFormEditingExtraItemValues,
|
||||||
|
|
@ -208,6 +206,13 @@ const getActiveEditingForm = (component: any) => {
|
||||||
return editForm?.getEditor || editForm?.itemOption ? editForm : undefined
|
return editForm?.getEditor || editForm?.itemOption ? editForm : undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const flattenEditingFormItems = (items: any[] = []): EditingFormItemDto[] =>
|
||||||
|
items.flatMap((item) => [
|
||||||
|
...(item?.dataField ? [item] : []),
|
||||||
|
...flattenEditingFormItems(item?.items || []),
|
||||||
|
...(item?.tabs || []).flatMap((tab: any) => flattenEditingFormItems(tab?.items || [])),
|
||||||
|
])
|
||||||
|
|
||||||
const getValueByField = (data: Record<string, any> = {}, field?: string) => {
|
const getValueByField = (data: Record<string, any> = {}, field?: string) => {
|
||||||
if (!field) return undefined
|
if (!field) return undefined
|
||||||
if (Object.prototype.hasOwnProperty.call(data, field)) return data[field]
|
if (Object.prototype.hasOwnProperty.call(data, field)) return data[field]
|
||||||
|
|
@ -659,10 +664,11 @@ const Tree = (props: TreeProps) => {
|
||||||
|
|
||||||
function onEditorPreparing(editor: TreeListTypes.EditorPreparingEvent) {
|
function onEditorPreparing(editor: TreeListTypes.EditorPreparingEvent) {
|
||||||
if (editor.parentType === 'dataRow' && editor.dataField && gridDto) {
|
if (editor.parentType === 'dataRow' && editor.dataField && gridDto) {
|
||||||
const columnFormat = gridDto.columnFormats.find(
|
const formItem = gridDto.gridOptions.editingFormDto
|
||||||
(column) => column.fieldName === editor.dataField,
|
.flatMap((group) => flattenEditingFormItems([group]))
|
||||||
)
|
.find((i) => i.dataField === editor.dataField)
|
||||||
const formItem = columnFormat?.editOrderNo != null ? columnFormat : undefined
|
const fieldName = editor.dataField.split(':')[0]
|
||||||
|
const columnFormat = gridDto.columnFormats.find((column) => column.fieldName === fieldName)
|
||||||
const isNewRow = Boolean((editor as any).row?.isNewRow) || mode === 'new'
|
const isNewRow = Boolean((editor as any).row?.isNewRow) || mode === 'new'
|
||||||
|
|
||||||
const hasReadOnlyEditorOption = editor.editorOptions?.readOnly === true
|
const hasReadOnlyEditorOption = editor.editorOptions?.readOnly === true
|
||||||
|
|
@ -683,7 +689,7 @@ const Tree = (props: TreeProps) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cascade disabled mantığı
|
// Cascade disabled mantığı
|
||||||
const colFormat = columnFormat
|
const colFormat = gridDto.columnFormats.find((c) => c.fieldName === editor.dataField)
|
||||||
if (colFormat?.lookupDto?.cascadeParentFields) {
|
if (colFormat?.lookupDto?.cascadeParentFields) {
|
||||||
const parentFields = colFormat.lookupDto.cascadeParentFields
|
const parentFields = colFormat.lookupDto.cascadeParentFields
|
||||||
.split(',')
|
.split(',')
|
||||||
|
|
@ -727,8 +733,11 @@ const Tree = (props: TreeProps) => {
|
||||||
try {
|
try {
|
||||||
const editorInstance = formInstance.getEditor(col.fieldName!)
|
const editorInstance = formInstance.getEditor(col.fieldName!)
|
||||||
if (editorInstance) {
|
if (editorInstance) {
|
||||||
const editorOptions = col.editorOptions
|
const formItem = gridDto.gridOptions.editingFormDto
|
||||||
? JSON.parse(col.editorOptions)
|
.flatMap((group) => flattenEditingFormItems([group]))
|
||||||
|
.find((i) => i.dataField === col.fieldName)
|
||||||
|
const editorOptions = formItem?.editorOptions
|
||||||
|
? JSON.parse(formItem.editorOptions)
|
||||||
: {}
|
: {}
|
||||||
|
|
||||||
editorInstance.option(
|
editorInstance.option(
|
||||||
|
|
@ -795,7 +804,7 @@ const Tree = (props: TreeProps) => {
|
||||||
setFormData,
|
setFormData,
|
||||||
})
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Script exec error', formItem.fieldName, err)
|
console.error('Script exec error', formItem.dataField, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1260,7 +1269,9 @@ const Tree = (props: TreeProps) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const runReadOnlyScripts = () => {
|
const runReadOnlyScripts = () => {
|
||||||
const formItems = getEditingFormFields(gridDto)
|
const formItems = gridDto.gridOptions.editingFormDto.flatMap((group) =>
|
||||||
|
flattenEditingFormItems([group]),
|
||||||
|
)
|
||||||
const scriptItems = formItems.filter((formItem) =>
|
const scriptItems = formItems.filter((formItem) =>
|
||||||
shouldRunEditorScriptOnContentReady(formItem.editorScript),
|
shouldRunEditorScriptOnContentReady(formItem.editorScript),
|
||||||
)
|
)
|
||||||
|
|
@ -1271,9 +1282,9 @@ const Tree = (props: TreeProps) => {
|
||||||
|
|
||||||
const editorValues = formItems.reduce<Record<string, any>>(
|
const editorValues = formItems.reduce<Record<string, any>>(
|
||||||
(values, formItem) => {
|
(values, formItem) => {
|
||||||
const editorInstance = form?.getEditor?.(formItem.fieldName)
|
const editorInstance = form?.getEditor?.(formItem.dataField)
|
||||||
if (editorInstance?.option) {
|
if (editorInstance?.option) {
|
||||||
values[formItem.fieldName!] = editorInstance.option('value')
|
values[formItem.dataField] = editorInstance.option('value')
|
||||||
}
|
}
|
||||||
return values
|
return values
|
||||||
},
|
},
|
||||||
|
|
@ -1288,17 +1299,17 @@ const Tree = (props: TreeProps) => {
|
||||||
|
|
||||||
scriptItems.forEach((formItem) => {
|
scriptItems.forEach((formItem) => {
|
||||||
try {
|
try {
|
||||||
const editorInstance = form?.getEditor?.(formItem.fieldName)
|
const editorInstance = form?.getEditor?.(formItem.dataField)
|
||||||
const editorValue =
|
const editorValue =
|
||||||
editorInstance?.option?.('value') ??
|
editorInstance?.option?.('value') ??
|
||||||
getValueByField(formData, formItem.fieldName)
|
getValueByField(formData, formItem.dataField)
|
||||||
const editor = {
|
const editor = {
|
||||||
dataField: formItem.fieldName,
|
dataField: formItem.dataField,
|
||||||
component: grid,
|
component: grid,
|
||||||
}
|
}
|
||||||
const e = {
|
const e = {
|
||||||
component: form,
|
component: form,
|
||||||
dataField: formItem.fieldName,
|
dataField: formItem.dataField,
|
||||||
scriptEvent: 'contentReady',
|
scriptEvent: 'contentReady',
|
||||||
value: editorValue,
|
value: editorValue,
|
||||||
}
|
}
|
||||||
|
|
@ -1313,7 +1324,7 @@ const Tree = (props: TreeProps) => {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(
|
console.error(
|
||||||
'Script exec error on contentReady',
|
'Script exec error on contentReady',
|
||||||
formItem.fieldName!,
|
formItem.dataField,
|
||||||
err,
|
err,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1329,10 +1340,11 @@ const Tree = (props: TreeProps) => {
|
||||||
...(e.component?.option?.('formData') || {}),
|
...(e.component?.option?.('formData') || {}),
|
||||||
}
|
}
|
||||||
|
|
||||||
const formItem = getEditingFormFields(gridDto)
|
const formItem = gridDto.gridOptions.editingFormDto
|
||||||
|
.flatMap((group) => flattenEditingFormItems([group]))
|
||||||
.find(
|
.find(
|
||||||
(i) =>
|
(i) =>
|
||||||
String(i.fieldName || '').toLowerCase() ===
|
String(i.dataField || '').toLowerCase() ===
|
||||||
String(e.dataField || '').toLowerCase(),
|
String(e.dataField || '').toLowerCase(),
|
||||||
)
|
)
|
||||||
if (formItem?.editorScript) {
|
if (formItem?.editorScript) {
|
||||||
|
|
@ -1375,9 +1387,9 @@ const Tree = (props: TreeProps) => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
items:
|
items:
|
||||||
getEditingFormGroups(gridDto)?.length > 0
|
gridDto.gridOptions.editingFormDto?.length > 0
|
||||||
? (() => {
|
? (() => {
|
||||||
const sortedFormDto = getEditingFormGroups(gridDto)
|
const sortedFormDto = gridDto.gridOptions.editingFormDto
|
||||||
.slice()
|
.slice()
|
||||||
.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
||||||
|
|
||||||
|
|
@ -1388,7 +1400,7 @@ const Tree = (props: TreeProps) => {
|
||||||
const result: any[] = []
|
const result: any[] = []
|
||||||
|
|
||||||
// Helper function: item mapper
|
// Helper function: item mapper
|
||||||
const mapFormItem = (i: ColumnFormatDto) => {
|
const mapFormItem = (i: EditingFormItemDto) => {
|
||||||
let editorOptions: EditorOptionsWithButtons = {}
|
let editorOptions: EditorOptionsWithButtons = {}
|
||||||
let parsedEditorOptions: EditorOptionsWithButtons = {}
|
let parsedEditorOptions: EditorOptionsWithButtons = {}
|
||||||
const forcedEditorOptions: EditorOptionsWithButtons = {}
|
const forcedEditorOptions: EditorOptionsWithButtons = {}
|
||||||
|
|
@ -1403,12 +1415,12 @@ const Tree = (props: TreeProps) => {
|
||||||
const filters = extractSearchParamsFields(parsed)
|
const filters = extractSearchParamsFields(parsed)
|
||||||
|
|
||||||
const hasFilter = filters.some(
|
const hasFilter = filters.some(
|
||||||
([field, op, val]) => field === i.fieldName,
|
([field, op, val]) => field === i.dataField,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (hasFilter) {
|
if (hasFilter) {
|
||||||
const existsInExtra = extraFilters.some(
|
const existsInExtra = extraFilters.some(
|
||||||
(f) => f.fieldName === i.fieldName && !!f.value,
|
(f) => f.fieldName === i.dataField && !!f.value,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!existsInExtra) {
|
if (!existsInExtra) {
|
||||||
|
|
@ -1417,11 +1429,13 @@ const Tree = (props: TreeProps) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err){
|
} catch (err){
|
||||||
console.error('EditorOptions parse error:', i.fieldName, err)
|
console.error('EditorOptions parse error:', i.dataField, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
const fieldName = i.fieldName!
|
const fieldName = i.dataField.split(':')[0]
|
||||||
const listFormField = i
|
const listFormField = gridDto.columnFormats.find(
|
||||||
|
(x: any) => x.fieldName === fieldName,
|
||||||
|
)
|
||||||
|
|
||||||
const defaultEditorOptions: EditorOptionsWithButtons = {}
|
const defaultEditorOptions: EditorOptionsWithButtons = {}
|
||||||
|
|
||||||
|
|
@ -1470,8 +1484,8 @@ const Tree = (props: TreeProps) => {
|
||||||
canExport: listFormField?.canExport ?? false,
|
canExport: listFormField?.canExport ?? false,
|
||||||
allowEditing: listFormField?.allowEditing ?? true,
|
allowEditing: listFormField?.allowEditing ?? true,
|
||||||
allowAdding: listFormField?.allowAdding ?? true,
|
allowAdding: listFormField?.allowAdding ?? true,
|
||||||
dataField: i.fieldName,
|
dataField: i.dataField,
|
||||||
name: i.fieldName,
|
name: i.dataField,
|
||||||
editorType2: i.editorType2,
|
editorType2: i.editorType2,
|
||||||
editorType:
|
editorType:
|
||||||
i.editorType2 == PlatformEditorTypes.dxGridBox
|
i.editorType2 == PlatformEditorTypes.dxGridBox
|
||||||
|
|
@ -1489,12 +1503,12 @@ const Tree = (props: TreeProps) => {
|
||||||
item.template = 'cellEditImageViewer'
|
item.template = 'cellEditImageViewer'
|
||||||
item.editorOptions = {
|
item.editorOptions = {
|
||||||
...item.editorOptions,
|
...item.editorOptions,
|
||||||
value: getValueByField(editingFormDataRef.current, i.fieldName),
|
value: getValueByField(editingFormDataRef.current, i.dataField),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.fieldName?.indexOf(':') >= 0) {
|
if (i.dataField.indexOf(':') >= 0) {
|
||||||
item.label = { text: captionize(i.fieldName.split(':')[1]) }
|
item.label = { text: captionize(i.dataField.split(':')[1]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
@ -1518,9 +1532,7 @@ const Tree = (props: TreeProps) => {
|
||||||
colSpan: e.colSpan,
|
colSpan: e.colSpan,
|
||||||
caption: e.caption, // Group'larda caption olmalı
|
caption: e.caption, // Group'larda caption olmalı
|
||||||
items: e.items
|
items: e.items
|
||||||
?.sort((a: any, b: any) =>
|
?.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
||||||
(a.editOrderNo ?? 0) >= (b.editOrderNo ?? 0) ? 1 : -1,
|
|
||||||
)
|
|
||||||
.map(mapFormItem)
|
.map(mapFormItem)
|
||||||
.filter((a: any) => {
|
.filter((a: any) => {
|
||||||
if (mode === 'view') {
|
if (mode === 'view') {
|
||||||
|
|
@ -1549,9 +1561,7 @@ const Tree = (props: TreeProps) => {
|
||||||
title: tabbedItem.caption, // Her tab'ın title'ı
|
title: tabbedItem.caption, // Her tab'ın title'ı
|
||||||
colCount: effectiveColCount,
|
colCount: effectiveColCount,
|
||||||
items: tabbedItem.items
|
items: tabbedItem.items
|
||||||
?.sort((a: any, b: any) =>
|
?.sort((a: any, b: any) => (a.order >= b.order ? 1 : -1))
|
||||||
(a.editOrderNo ?? 0) >= (b.editOrderNo ?? 0) ? 1 : -1,
|
|
||||||
)
|
|
||||||
.map(mapFormItem)
|
.map(mapFormItem)
|
||||||
.filter((a: any) => {
|
.filter((a: any) => {
|
||||||
if (mode === 'view') {
|
if (mode === 'view') {
|
||||||
|
|
|
||||||
|
|
@ -2,24 +2,6 @@ import type { DataType } from 'devextreme/common'
|
||||||
import type { PivotGridDataType } from 'devextreme/ui/pivot_grid/data_source'
|
import type { PivotGridDataType } from 'devextreme/ui/pivot_grid/data_source'
|
||||||
import { MULTIVALUE_DELIMITER } from '../../constants/app.constant'
|
import { MULTIVALUE_DELIMITER } from '../../constants/app.constant'
|
||||||
import { ChartSeriesDto } from '@/proxy/admin/charts/models'
|
import { ChartSeriesDto } from '@/proxy/admin/charts/models'
|
||||||
import type { GridDto } from '@/proxy/form/models'
|
|
||||||
|
|
||||||
/** EditingFormDto gruplarını ColumnFormatDto alanlarıyla DevExtreme için birleştirir. */
|
|
||||||
export const getEditingFormFields = (gridDto: GridDto) =>
|
|
||||||
gridDto.columnFormats
|
|
||||||
.filter((field) => field.editOrderNo != null && field.fieldName)
|
|
||||||
.sort((left, right) => left.editOrderNo! - right.editOrderNo!)
|
|
||||||
|
|
||||||
export const getEditingFormGroups = (gridDto: GridDto) => {
|
|
||||||
const fields = getEditingFormFields(gridDto)
|
|
||||||
|
|
||||||
return [...(gridDto.gridOptions.editingFormDto ?? [])]
|
|
||||||
.sort((left, right) => left.order - right.order)
|
|
||||||
.map((group) => ({
|
|
||||||
...group,
|
|
||||||
items: fields.filter((field) => (field.editGroupOrderNo ?? 1) === group.order),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GridExtraFilterState {
|
export interface GridExtraFilterState {
|
||||||
fieldName: string
|
fieldName: string
|
||||||
|
|
@ -149,15 +131,19 @@ export function pivotFieldConvertDataType(fieldDbType?: DataType): PivotGridData
|
||||||
|
|
||||||
export function setGridPanelColor(color: any) {
|
export function setGridPanelColor(color: any) {
|
||||||
//DataGrid icin
|
//DataGrid icin
|
||||||
const pnlGrid = document.querySelector<HTMLElement>('.dx-datagrid-header-panel')
|
const pnlGrid = document.getElementsByClassName(
|
||||||
if (pnlGrid) {
|
'dx-datagrid-header-panel',
|
||||||
pnlGrid.style.borderBottom = `3px solid ${color}`
|
) as HTMLCollectionOf<HTMLElement>
|
||||||
|
if (pnlGrid?.length) {
|
||||||
|
pnlGrid[0].style.borderBottom = `3px solid ${color}`
|
||||||
}
|
}
|
||||||
|
|
||||||
//TreeList icin
|
//TreeList icin
|
||||||
const pnlTree = document.querySelector<HTMLElement>('.dx-treelist-header-panel')
|
const pnlTree = document.getElementsByClassName(
|
||||||
if (pnlTree) {
|
'dx-treelist-header-panel',
|
||||||
pnlTree.style.borderBottom = `3px solid ${color}`
|
) as HTMLCollectionOf<HTMLElement>
|
||||||
|
if (pnlTree?.length) {
|
||||||
|
pnlTree[0].style.borderBottom = `3px solid ${color}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,13 @@ import { dynamicFetch } from '@/services/form.service'
|
||||||
import { GridColumnData } from './GridColumnData'
|
import { GridColumnData } from './GridColumnData'
|
||||||
import {
|
import {
|
||||||
ColumnFormatDto,
|
ColumnFormatDto,
|
||||||
|
EditingFormItemDto,
|
||||||
GridDto,
|
GridDto,
|
||||||
PlatformEditorTypes,
|
PlatformEditorTypes,
|
||||||
UiCommandButtonPositionTypeEnum,
|
UiCommandButtonPositionTypeEnum,
|
||||||
UiLookupDataSourceTypeEnum,
|
UiLookupDataSourceTypeEnum,
|
||||||
} from '@/proxy/form/models'
|
} from '@/proxy/form/models'
|
||||||
import { addCss, getEditingFormFields } from './Utils'
|
import { addCss } from './Utils'
|
||||||
|
|
||||||
const NO_IMAGE = '/img/others/no-image.png'
|
const NO_IMAGE = '/img/others/no-image.png'
|
||||||
|
|
||||||
|
|
@ -922,18 +923,15 @@ const useListFormColumns = ({
|
||||||
|
|
||||||
column.allowEditing = colData?.allowEditing || colData?.allowAdding
|
column.allowEditing = colData?.allowEditing || colData?.allowAdding
|
||||||
|
|
||||||
if (colData.editorType2 === 'dxHtmlEditor') {
|
|
||||||
column.encodeHtml = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// #region lookup ayarlari
|
// #region lookup ayarlari
|
||||||
if (colData.lookupDto?.dataSourceType) {
|
if (colData.lookupDto?.dataSourceType) {
|
||||||
// UiColumnEditorTemplateTypeEnum : None:0, Table:1, TagBox:2
|
// UiColumnEditorTemplateTypeEnum : None:0, Table:1, TagBox:2
|
||||||
const formItem = colData.editOrderNo != null ? colData : undefined
|
const allItems = gridDto.gridOptions.editingFormDto.flatMap((group) => group.items)
|
||||||
|
const formItem = allItems.find((a) => a?.dataField === colData.fieldName)
|
||||||
if (formItem?.editorType2 === PlatformEditorTypes.dxTagBox) {
|
if (formItem?.editorType2 === PlatformEditorTypes.dxTagBox) {
|
||||||
column.extras = {
|
column.extras = {
|
||||||
multiValue: true,
|
multiValue: true,
|
||||||
editorOptions,
|
editorOptions: formItem.editorOptions,
|
||||||
tagBoxOptions: formItem.tagBoxOptions,
|
tagBoxOptions: formItem.tagBoxOptions,
|
||||||
}
|
}
|
||||||
column.editCellTemplate = 'cellEditTagBox'
|
column.editCellTemplate = 'cellEditTagBox'
|
||||||
|
|
@ -942,7 +940,7 @@ const useListFormColumns = ({
|
||||||
} else if (formItem?.editorType2 === PlatformEditorTypes.dxGridBox) {
|
} else if (formItem?.editorType2 === PlatformEditorTypes.dxGridBox) {
|
||||||
column.extras = {
|
column.extras = {
|
||||||
multiValue: false,
|
multiValue: false,
|
||||||
editorOptions,
|
editorOptions: formItem.editorOptions,
|
||||||
gridBoxOptions: formItem.gridBoxOptions,
|
gridBoxOptions: formItem.gridBoxOptions,
|
||||||
}
|
}
|
||||||
column.editCellTemplate = 'cellEditGridBox'
|
column.editCellTemplate = 'cellEditGridBox'
|
||||||
|
|
@ -978,7 +976,8 @@ const useListFormColumns = ({
|
||||||
|
|
||||||
// #region image upload editor
|
// #region image upload editor
|
||||||
if (!colData.lookupDto?.dataSourceType) {
|
if (!colData.lookupDto?.dataSourceType) {
|
||||||
const imageFormItem = colData.editOrderNo != null ? colData : undefined
|
const allFormItems = gridDto.gridOptions.editingFormDto.flatMap((group) => group.items)
|
||||||
|
const imageFormItem = allFormItems.find((a) => a?.dataField === colData.fieldName)
|
||||||
const isImageUploadEditor =
|
const isImageUploadEditor =
|
||||||
imageFormItem?.editorType2 === PlatformEditorTypes.dxImageUpload
|
imageFormItem?.editorType2 === PlatformEditorTypes.dxImageUpload
|
||||||
const isImageViewerEditor =
|
const isImageViewerEditor =
|
||||||
|
|
@ -1007,7 +1006,7 @@ const useListFormColumns = ({
|
||||||
}
|
}
|
||||||
column.extras = {
|
column.extras = {
|
||||||
multiValue: imageUploadOptions?.multiple ?? false,
|
multiValue: imageUploadOptions?.multiple ?? false,
|
||||||
editorOptions,
|
editorOptions: imageFormItem?.editorOptions ?? colData.editorOptions,
|
||||||
imageUploadOptions: imageUploadOptions,
|
imageUploadOptions: imageUploadOptions,
|
||||||
}
|
}
|
||||||
if (isImageUploadEditor) {
|
if (isImageUploadEditor) {
|
||||||
|
|
@ -1092,19 +1091,25 @@ const useListFormColumns = ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Formda kullanılan fakat listede görünmeyen ColumnFormatDto alanlarını
|
// FormEditingExtraItem
|
||||||
// DevExtreme'in düzenleme modeline gizli kolon olarak ekliyoruz.
|
// Devexpress Gridde kaydete basılınca
|
||||||
|
// formda gözükecek olan EditingFormDto.Items elemanları gelmiyor
|
||||||
|
// Sadece grid'de tanımlanmış columnları getiriyor.
|
||||||
|
// Bu elemanları da getirmesi için aşağıdaki şekilde,
|
||||||
|
// columns'da olmayan alanları da gizli olarak ekliyoruz
|
||||||
if (columns?.length) {
|
if (columns?.length) {
|
||||||
getEditingFormFields(gridDto).forEach((item: ColumnFormatDto) => {
|
gridDto.gridOptions.editingFormDto.forEach((group) => {
|
||||||
if (!columns.some((a) => a.dataField === item.fieldName)) {
|
group.items?.forEach((item: EditingFormItemDto) => {
|
||||||
columns.push({
|
if (!columns.some((a) => a.dataField === item.dataField)) {
|
||||||
dataField: item.fieldName,
|
columns.push({
|
||||||
visible: false,
|
dataField: item.dataField,
|
||||||
showInColumnChooser: false,
|
visible: false,
|
||||||
allowSearch: false,
|
showInColumnChooser: false,
|
||||||
})
|
allowSearch: false
|
||||||
insertedColumns.push(item.fieldName)
|
})
|
||||||
}
|
insertedColumns.push(item.dataField)
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue