diff --git a/api/src/Erp.Platform.Application.Contracts/ListForms/GridOptionsDto/TreeOptionDto.cs b/api/src/Erp.Platform.Application.Contracts/ListForms/GridOptionsDto/TreeOptionDto.cs index 44c4b4f6..4ba514a1 100644 --- a/api/src/Erp.Platform.Application.Contracts/ListForms/GridOptionsDto/TreeOptionDto.cs +++ b/api/src/Erp.Platform.Application.Contracts/ListForms/GridOptionsDto/TreeOptionDto.cs @@ -38,5 +38,25 @@ public class TreeOptionDto /// Alt kayıtlar seçildiğinde parent kayıtları da seç (recursive selection) /// public bool RecursiveSelection { get; set; } = false; + + /// + /// Başlık alanı (örn: "Title") + /// + public string TitleExpr { get; set; } + + /// + /// Başlangıç Tarihi ifadesi (örn: "0001-01-01") + /// + public string StartExpr { get; set; } + + /// + /// Bitiş Tarihi ifadesi (örn: "9999-12-31") + /// + public string EndExpr { get; set; } + + /// + /// İlerleme ifadesi (örn: "%50") + /// + public string ProgressExpr { get; set; } } diff --git a/api/src/Erp.Platform.DbMigrator/Seeds/LanguagesData.json b/api/src/Erp.Platform.DbMigrator/Seeds/LanguagesData.json index 629951dc..7bfc0265 100644 --- a/api/src/Erp.Platform.DbMigrator/Seeds/LanguagesData.json +++ b/api/src/Erp.Platform.DbMigrator/Seeds/LanguagesData.json @@ -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", diff --git a/api/src/Erp.Platform.DbMigrator/Seeds/ListFormSeeder_Project.cs b/api/src/Erp.Platform.DbMigrator/Seeds/ListFormSeeder_Project.cs index 65da29d2..767bf590 100644 --- a/api/src/Erp.Platform.DbMigrator/Seeds/ListFormSeeder_Project.cs +++ b/api/src/Erp.Platform.DbMigrator/Seeds/ListFormSeeder_Project.cs @@ -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() + { + 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, diff --git a/api/src/Erp.Platform.DbMigrator/Seeds/MenusData.json b/api/src/Erp.Platform.DbMigrator/Seeds/MenusData.json index aea716c0..3c4e3254 100644 --- a/api/src/Erp.Platform.DbMigrator/Seeds/MenusData.json +++ b/api/src/Erp.Platform.DbMigrator/Seeds/MenusData.json @@ -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 diff --git a/api/src/Erp.Platform.DbMigrator/Seeds/PermissionsData.json b/api/src/Erp.Platform.DbMigrator/Seeds/PermissionsData.json index 59e14e7c..68236289 100644 --- a/api/src/Erp.Platform.DbMigrator/Seeds/PermissionsData.json +++ b/api/src/Erp.Platform.DbMigrator/Seeds/PermissionsData.json @@ -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", @@ -13041,4 +13037,4 @@ "MenuGroup": "Erp" } ] -} +} \ No newline at end of file diff --git a/api/src/Erp.Platform.DbMigrator/Seeds/SeederDefaults.cs b/api/src/Erp.Platform.DbMigrator/Seeds/SeederDefaults.cs index 849934dc..a25ad7d6 100644 --- a/api/src/Erp.Platform.DbMigrator/Seeds/SeederDefaults.cs +++ b/api/src/Erp.Platform.DbMigrator/Seeds/SeederDefaults.cs @@ -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 diff --git a/api/src/Erp.Platform.Domain.Shared/Enums/ListFormTypeEnum.cs b/api/src/Erp.Platform.Domain.Shared/Enums/ListFormTypeEnum.cs index bcb1df26..7317bc63 100644 --- a/api/src/Erp.Platform.Domain.Shared/Enums/ListFormTypeEnum.cs +++ b/api/src/Erp.Platform.Domain.Shared/Enums/ListFormTypeEnum.cs @@ -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"; } diff --git a/api/src/Erp.Platform.Domain/Data/SeedConsts.cs b/api/src/Erp.Platform.Domain/Data/SeedConsts.cs index 84d09b62..54fbb493 100644 --- a/api/src/Erp.Platform.Domain/Data/SeedConsts.cs +++ b/api/src/Erp.Platform.Domain/Data/SeedConsts.cs @@ -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"; } diff --git a/api/src/Erp.Platform.EntityFrameworkCore/Tenants/TenantDatabaseViewCreator.cs b/api/src/Erp.Platform.EntityFrameworkCore/Tenants/TenantDatabaseViewCreator.cs index 5e32297d..badddddd 100644 --- a/api/src/Erp.Platform.EntityFrameworkCore/Tenants/TenantDatabaseViewCreator.cs +++ b/api/src/Erp.Platform.EntityFrameworkCore/Tenants/TenantDatabaseViewCreator.cs @@ -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; } } + + /// + /// Creates or updates the V_T_Scp_ProjectWorkload view + /// + 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; + } + } + } diff --git a/ui/src/proxy/admin/list-form/options.ts b/ui/src/proxy/admin/list-form/options.ts index f03a3035..87445e1a 100644 --- a/ui/src/proxy/admin/list-form/options.ts +++ b/ui/src/proxy/admin/list-form/options.ts @@ -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 = { - 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' }, diff --git a/ui/src/proxy/form/models.ts b/ui/src/proxy/form/models.ts index 973bbeb8..0b810543 100644 --- a/ui/src/proxy/form/models.ts +++ b/ui/src/proxy/form/models.ts @@ -386,6 +386,10 @@ export interface TreeOptionDto { expandedRowKeys?: any[] autoExpandAll?: boolean recursiveSelection?: boolean + titleExpr?: string + startExpr?: string + endExpr?: string + progressExpr?: string } export interface GridEditingDto { diff --git a/ui/src/views/admin/listForm/edit/FormEdit.tsx b/ui/src/views/admin/listForm/edit/FormEdit.tsx index 6386bf84..02d45065 100644 --- a/ui/src/views/admin/listForm/edit/FormEdit.tsx +++ b/ui/src/views/admin/listForm/edit/FormEdit.tsx @@ -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 = () => { - + diff --git a/ui/src/views/admin/listForm/edit/FormTabDetails.tsx b/ui/src/views/admin/listForm/edit/FormTabDetails.tsx index 1f06a3b5..463e540e 100644 --- a/ui/src/views/admin/listForm/edit/FormTabDetails.tsx +++ b/ui/src/views/admin/listForm/edit/FormTabDetails.tsx @@ -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(), }), diff --git a/ui/src/views/admin/listForm/edit/FormTabTree.tsx b/ui/src/views/admin/listForm/edit/FormTabTree.tsx deleted file mode 100644 index 83c42f77..00000000 --- a/ui/src/views/admin/listForm/edit/FormTabTree.tsx +++ /dev/null @@ -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([]) - - 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( - - Alanlar getirilemedi - {error.toString()} - , - { - placement: 'top-end', - }, - ) - } - } - - useEffect(() => { - getFields() - }, [listFormCode]) - - const listFormValues = useStoreState((s) => s.admin.lists.values) - if (!listFormValues) { - return null - } - - return ( - - { - await props.onSubmit(ListFormEditTabs.TreeForm, values, formikHelpers) - }} - > - {({ touched, errors, isSubmitting, values }) => ( -
- - - - {({ field, form }: FieldProps) => ( - option.value === values.treeOptionDto.parentIdExpr, - )} - onChange={(option) => form.setFieldValue(field.name, option?.value)} - /> - )} - - - - - - - - - - - - - - - - - - - - - -
- )} -
-
- ) -} - -export default FormTabTree diff --git a/ui/src/views/admin/listForm/edit/FormTabTreeGantt.tsx b/ui/src/views/admin/listForm/edit/FormTabTreeGantt.tsx new file mode 100644 index 00000000..61893e1e --- /dev/null +++ b/ui/src/views/admin/listForm/edit/FormTabTreeGantt.tsx @@ -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([]) + + 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( + + Alanlar getirilemedi + {error.toString()} + , + { + placement: 'top-end', + }, + ) + } + } + + useEffect(() => { + getFields() + }, [listFormCode]) + + const listFormValues = useStoreState((s) => s.admin.lists.values) + if (!listFormValues) { + return null + } + + return ( + { + await props.onSubmit(ListFormEditTabs.TreeForm, values, formikHelpers) + }} + > + {({ touched, errors, isSubmitting, values }) => ( +
+ +
+ + + + {({ field, form }: FieldProps) => ( + option.value === values.treeOptionDto.parentIdExpr, + )} + onChange={(option) => form.setFieldValue(field.name, option?.value)} + /> + )} + + + + + + + + + + + + + + + + + + + + + + + + {({ field, form }: FieldProps) => ( + option.value === values.treeOptionDto.startExpr, + )} + onChange={(option) => form.setFieldValue(field.name, option?.value)} + /> + )} + + + + + + {({ field, form }: FieldProps) => ( + option.value === values.treeOptionDto.progressExpr, + )} + onChange={(option) => form.setFieldValue(field.name, option?.value)} + /> + )} + + + +
+ +
+
+ )} +
+ ) +} + +export default FormTabTreeGantt diff --git a/ui/src/views/admin/listForm/edit/options.ts b/ui/src/views/admin/listForm/edit/options.ts index 7682c4aa..addf2b64 100644 --- a/ui/src/views/admin/listForm/edit/options.ts +++ b/ui/src/views/admin/listForm/edit/options.ts @@ -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' }, ] diff --git a/ui/src/views/list/GanttView.tsx b/ui/src/views/list/GanttView.tsx index 76909a98..7f045eb2 100644 --- a/ui/src/views/list/GanttView.tsx +++ b/ui/src/views/list/GanttView.tsx @@ -6,17 +6,15 @@ 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 +43,7 @@ const GanttView = (props: GanttViewProps) => { const refListFormCode = useRef('') const widgetGroupRef = useRef(null) - const [ganttDataSource, setGanttDataSource] = useState>() + const [ganttDataSource, setGanttDataSource] = useState>() const [gridDto, setGridDto] = useState() const [widgetGroupHeight, setWidgetGroupHeight] = useState(0) @@ -132,7 +130,7 @@ const GanttView = (props: GanttViewProps) => { useEffect(() => { if (!gridDto) return - const dataSource = createSelectDataSource( + const customStore = createSelectDataSource( gridDto.gridOptions, listFormCode, searchParams, @@ -140,8 +138,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 @@ -207,46 +211,6 @@ const GanttView = (props: GanttViewProps) => { {gridDto && !ganttDataSource &&
Loading data source...
} {gridDto && ganttDataSource && ( <> - {/* Custom Toolbar */} - {(toolbarData.length > 0 || filterToolbarData.length > 0) && ( -
- {toolbarData.map((item: any) => { - if (item.widget === 'dxButton' && item.options) { - return ( - - ) - } - return null - })} - {filterToolbarData.map((item: any) => { - if (item.widget === 'dxButton' && item.options) { - return ( - - ) - } - return null - })} -
- )} -
{ 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 +237,32 @@ const GanttView = (props: GanttViewProps) => { onTaskUpdated={onTaskUpdated} onTaskDeleted={onTaskDeleted} > - - - - + + + + + + + + + + + + + + +