Skip to content

Commit

Permalink
Added some Basic Localization functionality.
Browse files Browse the repository at this point in the history
Added Language Selector
Added Some NavMenu translations
Fixed issue on Brands and Producsts where View and Delete option was showing in edit screen duplicated.
Added Header conformity to Login,SelfRegister and ForgotPassword
  • Loading branch information
kallievz committed Jan 9, 2025
1 parent 8e762f0 commit 2d36de4
Show file tree
Hide file tree
Showing 57 changed files with 4,458 additions and 129 deletions.
7 changes: 7 additions & 0 deletions src/Shared/Constants/LanguageCode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace FSH.Starter.Shared.Constants;

public class LanguageCode
{
public string DisplayName { get; set; }

Check warning on line 5 in src/Shared/Constants/LanguageCode.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'DisplayName' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 5 in src/Shared/Constants/LanguageCode.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'DisplayName' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
public string Code { get; set; }

Check warning on line 6 in src/Shared/Constants/LanguageCode.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Code' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 6 in src/Shared/Constants/LanguageCode.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Code' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
}
17 changes: 17 additions & 0 deletions src/Shared/Constants/LocalizationConstants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace FSH.Starter.Shared.Constants;

public static class LocalizationConstants
{
public static readonly LanguageCode[] SupportedLanguages = {
new LanguageCode
{
Code = "en-US",
DisplayName= "English"
},
new LanguageCode
{
Code = "af-ZA",
DisplayName = "Afrikaans"
}
};
}
3 changes: 2 additions & 1 deletion src/api/framework/Core/Persistence/DatabaseOptions.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System.ComponentModel.DataAnnotations;

namespace FSH.Framework.Core.Persistence;

public class DatabaseOptions : IValidatableObject
{
public string Provider { get; set; } = "postgresql";
public string Provider { get; set; } = "mssql";
public string ConnectionString { get; set; } = string.Empty;

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
Expand Down
4 changes: 4 additions & 0 deletions src/api/framework/Infrastructure/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public static WebApplicationBuilder ConfigureFshFramework(this WebApplicationBui
builder.AddServiceDefaults();
builder.ConfigureSerilog();
builder.ConfigureDatabase();
builder.Services.AddLocalization(options =>
{
options.ResourcesPath = "Resources";
});
builder.Services.ConfigureMultitenancy();
builder.Services.ConfigureIdentity();
builder.Services.AddCorsPolicy(builder.Configuration);
Expand Down
4 changes: 2 additions & 2 deletions src/api/server/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"DatabaseOptions": {
"Provider": "postgresql",
"ConnectionString": "Server=192.168.1.110;Database=fullstackherodb;User Id=postgres;Password=password"
"Provider": "mssql",
"ConnectionString": "Data Source=KALLIE-LT\\SQL2019;Integrated Security=True;User ID=KALLIE-LT\\Kallie;Database=RUMAS_Q;TrustServerCertificate=True;"
},
"OriginOptions": {
"OriginUrl": "https://localhost:7000"
Expand Down
1 change: 1 addition & 0 deletions src/apps/blazor/client/Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<RootNamespace>FSH.Starter.Blazor.Client</RootNamespace>
<AssemblyName>FSH.Starter.Blazor.Client</AssemblyName>
<ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
<MudDialog>
@inject Microsoft.Extensions.Localization.IStringLocalizer<DeleteConfirmation> _localizer
<MudDialog>
<TitleContent>
<MudText Typo="Typo.h6">
<MudIcon Icon="@Icons.Material.Filled.Delete" Class="mr-3 mb-n1" />
Delete Confirmation
@_localizer["Delete Confirmation"]
</MudText>
</TitleContent>
<DialogContent>
<MudText>@ContentText</MudText>
</DialogContent>
<DialogActions>
<MudButton DropShadow=false StartIcon="@Icons.Material.Filled.Cancel" OnClick="Cancel">Cancel</MudButton>
<MudButton DropShadow=false StartIcon="@Icons.Material.Filled.Delete" Color="Color.Error" Variant="Variant.Filled" OnClick="Submit">Confirm</MudButton>
<MudButton DropShadow=false StartIcon="@Icons.Material.Filled.Cancel" OnClick="Cancel">@_localizer["Cancel"]</MudButton>
<MudButton DropShadow=false StartIcon="@Icons.Material.Filled.Delete" Color="Color.Error" Variant="Variant.Filled" OnClick="Submit">@_localizer["Confirm"]</MudButton>
</DialogActions>
</MudDialog>

Expand Down
6 changes: 3 additions & 3 deletions src/apps/blazor/client/Components/Dialogs/Logout.razor
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
@namespace FSH.Starter.Blazor.Client.Components.Dialogs

@inject Microsoft.Extensions.Localization.IStringLocalizer<Logout> _localizer

@inject IAuthenticationService AuthService

<MudDialog Class="py-4 px-4">
<TitleContent>
<MudText Typo="Typo.h6">
<MudIcon Icon="@Icons.Material.Filled.Logout" Class="mr-3 mb-n1" />
Logout Confirmation
@_localizer["Logout Confirmation"]
</MudText>
</TitleContent>
<DialogContent>
<MudText>@ContentText</MudText>
</DialogContent>
<DialogActions>
<MudButton DropShadow=false StartIcon="@Icons.Material.Filled.Cancel" Variant="Variant.Filled" OnClick="Cancel">Cancel</MudButton>
<MudButton DropShadow=false StartIcon="@Icons.Material.Filled.Cancel" Variant="Variant.Filled" OnClick="Cancel">@_localizer["Cancel"]</MudButton>
<MudButton DropShadow=false StartIcon="@Icons.Material.Filled.Logout" Color="@Color" Variant="Variant.Filled" OnClick="Submit">@ButtonText</MudButton>
</DialogActions>
</MudDialog>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,5 @@
</MudButton>
}
</DialogActions>

</MudDialog>
</EditForm>
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@typeparam TEntity

@typeparam TEntity
@typeparam TId
@typeparam TRequest

Expand All @@ -12,7 +13,6 @@

<ErrorBoundary>
<ChildContent>

@if (_canSearch && (Context.AdvancedSearchEnabled || AdvancedSearchContent is not null))
{
<MudExpansionPanel @bind-bind-Expanded="_advancedSearchExpanded"
Expand All @@ -35,13 +35,11 @@
</div>
} *@
@AdvancedSearchContent

</MudExpansionPanel>
}

<FshTable @ref="_table" Outlined ServerData="@ServerReloadFunc" Items="@_entityList" Filter="LocalSearch"
Loading="@Loading" LoadingProgressColor="@Color.Secondary" ChildRowContent="@ChildRowContent">

<ToolBarContent>
<div class="justify-center mud-text-align-center">
@if (_canCreate)
Expand Down Expand Up @@ -136,13 +134,10 @@
}
</MudTd>
</RowTemplate>

