Skip to content

Commit

Permalink
Merge branch 'master' into net9
Browse files Browse the repository at this point in the history
  • Loading branch information
hakenr committed Nov 5, 2024
2 parents 6ed1e96 + 004408b commit 87dc7da
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
.hx-context-menu-btn {
display: flex;
align-items: center;
justify-content: center;
color: var(--hx-context-menu-button-color);
border: var(--hx-context-menu-button-border);
border-radius: var(--hx-context-menu-button-border-radius);
padding: var(--hx-context-menu-button-padding);
font-size: var(--hx-context-menu-button-font-size);
}

.hx-context-menu-btn:hover {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
}

::deep .hx-grid {
--hx-context-menu-button-border-radius: .25rem;
margin-bottom: 0;
font-size: var(--hx-list-layout-table-font-size);
}
Expand Down
1 change: 1 addition & 0 deletions Havit.Blazor.Components.Web.Bootstrap/wwwroot/defaults.css
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
--hx-context-menu-button-border-radius: var(--bs-border-radius-sm);
--hx-context-menu-button-padding: 0 .25rem;
--hx-context-menu-button-hover-background: var(--bs-secondary-bg);
--hx-context-menu-button-font-size: inherit;
--hx-context-menu-item-icon-margin: 0 .5rem 0 0;

/* HxDropdown */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
<ComponentApiDocCssVariable Name="--hx-context-menu-button-padding" Default="0 .25rem">
Padding of the context menu button.
</ComponentApiDocCssVariable>
<ComponentApiDocCssVariable Name="--hx-context-menu-button-font-size" Default="inherit">
Font size of the context menu button icon.
</ComponentApiDocCssVariable>
<ComponentApiDocCssVariable Name="--hx-context-menu-item-icon-margin" Default="0 .5rem 0 0">
Margin of the item icon.
</ComponentApiDocCssVariable>
Expand Down
14 changes: 6 additions & 8 deletions Havit.Blazor.Documentation/Pages/Premium/GetPremium.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@
<PageTitle>Get Premium | HAVIT Blazor Bootstrap - Free components for ASP.NET Core Blazor</PageTitle>
<PageCanonicalUrl RelativeUrl="/premium" />

<div class="container-fluid">
<div style="height: 400px;" class="hero d-flex flex-column align-items-center justify-content-center">
<h1 class="fw-bold text-center display-3">Upgrade to Premium</h1>
<div style="max-width: 800px;" class="lead text-center">
Enjoy access to a carefully selected collection of <a href="https://blocks.havit.blazor.eu">prebuilt UI blocks</a>, complete with Blazor, C# and CSS source code,
priority support, and enterprise project source code for your inspiration.
</div>
</div>
<div style="height: 400px;" class="hero d-flex flex-column align-items-center justify-content-center">
<h1 class="fw-bold text-center display-3">Upgrade to Premium</h1>
<div style="max-width: 800px;" class="lead text-center">
Enjoy access to a carefully selected collection of <a href="https://blocks.havit.blazor.eu">prebuilt UI blocks</a>, complete with Blazor, C# and CSS source code,
priority support, and enterprise project source code for your inspiration.
</div>
</div>

<div class="container">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@bind-Value="@SelectedResult"
MinimumLength="1"
Delay="1"
CssClass="sidebar-search pt-1"
CssClass="sidebar-search"
DataProvider="ProvideSuggestions"
@ref="_autosuggest">
<ItemTemplate Context="searchItem"><span class="small">@searchItem.Title</span></ItemTemplate>
Expand Down
2 changes: 1 addition & 1 deletion Havit.Blazor.Documentation/Shared/MainLayout.razor
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<div class="container-fluid d-md-flex min-vh-100">
<Sidebar />

<div style="min-width: 0;" class="doc-content main p-4 pt-0 flex-grow-1">
<div style="min-width: 0;" class="doc-content main p-4 pt-0 flex-grow-1 overflow-hidden">
<CascadingValue Value="_pageCanonicalUrlTracker" IsFixed="true">
@Body
</CascadingValue>
Expand Down
4 changes: 2 additions & 2 deletions Havit.Blazor.Documentation/Shared/Navbar.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
<img src="./logo.png" width="32" alt="HAVIT Blazor">
<span class="fw-semibold">HAVIT Blazor</span>
</HxNavbarBrand>
<HxNavbarToggler />
<HxNavbarToggler CssClass="border-0" />
<HxNavbarCollapse>
<HxNav CssClass="mx-auto justify-content-center row-gap-2 column-gap-3 mt-lg-0">
<HxNav CssClass="mx-auto justify-content-center gap-3 my-3 my-lg-0">
<HxNavLink Href="/" CssClass="px-3 link-body-emphasis link-opacity-75 link-opacity-100-hover" Match="NavLinkMatch.All">
Introduction
</HxNavLink>
Expand Down
51 changes: 47 additions & 4 deletions Havit.Blazor.Grpc.Client/GrpcClientServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using System.Reflection;
using System.Runtime.InteropServices;
using Grpc.Net.Client.Web;
using Grpc.Net.ClientFactory;
using Havit.Blazor.Grpc.Client.HttpHeaders;
using Havit.Blazor.Grpc.Client.Infrastructure;
using Havit.Blazor.Grpc.Client.ServerExceptions;
using Havit.Blazor.Grpc.Core;
using Havit.ComponentModel;
using Havit.Diagnostics.Contracts;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
Expand All @@ -25,16 +25,30 @@ public static class GrpcClientServiceCollectionExtensions
/// Adds the necessary infrastructure for gRPC clients.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
/// <param name="assemblyToScanForDataContracts">The assembly to scan for data contracts.</param>
/// <param name="assemblyToScanForDataContracts">Assembly to scan for data contracts.</param>
public static void AddGrpcClientInfrastructure(
this IServiceCollection services,
Assembly assemblyToScanForDataContracts)
{
AddGrpcClientInfrastructure(services, [assemblyToScanForDataContracts]);
}

