Skip to content

Commit

Permalink
Razor Component Integration (#3545)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib authored Apr 19, 2021
1 parent ba35ca2 commit 82143fb
Show file tree
Hide file tree
Showing 36 changed files with 2,295 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public enum SyntaxKind
EnumTypeExtension,
InputObjectTypeExtension,
DirectiveDefinition,
FloatValue
FloatValue,
PublicKeyword
}
}
15 changes: 15 additions & 0 deletions src/StrawberryShake/Client/StrawberryShake.Client.sln
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StrawberryShake.Persistence
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StrawberryShake.Persistence.SQLite.Tests", "test\Persistence.SQLite.Tests\StrawberryShake.Persistence.SQLite.Tests.csproj", "{9A5345E8-A2EB-410F-BD72-6F268794D2DC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StrawberryShake.Razor", "src\Razor\StrawberryShake.Razor.csproj", "{2A834588-BA60-4906-B111-20AF9FD5B1E6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -204,6 +206,18 @@ Global
{9A5345E8-A2EB-410F-BD72-6F268794D2DC}.Release|x64.Build.0 = Release|Any CPU
{9A5345E8-A2EB-410F-BD72-6F268794D2DC}.Release|x86.ActiveCfg = Release|Any CPU
{9A5345E8-A2EB-410F-BD72-6F268794D2DC}.Release|x86.Build.0 = Release|Any CPU
{2A834588-BA60-4906-B111-20AF9FD5B1E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2A834588-BA60-4906-B111-20AF9FD5B1E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2A834588-BA60-4906-B111-20AF9FD5B1E6}.Debug|x64.ActiveCfg = Debug|Any CPU
{2A834588-BA60-4906-B111-20AF9FD5B1E6}.Debug|x64.Build.0 = Debug|Any CPU
{2A834588-BA60-4906-B111-20AF9FD5B1E6}.Debug|x86.ActiveCfg = Debug|Any CPU
{2A834588-BA60-4906-B111-20AF9FD5B1E6}.Debug|x86.Build.0 = Debug|Any CPU
{2A834588-BA60-4906-B111-20AF9FD5B1E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A834588-BA60-4906-B111-20AF9FD5B1E6}.Release|Any CPU.Build.0 = Release|Any CPU
{2A834588-BA60-4906-B111-20AF9FD5B1E6}.Release|x64.ActiveCfg = Release|Any CPU
{2A834588-BA60-4906-B111-20AF9FD5B1E6}.Release|x64.Build.0 = Release|Any CPU
{2A834588-BA60-4906-B111-20AF9FD5B1E6}.Release|x86.ActiveCfg = Release|Any CPU
{2A834588-BA60-4906-B111-20AF9FD5B1E6}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{61894B9B-EC9A-4FC0-AAAF-9922978A5AB8} = {5F283FE4-BB0A-4806-B079-42DBFE0B2EDF}
Expand All @@ -219,5 +233,6 @@ Global
{1B3B2075-6587-45C7-B4DD-65EC76646EB7} = {264FDF20-A58F-476E-9E02-9F082FB65612}
{DFFA574E-439F-4FCE-BF6D-CE5BEACA360A} = {5F283FE4-BB0A-4806-B079-42DBFE0B2EDF}
{9A5345E8-A2EB-410F-BD72-6F268794D2DC} = {4E0B9145-BE75-4F46-906B-092DFF4AD5CC}
{2A834588-BA60-4906-B111-20AF9FD5B1E6} = {5F283FE4-BB0A-4806-B079-42DBFE0B2EDF}
EndGlobalSection
EndGlobal
12 changes: 7 additions & 5 deletions src/StrawberryShake/Client/src/Core/IOperationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@ namespace StrawberryShake
/// <summary>
/// The result of a GraphQL operation.
/// </summary>
public interface IOperationResult<T> : IOperationResult where T : class
public interface IOperationResult<TResultData>
: IOperationResult
where TResultData : class
{
/// <summary>
/// Gets the data object or <c>null</c>.
/// </summary>
new T? Data { get; }
new TResultData? Data { get; }

/// <summary>
/// Gets the data factory which can build from the
/// <see cref="DataInfo"/> a new <see cref="Data"/>.
/// <see cref="IOperationResultDataInfo"/> a new <see cref="Data"/>.
/// </summary>
new IOperationResultDataFactory<T> DataFactory { get; }
new IOperationResultDataFactory<TResultData> DataFactory { get; }

IOperationResult<T> WithData(T data, IOperationResultDataInfo dataInfo);
IOperationResult<TResultData> WithData(TResultData data, IOperationResultDataInfo dataInfo);
}

/// <summary>
Expand Down
44 changes: 44 additions & 0 deletions src/StrawberryShake/Client/src/Razor/DataComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Components;

namespace StrawberryShake.Razor
{
public abstract class DataComponent<TClientOrOperation>
: ComponentBase
, IDisposable
{
private readonly List<IDisposable> _subscriptions = new();
private bool _disposed;

[Inject]
protected internal TClientOrOperation ClientOrOperation { get; internal set; } = default!;

public void Subscribe(Func<TClientOrOperation, IDisposable> subscribe)
{
_subscriptions.Add(subscribe(ClientOrOperation));
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
foreach (var subscription in _subscriptions)
{
subscription.Dispose();
}
}

_disposed = true;
}
}
}
}
85 changes: 85 additions & 0 deletions src/StrawberryShake/Client/src/Razor/QueryBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;