<PagerContent>
<TablePager />
</PagerContent>

</FshTable>

</ChildContent>
<ErrorContent>
<FshCustomError />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
@using FSH.Starter.Shared.Constants
@using FSH.Starter.Blazor.Infrastructure.Preferences;
@inject Microsoft.Extensions.Localization.IStringLocalizer<LanguageSelector> L
<MudTooltip Text="@CurrentLanguage">
<MudMenu Icon="@Icons.Material.Outlined.Translate" Color="Color.Inherit" Direction="Direction.Bottom" OffsetY="true"
Dense="true">
@foreach (var language in LocalizationConstants.SupportedLanguages)
{
if (language.Code == CurrentLanguage)
{
<MudMenuItem style="background:var(--mud-palette-primary); color:white">@L[language.DisplayName]</MudMenuItem>
}
else
{
<MudMenuItem OnClick="(()=> ChangeLanguageAsync(language.Code))">@L[language.DisplayName]</MudMenuItem>
}
}
</MudMenu>
</MudTooltip>

@code {
public string? CurrentLanguage { get; set; } = "en-US";

protected override async Task OnInitializedAsync()
{
var currentPreference = await ClientPreferences.GetPreference() as ClientPreference;
if (currentPreference != null)
{
CurrentLanguage = currentPreference.LanguageCode;
}
else
{
CurrentLanguage = "en-US";
}

}
private async Task ChangeLanguageAsync(string languageCode)
{
var result = await ClientPreferences.ChangeLanguageAsync(languageCode);
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
}
}
2 changes: 2 additions & 0 deletions src/apps/blazor/client/Layout/MainLayout.razor
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
</MudButton>
<MudSpacer />
<MudHidden Breakpoint="Breakpoint.MdAndUp" Invert="true">
<LanguageSelector />
<MudButton Variant="Variant.Filled" DropShadow="false" Color="Color.Primary"
Href="https://opencollective.com/fullstackhero" Target="_blank" StartIcon="@Icons.Material.Filled.Favorite">
Sponsor</MudButton>
Expand Down Expand Up @@ -36,6 +37,7 @@
</MudTooltip>
</MudHidden>
<MudHidden Breakpoint="Breakpoint.SmAndDown" Invert="true">

