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)
|
||||
/// </summary>
|
||||
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",
|
||||
"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",
|
||||
"key": "ListForms.ListFormEdit.RootValue",
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
|||
var listForm = await _listFormRepository.InsertAsync(
|
||||
new ListForm()
|
||||
{
|
||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
||||
ListFormType = ListFormTypeEnum.List,
|
||||
ExportJson = DefaultExportJson,
|
||||
IsSubForm = false,
|
||||
ShowNote = true,
|
||||
LayoutJson = DefaultLayoutJson,
|
||||
|
|
@ -176,7 +177,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
|||
var listForm = await _listFormRepository.InsertAsync(
|
||||
new ListForm()
|
||||
{
|
||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
||||
ListFormType = ListFormTypeEnum.List,
|
||||
ExportJson = DefaultExportJson,
|
||||
IsSubForm = false,
|
||||
ShowNote = true,
|
||||
LayoutJson = DefaultLayoutJson,
|
||||
|
|
@ -299,7 +301,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
|||
var listForm = await _listFormRepository.InsertAsync(
|
||||
new ListForm()
|
||||
{
|
||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
||||
ListFormType = ListFormTypeEnum.List,
|
||||
ExportJson = DefaultExportJson,
|
||||
IsSubForm = false,
|
||||
ShowNote = true,
|
||||
LayoutJson = DefaultLayoutJson,
|
||||
|
|
@ -422,7 +425,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
|||
var listForm = await _listFormRepository.InsertAsync(
|
||||
new ListForm()
|
||||
{
|
||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
||||
ListFormType = ListFormTypeEnum.List,
|
||||
ExportJson = DefaultExportJson,
|
||||
IsSubForm = false,
|
||||
ShowNote = true,
|
||||
LayoutJson = DefaultLayoutJson,
|
||||
|
|
@ -545,7 +549,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
|||
var listForm = await _listFormRepository.InsertAsync(
|
||||
new ListForm()
|
||||
{
|
||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
||||
ListFormType = ListFormTypeEnum.List,
|
||||
ExportJson = DefaultExportJson,
|
||||
IsSubForm = false,
|
||||
ShowNote = true,
|
||||
LayoutJson = DefaultLayoutJson,
|
||||
|
|
@ -668,7 +673,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
|||
var listForm = await _listFormRepository.InsertAsync(
|
||||
new ListForm()
|
||||
{
|
||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
||||
ListFormType = ListFormTypeEnum.List,
|
||||
ExportJson = DefaultExportJson,
|
||||
IsSubForm = false,
|
||||
ShowNote = true,
|
||||
LayoutJson = DefaultLayoutJson,
|
||||
|
|
@ -791,7 +797,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
|||
var listForm = await _listFormRepository.InsertAsync(
|
||||
new ListForm()
|
||||
{
|
||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
||||
ListFormType = ListFormTypeEnum.List,
|
||||
ExportJson = DefaultExportJson,
|
||||
IsSubForm = false,
|
||||
ShowNote = true,
|
||||
LayoutJson = DefaultLayoutJson,
|
||||
|
|
@ -1199,7 +1206,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
|||
var listForm = await _listFormRepository.InsertAsync(
|
||||
new ListForm()
|
||||
{
|
||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
||||
ListFormType = ListFormTypeEnum.List,
|
||||
ExportJson = DefaultExportJson,
|
||||
IsSubForm = true,
|
||||
ShowNote = true,
|
||||
LayoutJson = DefaultLayoutJson,
|
||||
|
|
@ -1286,7 +1294,7 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
|||
var listForm = await _listFormRepository.InsertAsync(
|
||||
new ListForm()
|
||||
{
|
||||
ListFormType = ListFormTypeEnum.Tree,
|
||||
ListFormType = ListFormTypeEnum.List,
|
||||
IsSubForm = true,
|
||||
ShowNote = true,
|
||||
LayoutJson = DefaultLayoutJson,
|
||||
|
|
@ -1422,7 +1430,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
|||
var listForm = await _listFormRepository.InsertAsync(
|
||||
new ListForm()
|
||||
{
|
||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
||||
ListFormType = ListFormTypeEnum.List,
|
||||
ExportJson = DefaultExportJson,
|
||||
IsSubForm = false,
|
||||
ShowNote = true,
|
||||
LayoutJson = DefaultLayoutJson,
|
||||
|
|
@ -1774,7 +1783,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
|||
var listForm = await _listFormRepository.InsertAsync(
|
||||
new ListForm()
|
||||
{
|
||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
||||
ListFormType = ListFormTypeEnum.List,
|
||||
ExportJson = DefaultExportJson,
|
||||
IsSubForm = false,
|
||||
ShowNote = true,
|
||||
LayoutJson = DefaultLayoutJson,
|
||||
|
|
@ -2059,6 +2069,196 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
|||
}
|
||||
#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
|
||||
listFormName = AppCodes.Project.ProjectTaskDaily;
|
||||
if (!await _listFormRepository.AnyAsync(a => a.ListFormCode == listFormName))
|
||||
|
|
@ -2066,7 +2266,8 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
|
|||
var listForm = await _listFormRepository.InsertAsync(
|
||||
new ListForm()
|
||||
{
|
||||
ListFormType = ListFormTypeEnum.List, ExportJson = DefaultExportJson,
|
||||
ListFormType = ListFormTypeEnum.List,
|
||||
ExportJson = DefaultExportJson,
|
||||
IsSubForm = false,
|
||||
ShowNote = true,
|
||||
LayoutJson = DefaultLayoutJson,
|
||||
|
|
|
|||
|
|
@ -2558,7 +2558,6 @@
|
|||
"RequiredPermissionName": null,
|
||||
"IsDisabled": false
|
||||
},
|
||||
|
||||
{
|
||||
"ParentCode": "App.Store.Definitions",
|
||||
"Code": "App.Store.WarehouseType",
|
||||
|
|
@ -2804,7 +2803,7 @@
|
|||
"Code": "App.Project.Workload",
|
||||
"DisplayName": "App.Project.Workload",
|
||||
"Order": 7,
|
||||
"Url": "/admin/projects/workload",
|
||||
"Url": "/admin/list/App.Project.Workload",
|
||||
"Icon": "FcComboChart",
|
||||
"RequiredPermissionName": "App.Project.Workload",
|
||||
"IsDisabled": false
|
||||
|
|
|
|||
|
|
@ -5557,7 +5557,6 @@
|
|||
"MultiTenancySide": 3,
|
||||
"MenuGroup": "Erp"
|
||||
},
|
||||
|
||||
{
|
||||
"GroupName": "App.SupplyChain",
|
||||
"Name": "App.SupplyChain.SupplyType",
|
||||
|
|
@ -5999,7 +5998,6 @@
|
|||
"MultiTenancySide": 3,
|
||||
"MenuGroup": "Erp"
|
||||
},
|
||||
|
||||
{
|
||||
"GroupName": "App.SupplyChain",
|
||||
"Name": "App.SupplyChain.QuotationStatus",
|
||||
|
|
@ -6423,7 +6421,6 @@
|
|||
"MultiTenancySide": 3,
|
||||
"MenuGroup": "Erp"
|
||||
},
|
||||
|
||||
{
|
||||
"GroupName": "App.SupplyChain",
|
||||
"Name": "App.SupplyChain.QuotationItem",
|
||||
|
|
@ -6487,7 +6484,6 @@
|
|||
"MultiTenancySide": 3,
|
||||
"MenuGroup": "Erp"
|
||||
},
|
||||
|
||||
{
|
||||
"GroupName": "App.SupplyChain",
|
||||
"Name": "App.SupplyChain.Approval",
|
||||
|
|
|
|||
|
|
@ -92,11 +92,11 @@ public static class SeederDefaults
|
|||
Mode = GridOptions.SelectionModeMultiple,
|
||||
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,
|
||||
ParentIdExpr = ParentIdExpr,
|
||||
RootValue = null,
|
||||
RootValue = RootValue,
|
||||
AutoExpandAll = AutoExpandAll
|
||||
});
|
||||
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 Form = "Form";
|
||||
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 ProjectTeam = Default + ".ProjectTeam";
|
||||
public const string ProjectTask = Default + ".ProjectTask";
|
||||
public const string Workload = Default + ".Workload";
|
||||
public const string ProjectTaskDaily = Default + ".ProjectTaskDaily";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ public class DatabaseViewSeeder : IDataSeedContributor, ITransientDependency
|
|||
|
||||
await CreateOrUpdateMaterialGroupView(dbContext, nameof(TableNameEnum.MaterialGroup));
|
||||
|
||||
await CreateOrUpdateProjectTaskView(dbContext, nameof(TableNameEnum.ProjectTask));
|
||||
|
||||
_logger.LogInformation("Database view seeding completed successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -102,5 +104,75 @@ public class DatabaseViewSeeder : IDataSeedContributor, ITransientDependency
|
|||
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 = [
|
||||
{ value: 'Select', label: 'Select' },
|
||||
{ value: 'TextBox', label: 'TextBox' },
|
||||
|
|
@ -73,55 +75,55 @@ export const ListFormEditTabs = {
|
|||
} as const
|
||||
|
||||
export const tabVisibilityConfig: Record<string, string[]> = {
|
||||
List: [
|
||||
'details',
|
||||
'database',
|
||||
'permissions',
|
||||
'commands',
|
||||
'edit',
|
||||
'sortingForm',
|
||||
'filterRow',
|
||||
'rowForm',
|
||||
'search',
|
||||
'group',
|
||||
'select',
|
||||
'columns',
|
||||
'pivots',
|
||||
'tree',
|
||||
'pager',
|
||||
'state',
|
||||
'extrafilter',
|
||||
'customization',
|
||||
'fields',
|
||||
'editForm',
|
||||
'widget',
|
||||
//Chart tabları
|
||||
'commonSettings',
|
||||
'series',
|
||||
'axis',
|
||||
'panes',
|
||||
'animationsOptions',
|
||||
'annotations',
|
||||
'zoomAndPanSettings',
|
||||
'legendSettings',
|
||||
'exportSettings',
|
||||
'crosshairOptions',
|
||||
'subForms',
|
||||
],
|
||||
Form: [
|
||||
'details',
|
||||
'database',
|
||||
'permissions',
|
||||
'commands',
|
||||
'edit',
|
||||
'fields',
|
||||
'editForm',
|
||||
'widget',
|
||||
'subForms',
|
||||
],
|
||||
}
|
||||
List: [
|
||||
'details',
|
||||
'database',
|
||||
'permissions',
|
||||
'commands',
|
||||
'edit',
|
||||
'sortingForm',
|
||||
'filterRow',
|
||||
'rowForm',
|
||||
'search',
|
||||
'group',
|
||||
'select',
|
||||
'columns',
|
||||
'pivots',
|
||||
'tree',
|
||||
'pager',
|
||||
'state',
|
||||
'extrafilter',
|
||||
'customization',
|
||||
'fields',
|
||||
'editForm',
|
||||
'widget',
|
||||
//Chart tabları
|
||||
'commonSettings',
|
||||
'series',
|
||||
'axis',
|
||||
'panes',
|
||||
'animationsOptions',
|
||||
'annotations',
|
||||
'zoomAndPanSettings',
|
||||
'legendSettings',
|
||||
'exportSettings',
|
||||
'crosshairOptions',
|
||||
'subForms',
|
||||
],
|
||||
Form: [
|
||||
'details',
|
||||
'database',
|
||||
'permissions',
|
||||
'commands',
|
||||
'edit',
|
||||
'fields',
|
||||
'editForm',
|
||||
'widget',
|
||||
'subForms',
|
||||
],
|
||||
}
|
||||
|
||||
export const themeOptions = [
|
||||
export const themeOptions = [
|
||||
{ value: 'generic.dark', label: 'Generic Dark' },
|
||||
{ value: 'generic.light', label: 'Generic Carmine' },
|
||||
{ value: 'generic.contrast', label: 'Generic Contrast' },
|
||||
|
|
|
|||
|
|
@ -386,6 +386,10 @@ export interface TreeOptionDto {
|
|||
expandedRowKeys?: any[]
|
||||
autoExpandAll?: boolean
|
||||
recursiveSelection?: boolean
|
||||
titleExpr?: string
|
||||
startExpr?: string
|
||||
endExpr?: string
|
||||
progressExpr?: string
|
||||
}
|
||||
|
||||
export interface GridEditingDto {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ import FormTabWidgets from './FormTabWidgets'
|
|||
import FormTabExtraFilters from './FormTabExtraFilters'
|
||||
import FormTabEditForm from './FormTabEditForm'
|
||||
import FormTabPivots from './FormTabPivots'
|
||||
import FormTabTree from './FormTabTree'
|
||||
import FormTabTreeGantt from './FormTabTreeGantt'
|
||||
import ChartTabAnimation from './ChartTabAnimation'
|
||||
import ChartTabAnnotations from './ChartTabAnnotations'
|
||||
import ChartTabZoomAndPan from './ChartTabZoomAndPan'
|
||||
|
|
@ -360,7 +360,7 @@ const FormEdit = () => {
|
|||
<FormTabPivots onSubmit={onSubmit} />
|
||||
</TabContent>
|
||||
<TabContent value="tree" className="px-2">
|
||||
<FormTabTree onSubmit={onSubmit} />
|
||||
<FormTabTreeGantt onSubmit={onSubmit} />
|
||||
</TabContent>
|
||||
<TabContent value="pager" className="px-2">
|
||||
<FormTabPager onSubmit={onSubmit} />
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ const schema = Yup.object().shape({
|
|||
pivot: Yup.boolean(),
|
||||
chart: Yup.boolean(),
|
||||
tree: Yup.boolean(),
|
||||
gantt: Yup.boolean(),
|
||||
defaultLayout: Yup.string(),
|
||||
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 = [
|
||||
{ value: 'Form', label: 'Form' },
|
||||
{ value: 'List', label: 'List' },
|
||||
{ value: 'Tree', label: 'Tree' },
|
||||
{ value: 'Chart', label: 'Chart' },
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -6,17 +6,14 @@ import { useLocalization } from '@/utils/hooks/useLocalization'
|
|||
import useResponsive from '@/utils/hooks/useResponsive'
|
||||
import Gantt, {
|
||||
Column,
|
||||
Dependencies,
|
||||
Editing,
|
||||
GanttRef,
|
||||
GanttTypes,
|
||||
ResourceAssignments,
|
||||
Resources,
|
||||
Item,
|
||||
Tasks,
|
||||
Toolbar,
|
||||
Validation,
|
||||
} from 'devextreme-react/gantt'
|
||||
import { Button } from '@/components/ui'
|
||||
import CustomStore from 'devextreme/data/custom_store'
|
||||
import DataSource from 'devextreme/data/data_source'
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { getList } from '@/services/form.service'
|
||||
|
|
@ -45,7 +42,7 @@ const GanttView = (props: GanttViewProps) => {
|
|||
const refListFormCode = useRef('')
|
||||
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 [widgetGroupHeight, setWidgetGroupHeight] = useState(0)
|
||||
|
||||
|
|
@ -132,7 +129,7 @@ const GanttView = (props: GanttViewProps) => {
|
|||
useEffect(() => {
|
||||
if (!gridDto) return
|
||||
|
||||
const dataSource = createSelectDataSource(
|
||||
const customStore = createSelectDataSource(
|
||||
gridDto.gridOptions,
|
||||
listFormCode,
|
||||
searchParams,
|
||||
|
|
@ -140,8 +137,14 @@ const GanttView = (props: GanttViewProps) => {
|
|||
undefined,
|
||||
)
|
||||
|
||||
// Gantt için DataSource wrapper'ı oluştur
|
||||
const dataSource = new DataSource({
|
||||
store: customStore,
|
||||
reshapeOnPush: true,
|
||||
})
|
||||
|
||||
setGanttDataSource(dataSource)
|
||||
}, [gridDto, searchParams])
|
||||
}, [gridDto, searchParams, createSelectDataSource])
|
||||
|
||||
useEffect(() => {
|
||||
refListFormCode.current = listFormCode
|
||||
|
|
@ -201,52 +204,14 @@ const GanttView = (props: GanttViewProps) => {
|
|||
titleTemplate="%s | Erp Platform"
|
||||
title={translate('::' + gridDto?.gridOptions.title)}
|
||||
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 && !ganttDataSource && <div className="p-4">Loading data source...</div>}
|
||||
{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">
|
||||
<Gantt
|
||||
ref={ganttRef as any}
|
||||
|
|
@ -254,6 +219,12 @@ const GanttView = (props: GanttViewProps) => {
|
|||
id={'Gantt-' + listFormCode}
|
||||
taskListWidth={500}
|
||||
scaleType="weeks"
|
||||
rootValue={
|
||||
gridDto.gridOptions.treeOptionDto?.rootValue === '' ||
|
||||
gridDto.gridOptions.treeOptionDto?.rootValue === undefined
|
||||
? null
|
||||
: gridDto.gridOptions.treeOptionDto?.rootValue
|
||||
}
|
||||
height={
|
||||
gridDto.gridOptions.height > 0
|
||||
? gridDto.gridOptions.height
|
||||
|
|
@ -267,17 +238,32 @@ const GanttView = (props: GanttViewProps) => {
|
|||
onTaskUpdated={onTaskUpdated}
|
||||
onTaskDeleted={onTaskDeleted}
|
||||
>
|
||||
<Tasks dataSource={ganttDataSource} />
|
||||
<Dependencies dataSource={[]} />
|
||||
<Resources dataSource={[]} />
|
||||
<ResourceAssignments dataSource={[]} />
|
||||
<Tasks
|
||||
dataSource={ganttDataSource}
|
||||
keyExpr={gridDto.gridOptions.treeOptionDto?.keyExpr}
|
||||
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
|
||||
enabled={
|
||||
gridDto.gridOptions.editingOptionDto?.allowAdding ||
|
||||
gridDto.gridOptions.editingOptionDto?.allowUpdating ||
|
||||
gridDto.gridOptions.editingOptionDto?.allowDeleting
|
||||
}
|
||||
enabled={gridDto.gridOptions.editingOptionDto?.allowUpdating}
|
||||
allowTaskAdding={gridDto.gridOptions.editingOptionDto?.allowAdding}
|
||||
allowTaskUpdating={gridDto.gridOptions.editingOptionDto?.allowUpdating}
|
||||
allowTaskDeleting={gridDto.gridOptions.editingOptionDto?.allowDeleting}
|
||||
|
|
|
|||
Loading…
Reference in a new issue