namespace StrawberryShake.Razor
{
public abstract class QueryBase<TResult>
: ComponentBase
, IDisposable
where TResult : class
{
private IDisposable? _subscription;
private bool _isLoading = true;
private bool _isErrorResult;
private bool _isSuccessResult;
private TResult? _result;
private IReadOnlyList<IClientError>? _errors;
private bool _disposed;

[Parameter]
public RenderFragment<TResult> Content { get; set; } = default!;

[Parameter]
public RenderFragment<IReadOnlyList<IClientError>>? Error { get; set; }

[Parameter]
public RenderFragment? Loading { get; set; }

[Parameter]
public ExecutionStrategy Strategy { get; set; }

protected void Subscribe(IObservable<IOperationResult<TResult>> observable)
{
_subscription = observable.Subscribe(operationResult =>
{
_result = operationResult.Data;
_errors = operationResult.Errors;
_isErrorResult = operationResult.IsErrorResult();
_isSuccessResult = operationResult.IsSuccessResult();
_isLoading = false;
StateHasChanged();
});
}

protected override void BuildRenderTree(RenderTreeBuilder builder)
{
if (_isLoading && Loading is not null)
{
builder.AddContent(0, Loading);
}

if (_isErrorResult)
{
builder.AddContent(0, Error, _errors!);
}

if (_isSuccessResult)
{
builder.AddContent(0, Content, _result!);
}

base.BuildRenderTree(builder);
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_subscription?.Dispose();
}

_disposed = true;
}
}
}
}
27 changes: 27 additions & 0 deletions src/StrawberryShake/Client/src/Razor/StrawberryShake.Razor.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<PackageId>StrawberryShake.Razor</PackageId>
<AssemblyName>StrawberryShake.Razor</AssemblyName>
<RootNamespace>StrawberryShake.Razor</RootNamespace>
<Nullable>enable</Nullable>
<Description>Provides razor components for using StrawberryShake.</Description>
<TargetFrameworks>net5.0</TargetFrameworks>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>


<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="5.0.4" />
<PackageReference Include="System.Reactive" Version="5.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Core\StrawberryShake.Core.csproj" />
</ItemGroup>

</Project>
2 changes: 2 additions & 0 deletions src/StrawberryShake/Client/src/Razor/_Imports.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@using Microsoft.AspNetCore.Components.Web
@using StrawberryShake
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ public static class CSharpGenerator
new InputTypeGenerator(),
new InputTypeStateInterfaceGenerator(),
new ResultInterfaceGenerator(),
new DataTypeGenerator()
new DataTypeGenerator(),
new RazorQueryGenerator()
};

public static CSharpGeneratorResult Generate(
Expand Down Expand Up @@ -240,7 +241,8 @@ private static void GenerateSingleCSharpDocument(
var generatorSettings = new CSharpSyntaxGeneratorSettings(
settings.NoStore,
settings.InputRecords,
settings.EntityRecords);
settings.EntityRecords,
settings.RazorComponents);

var results = new List<(Type Generator, CSharpSyntaxGeneratorResult Result)>();

Expand Down Expand Up @@ -307,7 +309,8 @@ private static void GenerateMultipleCSharpDocuments(
var generatorSettings = new CSharpSyntaxGeneratorSettings(
settings.NoStore,
settings.InputRecords,
settings.EntityRecords);
settings.EntityRecords,
settings.RazorComponents);

var results = new List<(Type Generator, CSharpSyntaxGeneratorResult Result)>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public class CSharpGeneratorSettings
/// </summary>
public bool EntityRecords { get; set; }

/// <summary>
/// Generate razor components.
/// </summary>
public bool RazorComponents { get; set; }

/// <summary>
/// Generate a single CSharp code file.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public class OperationServiceGenerator : ClassBaseGenerator<OperationDescriptor>
private const string _value = "value";
private const string _cancellationToken = "cancellationToken";

protected override void Generate(OperationDescriptor descriptor,
protected override void Generate(
OperationDescriptor descriptor,
CSharpSyntaxGeneratorSettings settings,
CodeWriter writer,
out string fileName,
Expand Down Expand Up @@ -53,11 +54,11 @@ protected override void Generate(OperationDescriptor descriptor,
.AddConstructor()
.SetTypeName(fileName);

var runtimeTypeName =
var resultTypeName =
descriptor.ResultTypeReference.GetRuntimeType().Name;

AddConstructorAssignedField(
TypeNames.IOperationExecutor.WithGeneric(runtimeTypeName),
TypeNames.IOperationExecutor.WithGeneric(resultTypeName),
_operationExecutor,
operationExecutor,
classBuilder,
Expand All @@ -67,10 +68,10 @@ protected override void Generate(OperationDescriptor descriptor,

if (descriptor is not SubscriptionOperationDescriptor)
{
classBuilder.AddMethod(CreateExecuteMethod(descriptor, runtimeTypeName));
classBuilder.AddMethod(CreateExecuteMethod(descriptor, resultTypeName));
}

classBuilder.AddMethod(CreateWatchMethod(descriptor, runtimeTypeName));
classBuilder.AddMethod(CreateWatchMethod(descriptor, resultTypeName));
classBuilder.AddMethod(CreateRequestMethod(descriptor));
classBuilder.AddMethod(CreateRequestVariablesMethod(descriptor));

Expand All @@ -79,7 +80,7 @@ protected override void Generate(OperationDescriptor descriptor,
classBuilder
.AddProperty("ResultType")
.SetType(TypeNames.Type)
.AsLambda($"typeof({runtimeTypeName})")
.AsLambda($"typeof({resultTypeName})")
.SetInterface(TypeNames.IOperationRequestFactory);

MethodCallBuilder createRequestCall = MethodCallBuilder
Expand Down
Loading

0 comments on commit 82143fb

Please sign in to comment.