<MudTooltip Text="Sponsor">
<MudIconButton Icon="@Icons.Material.Filled.Favorite" Color="Color.Inherit"
Href="https://opencollective.com/fullstackhero" Target="_blank" />
Expand Down
13 changes: 7 additions & 6 deletions src/apps/blazor/client/Layout/NavMenu.razor
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
<PersonCard Style="background-color: var(--mud-palette-drawer-background);color: var(--mud-palette-drawer-text); margin-bottom:0px!important" />
@inject Microsoft.Extensions.Localization.IStringLocalizer<NavMenu> _localizer
<PersonCard Style="background-color: var(--mud-palette-drawer-background);color: var(--mud-palette-drawer-text); margin-bottom:0px!important" />
<MudNavMenu>
<MudText Typo="Typo.subtitle2" Color="Color.Surface" Class="ml-4 my-3">Start</MudText>
<MudNavLink Href="" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Home">Home</MudNavLink>
<MudText Typo="Typo.subtitle2" Color="Color.Surface" Class="ml-4 my-3">@_localizer["Start"]</MudText>
<MudNavLink Href="" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Home">@_localizer["Home"]</MudNavLink>
<MudNavLink Href="counter" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.Add">Counter</MudNavLink>
@if (_canViewAuditTrails)
{
<MudNavLink Match="NavLinkMatch.Prefix" Href="/identity/audit-trail" Icon="@Icons.Material.Filled.WorkHistory">Audit Trail</MudNavLink>
<MudNavLink Match="NavLinkMatch.Prefix" Href="/identity/audit-trail" Icon="@Icons.Material.Filled.WorkHistory">@_localizer["Audit Trail"]</MudNavLink>
}
<MudText Typo="Typo.subtitle2" Color="Color.Surface" Class="ml-4 my-3">Modules</MudText>
<MudNavGroup Title="Catalog" Icon="@Icons.Material.Filled.AddBox">
<MudText Typo="Typo.subtitle2" Color="Color.Surface" Class="ml-4 my-3">@_localizer["Modules"]</MudText>
<MudNavGroup Title="@_localizer["Catalog"]" Icon="@Icons.Material.Filled.AddBox">
<MudNavLink Href="/catalog/products" Icon="@Icons.Material.Filled.ShoppingBag" Class="fsh-nav-child">Products</MudNavLink>
<MudNavLink Href="/catalog/brands" Icon="@Icons.Material.Filled.Label" Class="fsh-nav-child">Brands</MudNavLink>
</MudNavGroup>
Expand Down
17 changes: 7 additions & 10 deletions src/apps/blazor/client/Pages/Auth/ForgotPassword.razor
Original file line number Diff line number Diff line change
@@ -1,41 +1,38 @@
@page "/forgot-password"
@attribute [AllowAnonymous]
@inject Microsoft.Extensions.Localization.IStringLocalizer<ForgotPassword> _localizer

<PageTitle>Forgot Password</PageTitle>
<PageHeader Title="@_localizer["Title"]" Header="@_localizer["Header"]" SubHeader="@_localizer["SubHeader"]" />

<EditForm Model="@_forgotPasswordRequest" OnValidSubmit="SubmitAsync">
<MudCard Elevation="0">
<MudCardHeader>
<CardHeaderContent>
<MudTooltip Text="Go Back">
<MudTooltip Text="@_localizer["GoBack"]">
<MudIconButton Icon="@Icons.Material.Filled.ArrowBack" Color="Color.Inherit" Edge="Edge.Start"
Href="/" />
</MudTooltip>
<div class="fsh-center-text" style="padding-top: 20px;">
<MudText Typo="Typo.h4" GutterBottom="true" style="margin-bottom:5px">Forgot Password?
</MudText>
<MudText>We can help you by resetting your password.</MudText>
</div>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent>
<MudGrid>
<DataAnnotationsValidator />
<FshValidation @ref="_customValidation" />
<MudItem xs="12">
<MudTextField T="string" Label="Tenant" Variant="Variant.Outlined" @bind-Value="Tenant"
<MudTextField T="string" Label="@_localizer["Tenant"]" Variant="Variant.Outlined" @bind-Value="Tenant"
For="@(() => Tenant)" Required />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="E-mail" Variant="Variant.Outlined"
<MudTextField T="string" Label="@_localizer["Email"]" Variant="Variant.Outlined"
@bind-Value="_forgotPasswordRequest.Email" For="@(() => _forgotPasswordRequest.Email)"
InputType="InputType.Email" Adornment="Adornment.End" />
</MudItem>
</MudGrid>
</MudCardContent>
<MudCardActions Class="pb-4 pl-4">
<MudButton DropShadow="false" Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.LockReset" ButtonType="ButtonType.Submit" Disabled="BusySubmitting" Class="ml-auto">
Forgot Password</MudButton>
@_localizer["ForgotPassword"]
</MudButton>
</MudCardActions>
</MudCard>
</EditForm>
25 changes: 9 additions & 16 deletions src/apps/blazor/client/Pages/Auth/Login.razor
Original file line number Diff line number Diff line change
@@ -1,46 +1,39 @@
@page "/login"
@attribute [AllowAnonymous]
@inject IAuthenticationService authService
@inject Microsoft.Extensions.Localization.IStringLocalizer<Login> _localizer