/// <summary>
/// Adds the necessary infrastructure for gRPC clients.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
/// <param name="assembliesToScanForDataContracts">Assemblies to scan for data contracts.</param>
public static void AddGrpcClientInfrastructure(
this IServiceCollection services,
Assembly[] assembliesToScanForDataContracts)
{
services.AddTransient<ServerExceptionsGrpcClientInterceptor>();
services.AddSingleton<GlobalizationLocalizationGrpcClientInterceptor>();
services.AddScoped<ClientUriGrpcClientInterceptor>();
services.AddTransient<GrpcWebHandler>(provider => new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
services.AddSingleton<ClientFactory>(ClientFactory.Create(BinderConfiguration.Create(marshallerFactories: new[] { ProtoBufMarshallerFactory.Create(RuntimeTypeModel.Create().RegisterApplicationContracts(assemblyToScanForDataContracts)) }, binder: new ProtoBufServiceBinder())));
services.AddSingleton<ClientFactory>(ClientFactory.Create(BinderConfiguration.Create(
marshallerFactories: CreateMarshallerFactories(assembliesToScanForDataContracts),
binder: new ProtoBufServiceBinder())));

services.TryAddScoped<IGrpcClientClientUriResolver, NavigationManagerGrpcClientClientUriResolver>();
}
Expand All @@ -57,7 +71,31 @@ public static void AddGrpcClientsByApiContractAttributes(
Action<IHttpClientBuilder> configureGrpClientAll = null,
Action<IServiceProvider, GrpcClientFactoryOptions> configureGrpcClientFactory = null)
{
var interfacesAndAttributes = (from type in assemblyToScan.GetTypes()
AddGrpcClientsByApiContractAttributes(services, [assemblyToScan], configureGrpcClientWithAuthorization, configureGrpClientAll, configureGrpcClientFactory);
}

/// <summary>
/// Adds gRPC clients based on API contract attributes.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
/// <param name="assembliesToScan">The assembly to scan for API contract attributes.</param>
/// <param name="configureGrpcClientWithAuthorization">An optional action to configure gRPC clients with authorization.</param>
/// <param name="configureGrpClientAll">An optional action to configure all gRPC clients.</param>
/// <param name="configureGrpcClientFactory">
/// An optional action to configure the gRPC client factory.
/// If Not provided, <c>options.Address</c> (backend URL) will be configured from <c>NavigationManager.BaseUri</c>.
/// </param>
public static void AddGrpcClientsByApiContractAttributes(
this IServiceCollection services,
Assembly[] assembliesToScan,
Action<IHttpClientBuilder> configureGrpcClientWithAuthorization = null,
Action<IHttpClientBuilder> configureGrpClientAll = null,
Action<IServiceProvider, GrpcClientFactoryOptions> configureGrpcClientFactory = null)
{
Contract.Requires<ArgumentNullException>(assembliesToScan is not null);

var interfacesAndAttributes = (from assembly in assembliesToScan
from type in assembly.GetTypes()
from apiContractAttribute in type.GetCustomAttributes(typeof(ApiContractAttribute), false).Cast<ApiContractAttribute>()
select new { Interface = type, Attribute = apiContractAttribute }).ToArray();

Expand All @@ -77,6 +115,11 @@ from apiContractAttribute in type.GetCustomAttributes(typeof(ApiContractAttribut
}
}

private static List<MarshallerFactory> CreateMarshallerFactories(Assembly[] assembliesToScanForDataContracts) =>
assembliesToScanForDataContracts
.Select(assembly => ProtoBufMarshallerFactory.Create(RuntimeTypeModel.Create().RegisterApplicationContracts(assembly)))
.ToList();

private static void AddGrpcClientCore<TService>(
this IServiceCollection services,
Action<IHttpClientBuilder> configureGrpcClientWithAuthorization = null,
Expand Down
21 changes: 19 additions & 2 deletions Havit.Blazor.Grpc.Server/EndpointRouteBuilderGrpcExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,28 @@ public static void MapGrpcServicesByApiContractAttributes(
Assembly assemblyToScan,
Action<GrpcServiceEndpointConventionBuilder> configureEndpointWithAuthorization = null,
Action<GrpcServiceEndpointConventionBuilder> configureEndpointAll = null)
{
MapGrpcServicesByApiContractAttributes(builder, [assemblyToScan], configureEndpointWithAuthorization, configureEndpointAll);
}

/// <summary>
/// Maps gRPC services with <see cref="ApiContractAttribute"/> as route endpoints.
/// </summary>
/// <param name="builder">Endpoint route builder.</param>
/// <param name="assembliesToScan">Assemblies to scan for interfaces with <see cref="ApiContractAttribute"/>.</param>
/// <param name="configureEndpointWithAuthorization">Optional configuration for endpoints with authorization (all except <c>[ApiContract(RequireAuthorization = false)]</c>). Usually you want to setup <c>endpoint.RequireAuthorization(...)</c> here."/></param>
/// <param name="configureEndpointAll">Optional configuration for all endpoints.</param>
public static void MapGrpcServicesByApiContractAttributes(
this IEndpointRouteBuilder builder,
Assembly[] assembliesToScan,
Action<GrpcServiceEndpointConventionBuilder> configureEndpointWithAuthorization = null,
Action<GrpcServiceEndpointConventionBuilder> configureEndpointAll = null)
{
Contract.Requires<ArgumentNullException>(builder is not null, nameof(builder));
Contract.Requires<ArgumentNullException>(assemblyToScan is not null, nameof(assemblyToScan));
Contract.Requires<ArgumentNullException>(assembliesToScan is not null, nameof(assembliesToScan));

var interfacesAndAttributes = (from type in assemblyToScan.GetTypes()
var interfacesAndAttributes = (from assembly in assembliesToScan
from type in assembly.GetTypes()
from apiContractAttribute in type.GetCustomAttributes(typeof(ApiContractAttribute), false).Cast<ApiContractAttribute>()
select new { Interface = type, Attribute = apiContractAttribute }).ToArray();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Havit.Blazor.Grpc.Core;
using Havit.Blazor.Grpc.Server.GlobalizationLocalization;
using Havit.Blazor.Grpc.Server.ServerExceptions;
using Havit.Diagnostics.Contracts;
using Microsoft.Extensions.DependencyInjection;
using ProtoBuf.Grpc.Configuration;
using ProtoBuf.Grpc.Server;
Expand All @@ -12,14 +13,38 @@ namespace Havit.Blazor.Grpc.Server;

public static class GrpcServerServiceCollectionExtensions
{
/// <summary>
/// Adds the necessary infrastructure for gRPC servers.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
/// <param name="assembliesToScanForDataContracts">Assembly to scan for data contracts</param>
/// <param name="configureOptions">gRPC Service options</param>
public static void AddGrpcServerInfrastructure(
this IServiceCollection services,
Assembly assemblyToScanForDataContracts,
Action<GrpcServiceOptions> configureOptions = null)
{
AddGrpcServerInfrastructure(services, [assemblyToScanForDataContracts], configureOptions);
}

/// <summary>
/// Adds the necessary infrastructure for gRPC servers.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
/// <param name="assembliesToScanForDataContracts">Assemblies to scan for data contracts</param>
/// <param name="configureOptions">gRPC Service options</param>
public static void AddGrpcServerInfrastructure(
this IServiceCollection services,
Assembly[] assembliesToScanForDataContracts,
Action<GrpcServiceOptions> configureOptions = null)
{
Contract.Requires<ArgumentNullException>(assembliesToScanForDataContracts is not null);

services.AddSingleton<GlobalizationLocalizationGrpcServerInterceptor>();
services.AddSingleton<ServerExceptionsGrpcServerInterceptor>();
services.AddSingleton(BinderConfiguration.Create(marshallerFactories: new[] { ProtoBufMarshallerFactory.Create(RuntimeTypeModel.Create().RegisterApplicationContracts(assemblyToScanForDataContracts)) }, binder: new ServiceBinderWithServiceResolutionFromServiceCollection(services)));
services.AddSingleton(BinderConfiguration.Create(
marshallerFactories: CreateMarshallerFactories(assembliesToScanForDataContracts),
binder: new ServiceBinderWithServiceResolutionFromServiceCollection(services)));

services.AddCodeFirstGrpc(options =>
{
Expand All @@ -30,4 +55,13 @@ public static void AddGrpcServerInfrastructure(
configureOptions?.Invoke(options);
});
}

/// <summary>
/// Creates marshaller factories for the specified assemblies.
/// Each assembly has its own marshaller factory.
/// </summary>
private static List<MarshallerFactory> CreateMarshallerFactories(Assembly[] assembliesToScanForDataContracts) =>
assembliesToScanForDataContracts
.Select(assembly => ProtoBufMarshallerFactory.Create(RuntimeTypeModel.Create().RegisterApplicationContracts(assembly)))
.ToList();
}

0 comments on commit 87dc7da

Please sign in to comment.