Skip to content

Commit

Permalink
Merge branch 'bitfoundation:develop' into 7761-dotnet9-rc2
Browse files Browse the repository at this point in the history
  • Loading branch information
ysmoradi authored Nov 5, 2024
2 parents b4b54d0 + 8cbc4d0 commit 6acc7e7
Show file tree
Hide file tree
Showing 16 changed files with 276 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,8 @@
"condition": "(appInsights != true)",
"exclude": [
"src/Client/Boilerplate.Client.Maui/Services/MauiTelemetryInitializer.cs",
"src/Client/Boilerplate.Client.Windows/Services/WindowsTelemetryInitializer.cs"
"src/Client/Boilerplate.Client.Windows/Services/WindowsTelemetryInitializer.cs",
"src/Client/Boilerplate.Client.Core/Services/AppInsightsJsSdkService.cs"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
//#if (signalr == true)
using Microsoft.AspNetCore.SignalR.Client;
//#endif
//#if (appInsights == true)
using BlazorApplicationInsights.Interfaces;
//#endif

namespace Boilerplate.Client.Core.Components;

Expand All @@ -15,6 +18,9 @@ public partial class AppInitializer : AppComponentBase
//#if (notification == true)
[AutoInject] private IPushNotificationService pushNotificationService = default!;
//#endif
//#if (appInsights == true)
[AutoInject] private IApplicationInsights appInsights = default!;
//#endif
[AutoInject] private Navigator navigator = default!;
[AutoInject] private IJSRuntime jsRuntime = default!;
[AutoInject] private Bit.Butil.Console console = default!;
Expand All @@ -29,7 +35,30 @@ protected override async Task OnInitAsync()
{
AuthenticationManager.AuthenticationStateChanged += AuthenticationStateChanged;

AuthenticationStateChanged(AuthenticationManager.GetAuthenticationStateAsync());
if (InPrerenderSession is false)
{
TelemetryContext.UserAgent = await navigator.GetUserAgent();
TelemetryContext.TimeZone = await jsRuntime.GetTimeZone();
TelemetryContext.Culture = CultureInfo.CurrentCulture.Name;
if (AppPlatform.IsBlazorHybrid is false)
{
TelemetryContext.OS = await jsRuntime.GetBrowserPlatform();
}

//#if (appInsights == true)
await appInsights.AddTelemetryInitializer(new()
{
Data = new()
{
["ai.application.ver"] = TelemetryContext.AppVersion,
["ai.session.id"] = TelemetryContext.AppSessionId,
["ai.device.locale"] = TelemetryContext.Culture
}
});
//#endif

AuthenticationStateChanged(AuthenticationManager.GetAuthenticationStateAsync());
}

if (AppPlatform.IsBlazorHybrid)
{
Expand All @@ -48,19 +77,6 @@ await storageService.GetItem("Culture") ?? // 2- User settings
await base.OnInitAsync();
}

protected override async Task OnAfterFirstRenderAsync()
{
await base.OnAfterFirstRenderAsync();

TelemetryContext.UserAgent = await navigator.GetUserAgent();
TelemetryContext.TimeZone = await jsRuntime.GetTimeZone();
TelemetryContext.Culture = CultureInfo.CurrentCulture.Name;
if (AppPlatform.IsBlazorHybrid is false)
{
TelemetryContext.OS = await jsRuntime.GetBrowserPlatform();
}
}

private async void AuthenticationStateChanged(Task<AuthenticationState> task)
{
try
Expand All @@ -69,23 +85,30 @@ private async void AuthenticationStateChanged(Task<AuthenticationState> task)
TelemetryContext.UserId = user.IsAuthenticated() ? user.GetUserId() : null;
TelemetryContext.UserSessionId = user.IsAuthenticated() ? user.GetSessionId() : null;

using var scope = authLogger.BeginScope(TelemetryContext.ToDictionary());
var data = TelemetryContext.ToDictionary();

//#if (appInsights == true)
if (user.IsAuthenticated())
{
authLogger.LogInformation("Authentication state changed.");
await appInsights.SetAuthenticatedUserContext(user.GetUserId().ToString());
}

//#if (signalr == true)
if (InPrerenderSession is false)
else
{
await ConnectSignalR();
await appInsights.ClearAuthenticatedUserContext();
}
//#endif

//#if (notification == true)
if (InPrerenderSession is false)
using var scope = authLogger.BeginScope(data);
{
await pushNotificationService.RegisterDevice(CurrentCancellationToken);
authLogger.LogInformation("Authentication state changed.");
}

//#if (signalr == true)
await ConnectSignalR();
//#endif

//#if (notification == true)
await pushNotificationService.RegisterDevice(CurrentCancellationToken);
//#endif
}
catch (Exception exp)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<section>
<BitStack HorizontalAlign="BitAlignment.Center" FillContent>
<EditForm EditContext="editContext" OnValidSubmit="WrapHandled(DoSignIn)" novalidate>
<EditForm Model="model" OnValidSubmit="WrapHandled(DoSignIn)" novalidate>
<AppDataAnnotationsValidator />

<BitStack HorizontalAlign="BitAlignment.Center">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public partial class SignInPage : IDisposable
private bool isWaiting;
private bool isOtpSent;
private bool requiresTwoFactor;
private EditContext editContext;
private readonly SignInRequestDto model = new();
private Action unsubscribeIdentityHeaderBackLinkClicked = default!;

Expand All @@ -53,8 +52,6 @@ protected override async Task OnInitAsync()
model.PhoneNumber = PhoneNumberQueryString;
model.DeviceInfo = telemetryContext.OS;

editContext = new EditContext(model);

if (string.IsNullOrEmpty(OtpQueryString) is false)
{
model.Otp = OtpQueryString;
Expand Down Expand Up @@ -151,7 +148,17 @@ private async Task SendOtp(bool resend)
{
if (model.Email is null && model.PhoneNumber is null) return;

if (editContext.Validate() is false) return;
if(model.Email is not null && new EmailAddressAttribute().IsValid(model.Email) is false)
{
SnackBarService.Error(string.Format(AppStrings.EmailAddressAttribute_ValidationError, AppStrings.Email));
return;
}

if (model.PhoneNumber is not null && new PhoneAttribute().IsValid(model.PhoneNumber) is false)
{
SnackBarService.Error(string.Format(AppStrings.PhoneAttribute_ValidationError, AppStrings.PhoneNumber));
return;
}

try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,23 @@
</BitPivotItem>
</BitPivot>

<BitTextField @bind-Value="Model.Password"
CanRevealPassword="true"
Type="BitInputType.Password"
AutoComplete="@BitAutoCompleteValue.CurrentPassword"
Placeholder="@Localizer[nameof(AppStrings.PasswordPlaceholder)]"
InputHtmlAttributes="@(new Dictionary<string,object> {["tabindex"]="2"})">
<LabelTemplate>
<BitStack Horizontal VerticalAlign="BitAlignment.Center">
<BitText>@Localizer[nameof(AppStrings.Password)]</BitText>
<BitSpacer />
<BitLink Href="@Urls.ForgotPasswordPage">@Localizer[nameof(AppStrings.ForgotPasswordLink)]</BitLink>
</BitStack>
</LabelTemplate>
</BitTextField>
<ValidationMessage For="@(() => Model.Password)" />
<BitStack Gap="0" FillContent>
<BitTextField @bind-Value="Model.Password"
CanRevealPassword="true"
Type="BitInputType.Password"
AutoComplete="@BitAutoCompleteValue.CurrentPassword"
Placeholder="@Localizer[nameof(AppStrings.PasswordPlaceholder)]"
InputHtmlAttributes="@(new Dictionary<string,object> {["tabindex"]="2"})">
<LabelTemplate>
<BitStack Horizontal VerticalAlign="BitAlignment.Center">
<BitText>@Localizer[nameof(AppStrings.Password)]</BitText>
<BitSpacer />
<BitLink Href="@Urls.ForgotPasswordPage">@Localizer[nameof(AppStrings.ForgotPasswordLink)]</BitLink>
</BitStack>
</LabelTemplate>
</BitTextField>
<ValidationMessage For="@(() => Model.Password)" />
</BitStack>
</BitStack>

<BitCheckbox @bind-Value="Model.RememberMe" Label="@Localizer[nameof(AppStrings.RememberMe)]" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@
<BitStack FillContent Gap="2rem">
<BitStack FillContent>
<BitPivot Alignment="BitAlignment.Center">
@* <BitPivotItem HeaderText="@Localizer[nameof(AppStrings.UserName)]">
<BitTextField @bind-Value="signUpModel.UserName"
Type="BitInputType.Text"
Label="@Localizer[nameof(AppStrings.UserName)]"
Placeholder="@Localizer[nameof(AppStrings.UserName)]"
InputHtmlAttributes="@(new Dictionary<string,object> {["tabindex"]="1"})" />
<ValidationMessage For="@(() => signUpModel.UserName)" />
</BitPivotItem> *@

<BitPivotItem HeaderText="@Localizer[nameof(AppStrings.Email)]">
<BitTextField @bind-Value="signUpModel.Email"
Type="BitInputType.Email"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//#endif
//#if (appInsights == true)
using BlazorApplicationInsights;
using BlazorApplicationInsights.Interfaces;
//#endif
using Boilerplate.Client.Core;
using System.Diagnostics.CodeAnalysis;
Expand Down Expand Up @@ -97,13 +98,10 @@ public static IServiceCollection AddClientCoreProjectServices(this IServiceColle
//#endif

//#if (appInsights == true)
services.Add(ServiceDescriptor.Describe(typeof(IApplicationInsights), typeof(AppInsightsJsSdkService), AppPlatform.IsBrowser ? ServiceLifetime.Singleton : ServiceLifetime.Scoped));
services.AddBlazorApplicationInsights(x =>
{
var connectionString = configuration.Get<ClientCoreSettings>()!.ApplicationInsights?.ConnectionString;
if (string.IsNullOrEmpty(connectionString) is false)
{
x.ConnectionString = connectionString;
}
x.ConnectionString = configuration.Get<ClientCoreSettings>()!.ApplicationInsights?.ConnectionString;
});
//#endif

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
using BlazorApplicationInsights;
using BlazorApplicationInsights.Models;
using BlazorApplicationInsights.Interfaces;

namespace Boilerplate.Client.Core.Services;

public partial class AppInsightsJsSdkService : IApplicationInsights
{
private readonly ApplicationInsights applicationInsights = new();
private TaskCompletionSource? appInsightsReady;

[AutoInject] private IJSRuntime jsRuntime = default!;

public async Task AddTelemetryInitializer(TelemetryItem telemetryItem)
{
await EnsureReady();
await applicationInsights.AddTelemetryInitializer(telemetryItem);
}

public async Task ClearAuthenticatedUserContext()
{
await EnsureReady();
await applicationInsights.ClearAuthenticatedUserContext();
}

public async Task<TelemetryContext> Context()
{
await EnsureReady();
return await applicationInsights.Context();
}

public async Task Flush()
{
await EnsureReady();
await applicationInsights.Flush();
}

public CookieMgr GetCookieMgr()
{
if (appInsightsReady?.Task.IsCompleted is false)
throw new InvalidOperationException("app insights is not ready");

return applicationInsights.GetCookieMgr();
}

public void InitJSRuntime(IJSRuntime jSRuntime)
{
applicationInsights.InitJSRuntime(jSRuntime);
}

public async Task SetAuthenticatedUserContext(string authenticatedUserId, string? accountId = null, bool? storeInCookie = null)
{
await EnsureReady();
await applicationInsights.SetAuthenticatedUserContext(authenticatedUserId, accountId, storeInCookie);
}

public async Task StartTrackEvent(string name)
{
await EnsureReady();
await applicationInsights.StartTrackEvent(name);
}

public async Task StartTrackPage(string? name = null)
{
await EnsureReady();
await applicationInsights.StartTrackPage(name);
}

public async Task StopTrackEvent(string name, Dictionary<string, object?>? properties = null, Dictionary<string, decimal>? measurements = null)
{
await EnsureReady();
await applicationInsights.StopTrackEvent(name, properties, measurements);
}

public async Task StopTrackPage(string? name = null, string? url = null, Dictionary<string, object?>? customProperties = null, Dictionary<string, decimal>? measurements = null)
{
await EnsureReady();
await applicationInsights.StopTrackPage(name, url, customProperties, measurements);
}

public async Task TrackDependencyData(DependencyTelemetry dependency)
{
await EnsureReady();
await applicationInsights.TrackDependencyData(dependency);
}

public async Task TrackEvent(EventTelemetry @event)
{
await EnsureReady();
await applicationInsights.TrackEvent(@event);
}

public async Task TrackException(ExceptionTelemetry exception)
{
await EnsureReady();
await applicationInsights.TrackException(exception);
}

public async Task TrackMetric(MetricTelemetry metric)
{
await EnsureReady();
await applicationInsights.TrackMetric(metric);
}

public async Task TrackPageView(PageViewTelemetry? pageView = null)
{
await EnsureReady();
await applicationInsights.TrackPageView(pageView);
}

public async Task TrackPageViewPerformance(PageViewPerformanceTelemetry pageViewPerformance)
{
await EnsureReady();
await applicationInsights.TrackPageViewPerformance(pageViewPerformance);
}

public async Task TrackTrace(TraceTelemetry trace)
{
await EnsureReady();
await applicationInsights.TrackTrace(trace);
}

public async Task UpdateCfg(Config newConfig, bool mergeExisting = true)
{
await EnsureReady();
await applicationInsights.UpdateCfg(newConfig, mergeExisting);
}

private Task EnsureReady()
{
async void CheckForAppInsightsReady()
{
while (true)
{
try
{
var appInsightsVersion = await jsRuntime!.InvokeAsync<int>("eval", "window.appInsights.version");
appInsightsReady.SetResult();
break;
}
catch { await Task.Delay(250); }
}
}

if (appInsightsReady is null)
{
appInsightsReady = new TaskCompletionSource();
CheckForAppInsightsReady();
}

return appInsightsReady!.Task;
}
}
Loading

0 comments on commit 6acc7e7

Please sign in to comment.