<PageTitle>Login</PageTitle>
<PageHeader Title="@_localizer["Title"]" Header="@_localizer["Header"]" SubHeader="@_localizer["SubHeader"]" />

<div class="fsh-center-text">
<MudText Typo="Typo.h4" GutterBottom="true">Sign In</MudText>
<MudText>
Enter your credentials to get started.
</MudText>
</div>
<br />
<EditForm Model="@_tokenRequest" OnValidSubmit="SubmitAsync">
<MudGrid>
<DataAnnotationsValidator />
<FshValidation @ref="_customValidation" />
<MudItem xs="12">
<MudTextField T="string" Label="E-mail" Variant="Variant.Outlined" @bind-Value="_tokenRequest.Email"
<MudTextField T="string" Label="@_localizer["Email"]" Variant="Variant.Outlined" @bind-Value="_tokenRequest.Email"
For="@(() => _tokenRequest.Email)" />
</MudItem>
<MudItem xs="12">
<MudTextField Label="Password" Variant="Variant.Outlined" @bind-Value="_tokenRequest.Password"
<MudTextField Label="@_localizer["Password"]" Variant="Variant.Outlined" @bind-Value="_tokenRequest.Password"
For="@(() => _tokenRequest.Password)" InputType="@_passwordInput" Adornment="Adornment.End"
AdornmentIcon="@_passwordInputIcon" OnAdornmentClick="TogglePasswordVisibility" />
</MudItem>
<MudItem xs="12">
<MudTextField T="string" Label="Tenant" Variant="Variant.Outlined" @bind-Value="TenantId"
<MudTextField T="string" Label="@_localizer["Tenant"]" Variant="Variant.Outlined" @bind-Value="TenantId"
For="@(() => TenantId)" Required />
</MudItem>

<MudItem xs="12" md="6">
<MudButton StartIcon="@Icons.Material.Filled.AppRegistration" Href="/register">Register?</MudButton>
<MudButton StartIcon="@Icons.Material.Filled.AppRegistration" Href="/register">@_localizer["Register?"]</MudButton>
</MudItem>
<MudItem xs="12" md="6">
<MudButton StartIcon="@Icons.Material.Filled.LockReset" Href="/forgot-password">Forgot password?</MudButton>
<MudButton StartIcon="@Icons.Material.Filled.LockReset" Href="/forgot-password">@_localizer["Forgot password?"]</MudButton>
</MudItem>
<MudItem xs="12" Class="d-flex justify-center">
<MudButton ButtonType="ButtonType.Submit" Disabled="BusySubmitting" Variant="Variant.Filled"
Color="Color.Primary" DropShadow="false" Size="Size.Large" StartIcon="@Icons.Material.Filled.Login" Style="width: 100%;">Sign In</MudButton>
Color="Color.Primary" DropShadow="false" Size="Size.Large" StartIcon="@Icons.Material.Filled.Login" Style="width: 100%;">@_localizer["Sign In"]</MudButton>
</MudItem>
<MudItem xs="12" Class="d-flex justify-center">
<MudButton DropShadow="false" StartIcon="@Icons.Material.Filled.Password" OnClick="FillAdministratorCredentials">Fill Administrator Credentials</MudButton>
<MudButton DropShadow="false" StartIcon="@Icons.Material.Filled.Password" OnClick="FillAdministratorCredentials">@_localizer["Fill Administrator Credentials"]</MudButton>
</MudItem>
</MudGrid>
</EditForm>
Loading

0 comments on commit 2d36de4

Please sign in to comment.