-
Notifications
You must be signed in to change notification settings - Fork 483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow changing display language in dashboard settings #6805
base: main
Are you sure you want to change the base?
Allow changing display language in dashboard settings #6805
Conversation
Immediate="true" | ||
Label="@Loc[nameof(Dialogs.SettingsDialogLanguage)]" | ||
Items="@_languageOptions" | ||
OptionText="@(c => c.NativeName.Humanize())" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we know the default language for the browser? Having English (default)
in the list seems like it would be useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could determine this based on the Accept-Language header or whether UI culture differs from culture, but CultureInfo.CurrentUICulture
would just be set to english so that option would be selected, and the user would visibly see that it's english so it would seem a little redundant to me. What do you think?
NavigationManager.NavigateTo( | ||
DashboardUrls.SetLanguageUrl(_selectedUiCulture.Name, uri), | ||
forceLoad: true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the reason to use a redirect to change the language? Was it related to setting the cookie? Or was it updating all of the text to a new language?
The problem with using a redirect is it's inconsistent with changing the theme. That happens without reloading the page, while language change reloads the page and loses state (e.g. the settings dialog itself immediately closes).
Did you consider setting the cookie in the browser with JS interop like changing the theme? That plus triggering a StateHasChanged on the overall page to rerender everything seems like it could work. Although I wouldn't be surprised if changing the culture in the middle of a HTTP request is problematic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting the cookie isn't the problem, updating text is unfortunately the real issue.
Did you consider setting the cookie in the browser with JS interop like changing the theme? That plus triggering a StateHasChanged on the overall page to rerender everything seems like it could work. Although I wouldn't be surprised if changing the culture in the middle of a HTTP request is problematic.
I did, but this approach doesn't work. Even after CultureInfo.CurrentUICulture
is updated and localizers start returning the strings for the right language, StateHasChanged
just doesn't actually update the page text. I've read more into this the past day, and have not been able to get any of these workarounds to work, so I'd strongly prefer sticking with the current approach - it's the recommended approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those workarounds are specific to Blazor WASM which we're not using.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, those are the only workarounds I have found
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll take a look and see whether I can find a way to make it work.
If a refresh is required then I think a confirmation should be displayed after changing the language, e.g.
The dashboard must be refreshed when the language is changed. Are you sure you want to change the language?
Yes, No
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a refresh is required then I think a confirmation should be displayed after changing the language, e.g.
I don’t think this would be very useful. The user is pretty clear in their intent, the dialog adds unnecessary friction. Reloading (or opening a new page to select language in) is a common pattern, including on Microsoft websites
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But it’s inconsistent with the rest of the dashboard. Nothing else (adding filters, changing the theme, etc) triggers the dashboard to completely reload. Some page state could be lost.
There needs to be some notification that the page will reload. I think showing a yes/no dialog would be best, but a lower effort change could be to add some small text below the dropdown that changing the language will reload the dashboard.
@inject IStringLocalizer<Dialogs> Loc | ||
|
||
<FluentDialogBody> | ||
<FluentStack Orientation="Orientation.Vertical" Style="display: flex; height: 100%" VerticalGap="0"> | ||
<FluentStack Orientation="Orientation.Vertical" Style="display: flex; height: 100%" VerticalGap="5"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<FluentStack Orientation="Orientation.Vertical" Style="display: flex; height: 100%" VerticalGap="5"> | |
<FluentStack Orientation="Orientation.Vertical" Style="display: flex; height: 100%" VerticalGap="8"> |
@inject IStringLocalizer<Dialogs> Loc | ||
|
||
<FluentDialogBody> | ||
<FluentStack Orientation="Orientation.Vertical" Style="display: flex; height: 100%" VerticalGap="0"> | ||
<FluentStack Orientation="Orientation.Vertical" Style="display: flex; height: 100%" VerticalGap="5"> | ||
<FluentRadioGroup TValue="string" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Place in <div>
. Otherwise the label and content have gap inserted between them from stack
Orientation="Orientation.Vertical"> | ||
<FluentRadio Value="@ThemeManager.ThemeSettingSystem">@Loc[nameof(Dialogs.SettingsDialogSystemTheme)]</FluentRadio> | ||
<FluentRadio Value="@ThemeManager.ThemeSettingLight">@Loc[nameof(Dialogs.SettingsDialogLightTheme)]</FluentRadio> | ||
<FluentRadio Value="@ThemeManager.ThemeSettingDark">@Loc[nameof(Dialogs.SettingsDialogDarkTheme)]</FluentRadio> | ||
</FluentRadioGroup> | ||
|
||
<FluentSelect |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Place in <div>
. Otherwise the label and content have gap inserted between them from stack
httpContext.Response.Cookies.Append( | ||
CookieRequestCultureProvider.DefaultCookieName, | ||
// keep current culture for formatting, etc., but change ui (display) culture | ||
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(CultureInfo.CurrentCulture.Name, language))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now this is a session cookie and is lost when the browser is complete closed. Add an expiry:
new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
var uri = new Uri(NavigationManager.Uri) | ||
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped); | ||
|
||
NavigationManager.NavigateTo( | ||
DashboardUrls.SetLanguageUrl(_selectedUiCulture.Name, uri), | ||
forceLoad: true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment here that a cookie must be set and the dashboard reloaded to use the new culture set by localization middle.
if (!_languageOptions.Contains(CultureInfo.CurrentUICulture) | ||
&& !StringComparers.Culture.Equals(CultureInfo.CurrentUICulture.TwoLetterISOLanguageName, "zh") | ||
&& _languageOptions.FirstOrDefault(c => StringComparers.Culture.Equals(c.TwoLetterISOLanguageName, CultureInfo.CurrentUICulture.TwoLetterISOLanguageName)) is var matchedCulture) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like it could be prone to mistakes. Tests are needed here. It could be moved to a class and have some unit tests that test different cultures.
I looked at what the middleware does and it uses Parent property on culture. What about using that to match?
@@ -437,6 +438,19 @@ await Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions.Si | |||
{ | |||
_app.MapPost("/authentication/logout", () => TypedResults.SignOut(authenticationSchemes: [CookieAuthenticationDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme])); | |||
} | |||
|
|||
_app.MapGet("/api/set-language", (string? language, string redirectUrl, HttpContext httpContext) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Return BadRequest
result if language or redirectUrl are null or empty.
My understanding is that That might not be such a problem in the local development case, but for hosted environments like ACA, it might be problematic. If an issue, can we fix it, or allow this feature to be suppressed in such cases? |
|
Description
Currently, you can change the language of the Aspire dashboard by changing the language of the browser. This change adds a setting in the settings dialog to change the display language. Formatting is not affected, as
CultureInfo.CurrentCulture
is unchanged. OnlyCultureInfo.CurrentUICulture
is changed.The one edge case is if there is a culture (such as es-US or pt-PT) that the user is requesting that is different than our localized culture (es and pt-BR respectively). The resolved cultures will be
es
andpt-BR
, so we should select these as the active cultures in the dropdown - except in zh, since there are two differentzh
cultures that we localize for.The approach recommended by the Blazor globalization docs was taken.
Fixes #5009
Checklist
<remarks />
and<code />
elements on your triple slash comments?breaking-change
template):doc-idea
template):