From f65202208712f9dd0b4ce2346f8a2e8af0feb60e Mon Sep 17 00:00:00 2001 From: PavithraG-SF5066 Date: Tue, 24 Feb 2026 10:55:34 +0530 Subject: [PATCH 1/5] 1011302: added integration sample for GraphQL --- .../Blazor Web app/GanttDB.db | Bin 0 -> 16384 bytes .../GanttGraphQL/Components/App.razor | 22 ++ .../Components/Layout/MainLayout.razor | 12 + .../Components/Layout/MainLayout.razor.css | 98 ++++++++ .../Components/Layout/ReconnectModal.razor | 31 +++ .../GanttGraphQL/Components/Pages/Home.razor | 195 +++++++++++++++ .../Components/Pages/NotFound.razor | 5 + .../GanttGraphQL/Components/Routes.razor | 6 + .../GanttGraphQL/Components/_Imports.razor | 13 + .../GanttGraphQL/GanttGraphQL.csproj | 27 +++ .../GanttGraphQL/GanttGraphQL.csproj.user | 9 + .../GanttGraphQL/Models/DataManagerRequest.cs | 99 ++++++++ .../GanttGraphQL/Models/GanttDbContext.cs | 43 ++++ .../GanttGraphQL/Models/GraphQLMutation.cs | 159 ++++++++++++ .../GanttGraphQL/Models/GraphQLQuery.cs | 98 ++++++++ .../GanttGraphQL/Models/TaskDataModel.cs | 33 +++ .../Blazor Web app/GanttGraphQL/Program.cs | 47 ++++ .../Properties/launchSettings.json | 23 ++ .../GanttGraphQL/appsettings.Development.json | 8 + .../GanttGraphQL/appsettings.json | 13 + .../GanttGraphQL/wwwroot/app.css | 60 +++++ .../GanttGraphQL/wwwroot/favicon.png | Bin 0 -> 1148 bytes .../README.md | 226 ++++++++++++++++++ 23 files changed, 1227 insertions(+) create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttDB.db create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/App.razor create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor.css create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/ReconnectModal.razor create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Pages/Home.razor create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Pages/NotFound.razor create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Routes.razor create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/_Imports.razor create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/GanttGraphQL.csproj create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/GanttGraphQL.csproj.user create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/DataManagerRequest.cs create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GanttDbContext.cs create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLMutation.cs create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLQuery.cs create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/TaskDataModel.cs create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Program.cs create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Properties/launchSettings.json create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/appsettings.Development.json create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/appsettings.json create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/wwwroot/app.css create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/wwwroot/favicon.png create mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/README.md diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttDB.db b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttDB.db new file mode 100644 index 0000000000000000000000000000000000000000..7c89eb77d54b4348ab43b67f9a4f39a0901f03da GIT binary patch literal 16384 zcmeI&J#W)M7zc1W4lS*ST?wI1k&XeWQQ~lZi77@A1mdDVl7_^U$b<|rs7jltwkyO) zg;@AZNDORz8@6toUt+uEr687o{+1luclX?L_q)rGm(i2%e&CXqbMMdzh{kPjJkQ-D zgyXm>JB!K5v#XTcvrBY@WfvV)uKvDK5+vs@0x-0{J^yxf7*5eXK^h&7+NjcB6jP3m%S#nWUI7J*bzQ=+Tk5L zZ0o5_2E$ITH5`-2)|m8nZPMTCc57MVzH{hijn6e01&$Z6ht@EyawqN!RyX(JDZ~lGmT}U72itdyRV~fJBXoDwIM51rV62|sZo>CT#=&0MarE^i&#F5)pHGh z6yE8 zV`Qn>6qHi9lQ!6o`(KxJOJQ6PfB*y_009U<00Izz00bZa0SNrLz!hF7^NYWw6ms$T i`&=<@ApijgKmY;|fB*y_009U<00I#BmjwiYTl)s$?IM2w literal 0 HcmV?d00001 diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/App.razor b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/App.razor new file mode 100644 index 00000000..bab8ccbe --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/App.razor @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor new file mode 100644 index 00000000..a92fba16 --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor @@ -0,0 +1,12 @@ +@inherits LayoutComponentBase + +
+ +
+ +
+ @Body +
+
+
+ diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor.css b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor.css new file mode 100644 index 00000000..38d1f259 --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor.css @@ -0,0 +1,98 @@ +.page { + position: relative; + display: flex; + flex-direction: column; +} + +main { + flex: 1; +} + +.sidebar { + background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); +} + +.top-row { + background-color: #f7f7f7; + border-bottom: 1px solid #d6d5d5; + justify-content: flex-end; + height: 3.5rem; + display: flex; + align-items: center; +} + + .top-row ::deep a, .top-row ::deep .btn-link { + white-space: nowrap; + margin-left: 1.5rem; + text-decoration: none; + } + + .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { + text-decoration: underline; + } + + .top-row ::deep a:first-child { + overflow: hidden; + text-overflow: ellipsis; + } + +@media (max-width: 640.98px) { + .top-row { + justify-content: space-between; + } + + .top-row ::deep a, .top-row ::deep .btn-link { + margin-left: 0; + } +} + +@media (min-width: 641px) { + .page { + flex-direction: row; + } + + .sidebar { + width: 250px; + height: 100vh; + position: sticky; + top: 0; + } + + .top-row { + position: sticky; + top: 0; + z-index: 1; + } + + .top-row.auth ::deep a:first-child { + flex: 1; + text-align: right; + width: 0; + } + + .top-row, article { + padding-left: 2rem !important; + padding-right: 1.5rem !important; + } +} + +#blazor-error-ui { + color-scheme: light only; + background: lightyellow; + bottom: 0; + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); + box-sizing: border-box; + display: none; + left: 0; + padding: 0.6rem 1.25rem 0.7rem 1.25rem; + position: fixed; + width: 100%; + z-index: 1000; +} + + #blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; + } diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/ReconnectModal.razor b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/ReconnectModal.razor new file mode 100644 index 00000000..49d916bc --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/ReconnectModal.razor @@ -0,0 +1,31 @@ + + + +
+ +

+ Rejoining the server... +

+

+ Rejoin failed... trying again in seconds. +

+

+ Failed to rejoin.
Please retry or reload the page. +

+ +

+ The session has been paused by the server. +

+ +

+ Failed to resume the session.
Please reload the page. +

+
+
diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Pages/Home.razor b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Pages/Home.razor new file mode 100644 index 00000000..39c9be5d --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Pages/Home.razor @@ -0,0 +1,195 @@ +@page "/" +@rendermode InteractiveServer +@using Syncfusion.Blazor +@using Syncfusion.Blazor.Data +@using Syncfusion.Blazor.Gantt +@using GanttGraphQL.Models + + + + + + + + + + + + + + + + + + + + + + + + + +@code { + + public List ToolbarItems = new() { "Add", "Edit", "Update", "Delete", "Search" }; + + // GraphQL adaptor configuration: ResolverName must match your server method (PascalCase) + // and the query must select count + result with the fields the Gantt needs. + private Syncfusion.Blazor.Data.GraphQLAdaptorOptions AdaptorOptions => new() + { + ResolverName = "TaskData", + Query = @" + query TaskData($dataManager: DataManagerRequestInput!) { + taskData(dataManager: $dataManager) { + count + result { + taskID + taskName + startDate + endDate + duration + progress + predecessor + parentID + } + } + }", + + Mutation = new Syncfusion.Blazor.Data.GraphQLMutation + { + // INSERT (matches InsertTask parameters) + Insert = @" + mutation create($record: TaskDataModelInput!, $index: Int!, $action: String!, $additionalParameters: Any) { + createTask(record: $record, index: $index, action: $action, additionalParameters: $additionalParameters) { + taskID + taskName + startDate + endDate + duration + progress + predecessor + parentID + } + }", + Update = @"mutation update($record: TaskDataModelInput!, $action: String!, $primaryColumnName: String!, $primaryColumnValue: Int!, $additionalParameters: Any) { + updateTask(record: $record, action: $action, primaryColumnName: $primaryColumnName, primaryColumnValue: $primaryColumnValue, additionalParameters: $additionalParameters) { + taskID taskName startDate endDate duration progress predecessor parentID + } + }", + + // DELETE (matches DeleteTask parameters) + Delete = @"mutation delete($primaryColumnValue: ID!, $additionalParameters: Any) { + deleteTask(key: $primaryColumnValue, additionalParameters: $additionalParameters) + }", + Batch = @"mutation batch($changed: [TaskDataModelInput!], $added: [TaskDataModelInput!], $deleted: [TaskDataModelInput!], $action: String!, $primaryColumnName: String!, $additionalParameters: Any, $dropIndex: Int) { + batchUpdate(changed: $changed, added: $added, deleted: $deleted, action: $action, primaryColumnName: $primaryColumnName, additionalParameters: $additionalParameters, dropIndex: $dropIndex) { + taskID + taskName + startDate + endDate + duration + progress + predecessor + parentID + } + }" + } + }; +} + + diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Pages/NotFound.razor b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Pages/NotFound.razor new file mode 100644 index 00000000..917ada1d --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Pages/NotFound.razor @@ -0,0 +1,5 @@ +@page "/not-found" +@layout MainLayout + +

Not Found

+

Sorry, the content you are looking for does not exist.

\ No newline at end of file diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Routes.razor b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Routes.razor new file mode 100644 index 00000000..105855d4 --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Routes.razor @@ -0,0 +1,6 @@ + + + + + + diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/_Imports.razor b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/_Imports.razor new file mode 100644 index 00000000..b4a23038 --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/_Imports.razor @@ -0,0 +1,13 @@ +@using System.Net.Http +@using System.Net.Http.Json +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using static Microsoft.AspNetCore.Components.Web.RenderMode +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop +@using GanttGraphQL +@using GanttGraphQL.Components +@using GanttGraphQL.Components.Layout +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Navigations \ No newline at end of file diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/GanttGraphQL.csproj b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/GanttGraphQL.csproj new file mode 100644 index 00000000..90cb3772 --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/GanttGraphQL.csproj @@ -0,0 +1,27 @@ + + + + net10.0 + enable + enable + true + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/GanttGraphQL.csproj.user b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/GanttGraphQL.csproj.user new file mode 100644 index 00000000..c404400a --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/GanttGraphQL.csproj.user @@ -0,0 +1,9 @@ + + + + https + + + ProjectDebugger + + \ No newline at end of file diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/DataManagerRequest.cs b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/DataManagerRequest.cs new file mode 100644 index 00000000..7376a752 --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/DataManagerRequest.cs @@ -0,0 +1,99 @@ +using HotChocolate; +using Syncfusion.Blazor.Data; +using System.Collections.Generic; + +namespace GanttGraphQL.Models +{ + /// + /// Represents the input structure for data manager requests from the Gantt Chart. + /// Contains all parameters needed for data operations like filtering, sorting, and searching. + /// + public class DataManagerRequestInput + { + /// + /// Number of records to skip from the beginning. + /// Example: Skip=10 means start from the 11th record. + /// + [GraphQLName("Skip")] + public int Skip { get; set; } + + /// + /// Number of records to retrieve. + /// Example: Take=10 means retrieve 10 records per page. + /// + [GraphQLName("Take")] + public int Take { get; set; } + + /// + /// Indicates whether the total record count should be calculated. + /// Set to true when pagination requires knowing the total number of records. + /// + [GraphQLName("RequiresCounts")] + public bool RequiresCounts { get; set; } = false; + + /// + /// Additional custom parameters sent from the client. + /// Used for advanced scenarios requiring extra metadata. + /// + [GraphQLName("Params")] + [GraphQLType(typeof(AnyType))] + public IDictionary Params { get; set; } + + /// + /// Collection of search expressions used for keyword matching. + /// Example: searching across task name, duration, or other fields. + /// + [GraphQLName("Search")] + public List? Search { get; set; } + + /// + /// Collection of sorting instructions. + /// Supports multi-column sorting (e.g., sort by StartDate, then by TaskID). + /// + [GraphQLName("Sorted")] + public List? Sorted { get; set; } + + /// + /// Collection of filtering conditions (where clauses). + /// Supports operators like equals, contains, greater-than, etc. + /// + [GraphQLName("Where")] + [GraphQLType(typeof(AnyType))] + public List? Where { get; set; } + + /// + /// Table name associated with the request. + /// Commonly unused but included for DataManager compatibility. + /// + /// List of field names to select from the dataset. + /// Useful when projecting only selected columns. + /// + [GraphQLName("Select")] + public List? Select { get; set; } + + /// + /// Indicates whether server‑side grouping is enabled. + /// Required for hierarchical data scenarios. + /// + [GraphQLName("ServerSideGroup")] + public bool? ServerSideGroup { get; set; } + + /// + /// Indicates whether lazy loading is enabled for hierarchical data. + /// Used mainly by Gantt to load child records on demand. + /// + [GraphQLName("LazyLoad")] + public bool? LazyLoad { get; set; } + + /// + /// Indicates whether all groups should be expanded during lazy loading. + /// Used when the UI expands grouped records automatically. + /// + [GraphQLName("LazyExpandAllGroup")] + public bool? LazyExpandAllGroup { get; set; } + } +} \ No newline at end of file diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GanttDbContext.cs b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GanttDbContext.cs new file mode 100644 index 00000000..08ee4b51 --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GanttDbContext.cs @@ -0,0 +1,43 @@ +using Microsoft.EntityFrameworkCore; + +namespace GanttGraphQL.Models +{ + public class GanttDbContext : DbContext + { + public GanttDbContext(DbContextOptions options) : base(options) { } + + public DbSet Tasks => Set(); + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .ToTable("TaskData") + .HasKey(t => t.TaskID); + + modelBuilder.Entity() + .Property(t => t.TaskID).HasColumnName("TaskID").IsRequired(); + + modelBuilder.Entity() + .Property(t => t.TaskName).HasColumnName("TaskName").IsRequired(); + + modelBuilder.Entity() + .Property(t => t.StartDate).HasColumnName("StartDate"); + + modelBuilder.Entity() + .Property(t => t.EndDate).HasColumnName("EndDate"); + + modelBuilder.Entity() + .Property(t => t.Duration).HasColumnName("Duration"); + + modelBuilder.Entity() + .Property(t => t.Progress).HasColumnName("Progress"); + + modelBuilder.Entity() + .Property(t => t.Predecessor).HasColumnName("Predecessor"); + + modelBuilder.Entity() + .Property(t => t.ParentID).HasColumnName("ParentID"); + } + } +} + diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLMutation.cs b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLMutation.cs new file mode 100644 index 00000000..4f3616ab --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLMutation.cs @@ -0,0 +1,159 @@ +using HotChocolate; +using HotChocolate.Types; +using Microsoft.EntityFrameworkCore; + +namespace GanttGraphQL.Models +{ + /// + /// GraphQL mutation resolvers for Syncfusion Blazor Gantt. + /// Provides create, update, delete, and batch-update operations for tasks. + /// + public class GraphQLMutation + { + /// + /// Creates a new task record and persists it to the database. + /// Applies defaults for missing values (TaskName, StartDate, Duration, Progress). + /// + /// The task payload received from the client. + /// The target insertion index (unused for EF set ordering). + /// The action name sent by the client (e.g., "insert"). + /// Additional custom parameters sent from the client. + /// The EF Core database context. + /// The created entity. + public TaskDataModel CreateTask(TaskDataModel record, int index, string action, [GraphQLType(typeof(AnyType))] IDictionary additionalParameters, [Service] GanttDbContext db) + { + TaskDataModel? entity = new TaskDataModel + { + TaskName = string.IsNullOrWhiteSpace(record.TaskName) ? "New Task" : record.TaskName!, + StartDate = record.StartDate ?? DateTime.Now, + EndDate = record.EndDate, + Duration = record.Duration ?? "1", + Progress = record.Progress ?? 0, + Predecessor = record.Predecessor, + ParentID = record.ParentID + }; + + db.Tasks.Add(entity); + db.SaveChangesAsync(); + return entity; + } + + /// + /// Updates an existing task by primary key and persists the changes. + /// + /// The incoming task payload with updated values. + /// The action name sent by the client (e.g., "update"). + /// The primary key column name (e.g., "TaskID"). + /// The primary key value of the task to update. + /// Additional custom parameters sent from the client. + /// The EF Core database context. + /// The updated entity. + public TaskDataModel UpdateTask(TaskDataModel record, string action, string primaryColumnName, int primaryColumnValue, [GraphQLType(typeof(AnyType))] IDictionary additionalParameters, [Service] GanttDbContext db) + { + if (record == null) + throw new ArgumentNullException(nameof(record), "Task cannot be null"); + + TaskDataModel? previousRecord = db.Tasks.FirstOrDefault(x => x.TaskID == primaryColumnValue); + + previousRecord.TaskName = record.TaskName; + previousRecord.StartDate = record.StartDate; + previousRecord.EndDate = record.EndDate; + previousRecord.Duration = record.Duration; + previousRecord.Progress = record.Progress; + previousRecord.Predecessor = record.Predecessor; + previousRecord.ParentID = record.ParentID; + + db.SaveChangesAsync(); + return previousRecord; + } + + /// + /// Deletes a task by its key. + /// + /// The primary key value of the task to delete. + /// Additional custom parameters sent from the client. + /// The EF Core database context. + /// + /// if the task was found and removed; otherwise, . + /// + public bool DeleteTask([ID][GraphQLName("key")] int key, [GraphQLType(typeof(AnyType))] IDictionary additionalParameters, [Service] GanttDbContext db) + { + TaskDataModel record = db.Tasks.FirstOrDefault(t => t.TaskID == key); + if (record == null) return false; + + db.Tasks.Remove(record); + db.SaveChangesAsync(); + return true; + } + + /// + /// Applies batch operations (update, add, delete) to tasks in a single request and saves changes. + /// + /// The collection of modified task records to update. + /// The collection of new task records to insert. + /// The collection of task records to remove. + /// The batch action name sent by the client. + /// The primary key column name (e.g., "TaskID"). + /// Additional custom parameters sent from the client. + /// Target insert index (not applied unless you maintain an order column). + /// The EF Core database context. + /// The full list of tasks after applying the batch update. + public List BatchUpdate(List? changed, List? added, List? deleted, string action, string primaryColumnName, [GraphQLType(typeof(AnyType))] IDictionary additionalParameters, int? dropIndex, [Service] GanttDbContext db) + { + // Update existing tasks + if (changed != null) + { + foreach (TaskDataModel task in changed) + { + TaskDataModel record = db.Tasks.FirstOrDefault(t => t.TaskID == task.TaskID); + if (record != null) + { + record.TaskName = string.IsNullOrWhiteSpace(task.TaskName) ? record.TaskName : task.TaskName!; + record.StartDate = task.StartDate ?? record.StartDate; + record.EndDate = task.EndDate; + record.Duration = task.Duration ?? record.Duration; + record.Progress = task.Progress ?? record.Progress; + record.Predecessor = task.Predecessor; + record.ParentID = task.ParentID; + } + } + } + + // Add new tasks + if (added != null) + { + foreach (TaskDataModel task in added) + { + TaskDataModel record = new TaskDataModel + { + // TaskID is assumed to be identity; do not set it + TaskName = string.IsNullOrWhiteSpace(task.TaskName) ? "New Task" : task.TaskName!, + StartDate = task.StartDate ?? DateTime.Now, + EndDate = task.EndDate, + Duration = task.Duration ?? "1", + Progress = task.Progress ?? 0, + Predecessor = task.Predecessor, + ParentID = task.ParentID + }; + db.Tasks.Add(record); + } + } + + // Delete tasks + if (deleted != null) + { + foreach (TaskDataModel task in deleted) + { + TaskDataModel record = db.Tasks.FirstOrDefault(t => t.TaskID == task.TaskID); + if (record != null) + { + db.Tasks.Remove(record); + } + } + } + + db.SaveChanges(); + return db.Tasks.ToList(); + } + } +} diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLQuery.cs b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLQuery.cs new file mode 100644 index 00000000..19bb81e2 --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLQuery.cs @@ -0,0 +1,98 @@ +using HotChocolate; +using HotChocolate.Types; +using Microsoft.EntityFrameworkCore; +using Syncfusion.Blazor; +namespace GanttGraphQL.Models +{ + /// + /// GraphQL query resolver for the Syncfusion GraphQLAdaptor used by the Gantt Chart. + /// Exposes a field named taskData that accepts DataManager request parameters + /// and returns a payload containing the result set and total record count. + /// + public class GraphQLQuery + { + /// + /// Retrieves Gantt Chart task data and returns it along with the total record count. + /// Applies searching, filtering, sorting, skip, and take based on the incoming DataManager request parameters from the GraphQLAdaptor. + /// + /// + /// The data manager request input containing query parameters such as search, where (filters), sorted (multi-column sort), skip, take. + /// + /// The EF Core database context used to query task records. + /// + /// An instance of containing the filtered task list + /// and the corresponding record count (total count when RequiresCounts is true). + /// + [GraphQLName("taskData")] + public async Task GetTaskData([GraphQLName("dataManager")] DataManagerRequestInput dataManagerInput, [Service] GanttDbContext db) + { + DataManagerRequestInput dm = dataManagerInput ?? new DataManagerRequestInput + { + Skip = 0, + Take = 0, + RequiresCounts = false + }; + + List dataSource = await db.Tasks + .AsNoTracking() + .OrderBy(t => t.TaskID) + .ToListAsync(); + + IEnumerable query = dataSource; + + // 1) Searching + if (dm.Search is { Count: > 0 }) + { + query = DataOperations.PerformSearching(query, dm.Search); + } + + // 2) Filtering + if (dm.Where is { Count: > 0 }) + { + // Base condition "and"/"or" (default to "and" if missing) + string? baseCondition = dm.Where[0].Condition ?? dm.Where[0].Operator; + if (string.IsNullOrWhiteSpace(baseCondition)) baseCondition = "and"; + + query = DataOperations.PerformFiltering(query, dm.Where, baseCondition); + } + + // 3) Sorting (multi-column supported) + if (dm.Sorted is { Count: > 0 }) + { + query = DataOperations.PerformSorting(query, dm.Sorted); + } + + int totalCount = query.Count(); + + if (dm.Skip > 0) query = DataOperations.PerformSkip(query, dm.Skip); + if (dm.Take > 0) query = DataOperations.PerformTake(query, dm.Take); + + return new TaskDataResponse + { + Count = dm.RequiresCounts ? totalCount : query.Count(), // return total only if asked + Result = query.ToList() + }; + } + } + + /// + /// Response payload expected by the Syncfusion GraphQLAdaptor for list queries. + /// Must expose count and result fields to enable paging and total count. + /// + public class TaskDataResponse + { + /// + /// Total number of records for the current query. + /// When RequiresCounts is true in the request, this should reflect the total + /// count before paging; otherwise it may be the count of the returned page. + /// + [GraphQLName("count")] + public int Count { get; set; } + + /// + /// The collection of task records returned for the current request. + /// + [GraphQLName("result")] + public List Result { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/TaskDataModel.cs b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/TaskDataModel.cs new file mode 100644 index 00000000..4a99ae66 --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/TaskDataModel.cs @@ -0,0 +1,33 @@ +using System.Text.Json.Serialization; + +namespace GanttGraphQL.Models +{ + public class TaskDataModel + { + [JsonPropertyName("taskID")] + public int? TaskID { get; set; } + + [JsonPropertyName("taskName")] + public string? TaskName { get; set; } + + [JsonPropertyName("startDate")] + public DateTime? StartDate { get; set; } + + [JsonPropertyName("endDate")] + public DateTime? EndDate { get; set; } + + [JsonPropertyName("duration")] + public string? Duration { get; set; } + + [JsonPropertyName("progress")] + public int? Progress { get; set; } + + [JsonPropertyName("predecessor")] + public string? Predecessor { get; set; } + + [JsonPropertyName("parentID")] + public int? ParentID { get; set; } + } +} + + diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Program.cs b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Program.cs new file mode 100644 index 00000000..64382e8f --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Program.cs @@ -0,0 +1,47 @@ +using GanttGraphQL.Components; +using GanttGraphQL.Models; +using Microsoft.EntityFrameworkCore; +using Syncfusion.Blazor; + +var builder = WebApplication.CreateBuilder(args); + +var cs = builder.Configuration.GetConnectionString("GanttDb"); +builder.Services.AddDbContext(options => + options.UseSqlite(cs)); + +builder.Services.AddSyncfusionBlazor(); +builder.Services.AddServerSideBlazor() + .AddCircuitOptions(options => { options.DetailedErrors = true; }); + +// Add services to the container. +builder.Services.AddRazorComponents() + .AddInteractiveServerComponents(); + +// Register GraphQL services. +builder.Services.AddGraphQLServer().AddQueryType().AddMutationType().ModifyRequestOptions(o => o.IncludeExceptionDetails = true); + +// Add services to the container. +builder.Services.AddRazorComponents() + .AddInteractiveServerComponents(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Error", createScopeForErrors: true); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); +} +app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true); +app.UseHttpsRedirection(); + +app.UseAntiforgery(); + +app.MapStaticAssets(); +app.MapRazorComponents() + .AddInteractiveServerRenderMode(); + +app.MapGraphQL("/graphql"); // Maps the /graphql endpoint by default. + +app.Run(); diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Properties/launchSettings.json b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Properties/launchSettings.json new file mode 100644 index 00000000..11daf84f --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Properties/launchSettings.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5167", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7000;http://localhost:5167", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } + } diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/appsettings.Development.json b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/appsettings.Development.json new file mode 100644 index 00000000..0c208ae9 --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/appsettings.json b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/appsettings.json new file mode 100644 index 00000000..459da8c8 --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/appsettings.json @@ -0,0 +1,13 @@ +{ + "ConnectionStrings": { + "GanttDb": "Data Source=D:\\GanttGraphQL\\GanttDB.db" + }, + + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/wwwroot/app.css b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/wwwroot/app.css new file mode 100644 index 00000000..73a69d6f --- /dev/null +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/wwwroot/app.css @@ -0,0 +1,60 @@ +html, body { + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; +} + +a, .btn-link { + color: #006bb7; +} + +.btn-primary { + color: #fff; + background-color: #1b6ec2; + border-color: #1861ac; +} + +.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus { + box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb; +} + +.content { + padding-top: 1.1rem; +} + +h1:focus { + outline: none; +} + +.valid.modified:not([type=checkbox]) { + outline: 1px solid #26b050; +} + +.invalid { + outline: 1px solid #e50000; +} + +.validation-message { + color: #e50000; +} + +.blazor-error-boundary { + background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; + padding: 1rem 1rem 1rem 3.7rem; + color: white; +} + + .blazor-error-boundary::after { + content: "An error has occurred." + } + +.darker-border-checkbox.form-check-input { + border-color: #929292; +} + +.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder { + color: var(--bs-secondary-color); + text-align: end; +} + +.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder { + text-align: start; +} \ No newline at end of file diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/wwwroot/favicon.png b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/wwwroot/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..8422b59695935d180d11d5dbe99653e711097819 GIT binary patch literal 1148 zcmV-?1cUpDP)9h26h2-Cs%i*@Moc3?#6qJID|D#|3|2Hn7gTIYEkr|%Xjp);YgvFmB&0#2E2b=| zkVr)lMv9=KqwN&%obTp-$<51T%rx*NCwceh-E+=&e(oLO`@Z~7gybJ#U|^tB2Pai} zRN@5%1qsZ1e@R(XC8n~)nU1S0QdzEYlWPdUpH{wJ2Pd4V8kI3BM=)sG^IkUXF2-j{ zrPTYA6sxpQ`Q1c6mtar~gG~#;lt=s^6_OccmRd>o{*=>)KS=lM zZ!)iG|8G0-9s3VLm`bsa6e ze*TlRxAjXtm^F8V`M1%s5d@tYS>&+_ga#xKGb|!oUBx3uc@mj1%=MaH4GR0tPBG_& z9OZE;->dO@`Q)nr<%dHAsEZRKl zedN6+3+uGHejJp;Q==pskSAcRcyh@6mjm2z-uG;s%dM-u0*u##7OxI7wwyCGpS?4U zBFAr(%GBv5j$jS@@t@iI8?ZqE36I^4t+P^J9D^ELbS5KMtZ z{Qn#JnSd$15nJ$ggkF%I4yUQC+BjDF^}AtB7w348EL>7#sAsLWs}ndp8^DsAcOIL9 zTOO!!0!k2`9BLk25)NeZp7ev>I1Mn={cWI3Yhx2Q#DnAo4IphoV~R^c0x&nw*MoIV zPthX?{6{u}sMS(MxD*dmd5rU(YazQE59b|TsB5Tm)I4a!VaN@HYOR)DwH1U5y(E)z zQqQU*B%MwtRQ$%x&;1p%ANmc|PkoFJZ%<-uq%PX&C!c-7ypis=eP+FCeuv+B@h#{4 zGx1m0PjS~FJt}3mdt4c!lel`1;4W|03kcZRG+DzkTy|7-F~eDsV2Tx!73dM0H0CTh zl)F-YUkE1zEzEW(;JXc|KR5{ox%YTh{$%F$a36JP6Nb<0%#NbSh$dMYF-{ z1_x(Vx)}fs?5_|!5xBTWiiIQHG<%)*e=45Fhjw_tlnmlixq;mUdC$R8v#j( zhQ$9YR-o%i5Uc`S?6EC51!bTRK=Xkyb<18FkCKnS2;o*qlij1YA@-nRpq#OMTX&RbL<^2q@0qja!uIvI;j$6>~k@IMwD42=8$$!+R^@5o6HX(*n~ + cd "Binding SQLite using GraphQL Adaptor" + cd "Blazor Web app/GanttGraphQL" + ``` + +2. **Create the database and table** + + Open DB Browser for SQLite and Create Database GanttDB in the desired location + ```sql + + CREATE TABLE IF NOT EXISTS TaskData ( + TaskID INTEGER PRIMARY KEY, + TaskName TEXT NOT NULL, + StartDate DATETIME, + EndDate DATETIME, + Duration TEXT, + Progress INTEGER, + Predecessor TEXT, + ParentID INTEGER + ); + ``` + +3. **Update the connection string** + + SQLite uses a **file‑based database**, so to connect to the database, simply point to the location of the .db file. + The key **GanttDb** refers to the database name used by the application and it can be renamed as needed. + + Open `appsettings.json` and configure the SQLite connection: + ```json + { + "ConnectionStrings": { + "GanttDb": "Data Source=D:\\GanttGraphQL\\GanttDB.db" + }, + "AllowedHosts": "*" + } + ``` + +4. **Restore packages and build** + ```bash + dotnet restore + dotnet build + ``` + +5. **Run the application** + ```bash + dotnet run + ``` + +6. **Open the application** + + Navigate to the local URL displayed in the terminal (typically `https://localhost:xxxx`). + +7. **Access GraphQL Playground (Optional)** + + Navigate to `https://localhost:70xx/graphql` (Replace `70xx` with the port number shown in the **launchSettings.json**) to explore the GraphQL schema and test queries/mutations manually. + +## Configuration + +### GraphQL Endpoint Port Configuration + +The GraphQL endpoint port is configured in `Properties/launchSettings.json`. This file controls where the application runs and where the GraphQL endpoint is exposed. + +**Instructions to Change the Port:** + +1. Open `Properties/launchSettings.json` in the project root. +2. Locate the `https` profile section: + +```json +"https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7000;http://localhost:5167", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } +} +``` + +3. Modify the `applicationUrl` property to change port numbers: + - `https://localhost:7000` - HTTPS port for GraphQL endpoint + - `http://localhost:5167` - HTTP port for GraphQL endpoint + +4. Update the Gantt Chart connection URL in `Components/Pages/Home.razor` to match the configured port: + ```html + + ``` + +**Important Notes:** +- Port numbers must be between 1024 and 65535 +- Avoid using ports already in use by other applications +- The GraphQL endpoint is always accessible at `/graphql` path (configured via `app.MapGraphQL()` in Program.cs) + +### GraphQL Adaptor Configuration + +The `GraphQLAdaptorOptions` in `Home.razor` defines how the Gantt Chart communicates with the GraphQL backend. This configuration specifies: + +- **Query**: GraphQL query for reading task records with data operations support +- **ResolverName**: The backend resolver method name — for the Gantt Chart sample this refers to TaskData (or whatever you named your GraphQL query resolver that returns the task list) +- **Mutation.Insert**: GraphQL mutation for creating new tasks +- **Mutation.Update**: GraphQL mutation for updating existing tasks +- **Mutation.Delete**: GraphQL mutation for deleting tasks +- **Mutation.Batch**: GraphQL mutation for batch operations + +## Project Layout + +| File/Folder | Purpose | +|-------------|---------| +| `/Models/TaskDataModel.cs` | Data model representing Task Data | +| `/Models/GraphQLQuery.cs` | Query resolvers for retrieving task data (e.g., GetTaskData) | +| `/Models/GraphQLMutation.cs` | Mutation resolvers for creating, updating, deleting, and batch-updating tasks | +| `/Models/DataManagerRequestInput.cs` | Input type for data operation parameters (filter, sort, search) | +| `/Components/Pages/Home.razor` | Gantt Chart page with GraphQL adaptor configuration and task management UI | +| `/Program.cs` | Service registration for Hot Chocolate GraphQL server | +| `/Properties/launchSettings.json` | Port configuration for GraphQL endpoint | + +## Common Tasks + +### Add a Task +1. Click the **Add** button in the toolbar +2. Fill in the Dialog fields +3. Click **Save** to persist the record to the database + +### Edit a Task +1. Select a task row in the Gantt Chart +2. Click the **Edit** button in the toolbar +3. Modify the required fields +4. Click **Save** to save changes + +### Delete a Task +1. Select a task row in the Gantt Chart +2. Click the **Delete** button in the toolbar +3. Confirm the deletion in the dialog + +### Search Records +1. Use the **Search** box in the toolbar +2. Enter keywords to filter records (searches across all columns) + +### Filter Records +1. Click the filter icon in any column header +2. Select filter criteria (equals, contains, greater than, etc.) +3. Click **Filter** to apply + +### Sort Records +1. Click the column header to sort ascending +2. Click again to sort descending + +## Troubleshooting + +### GraphQL Endpoint Not Responding + +- Verify the application is running: Check terminal for `Now listening on: https://localhost:70xx` (Replace `70xx` with the port number shown in the **launchSettings.json**) +- Confirm the URL in `SfDataManager` matches the running port +- Ensure `app.MapGraphQL()` is configured in `Program.cs` +- Check firewall settings if accessing from a different machine + +### Static Files Not Loading (CSS/Scripts) + +- Verify Syncfusion stylesheet is referenced in `Components/App.razor`: + ```html + + ``` +- Verify Syncfusion scripts are referenced in `Components/App.razor`: + ```html + + ``` +- Check browser developer tools (F12) for 404 errors on static resources + +### CRUD Operations Not Working + +- Verify the GraphQL endpoint URL in `Home.razor` SfDataManager matches the backend port +- Check browser console for GraphQL errors (Network tab → GraphQL requests) +- Ensure all GraphQL mutation resolvers are implemented in `GraphQLMutation.cs` +- Verify the `DataManagerRequestInput` class includes all required properties for data operations + +### Version Conflicts + +- Align HotChocolate.AspNetCore and Syncfusion package versions +- Run `dotnet restore` to update NuGet packages +- Check the `GanttGraphQLAdaptor.csproj` file for conflicting version constraints +- Verify all packages are compatible with .NET 10.0 or later + +### Connection Error +- Verify that the database file exists at the path specified in the connection string. +- Ensure the .db file is not locked or opened exclusively by another program. +- Confirm that the application has read/write permissions to the folder where the database file is stored. +- If you changed the database location or filename, make sure the Data Source= path is updated accordingly in **appsettings.json**. + +### Port Already in Use + +- Change the port numbers in `launchSettings.json` to available ports +- Or identify the process using the port: `Get-Process | Where-Object {$_.Handles -gt 500} | Select-Object Name, Id` +- Update the Gantt Chart connection URL to match the new port + From 497567e23d2f3c8a742484cee8d2d659b8422c03 Mon Sep 17 00:00:00 2001 From: PavithraG-SF5066 Date: Tue, 24 Feb 2026 11:16:24 +0530 Subject: [PATCH 2/5] 1011302: removed the favicon.png --- .../Components/Layout/MainLayout.razor | 6 +- .../Components/Layout/MainLayout.razor.css | 89 ------------------ .../GanttGraphQL/wwwroot/favicon.png | Bin 1148 -> 0 bytes .../README.md | 7 +- 4 files changed, 5 insertions(+), 97 deletions(-) delete mode 100644 Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/wwwroot/favicon.png diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor index a92fba16..755d03e3 100644 --- a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor @@ -1,9 +1,7 @@ @inherits LayoutComponentBase -
- -
- +
+
@Body
diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor.css b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor.css index 38d1f259..116575a1 100644 --- a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor.css +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Layout/MainLayout.razor.css @@ -7,92 +7,3 @@ main { flex: 1; } - -.sidebar { - background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); -} - -.top-row { - background-color: #f7f7f7; - border-bottom: 1px solid #d6d5d5; - justify-content: flex-end; - height: 3.5rem; - display: flex; - align-items: center; -} - - .top-row ::deep a, .top-row ::deep .btn-link { - white-space: nowrap; - margin-left: 1.5rem; - text-decoration: none; - } - - .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { - text-decoration: underline; - } - - .top-row ::deep a:first-child { - overflow: hidden; - text-overflow: ellipsis; - } - -@media (max-width: 640.98px) { - .top-row { - justify-content: space-between; - } - - .top-row ::deep a, .top-row ::deep .btn-link { - margin-left: 0; - } -} - -@media (min-width: 641px) { - .page { - flex-direction: row; - } - - .sidebar { - width: 250px; - height: 100vh; - position: sticky; - top: 0; - } - - .top-row { - position: sticky; - top: 0; - z-index: 1; - } - - .top-row.auth ::deep a:first-child { - flex: 1; - text-align: right; - width: 0; - } - - .top-row, article { - padding-left: 2rem !important; - padding-right: 1.5rem !important; - } -} - -#blazor-error-ui { - color-scheme: light only; - background: lightyellow; - bottom: 0; - box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); - box-sizing: border-box; - display: none; - left: 0; - padding: 0.6rem 1.25rem 0.7rem 1.25rem; - position: fixed; - width: 100%; - z-index: 1000; -} - - #blazor-error-ui .dismiss { - cursor: pointer; - position: absolute; - right: 0.75rem; - top: 0.5rem; - } diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/wwwroot/favicon.png b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/wwwroot/favicon.png deleted file mode 100644 index 8422b59695935d180d11d5dbe99653e711097819..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1148 zcmV-?1cUpDP)9h26h2-Cs%i*@Moc3?#6qJID|D#|3|2Hn7gTIYEkr|%Xjp);YgvFmB&0#2E2b=| zkVr)lMv9=KqwN&%obTp-$<51T%rx*NCwceh-E+=&e(oLO`@Z~7gybJ#U|^tB2Pai} zRN@5%1qsZ1e@R(XC8n~)nU1S0QdzEYlWPdUpH{wJ2Pd4V8kI3BM=)sG^IkUXF2-j{ zrPTYA6sxpQ`Q1c6mtar~gG~#;lt=s^6_OccmRd>o{*=>)KS=lM zZ!)iG|8G0-9s3VLm`bsa6e ze*TlRxAjXtm^F8V`M1%s5d@tYS>&+_ga#xKGb|!oUBx3uc@mj1%=MaH4GR0tPBG_& z9OZE;->dO@`Q)nr<%dHAsEZRKl zedN6+3+uGHejJp;Q==pskSAcRcyh@6mjm2z-uG;s%dM-u0*u##7OxI7wwyCGpS?4U zBFAr(%GBv5j$jS@@t@iI8?ZqE36I^4t+P^J9D^ELbS5KMtZ z{Qn#JnSd$15nJ$ggkF%I4yUQC+BjDF^}AtB7w348EL>7#sAsLWs}ndp8^DsAcOIL9 zTOO!!0!k2`9BLk25)NeZp7ev>I1Mn={cWI3Yhx2Q#DnAo4IphoV~R^c0x&nw*MoIV zPthX?{6{u}sMS(MxD*dmd5rU(YazQE59b|TsB5Tm)I4a!VaN@HYOR)DwH1U5y(E)z zQqQU*B%MwtRQ$%x&;1p%ANmc|PkoFJZ%<-uq%PX&C!c-7ypis=eP+FCeuv+B@h#{4 zGx1m0PjS~FJt}3mdt4c!lel`1;4W|03kcZRG+DzkTy|7-F~eDsV2Tx!73dM0H0CTh zl)F-YUkE1zEzEW(;JXc|KR5{ox%YTh{$%F$a36JP6Nb<0%#NbSh$dMYF-{ z1_x(Vx)}fs?5_|!5xBTWiiIQHG<%)*e=45Fhjw_tlnmlixq;mUdC$R8v#j( zhQ$9YR-o%i5Uc`S?6EC51!bTRK=Xkyb<18FkCKnS2;o*qlij1YA@-nRpq#OMTX&RbL<^2q@0qja!uIvI;j$6>~k@IMwD42=8$$!+R^@5o6HX(*n~ Date: Tue, 24 Feb 2026 11:24:44 +0530 Subject: [PATCH 3/5] 1011302: remove unwanted spaces. --- .../GanttGraphQL/Components/Pages/Home.razor | 87 ++++++++----------- 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Pages/Home.razor b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Pages/Home.razor index 39c9be5d..ac55eaad 100644 --- a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Pages/Home.razor +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Components/Pages/Home.razor @@ -10,14 +10,9 @@ Width="100%" AllowFiltering="true" AllowSorting="true" - TreeColumnIndex="1" - EnableContextMenu="true" Toolbar="@ToolbarItems"> - - + - @@ -76,33 +68,29 @@ public List ToolbarItems = new() { "Add", "Edit", "Update", "Delete", "Search" }; - // GraphQL adaptor configuration: ResolverName must match your server method (PascalCase) - // and the query must select count + result with the fields the Gantt needs. private Syncfusion.Blazor.Data.GraphQLAdaptorOptions AdaptorOptions => new() { ResolverName = "TaskData", - Query = @" - query TaskData($dataManager: DataManagerRequestInput!) { - taskData(dataManager: $dataManager) { - count - result { - taskID - taskName - startDate - endDate - duration - progress - predecessor - parentID - } - } - }", + Query = @"query TaskData($dataManager: DataManagerRequestInput!) { + taskData(dataManager: $dataManager) { + count + result { + taskID + taskName + startDate + endDate + duration + progress + predecessor + parentID + } + } + }", Mutation = new Syncfusion.Blazor.Data.GraphQLMutation { // INSERT (matches InsertTask parameters) - Insert = @" - mutation create($record: TaskDataModelInput!, $index: Int!, $action: String!, $additionalParameters: Any) { + Insert = @"mutation create($record: TaskDataModelInput!, $index: Int!, $action: String!, $additionalParameters: Any) { createTask(record: $record, index: $index, action: $action, additionalParameters: $additionalParameters) { taskID taskName @@ -114,28 +102,29 @@ parentID } }", - Update = @"mutation update($record: TaskDataModelInput!, $action: String!, $primaryColumnName: String!, $primaryColumnValue: Int!, $additionalParameters: Any) { + Update = @"mutation update($record: TaskDataModelInput!, $action: String!, $primaryColumnName: String!, $primaryColumnValue: Int!, $additionalParameters: Any) { updateTask(record: $record, action: $action, primaryColumnName: $primaryColumnName, primaryColumnValue: $primaryColumnValue, additionalParameters: $additionalParameters) { taskID taskName startDate endDate duration progress predecessor parentID } - }", + }", // DELETE (matches DeleteTask parameters) - Delete = @"mutation delete($primaryColumnValue: ID!, $additionalParameters: Any) { + Delete = @"mutation delete($primaryColumnValue: ID!, $additionalParameters: Any) { deleteTask(key: $primaryColumnValue, additionalParameters: $additionalParameters) }", - Batch = @"mutation batch($changed: [TaskDataModelInput!], $added: [TaskDataModelInput!], $deleted: [TaskDataModelInput!], $action: String!, $primaryColumnName: String!, $additionalParameters: Any, $dropIndex: Int) { - batchUpdate(changed: $changed, added: $added, deleted: $deleted, action: $action, primaryColumnName: $primaryColumnName, additionalParameters: $additionalParameters, dropIndex: $dropIndex) { - taskID - taskName - startDate - endDate - duration - progress - predecessor - parentID - } - }" + + Batch = @"mutation batch($changed: [TaskDataModelInput!], $added: [TaskDataModelInput!], $deleted: [TaskDataModelInput!], $action: String!, $primaryColumnName: String!, $additionalParameters: Any, $dropIndex: Int) { + batchUpdate(changed: $changed, added: $added, deleted: $deleted, action: $action, primaryColumnName: $primaryColumnName, additionalParameters: $additionalParameters, dropIndex: $dropIndex) { + taskID + taskName + startDate + endDate + duration + progress + predecessor + parentID + } + }" } }; } From 1a0d502e4838c500714b6c696e0df20149a3545e Mon Sep 17 00:00:00 2001 From: PavithraG-SF5066 Date: Tue, 24 Feb 2026 12:48:00 +0530 Subject: [PATCH 4/5] 1011302: code changes --- .../GanttGraphQL/Models/GraphQLQuery.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLQuery.cs b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLQuery.cs index 19bb81e2..cc3f0d2f 100644 --- a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLQuery.cs +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLQuery.cs @@ -46,16 +46,16 @@ public async Task GetTaskData([GraphQLName("dataManager")] Dat query = DataOperations.PerformSearching(query, dm.Search); } - // 2) Filtering - if (dm.Where is { Count: > 0 }) + // Filtering + if (dm.Where != null && dm.Where.Count > 0) { - // Base condition "and"/"or" (default to "and" if missing) - string? baseCondition = dm.Where[0].Condition ?? dm.Where[0].Operator; - if (string.IsNullOrWhiteSpace(baseCondition)) baseCondition = "and"; - - query = DataOperations.PerformFiltering(query, dm.Where, baseCondition); + if (dm.Where[0].Field != null && dm.Where[0].Field == nameof(TaskDataModel.ParentID)) { } + else + { + query = DataOperations.PerformFiltering(query, dm.Where, dm.Where[0].Operator); + } } - + // 3) Sorting (multi-column supported) if (dm.Sorted is { Count: > 0 }) { From 80251a54b858b90adeaf0a8c8e4150d4e0385e02 Mon Sep 17 00:00:00 2001 From: PavithraG-SF5066 Date: Tue, 24 Feb 2026 14:07:06 +0530 Subject: [PATCH 5/5] 1011302: changed the file path for db connection. --- .../Blazor Web app/GanttDB.db | Bin 16384 -> 16384 bytes .../GanttGraphQL/Models/GraphQLMutation.cs | 8 ++++---- .../GanttGraphQL/appsettings.json | 2 +- .../README.md | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttDB.db b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttDB.db index 7c89eb77d54b4348ab43b67f9a4f39a0901f03da..8d116b73065484a9b3394a1d2403f9d109c68385 100644 GIT binary patch literal 16384 zcmeI2-E!MR6vtO~aiZ9g4QVG=fi0ggO{rFnow&3EPHeXx64zKRCEPH=-o(a^Lz{6s4VP$ny`R=A~e>378dorxrz8#+vJMCJfQ=^^A z_AdO4dg+?BMBxzEjjCwD(W!mep{;gfuhQP9pVjth^G=60@9yrdPmP=Q5uX}AWnlTX z=Y#XWq6%I+jlJ4>U>=T8b9!+%rOz^`9(%Swa2@F)a^3RWLyu1;!Tmeune8HY>zvBlx3vVmh!DcYURomWj~-cxj%w^=hqW{|Cl>4*!*R3j^R_C zYYre;2W1{gLJwwQPmKBSS~M^0Mdu}od3I|4moozVH2nv1G5v^S|H%HF{UZCW{zU&J z{Yba;x3#~u$J$TYSK3{Nt@D_t#jvt&6n=_W@h;N<| zv*#4wUQkIH!d5h;4SS@4$B$r7HKDg`zt6pab126toz0+3;|$D|RQV!|bop|2@shIR z_BgG3oIl|7eR|t=dhQAL;*reav}Lez-O3e~ft`@Pr8FF$ABI~+X(d6J8z$SVTkC8K zM4NA@q!{|EdoIYF9otn85=NHm*~J#K#JZG0RGqG7><=>-J%P-1Uz=4)jEv z($iE2*oE%Hv`XF!0YoXa`u2oBLr~f=_w0k|yvT*XOcRPAbxn=( zSXSjbYzGENSTW&xhldDF5Iz*|6t$@#9M~g(%6!%vZ$OCtl7LM zQf2v^a{nX+@dxXIv_`h$z)GNV*&1ip11re&P+DNG#nGudeRzAqJz5!$J@>>O$(Upb z7)4{FZW$LsX3DaZ%-4*uF_p46paNkx)q` z6vDfmA@94R9z@va!O9sN47zi5ZOlAOSdY~$rl^DoH6gLvh5-K`Dos2sbMVLgf94;X zc!dOz01`j~NB{{S0VIF~kN^@u0!RP}yvhVJN^(_+|1BjklgVs*<~BBw01`j~NB{{S Z0VIF~kN^@u0!RP}Ac0qzKr%_xe*qY10O0@t delta 484 zcmZo@U~Fh$oFL7pJyFJ)QF~*;LVjWX0}RZ3KNT;!u6UU zDa5Cj#g+-AxgKbEzA~YBSHJIrd80i{;HJF%K8CyVvjCBow zLY7trW>$tKW_o7kwkB@Dx<-1&3Mq+|#a1j3r`IF<8{~F~VI~R&rd9?PaKnJ+o5F<* rAx_71IWc+--GUhy80^784)nMQEX)xeL0ANLjv2ykpeGC$DJTE{mP2GW diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLMutation.cs b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLMutation.cs index 4f3616ab..1ff4a191 100644 --- a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLMutation.cs +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/Models/GraphQLMutation.cs @@ -78,7 +78,7 @@ public TaskDataModel UpdateTask(TaskDataModel record, string action, string prim /// public bool DeleteTask([ID][GraphQLName("key")] int key, [GraphQLType(typeof(AnyType))] IDictionary additionalParameters, [Service] GanttDbContext db) { - TaskDataModel record = db.Tasks.FirstOrDefault(t => t.TaskID == key); + TaskDataModel? record = db.Tasks.FirstOrDefault(t => t.TaskID == key); if (record == null) return false; db.Tasks.Remove(record); @@ -105,7 +105,7 @@ public List BatchUpdate(List? changed, List t.TaskID == task.TaskID); + TaskDataModel? record = db.Tasks.FirstOrDefault(t => t.TaskID == task.TaskID); if (record != null) { record.TaskName = string.IsNullOrWhiteSpace(task.TaskName) ? record.TaskName : task.TaskName!; @@ -124,7 +124,7 @@ public List BatchUpdate(List? changed, List BatchUpdate(List? changed, List t.TaskID == task.TaskID); + TaskDataModel? record = db.Tasks.FirstOrDefault(t => t.TaskID == task.TaskID); if (record != null) { db.Tasks.Remove(record); diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/appsettings.json b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/appsettings.json index 459da8c8..c57d37b5 100644 --- a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/appsettings.json +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/Blazor Web app/GanttGraphQL/appsettings.json @@ -1,6 +1,6 @@ { "ConnectionStrings": { - "GanttDb": "Data Source=D:\\GanttGraphQL\\GanttDB.db" + "GanttDb": "Data Source=..\\GanttDB.db" }, "Logging": { diff --git a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/README.md b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/README.md index 33c0554e..501cabfb 100644 --- a/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/README.md +++ b/Gantt/IntegrationWithNet10/Binding SQLite using GraphQL Adaptor/README.md @@ -61,7 +61,7 @@ This repository demonstrates a production-ready pattern for binding **GraphQL** ```json { "ConnectionStrings": { - "GanttDb": "Data Source=D:\\GanttGraphQL\\GanttDB.db" + "GanttDb": "Data Source=D:..\\GanttDB.db" }, "AllowedHosts": "*" }