Gantt düzenlemesi
This commit is contained in:
parent
3e588fb98b
commit
7cf448ec13
19 changed files with 798 additions and 337 deletions
|
|
@ -38,5 +38,25 @@ public class TreeOptionDto
|
||||||
/// Alt kayıtlar seçildiğinde parent kayıtları da seç (recursive selection)
|
/// Alt kayıtlar seçildiğinde parent kayıtları da seç (recursive selection)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool RecursiveSelection { get; set; } = false;
|
public bool RecursiveSelection { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Başlık alanı (örn: "Title")
|
||||||
|
/// </summary>
|
||||||
|
public string TitleExpr { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Başlangıç Tarihi ifadesi (örn: "0001-01-01")
|
||||||
|
/// </summary>
|
||||||
|
public string StartExpr { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Bitiş Tarihi ifadesi (örn: "9999-12-31")
|
||||||
|
/// </summary>
|
||||||
|
public string EndExpr { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// İlerleme ifadesi (örn: "%50")
|
||||||
|
/// </summary>
|
||||||
|
public string ProgressExpr { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4561,6 +4561,30 @@
|
||||||
"en": "Parent Field Name",
|
"en": "Parent Field Name",
|
||||||
"tr": "Üst Kimlik İfadesi"
|
"tr": "Üst Kimlik İfadesi"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormEdit.TitleExpr",
|
||||||
|
"en": "Title Field Name",
|
||||||
|
"tr": "Başlık Alanı Adı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormEdit.StartExpr",
|
||||||
|
"en": "Start Field Name",
|
||||||
|
"tr": "Başlangıç Alanı Adı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormEdit.EndExpr",
|
||||||
|
"en": "End Field Name",
|
||||||
|
"tr": "Bitiş Alanı Adı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "ListForms.ListFormEdit.ProgressExpr",
|
||||||
|
"en": "Progress Field Name",
|
||||||
|
"tr": "İlerleme Alanı Adı"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormEdit.RootValue",
|
"key": "ListForms.ListFormEdit.RootValue",
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
||||||
var listForm = await _listFormRepository.InsertAsync(
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
new ListForm()
|
new ListForm()
|
||||||
{
|
{
|
||||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
ListFormType = ListFormTypeEnum.List,
|
||||||
|
ExportJson = DefaultExportJson,
|
||||||
IsSubForm = false,
|
IsSubForm = false,
|
||||||
ShowNote = true,
|
ShowNote = true,
|
||||||
LayoutJson = DefaultLayoutJson,
|
LayoutJson = DefaultLayoutJson,
|
||||||
|
|
@ -176,7 +177,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
||||||
var listForm = await _listFormRepository.InsertAsync(
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
new ListForm()
|
new ListForm()
|
||||||
{
|
{
|
||||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
ListFormType = ListFormTypeEnum.List,
|
||||||
|
ExportJson = DefaultExportJson,
|
||||||
IsSubForm = false,
|
IsSubForm = false,
|
||||||
ShowNote = true,
|
ShowNote = true,
|
||||||
LayoutJson = DefaultLayoutJson,
|
LayoutJson = DefaultLayoutJson,
|
||||||
|
|
@ -299,7 +301,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
||||||
var listForm = await _listFormRepository.InsertAsync(
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
new ListForm()
|
new ListForm()
|
||||||
{
|
{
|
||||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
ListFormType = ListFormTypeEnum.List,
|
||||||
|
ExportJson = DefaultExportJson,
|
||||||
IsSubForm = false,
|
IsSubForm = false,
|
||||||
ShowNote = true,
|
ShowNote = true,
|
||||||
LayoutJson = DefaultLayoutJson,
|
LayoutJson = DefaultLayoutJson,
|
||||||
|
|
@ -422,7 +425,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
||||||
var listForm = await _listFormRepository.InsertAsync(
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
new ListForm()
|
new ListForm()
|
||||||
{
|
{
|
||||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
ListFormType = ListFormTypeEnum.List,
|
||||||
|
ExportJson = DefaultExportJson,
|
||||||
IsSubForm = false,
|
IsSubForm = false,
|
||||||
ShowNote = true,
|
ShowNote = true,
|
||||||
LayoutJson = DefaultLayoutJson,
|
LayoutJson = DefaultLayoutJson,
|
||||||
|
|
@ -545,7 +549,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
||||||
var listForm = await _listFormRepository.InsertAsync(
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
new ListForm()
|
new ListForm()
|
||||||
{
|
{
|
||||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
ListFormType = ListFormTypeEnum.List,
|
||||||
|
ExportJson = DefaultExportJson,
|
||||||
IsSubForm = false,
|
IsSubForm = false,
|
||||||
ShowNote = true,
|
ShowNote = true,
|
||||||
LayoutJson = DefaultLayoutJson,
|
LayoutJson = DefaultLayoutJson,
|
||||||
|
|
@ -668,7 +673,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
||||||
var listForm = await _listFormRepository.InsertAsync(
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
new ListForm()
|
new ListForm()
|
||||||
{
|
{
|
||||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
ListFormType = ListFormTypeEnum.List,
|
||||||
|
ExportJson = DefaultExportJson,
|
||||||
IsSubForm = false,
|
IsSubForm = false,
|
||||||
ShowNote = true,
|
ShowNote = true,
|
||||||
LayoutJson = DefaultLayoutJson,
|
LayoutJson = DefaultLayoutJson,
|
||||||
|
|
@ -791,7 +797,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
||||||
var listForm = await _listFormRepository.InsertAsync(
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
new ListForm()
|
new ListForm()
|
||||||
{
|
{
|
||||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
ListFormType = ListFormTypeEnum.List,
|
||||||
|
ExportJson = DefaultExportJson,
|
||||||
IsSubForm = false,
|
IsSubForm = false,
|
||||||
ShowNote = true,
|
ShowNote = true,
|
||||||
LayoutJson = DefaultLayoutJson,
|
LayoutJson = DefaultLayoutJson,
|
||||||
|
|
@ -1199,7 +1206,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
||||||
var listForm = await _listFormRepository.InsertAsync(
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
new ListForm()
|
new ListForm()
|
||||||
{
|
{
|
||||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
ListFormType = ListFormTypeEnum.List,
|
||||||
|
ExportJson = DefaultExportJson,
|
||||||
IsSubForm = true,
|
IsSubForm = true,
|
||||||
ShowNote = true,
|
ShowNote = true,
|
||||||
LayoutJson = DefaultLayoutJson,
|
LayoutJson = DefaultLayoutJson,
|
||||||
|
|
@ -1286,7 +1294,7 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
||||||
var listForm = await _listFormRepository.InsertAsync(
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
new ListForm()
|
new ListForm()
|
||||||
{
|
{
|
||||||
ListFormType = ListFormTypeEnum.Tree,
|
ListFormType = ListFormTypeEnum.List,
|
||||||
IsSubForm = true,
|
IsSubForm = true,
|
||||||
ShowNote = true,
|
ShowNote = true,
|
||||||
LayoutJson = DefaultLayoutJson,
|
LayoutJson = DefaultLayoutJson,
|
||||||
|
|
@ -1422,7 +1430,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
||||||
var listForm = await _listFormRepository.InsertAsync(
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
new ListForm()
|
new ListForm()
|
||||||
{
|
{
|
||||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
ListFormType = ListFormTypeEnum.List,
|
||||||
|
ExportJson = DefaultExportJson,
|
||||||
IsSubForm = false,
|
IsSubForm = false,
|
||||||
ShowNote = true,
|
ShowNote = true,
|
||||||
LayoutJson = DefaultLayoutJson,
|
LayoutJson = DefaultLayoutJson,
|
||||||
|
|
@ -1774,7 +1783,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
||||||
var listForm = await _listFormRepository.InsertAsync(
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
new ListForm()
|
new ListForm()
|
||||||
{
|
{
|
||||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
ListFormType = ListFormTypeEnum.List,
|
||||||
|
ExportJson = DefaultExportJson,
|
||||||
IsSubForm = false,
|
IsSubForm = false,
|
||||||
ShowNote = true,
|
ShowNote = true,
|
||||||
LayoutJson = DefaultLayoutJson,
|
LayoutJson = DefaultLayoutJson,
|
||||||
|
|
@ -2059,6 +2069,196 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Project Task Workload
|
||||||
|
listFormName = AppCodes.Project.Workload;
|
||||||
|
if (!await _listFormRepository.AnyAsync(a => a.ListFormCode == listFormName))
|
||||||
|
{
|
||||||
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
|
new ListForm()
|
||||||
|
{
|
||||||
|
ListFormType = ListFormTypeEnum.List,
|
||||||
|
ExportJson = DefaultExportJson,
|
||||||
|
IsSubForm = false,
|
||||||
|
ShowNote = true,
|
||||||
|
LayoutJson = DefaultLayoutJson,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
ListFormCode = listFormName,
|
||||||
|
Name = listFormName,
|
||||||
|
Title = listFormName,
|
||||||
|
DataSourceCode = SeedConsts.DataSources.DefaultCode,
|
||||||
|
IsTenant = true,
|
||||||
|
IsBranch = false,
|
||||||
|
IsOrganizationUnit = false,
|
||||||
|
Description = listFormName,
|
||||||
|
SelectCommandType = SelectCommandTypeEnum.Table,
|
||||||
|
SelectCommand = TableNameResolver.GetFullViewName(nameof(TableNameEnum.ProjectTask)),
|
||||||
|
KeyFieldName = "Id",
|
||||||
|
KeyFieldDbSourceType = DbType.Guid,
|
||||||
|
DefaultFilter = DefaultFilterJson,
|
||||||
|
SortMode = GridOptions.SortModeSingle,
|
||||||
|
FilterRowJson = DefaultFilterRowJson,
|
||||||
|
HeaderFilterJson = DefaultHeaderFilterJson,
|
||||||
|
SearchPanelJson = DefaultSearchPanelJson,
|
||||||
|
GroupPanelJson = DefaultGroupPanelJson,
|
||||||
|
SelectionJson = DefaultSelectionSingleJson,
|
||||||
|
ColumnOptionJson = DefaultColumnOptionJson,
|
||||||
|
PermissionJson = DefaultPermissionJson(listFormName),
|
||||||
|
TreeOptionJson = JsonSerializer.Serialize(new TreeOptionDto
|
||||||
|
{
|
||||||
|
KeyExpr = "Id",
|
||||||
|
ParentIdExpr = "ParentId",
|
||||||
|
RootValue = null,
|
||||||
|
AutoExpandAll = true,
|
||||||
|
TitleExpr = "Name",
|
||||||
|
StartExpr = "StartDate",
|
||||||
|
EndExpr = "EndDate",
|
||||||
|
ProgressExpr = "Progress"
|
||||||
|
}),
|
||||||
|
DeleteCommand = DefaultDeleteCommand(nameof(TableNameEnum.ProjectTask)),
|
||||||
|
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson,
|
||||||
|
PagerOptionJson = DefaultPagerOptionJson,
|
||||||
|
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 400, true, true, true, true, false),
|
||||||
|
InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson,
|
||||||
|
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>()
|
||||||
|
{
|
||||||
|
new() {
|
||||||
|
Order=1, ColCount=2, ColSpan=1, ItemType="group", Items =[
|
||||||
|
new EditingFormItemDto { Order = 1, DataField="Name", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxTextBox },
|
||||||
|
new EditingFormItemDto { Order = 2, DataField="Description", ColSpan = 2, EditorType2 = EditorTypes.dxTextArea },
|
||||||
|
new EditingFormItemDto { Order = 3, DataField="StartDate", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxDateBox, EditorOptions = EditorOptionValues.DateTimeFormat },
|
||||||
|
new EditingFormItemDto { Order = 4, DataField="EndDate", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxDateBox, EditorOptions = EditorOptionValues.DateTimeFormat },
|
||||||
|
]}
|
||||||
|
}),
|
||||||
|
}, autoSave: true
|
||||||
|
);
|
||||||
|
|
||||||
|
#region Project Task Workload Fields
|
||||||
|
await _listFormFieldRepository.InsertManyAsync([
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Guid,
|
||||||
|
FieldName = "Id",
|
||||||
|
Width = 100,
|
||||||
|
ListOrderNo = 1,
|
||||||
|
Visible = false,
|
||||||
|
IsActive = true,
|
||||||
|
IsDeleted = false,
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Guid,
|
||||||
|
FieldName = "ParentId",
|
||||||
|
Width = 200,
|
||||||
|
ListOrderNo = 2,
|
||||||
|
Visible = false,
|
||||||
|
IsActive = true,
|
||||||
|
IsDeleted = false,
|
||||||
|
AllowSearch = true,
|
||||||
|
LookupJson = JsonSerializer.Serialize(new LookupDto
|
||||||
|
{
|
||||||
|
DataSourceType = UiLookupDataSourceTypeEnum.Query,
|
||||||
|
DisplayExpr = "Name",
|
||||||
|
ValueExpr = "Key",
|
||||||
|
LookupQuery = LookupQueryValues.DefaultLookupQuery(nameof(TableNameEnum.Projects), "Id", "Name"),
|
||||||
|
CascadeEmptyFields = "PhaseId"
|
||||||
|
}),
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.String,
|
||||||
|
FieldName = "Name",
|
||||||
|
Width = 200,
|
||||||
|
ListOrderNo = 3,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
IsDeleted = false,
|
||||||
|
AllowSearch = true,
|
||||||
|
SortIndex = 1,
|
||||||
|
SortDirection = GridColumnOptions.SortOrderAsc,
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.String,
|
||||||
|
FieldName = "Description",
|
||||||
|
Width = 400,
|
||||||
|
ListOrderNo = 4,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
IsDeleted = false,
|
||||||
|
AllowSearch = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.DateTime,
|
||||||
|
FieldName = "StartDate",
|
||||||
|
Width = 150,
|
||||||
|
ListOrderNo = 5,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
IsDeleted = false,
|
||||||
|
AllowSearch = true,
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.DateTime,
|
||||||
|
FieldName = "EndDate",
|
||||||
|
Width = 150,
|
||||||
|
ListOrderNo = 6,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
IsDeleted = false,
|
||||||
|
AllowSearch = true,
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Decimal,
|
||||||
|
FieldName = "Progress",
|
||||||
|
Width = 100,
|
||||||
|
ListOrderNo = 7,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
IsDeleted = false,
|
||||||
|
AllowSearch = true,
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Project Task Daily
|
#region Project Task Daily
|
||||||
listFormName = AppCodes.Project.ProjectTaskDaily;
|
listFormName = AppCodes.Project.ProjectTaskDaily;
|
||||||
if (!await _listFormRepository.AnyAsync(a => a.ListFormCode == listFormName))
|
if (!await _listFormRepository.AnyAsync(a => a.ListFormCode == listFormName))
|
||||||
|
|
@ -2066,7 +2266,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
||||||
var listForm = await _listFormRepository.InsertAsync(
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
new ListForm()
|
new ListForm()
|
||||||
{
|
{
|
||||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
ListFormType = ListFormTypeEnum.List,
|
||||||
|
ExportJson = DefaultExportJson,
|
||||||
IsSubForm = false,
|
IsSubForm = false,
|
||||||
ShowNote = true,
|
ShowNote = true,
|
||||||
LayoutJson = DefaultLayoutJson,
|
LayoutJson = DefaultLayoutJson,
|
||||||
|
|
|
||||||
|
|
@ -2558,7 +2558,6 @@
|
||||||
"RequiredPermissionName": null,
|
"RequiredPermissionName": null,
|
||||||
"IsDisabled": false
|
"IsDisabled": false
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"ParentCode": "App.Store.Definitions",
|
"ParentCode": "App.Store.Definitions",
|
||||||
"Code": "App.Store.WarehouseType",
|
"Code": "App.Store.WarehouseType",
|
||||||
|
|
@ -2804,7 +2803,7 @@
|
||||||
"Code": "App.Project.Workload",
|
"Code": "App.Project.Workload",
|
||||||
"DisplayName": "App.Project.Workload",
|
"DisplayName": "App.Project.Workload",
|
||||||
"Order": 7,
|
"Order": 7,
|
||||||
"Url": "/admin/projects/workload",
|
"Url": "/admin/list/App.Project.Workload",
|
||||||
"Icon": "FcComboChart",
|
"Icon": "FcComboChart",
|
||||||
"RequiredPermissionName": "App.Project.Workload",
|
"RequiredPermissionName": "App.Project.Workload",
|
||||||
"IsDisabled": false
|
"IsDisabled": false
|
||||||
|
|
|
||||||
|
|
@ -5557,7 +5557,6 @@
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"GroupName": "App.SupplyChain",
|
"GroupName": "App.SupplyChain",
|
||||||
"Name": "App.SupplyChain.SupplyType",
|
"Name": "App.SupplyChain.SupplyType",
|
||||||
|
|
@ -5999,7 +5998,6 @@
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"GroupName": "App.SupplyChain",
|
"GroupName": "App.SupplyChain",
|
||||||
"Name": "App.SupplyChain.QuotationStatus",
|
"Name": "App.SupplyChain.QuotationStatus",
|
||||||
|
|
@ -6423,7 +6421,6 @@
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"GroupName": "App.SupplyChain",
|
"GroupName": "App.SupplyChain",
|
||||||
"Name": "App.SupplyChain.QuotationItem",
|
"Name": "App.SupplyChain.QuotationItem",
|
||||||
|
|
@ -6487,7 +6484,6 @@
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"MenuGroup": "Erp"
|
"MenuGroup": "Erp"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"GroupName": "App.SupplyChain",
|
"GroupName": "App.SupplyChain",
|
||||||
"Name": "App.SupplyChain.Approval",
|
"Name": "App.SupplyChain.Approval",
|
||||||
|
|
|
||||||
|
|
@ -92,11 +92,11 @@ public static class SeederDefaults
|
||||||
Mode = GridOptions.SelectionModeMultiple,
|
Mode = GridOptions.SelectionModeMultiple,
|
||||||
SelectAllMode = GridOptions.SelectionAllModeAllPages
|
SelectAllMode = GridOptions.SelectionAllModeAllPages
|
||||||
});
|
});
|
||||||
public static string DefaultTreeOptionJson(string KeyExpr, string ParentIdExpr, bool AutoExpandAll = true) => JsonSerializer.Serialize(new TreeOptionDto
|
public static string DefaultTreeOptionJson(string KeyExpr, string ParentIdExpr, bool AutoExpandAll = true, object RootValue = null) => JsonSerializer.Serialize(new TreeOptionDto
|
||||||
{
|
{
|
||||||
KeyExpr = KeyExpr,
|
KeyExpr = KeyExpr,
|
||||||
ParentIdExpr = ParentIdExpr,
|
ParentIdExpr = ParentIdExpr,
|
||||||
RootValue = null,
|
RootValue = RootValue,
|
||||||
AutoExpandAll = AutoExpandAll
|
AutoExpandAll = AutoExpandAll
|
||||||
});
|
});
|
||||||
public static readonly string DefaultPagerOptionJson = JsonSerializer.Serialize(new GridPagerOptionDto
|
public static readonly string DefaultPagerOptionJson = JsonSerializer.Serialize(new GridPagerOptionDto
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,5 @@ public static class ListFormTypeEnum
|
||||||
public const string List = "List";
|
public const string List = "List";
|
||||||
public const string Form = "Form";
|
public const string Form = "Form";
|
||||||
public const string Chart = "Chart";
|
public const string Chart = "Chart";
|
||||||
public const string Pivot = "Pivot";
|
|
||||||
public const string Tree = "Tree";
|
|
||||||
public const string Gantt = "Gantt";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -587,6 +587,7 @@ public static class SeedConsts
|
||||||
public const string ProjectRisk = Default + ".ProjectRisk";
|
public const string ProjectRisk = Default + ".ProjectRisk";
|
||||||
public const string ProjectTeam = Default + ".ProjectTeam";
|
public const string ProjectTeam = Default + ".ProjectTeam";
|
||||||
public const string ProjectTask = Default + ".ProjectTask";
|
public const string ProjectTask = Default + ".ProjectTask";
|
||||||
|
public const string Workload = Default + ".Workload";
|
||||||
public const string ProjectTaskDaily = Default + ".ProjectTaskDaily";
|
public const string ProjectTaskDaily = Default + ".ProjectTaskDaily";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ public class DatabaseViewSeeder : IDataSeedContributor, ITransientDependency
|
||||||
|
|
||||||
await CreateOrUpdateMaterialGroupView(dbContext, nameof(TableNameEnum.MaterialGroup));
|
await CreateOrUpdateMaterialGroupView(dbContext, nameof(TableNameEnum.MaterialGroup));
|
||||||
|
|
||||||
|
await CreateOrUpdateProjectTaskView(dbContext, nameof(TableNameEnum.ProjectTask));
|
||||||
|
|
||||||
_logger.LogInformation("Database view seeding completed successfully.");
|
_logger.LogInformation("Database view seeding completed successfully.");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -102,5 +104,75 @@ public class DatabaseViewSeeder : IDataSeedContributor, ITransientDependency
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates or updates the V_T_Scp_ProjectWorkload view
|
||||||
|
/// </summary>
|
||||||
|
private async Task CreateOrUpdateProjectTaskView(PlatformDbContext dbContext, string viewName)
|
||||||
|
{
|
||||||
|
string fullViewName = TableNameResolver.GetFullViewName(viewName);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var createViewSql = $@"
|
||||||
|
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[{fullViewName}]'))
|
||||||
|
DROP VIEW [dbo].[{fullViewName}];
|
||||||
|
|
||||||
|
EXEC('
|
||||||
|
CREATE VIEW [dbo].[{fullViewName}]
|
||||||
|
AS
|
||||||
|
SELECT
|
||||||
|
TenantId,
|
||||||
|
Id,
|
||||||
|
NULL AS ParentId,
|
||||||
|
[Name],
|
||||||
|
[Description],
|
||||||
|
[StartDate],
|
||||||
|
[EndDate],
|
||||||
|
[IsDeleted],
|
||||||
|
[Progress]
|
||||||
|
FROM [Erp].[dbo].[Prj_T_Projects]
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
TenantId,
|
||||||
|
Id,
|
||||||
|
ProjectId AS ParentId,
|
||||||
|
[Name],
|
||||||
|
[Description],
|
||||||
|
[StartDate],
|
||||||
|
[EndDate],
|
||||||
|
[IsDeleted],
|
||||||
|
100 AS [Progress]
|
||||||
|
FROM [Erp].[dbo].[Prj_T_ProjectPhase]
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
TenantId,
|
||||||
|
Id,
|
||||||
|
PhaseId AS ParentId,
|
||||||
|
[Name],
|
||||||
|
[Description],
|
||||||
|
[StartDate],
|
||||||
|
[EndDate],
|
||||||
|
[IsDeleted],
|
||||||
|
[Progress]
|
||||||
|
FROM [Erp].[dbo].[Prj_T_ProjectTask]
|
||||||
|
')
|
||||||
|
";
|
||||||
|
|
||||||
|
await dbContext.Database.ExecuteSqlRawAsync(createViewSql);
|
||||||
|
|
||||||
|
_logger.LogInformation($"Created/Updated {fullViewName} view successfully.");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, $"Error occurred while creating {fullViewName} view.");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
8
ui/public/css/gantt/dx-gantt.min.css
vendored
Normal file
8
ui/public/css/gantt/dx-gantt.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
39
ui/public/css/gantt/dx-gantt.min.js
vendored
Normal file
39
ui/public/css/gantt/dx-gantt.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { Gantt } from 'devextreme-react'
|
||||||
|
|
||||||
export const extraFilterControlTypeOptions = [
|
export const extraFilterControlTypeOptions = [
|
||||||
{ value: 'Select', label: 'Select' },
|
{ value: 'Select', label: 'Select' },
|
||||||
{ value: 'TextBox', label: 'TextBox' },
|
{ value: 'TextBox', label: 'TextBox' },
|
||||||
|
|
|
||||||
|
|
@ -386,6 +386,10 @@ export interface TreeOptionDto {
|
||||||
expandedRowKeys?: any[]
|
expandedRowKeys?: any[]
|
||||||
autoExpandAll?: boolean
|
autoExpandAll?: boolean
|
||||||
recursiveSelection?: boolean
|
recursiveSelection?: boolean
|
||||||
|
titleExpr?: string
|
||||||
|
startExpr?: string
|
||||||
|
endExpr?: string
|
||||||
|
progressExpr?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GridEditingDto {
|
export interface GridEditingDto {
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ import FormTabWidgets from './FormTabWidgets'
|
||||||
import FormTabExtraFilters from './FormTabExtraFilters'
|
import FormTabExtraFilters from './FormTabExtraFilters'
|
||||||
import FormTabEditForm from './FormTabEditForm'
|
import FormTabEditForm from './FormTabEditForm'
|
||||||
import FormTabPivots from './FormTabPivots'
|
import FormTabPivots from './FormTabPivots'
|
||||||
import FormTabTree from './FormTabTree'
|
import FormTabTreeGantt from './FormTabTreeGantt'
|
||||||
import ChartTabAnimation from './ChartTabAnimation'
|
import ChartTabAnimation from './ChartTabAnimation'
|
||||||
import ChartTabAnnotations from './ChartTabAnnotations'
|
import ChartTabAnnotations from './ChartTabAnnotations'
|
||||||
import ChartTabZoomAndPan from './ChartTabZoomAndPan'
|
import ChartTabZoomAndPan from './ChartTabZoomAndPan'
|
||||||
|
|
@ -360,7 +360,7 @@ const FormEdit = () => {
|
||||||
<FormTabPivots onSubmit={onSubmit} />
|
<FormTabPivots onSubmit={onSubmit} />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="tree" className="px-2">
|
<TabContent value="tree" className="px-2">
|
||||||
<FormTabTree onSubmit={onSubmit} />
|
<FormTabTreeGantt onSubmit={onSubmit} />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value="pager" className="px-2">
|
<TabContent value="pager" className="px-2">
|
||||||
<FormTabPager onSubmit={onSubmit} />
|
<FormTabPager onSubmit={onSubmit} />
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ const schema = Yup.object().shape({
|
||||||
pivot: Yup.boolean(),
|
pivot: Yup.boolean(),
|
||||||
chart: Yup.boolean(),
|
chart: Yup.boolean(),
|
||||||
tree: Yup.boolean(),
|
tree: Yup.boolean(),
|
||||||
|
gantt: Yup.boolean(),
|
||||||
defaultLayout: Yup.string(),
|
defaultLayout: Yup.string(),
|
||||||
cardLayoutColumn: Yup.number(),
|
cardLayoutColumn: Yup.number(),
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -1,203 +0,0 @@
|
||||||
import { Container } from '@/components/shared'
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Notification,
|
|
||||||
Checkbox,
|
|
||||||
FormContainer,
|
|
||||||
FormItem,
|
|
||||||
Input,
|
|
||||||
Select,
|
|
||||||
toast,
|
|
||||||
} from '@/components/ui'
|
|
||||||
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
|
||||||
import { useStoreState } from '@/store'
|
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
|
||||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
|
||||||
import * as Yup from 'yup'
|
|
||||||
import { FormEditProps } from './FormEdit'
|
|
||||||
import { SelectBoxOption } from '@/types/shared'
|
|
||||||
import { useEffect, useState } from 'react'
|
|
||||||
import { getListFormFields } from '@/services/admin/list-form-field.service'
|
|
||||||
import { groupBy } from 'lodash'
|
|
||||||
import { useParams } from 'react-router-dom'
|
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({})
|
|
||||||
|
|
||||||
function FormTabTree(props: FormEditProps) {
|
|
||||||
const { listFormCode } = useParams()
|
|
||||||
const { translate } = useLocalization()
|
|
||||||
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
|
|
||||||
|
|
||||||
const getFields = async () => {
|
|
||||||
if (!listFormCode) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const resp = await getListFormFields({
|
|
||||||
listFormCode,
|
|
||||||
sorting: 'ListOrderNo',
|
|
||||||
maxResultCount: 1000,
|
|
||||||
})
|
|
||||||
if (resp.data?.items) {
|
|
||||||
const fieldNames = groupBy(resp?.data?.items, 'fieldName')
|
|
||||||
setFieldList(
|
|
||||||
Object.keys(fieldNames).map((a) => ({
|
|
||||||
value: a,
|
|
||||||
label: a,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
toast.push(
|
|
||||||
<Notification type="danger" duration={2000}>
|
|
||||||
Alanlar getirilemedi
|
|
||||||
{error.toString()}
|
|
||||||
</Notification>,
|
|
||||||
{
|
|
||||||
placement: 'top-end',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getFields()
|
|
||||||
}, [listFormCode])
|
|
||||||
|
|
||||||
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
|
||||||
if (!listFormValues) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Container className="grid xl:grid-cols-2">
|
|
||||||
<Formik
|
|
||||||
initialValues={listFormValues}
|
|
||||||
validationSchema={validationSchema}
|
|
||||||
onSubmit={async (values, formikHelpers) => {
|
|
||||||
await props.onSubmit(ListFormEditTabs.TreeForm, values, formikHelpers)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{({ touched, errors, isSubmitting, values }) => (
|
|
||||||
<Form>
|
|
||||||
<FormContainer size="sm">
|
|
||||||
<FormItem
|
|
||||||
label={translate('::ListForms.ListFormEdit.DatabaseDataSourceKeyFieldName')}
|
|
||||||
invalid={errors.treeOptionDto?.keyExpr && touched.treeOptionDto?.keyExpr}
|
|
||||||
errorMessage={errors.treeOptionDto?.keyExpr}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
type="text"
|
|
||||||
name="treeOptionDto.keyExpr"
|
|
||||||
placeholder={translate('::ListForms.ListFormEdit.DatabaseDataSourceKeyFieldName')}
|
|
||||||
>
|
|
||||||
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
|
||||||
<Select
|
|
||||||
field={field}
|
|
||||||
form={form}
|
|
||||||
isClearable={true}
|
|
||||||
options={fieldList}
|
|
||||||
value={fieldList?.filter(
|
|
||||||
(option) => option.value === values.treeOptionDto.keyExpr,
|
|
||||||
)}
|
|
||||||
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Field>
|
|
||||||
</FormItem>
|
|
||||||
|
|
||||||
<FormItem
|
|
||||||
label={translate('::ListForms.ListFormEdit.ParentIdExpr')}
|
|
||||||
invalid={errors.treeOptionDto?.parentIdExpr && touched.treeOptionDto?.parentIdExpr}
|
|
||||||
errorMessage={errors.treeOptionDto?.parentIdExpr}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
type="text"
|
|
||||||
name="treeOptionDto.parentIdExpr"
|
|
||||||
placeholder={translate('::ListForms.ListFormEdit.ParentIdExpr')}
|
|
||||||
>
|
|
||||||
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
|
||||||
<Select
|
|
||||||
field={field}
|
|
||||||
form={form}
|
|
||||||
isClearable={true}
|
|
||||||
options={fieldList}
|
|
||||||
value={fieldList?.filter(
|
|
||||||
(option) => option.value === values.treeOptionDto.parentIdExpr,
|
|
||||||
)}
|
|
||||||
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Field>
|
|
||||||
</FormItem>
|
|
||||||
|
|
||||||
<FormItem
|
|
||||||
label={translate('::ListForms.ListFormEdit.HasItemsExpr')}
|
|
||||||
invalid={errors.treeOptionDto?.hasItemsExpr && touched.treeOptionDto?.hasItemsExpr}
|
|
||||||
errorMessage={errors.treeOptionDto?.hasItemsExpr}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
type="text"
|
|
||||||
autoComplete="off"
|
|
||||||
name="treeOptionDto.hasItemsExpr"
|
|
||||||
placeholder={translate('::ListForms.ListFormEdit.HasItemsExpr')}
|
|
||||||
component={Input}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
|
|
||||||
<FormItem
|
|
||||||
label={translate('::ListForms.ListFormEdit.RootValue')}
|
|
||||||
invalid={!!(errors.treeOptionDto?.rootValue && touched.treeOptionDto?.rootValue)}
|
|
||||||
errorMessage={errors.treeOptionDto?.rootValue as string}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
type="text"
|
|
||||||
autoComplete="off"
|
|
||||||
name="treeOptionDto.rootValue"
|
|
||||||
placeholder={translate('::ListForms.ListFormEdit.RootValue')}
|
|
||||||
component={Input}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
|
|
||||||
<FormItem
|
|
||||||
label={translate('::ListForms.ListFormEdit.AutoExpandAll')}
|
|
||||||
invalid={
|
|
||||||
errors.treeOptionDto?.autoExpandAll && touched.treeOptionDto?.autoExpandAll
|
|
||||||
}
|
|
||||||
errorMessage={errors.treeOptionDto?.autoExpandAll}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
name="treeOptionDto.autoExpandAll"
|
|
||||||
placeholder={translate('::ListForms.ListFormEdit.AutoExpandAll')}
|
|
||||||
component={Checkbox}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
|
|
||||||
<FormItem
|
|
||||||
label={translate('::ListForms.ListFormEdit.RecursiveSelection')}
|
|
||||||
invalid={
|
|
||||||
errors.treeOptionDto?.recursiveSelection &&
|
|
||||||
touched.treeOptionDto?.recursiveSelection
|
|
||||||
}
|
|
||||||
errorMessage={errors.treeOptionDto?.recursiveSelection}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
name="treeOptionDto.recursiveSelection"
|
|
||||||
placeholder={translate('::ListForms.ListFormEdit.RecursiveSelection')}
|
|
||||||
component={Checkbox}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
|
|
||||||
<Button block variant="solid" loading={isSubmitting} type="submit" className="my-2">
|
|
||||||
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
|
|
||||||
</Button>
|
|
||||||
</FormContainer>
|
|
||||||
</Form>
|
|
||||||
)}
|
|
||||||
</Formik>
|
|
||||||
</Container>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FormTabTree
|
|
||||||
315
ui/src/views/admin/listForm/edit/FormTabTreeGantt.tsx
Normal file
315
ui/src/views/admin/listForm/edit/FormTabTreeGantt.tsx
Normal file
|
|
@ -0,0 +1,315 @@
|
||||||
|
import { Container } from '@/components/shared'
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Notification,
|
||||||
|
Checkbox,
|
||||||
|
FormContainer,
|
||||||
|
FormItem,
|
||||||
|
Input,
|
||||||
|
Select,
|
||||||
|
toast,
|
||||||
|
Card,
|
||||||
|
} from '@/components/ui'
|
||||||
|
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
||||||
|
import { useStoreState } from '@/store'
|
||||||
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||||
|
import * as Yup from 'yup'
|
||||||
|
import { FormEditProps } from './FormEdit'
|
||||||
|
import { SelectBoxOption } from '@/types/shared'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { getListFormFields } from '@/services/admin/list-form-field.service'
|
||||||
|
import { groupBy } from 'lodash'
|
||||||
|
import { useParams } from 'react-router-dom'
|
||||||
|
|
||||||
|
const validationSchema = Yup.object().shape({})
|
||||||
|
|
||||||
|
function FormTabTreeGantt(props: FormEditProps) {
|
||||||
|
const { listFormCode } = useParams()
|
||||||
|
const { translate } = useLocalization()
|
||||||
|
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
|
||||||
|
|
||||||
|
const getFields = async () => {
|
||||||
|
if (!listFormCode) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resp = await getListFormFields({
|
||||||
|
listFormCode,
|
||||||
|
sorting: 'ListOrderNo',
|
||||||
|
maxResultCount: 1000,
|
||||||
|
})
|
||||||
|
if (resp.data?.items) {
|
||||||
|
const fieldNames = groupBy(resp?.data?.items, 'fieldName')
|
||||||
|
setFieldList(
|
||||||
|
Object.keys(fieldNames).map((a) => ({
|
||||||
|
value: a,
|
||||||
|
label: a,
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
toast.push(
|
||||||
|
<Notification type="danger" duration={2000}>
|
||||||
|
Alanlar getirilemedi
|
||||||
|
{error.toString()}
|
||||||
|
</Notification>,
|
||||||
|
{
|
||||||
|
placement: 'top-end',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getFields()
|
||||||
|
}, [listFormCode])
|
||||||
|
|
||||||
|
const listFormValues = useStoreState((s) => s.admin.lists.values)
|
||||||
|
if (!listFormValues) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Formik
|
||||||
|
initialValues={listFormValues}
|
||||||
|
validationSchema={validationSchema}
|
||||||
|
onSubmit={async (values, formikHelpers) => {
|
||||||
|
await props.onSubmit(ListFormEditTabs.TreeForm, values, formikHelpers)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{({ touched, errors, isSubmitting, values }) => (
|
||||||
|
<Form>
|
||||||
|
<FormContainer size="sm">
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||||
|
<Card className="my-2" header="Tree Options">
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.DatabaseDataSourceKeyFieldName')}
|
||||||
|
invalid={errors.treeOptionDto?.keyExpr && touched.treeOptionDto?.keyExpr}
|
||||||
|
errorMessage={errors.treeOptionDto?.keyExpr}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
name="treeOptionDto.keyExpr"
|
||||||
|
placeholder={translate(
|
||||||
|
'::ListForms.ListFormEdit.DatabaseDataSourceKeyFieldName',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
||||||
|
<Select
|
||||||
|
field={field}
|
||||||
|
form={form}
|
||||||
|
isClearable={true}
|
||||||
|
options={fieldList}
|
||||||
|
value={fieldList?.filter(
|
||||||
|
(option) => option.value === values.treeOptionDto.keyExpr,
|
||||||
|
)}
|
||||||
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.ParentIdExpr')}
|
||||||
|
invalid={
|
||||||
|
errors.treeOptionDto?.parentIdExpr && touched.treeOptionDto?.parentIdExpr
|
||||||
|
}
|
||||||
|
errorMessage={errors.treeOptionDto?.parentIdExpr}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
name="treeOptionDto.parentIdExpr"
|
||||||
|
placeholder={translate('::ListForms.ListFormEdit.ParentIdExpr')}
|
||||||
|
>
|
||||||
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
||||||
|
<Select
|
||||||
|
field={field}
|
||||||
|
form={form}
|
||||||
|
isClearable={true}
|
||||||
|
options={fieldList}
|
||||||
|
value={fieldList?.filter(
|
||||||
|
(option) => option.value === values.treeOptionDto.parentIdExpr,
|
||||||
|
)}
|
||||||
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.HasItemsExpr')}
|
||||||
|
invalid={
|
||||||
|
errors.treeOptionDto?.hasItemsExpr && touched.treeOptionDto?.hasItemsExpr
|
||||||
|
}
|
||||||
|
errorMessage={errors.treeOptionDto?.hasItemsExpr}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
autoComplete="off"
|
||||||
|
name="treeOptionDto.hasItemsExpr"
|
||||||
|
placeholder={translate('::ListForms.ListFormEdit.HasItemsExpr')}
|
||||||
|
component={Input}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.RootValue')}
|
||||||
|
invalid={!!(errors.treeOptionDto?.rootValue && touched.treeOptionDto?.rootValue)}
|
||||||
|
errorMessage={errors.treeOptionDto?.rootValue as string}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
autoComplete="off"
|
||||||
|
name="treeOptionDto.rootValue"
|
||||||
|
placeholder={translate('::ListForms.ListFormEdit.RootValue')}
|
||||||
|
component={Input}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.AutoExpandAll')}
|
||||||
|
invalid={
|
||||||
|
errors.treeOptionDto?.autoExpandAll && touched.treeOptionDto?.autoExpandAll
|
||||||
|
}
|
||||||
|
errorMessage={errors.treeOptionDto?.autoExpandAll}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
name="treeOptionDto.autoExpandAll"
|
||||||
|
placeholder={translate('::ListForms.ListFormEdit.AutoExpandAll')}
|
||||||
|
component={Checkbox}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.RecursiveSelection')}
|
||||||
|
invalid={
|
||||||
|
errors.treeOptionDto?.recursiveSelection &&
|
||||||
|
touched.treeOptionDto?.recursiveSelection
|
||||||
|
}
|
||||||
|
errorMessage={errors.treeOptionDto?.recursiveSelection}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
name="treeOptionDto.recursiveSelection"
|
||||||
|
placeholder={translate('::ListForms.ListFormEdit.RecursiveSelection')}
|
||||||
|
component={Checkbox}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card className="my-2" header="Gantt Options">
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.TitleExpr')}
|
||||||
|
invalid={errors.treeOptionDto?.titleExpr && touched.treeOptionDto?.titleExpr}
|
||||||
|
errorMessage={errors.treeOptionDto?.titleExpr}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
name="treeOptionDto.titleExpr"
|
||||||
|
placeholder={translate('::ListForms.ListFormEdit.TitleExpr')}
|
||||||
|
>
|
||||||
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
||||||
|
<Select
|
||||||
|
field={field}
|
||||||
|
form={form}
|
||||||
|
isClearable={true}
|
||||||
|
options={fieldList}
|
||||||
|
value={fieldList?.filter(
|
||||||
|
(option) => option.value === values.treeOptionDto.titleExpr,
|
||||||
|
)}
|
||||||
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.StartExpr')}
|
||||||
|
invalid={errors.treeOptionDto?.startExpr && touched.treeOptionDto?.startExpr}
|
||||||
|
errorMessage={errors.treeOptionDto?.startExpr}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
name="treeOptionDto.startExpr"
|
||||||
|
placeholder={translate('::ListForms.ListFormEdit.StartExpr')}
|
||||||
|
>
|
||||||
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
||||||
|
<Select
|
||||||
|
field={field}
|
||||||
|
form={form}
|
||||||
|
isClearable={true}
|
||||||
|
options={fieldList}
|
||||||
|
value={fieldList?.filter(
|
||||||
|
(option) => option.value === values.treeOptionDto.startExpr,
|
||||||
|
)}
|
||||||
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.EndExpr')}
|
||||||
|
invalid={errors.treeOptionDto?.endExpr && touched.treeOptionDto?.endExpr}
|
||||||
|
errorMessage={errors.treeOptionDto?.endExpr}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
name="treeOptionDto.endExpr"
|
||||||
|
placeholder={translate('::ListForms.ListFormEdit.EndExpr')}
|
||||||
|
>
|
||||||
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
||||||
|
<Select
|
||||||
|
field={field}
|
||||||
|
form={form}
|
||||||
|
isClearable={true}
|
||||||
|
options={fieldList}
|
||||||
|
value={fieldList?.filter(
|
||||||
|
(option) => option.value === values.treeOptionDto.endExpr,
|
||||||
|
)}
|
||||||
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label={translate('::ListForms.ListFormEdit.ProgressExpr')}
|
||||||
|
invalid={
|
||||||
|
errors.treeOptionDto?.progressExpr && touched.treeOptionDto?.progressExpr
|
||||||
|
}
|
||||||
|
errorMessage={errors.treeOptionDto?.progressExpr}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
name="treeOptionDto.progressExpr"
|
||||||
|
placeholder={translate('::ListForms.ListFormEdit.ProgressExpr')}
|
||||||
|
>
|
||||||
|
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
||||||
|
<Select
|
||||||
|
field={field}
|
||||||
|
form={form}
|
||||||
|
isClearable={true}
|
||||||
|
options={fieldList}
|
||||||
|
value={fieldList?.filter(
|
||||||
|
(option) => option.value === values.treeOptionDto.progressExpr,
|
||||||
|
)}
|
||||||
|
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</FormItem>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
<Button block variant="solid" loading={isSubmitting} type="submit" className="my-2">
|
||||||
|
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
|
||||||
|
</Button>
|
||||||
|
</FormContainer>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FormTabTreeGantt
|
||||||
|
|
@ -203,7 +203,6 @@ export const columnEditorTypeListOptions = [
|
||||||
export const listFormTypeOptions = [
|
export const listFormTypeOptions = [
|
||||||
{ value: 'Form', label: 'Form' },
|
{ value: 'Form', label: 'Form' },
|
||||||
{ value: 'List', label: 'List' },
|
{ value: 'List', label: 'List' },
|
||||||
{ value: 'Tree', label: 'Tree' },
|
|
||||||
{ value: 'Chart', label: 'Chart' },
|
{ value: 'Chart', label: 'Chart' },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,14 @@ import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import useResponsive from '@/utils/hooks/useResponsive'
|
import useResponsive from '@/utils/hooks/useResponsive'
|
||||||
import Gantt, {
|
import Gantt, {
|
||||||
Column,
|
Column,
|
||||||
Dependencies,
|
|
||||||
Editing,
|
Editing,
|
||||||
GanttRef,
|
GanttRef,
|
||||||
GanttTypes,
|
Item,
|
||||||
ResourceAssignments,
|
|
||||||
Resources,
|
|
||||||
Tasks,
|
Tasks,
|
||||||
|
Toolbar,
|
||||||
Validation,
|
Validation,
|
||||||
} from 'devextreme-react/gantt'
|
} from 'devextreme-react/gantt'
|
||||||
import { Button } from '@/components/ui'
|
import DataSource from 'devextreme/data/data_source'
|
||||||
import CustomStore from 'devextreme/data/custom_store'
|
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
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'
|
||||||
|
|
@ -45,7 +42,7 @@ const GanttView = (props: GanttViewProps) => {
|
||||||
const refListFormCode = useRef('')
|
const refListFormCode = useRef('')
|
||||||
const widgetGroupRef = useRef<HTMLDivElement>(null)
|
const widgetGroupRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
const [ganttDataSource, setGanttDataSource] = useState<CustomStore<any, any>>()
|
const [ganttDataSource, setGanttDataSource] = useState<DataSource<any, any>>()
|
||||||
const [gridDto, setGridDto] = useState<GridDto>()
|
const [gridDto, setGridDto] = useState<GridDto>()
|
||||||
const [widgetGroupHeight, setWidgetGroupHeight] = useState(0)
|
const [widgetGroupHeight, setWidgetGroupHeight] = useState(0)
|
||||||
|
|
||||||
|
|
@ -132,7 +129,7 @@ const GanttView = (props: GanttViewProps) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!gridDto) return
|
if (!gridDto) return
|
||||||
|
|
||||||
const dataSource = createSelectDataSource(
|
const customStore = createSelectDataSource(
|
||||||
gridDto.gridOptions,
|
gridDto.gridOptions,
|
||||||
listFormCode,
|
listFormCode,
|
||||||
searchParams,
|
searchParams,
|
||||||
|
|
@ -140,8 +137,14 @@ const GanttView = (props: GanttViewProps) => {
|
||||||
undefined,
|
undefined,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Gantt için DataSource wrapper'ı oluştur
|
||||||
|
const dataSource = new DataSource({
|
||||||
|
store: customStore,
|
||||||
|
reshapeOnPush: true,
|
||||||
|
})
|
||||||
|
|
||||||
setGanttDataSource(dataSource)
|
setGanttDataSource(dataSource)
|
||||||
}, [gridDto, searchParams])
|
}, [gridDto, searchParams, createSelectDataSource])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
refListFormCode.current = listFormCode
|
refListFormCode.current = listFormCode
|
||||||
|
|
@ -201,52 +204,14 @@ const GanttView = (props: GanttViewProps) => {
|
||||||
titleTemplate="%s | Erp Platform"
|
titleTemplate="%s | Erp Platform"
|
||||||
title={translate('::' + gridDto?.gridOptions.title)}
|
title={translate('::' + gridDto?.gridOptions.title)}
|
||||||
defaultTitle="Erp Platform"
|
defaultTitle="Erp Platform"
|
||||||
></Helmet>
|
>
|
||||||
|
<link rel="stylesheet" href="/css/gantt/dx-gantt.min.css" />
|
||||||
|
</Helmet>
|
||||||
)}
|
)}
|
||||||
{!gridDto && <div className="p-4">Loading gantt configuration...</div>}
|
{!gridDto && <div className="p-4">Loading gantt configuration...</div>}
|
||||||
{gridDto && !ganttDataSource && <div className="p-4">Loading data source...</div>}
|
{gridDto && !ganttDataSource && <div className="p-4">Loading data source...</div>}
|
||||||
{gridDto && ganttDataSource && (
|
{gridDto && ganttDataSource && (
|
||||||
<>
|
<>
|
||||||
{/* Custom Toolbar */}
|
|
||||||
{(toolbarData.length > 0 || filterToolbarData.length > 0) && (
|
|
||||||
<div className="flex flex-wrap gap-2 p-2 border-b bg-white">
|
|
||||||
{toolbarData.map((item: any) => {
|
|
||||||
if (item.widget === 'dxButton' && item.options) {
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
key={item.name}
|
|
||||||
size="sm"
|
|
||||||
variant={item.options.type || 'solid'}
|
|
||||||
icon={item.options.icon}
|
|
||||||
onClick={item.options.onClick}
|
|
||||||
disabled={item.options.disabled}
|
|
||||||
>
|
|
||||||
{item.options.text}
|
|
||||||
</Button>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
})}
|
|
||||||
{filterToolbarData.map((item: any) => {
|
|
||||||
if (item.widget === 'dxButton' && item.options) {
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
key={item.name}
|
|
||||||
size="sm"
|
|
||||||
variant={item.options.type || 'solid'}
|
|
||||||
icon={item.options.icon}
|
|
||||||
onClick={item.options.onClick}
|
|
||||||
disabled={item.options.disabled}
|
|
||||||
>
|
|
||||||
{item.options.text}
|
|
||||||
</Button>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="p-1">
|
<div className="p-1">
|
||||||
<Gantt
|
<Gantt
|
||||||
ref={ganttRef as any}
|
ref={ganttRef as any}
|
||||||
|
|
@ -254,6 +219,12 @@ const GanttView = (props: GanttViewProps) => {
|
||||||
id={'Gantt-' + listFormCode}
|
id={'Gantt-' + listFormCode}
|
||||||
taskListWidth={500}
|
taskListWidth={500}
|
||||||
scaleType="weeks"
|
scaleType="weeks"
|
||||||
|
rootValue={
|
||||||
|
gridDto.gridOptions.treeOptionDto?.rootValue === '' ||
|
||||||
|
gridDto.gridOptions.treeOptionDto?.rootValue === undefined
|
||||||
|
? null
|
||||||
|
: gridDto.gridOptions.treeOptionDto?.rootValue
|
||||||
|
}
|
||||||
height={
|
height={
|
||||||
gridDto.gridOptions.height > 0
|
gridDto.gridOptions.height > 0
|
||||||
? gridDto.gridOptions.height
|
? gridDto.gridOptions.height
|
||||||
|
|
@ -267,17 +238,32 @@ const GanttView = (props: GanttViewProps) => {
|
||||||
onTaskUpdated={onTaskUpdated}
|
onTaskUpdated={onTaskUpdated}
|
||||||
onTaskDeleted={onTaskDeleted}
|
onTaskDeleted={onTaskDeleted}
|
||||||
>
|
>
|
||||||
<Tasks dataSource={ganttDataSource} />
|
<Tasks
|
||||||
<Dependencies dataSource={[]} />
|
dataSource={ganttDataSource}
|
||||||
<Resources dataSource={[]} />
|
keyExpr={gridDto.gridOptions.treeOptionDto?.keyExpr}
|
||||||
<ResourceAssignments dataSource={[]} />
|
parentIdExpr={gridDto.gridOptions.treeOptionDto?.parentIdExpr}
|
||||||
|
titleExpr={gridDto.gridOptions.treeOptionDto?.titleExpr}
|
||||||
|
startExpr={gridDto.gridOptions.treeOptionDto?.startExpr}
|
||||||
|
endExpr={gridDto.gridOptions.treeOptionDto?.endExpr}
|
||||||
|
progressExpr={gridDto.gridOptions.treeOptionDto?.progressExpr}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Toolbar>
|
||||||
|
<Item name="undo" />
|
||||||
|
<Item name="redo" />
|
||||||
|
<Item name="separator" />
|
||||||
|
<Item name="collapseAll" />
|
||||||
|
<Item name="expandAll" />
|
||||||
|
<Item name="separator" />
|
||||||
|
<Item name="addTask" />
|
||||||
|
<Item name="deleteTask" />
|
||||||
|
<Item name="separator" />
|
||||||
|
<Item name="zoomIn" />
|
||||||
|
<Item name="zoomOut" />
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
<Editing
|
<Editing
|
||||||
enabled={
|
enabled={gridDto.gridOptions.editingOptionDto?.allowUpdating}
|
||||||
gridDto.gridOptions.editingOptionDto?.allowAdding ||
|
|
||||||
gridDto.gridOptions.editingOptionDto?.allowUpdating ||
|
|
||||||
gridDto.gridOptions.editingOptionDto?.allowDeleting
|
|
||||||
}
|
|
||||||
allowTaskAdding={gridDto.gridOptions.editingOptionDto?.allowAdding}
|
allowTaskAdding={gridDto.gridOptions.editingOptionDto?.allowAdding}
|
||||||
allowTaskUpdating={gridDto.gridOptions.editingOptionDto?.allowUpdating}
|
allowTaskUpdating={gridDto.gridOptions.editingOptionDto?.allowUpdating}
|
||||||
allowTaskDeleting={gridDto.gridOptions.editingOptionDto?.allowDeleting}
|
allowTaskDeleting={gridDto.gridOptions.editingOptionDto?.allowDeleting}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue