Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<ResourcePreloader />
<link rel="stylesheet" href="@Assets["lib/bootstrap/dist/css/bootstrap.min.css"]" />
<link rel="stylesheet" href="@Assets["app.css"]" />
<link rel="stylesheet" href="@Assets["Gantt_GraphQl.styles.css"]" />
<link href="_content/Syncfusion.Blazor.Themes/tailwind3.css" rel="stylesheet" />
</head>

<body>
<Routes />
<ReconnectModal />
<script src="_framework/blazor.web.js"></script>
<script src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js" type="text/javascript"></script>
</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@inherits LayoutComponentBase

<div class="page">
<main>
<article class="content px-4">
@Body
</article>
</main>
</div>

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}

main {
flex: 1;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<script type="module" src="@Assets["Components/Layout/ReconnectModal.razor.js"]"></script>

<dialog id="components-reconnect-modal" data-nosnippet>
<div class="components-reconnect-container">
<div class="components-rejoining-animation" aria-hidden="true">
<div></div>
<div></div>
</div>
<p class="components-reconnect-first-attempt-visible">
Rejoining the server...
</p>
<p class="components-reconnect-repeated-attempt-visible">
Rejoin failed... trying again in <span id="components-seconds-to-next-attempt"></span> seconds.
</p>
<p class="components-reconnect-failed-visible">
Failed to rejoin.<br />Please retry or reload the page.
</p>
<button id="components-reconnect-button" class="components-reconnect-failed-visible">
Retry
</button>
<p class="components-pause-visible">
The session has been paused by the server.
</p>
<button id="components-resume-button" class="components-pause-visible">
Resume
</button>
<p class="components-resume-failed-visible">
Failed to resume the session.<br />Please reload the page.
</p>
</div>
</dialog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
@page "/"
@rendermode InteractiveServer
@using Syncfusion.Blazor
@using Syncfusion.Blazor.Data
@using Syncfusion.Blazor.Gantt
@using GanttGraphQL.Models

<SfGantt TValue="TaskDataModel"
Height="560px"
Width="100%"
AllowFiltering="true"
AllowSorting="true"
Toolbar="@ToolbarItems">

<SfDataManager Url="https://localhost:7000/graphql" Adaptor="Adaptors.GraphQLAdaptor" GraphQLAdaptorOptions="@AdaptorOptions"></SfDataManager>

<GanttTaskFields Id="@nameof(TaskDataModel.TaskID)" Name="@nameof(TaskDataModel.TaskName)" StartDate="@nameof(TaskDataModel.StartDate)"
EndDate="@nameof(TaskDataModel.EndDate)" Duration="@nameof(TaskDataModel.Duration)" Progress="@nameof(TaskDataModel.Progress)"
Dependency="@nameof(TaskDataModel.Predecessor)" ParentID="@nameof(TaskDataModel.ParentID)">
</GanttTaskFields>

<GanttColumns>
<GanttColumn Field="@nameof(TaskDataModel.TaskID)" HeaderText="Task ID" IsPrimaryKey="true" Width="110"></GanttColumn>
<GanttColumn Field="@nameof(TaskDataModel.TaskName)" HeaderText="Task Name" Width="240"></GanttColumn>
<GanttColumn Field="@nameof(TaskDataModel.StartDate)" HeaderText="Start Date" Format="d" Width="140"></GanttColumn>
<GanttColumn Field="@nameof(TaskDataModel.EndDate)" HeaderText="End Date" Format="d" Width="140"></GanttColumn>
<GanttColumn Field="@nameof(TaskDataModel.Duration)" HeaderText="Duration" Width="130"></GanttColumn>
<GanttColumn Field="@nameof(TaskDataModel.Progress)" HeaderText="Progress" Width="130">
<Template>
@{
TaskDataModel? taskRecord = context as TaskDataModel;
if (taskRecord == null) return;

string progressText = $"{taskRecord.Progress}%";
}
<div class="e-progress-custom">
<div class="e-progress-outer">
<div class="e-progress-bar" style="width:@(taskRecord.Progress)%;">
</div>
</div>
<div class="e-progress-inner">
<span>@progressText</span>
</div>
</div>
</Template>
</GanttColumn>
<GanttColumn Field="@nameof(TaskDataModel.Predecessor)" HeaderText="Predecessor" Width="200">
<Template>
@{
TaskDataModel? task = context as TaskDataModel;
string? value = task?.Predecessor;

if (!string.IsNullOrWhiteSpace(value))
{
<div class="e-dependencies">@value</div>;
}
else
{
<div> - </div>;
}
}
</Template>
</GanttColumn>
</GanttColumns>
<GanttEditSettings AllowEditing="true" AllowTaskbarEditing="true" AllowAdding="true" AllowDeleting="true" />
</SfGantt>
@code {

public List<object> ToolbarItems = new() { "Add", "Edit", "Update", "Delete", "Search" };

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
}
}"
}
};
}

<style>
.e-progress-custom {
display: flex;
align-items: center;
gap: 8px;
}

.e-progress-outer {
width: 120px;
height: 8px;
border-radius: 4px;
background: #e0e0e0;
position: relative;
overflow: hidden;
}

.e-progress-bar {
height: 100%;
background: #3b82f6;
}

.e-progress-inner span {
font-size: 12px;
}

/* Keep visibility when row selected */
.e-row.e-active .e-progress-outer,
.e-row.e-selectionbackground .e-progress-outer {
background: #cfcfcf;
}

.e-row.e-active .e-progress-bar,
.e-row.e-selectionbackground .e-progress-bar {
background: #2563eb;
}

.e-dependencies {
border-radius: 4px;
padding: 2px 8px;
width: fit-content;
border: 1px solid #b8b8b8;
font-weight: 400;
font-size: 14px;
line-height: 20px;
margin: 0 auto;
}

.e-row.e-active .e-dependencies,
.e-row.e-selectionbackground .e-dependencies {
background: #e5e7eb;
}

</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@page "/not-found"
@layout MainLayout

<h3>Not Found</h3>
<p>Sorry, the content you are looking for does not exist.</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Router AppAssembly="typeof(Program).Assembly" NotFoundPage="typeof(Pages.NotFound)">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="HotChocolate.AspNetCore" Version="15.1.12" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.3" />
<PackageReference Include="Syncfusion.Blazor.Data" Version="32.2.5" />
<PackageReference Include="Syncfusion.Blazor.Gantt" Version="32.2.5" />
<PackageReference Include="Syncfusion.Blazor.Themes" Version="32.2.5" />
</ItemGroup>

<ItemGroup>
<Folder Include="wwwroot\lib\bootstrap\dist\" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ActiveDebugProfile>https</ActiveDebugProfile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>
Loading