-
-
Notifications
You must be signed in to change notification settings - Fork 392
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
OBPIH-5161+5246 Make user transition in/out of translation mode smoother #3738
Conversation
…ff is understood by the .js files, not only .jsx files
…ugLocale and return translationModeLocale to sessionReducer
… get rid of useDebugLocale for enable/disable localization mode
…e and add styling for buttons
…ult locale to translation mode locale
src/js/components/Layout/Footer.jsx
Outdated
key={language.code} | ||
href="/openboxes/user/enableLocalizationMode" | ||
> | ||
<Translate id={`react.default.${language.name.toLowerCase()}.label`} /> {''} |
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.
Is {''}
necessary?
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.
Probably not, but since it has not been code that I've written, I did not catch such details
const mapDispatchToProps = { | ||
changeLocale: changeCurrentLocale, | ||
setLanguage: setActiveLanguage, |
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 do you think about using useDispatch()
instead of mapDispatchToProps
? I found an interesting discussion on stackoverflow about this two approach Should I use useselector/useDispatch instead of mapStateToProps and i am curious what do you think
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 don't see any pros/cons of using one versus another. I think it's rather what you prefer and what is more useful in each scenario (for example you can't use mapDispatchToProps
inside a custom hook, so you are obligated to use useDispatch()
.
What I'm sure about is that we shouldn't mix both if possible and probably in "regular" components stick with connect
approach as we've done for whole project, as it might be easier to read and debug, because we are used to this convention.
@drodzewicz any additional thoughts?
I need a bit more time to review this one. |
Marking it as a draft for a while, as I will probably want to bring back |
2b8da66
to
d497c9c
Compare
d497c9c
to
964c581
Compare
@jmiranda it's now ready for review. I've brought back |
@@ -88,6 +88,10 @@ class ApiController { | |||
def localizationMode | |||
def locale = localizationService.getCurrentLocale() | |||
Object[] emptyArgs = [] as Object [] | |||
def translationModeLocale = grailsApplication.config.openboxes.locale.translationModeLocale | |||
// If current locale is equal to translation mode locale, we are in localization mode | |||
session.useDebugLocale = locale == new Locale(translationModeLocale) |
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.
Instead of sprinkling this logic everywhere, we should probably have it done in a filter. InitializationFilters seems to be the best candidate but I'm open to suggestions.
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.
sounds good to me, I haven't thought about such a solution
@@ -57,12 +57,12 @@ class ApiController { | |||
|
|||
@CacheFlush(["megamenuCache"]) | |||
def chooseLocale = { | |||
Locale locale = localizationService.getLocale(params.id) | |||
if (!locale) { | |||
Locale newLocale = localizationService.getLocale(params.id) |
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 unnecessary.
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 do you mean as unnecessary here? I'm a bit confused, because I only changed the naming from locale
to newLocale
and I'm not sure if either changing of name seems unnecessary or this part: localizationService.getLocale(params.id)
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 meant changing the variable name isn't necessary and I want to avoid unnecessary changes as much as possible since it complicates the rebase process for OBGM.
@@ -197,7 +201,8 @@ class ApiController { | |||
currencyCode : currencyCode, | |||
localizedHelpScoutKey: localizedHelpScoutKey, | |||
isHelpScoutEnabled : isHelpScoutEnabled, | |||
localizationModeEnabled : localizationModeEnabled | |||
localizationModeEnabled : localizationModeEnabled, | |||
translationModeLocale : translationModeLocale |
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 is my fault since I kept referring to this as "translation mode", but let's either use the existing name "localization mode" or convert everything to "translation mode".
// If we are in localization mode and want to change the language through the footer on React side | ||
// we want to make sure we set the language to the clicked one, not for the previous locale | ||
// we want to set the prev locale only if we disable localization mode through "Disable localization mode" button | ||
Locale localeToSet = params?.localeToSet ? new Locale(params.localeToSet) : session?.prevLocale |
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.
Let's just call this request parameter and variable "locale" (not localeToSet) since that's what it's been called. I'm worried that adding a new request parameter will cause confusion.
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.
For now it is only used for React part, as I didn't have an idea how to determine whether I disable localization mode through button "Disable localization mode" or I just change the language.
When disabling the localization mode through button "Disable localization mode" we want to go back to previous chosen locale.
When changing the language while being in localization mode, we want to disable localization mode, but we don't want to go back to previous chosen locale, but to change it for the language we've just clicked, so that's why I had to figure out some way to determine this.
For GSP part it's unnecessary, because we always change the language through updateUserAuthLocale
.
For React part I just add something like this when changing the language being in localization mode:
href={`/openboxes/user/disableLocalizationMode?localeToSet=${language.code}`}
I know it may cause confusion, but I couldn't figure out anything better and that's why I make the checking if this param is provided and that's why I added a comment above this.
If you have any idea how I could deal with this case, I'd love to hear from you
} | ||
|
||
def enableLocalizationMode = { | ||
// We want to store the previous locale, so we can go back to it when disabling localization mode through button | ||
session.prevLocale = localizationService.getCurrentLocale() |
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.
Sorry to be nit-picky but let's avoid using abbreviations. session.previousLocale
is more readable.
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.
Also is there any difference between getting the current locale versus using session.locale
?
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.
Yeah, let me explain - when you log in and do not neither change the language nor enable localization mode before, session.locale
is still null
- your "initial" locale is taken from session.user.locale
. We set the session.locale
when we either change the language or like you see line below, we enable the localization mode.
This is why I modified getCurrentLocale()
method, because at the beginning, we do not have session.locale
// if no locale specified, do nothing | ||
if (!params.locale) { | ||
redirect(controller: "dashboard", action: "index") | ||
} |
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 know this isn't code you wrote, but we should probably remove the redirects since that's handled at the end. And instead of handling the
if (params.locale) {
// convert the passed locale parameter to an actual locale
Locale locale = new Locale(params.locale)
if (locale) {
// Change the locale
session.locale = locale
// remove all redirects since they aren't going to do anything
// Check if chosen locale is equal to translation mode locale, if so, enable localization mode
session.useDebugLocale = localizationService.isLocalizationModeEnabled()
}
}
log.info "Redirecting to " + params?.targetUri
if (params?.targetUri) {
redirect(uri: params.targetUri)
return
}
// redirect to the dashboard
redirect(controller: "dashboard", action: "index")
LocalizationService
isLocalizationModeEnabled() {
def localizationModeLocale = new Locale(grailsApplication.config.openboxes.locale.translationModeLocale)
return currentLocale == localizationModeLocale
@@ -28,7 +28,7 @@ class MessageTagLib { | |||
boolean databaseStoreEnabled = grailsApplication.config.openboxes.locale.custom.enabled | |||
if (!databaseStoreEnabled) { | |||
Locale defaultLocale = new Locale(grailsApplication.config.openboxes.locale.defaultLocale) | |||
attrs.locale = attrs.locale ?: session?.user?.locale ?: session.locale ?: defaultLocale | |||
attrs.locale = attrs.locale ?: session?.locale ?: session?.user?.locale ?: defaultLocale |
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.
👍
// First search for session locale, if none set, then search for user's default locale, otherwise get the default locale | ||
def session = RequestContextHolder.currentRequestAttributes().getSession() | ||
if (session?.locale) { | ||
return session.locale |
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.
👍
740be28
to
9f6e3ab
Compare
9f6e3ab
to
a3548c6
Compare
chooseLocale should implement the same rules. but @kchelstowski says he's implemented the rules properly in the initialization filter. there's a weird case where the state is not set until we get to the controller and therefore if there's logic that depends on that state in the filters, then we'll have one request where the logic will be wrong. I'll pull this down and check it. |
@jmiranda I played with it again and I reminded myself why I couldn't just stick with the
So I believe that if we'd like to stick with the |
useDebugLocale
logic, which Justin mentioned in the ticketBonus:
webpack
config, so all babel's and eslint's stuff works also fine for.js
files, not only.jsx
- example: optional chaining or nullish coalescing operator, which were added by me not a long time ago, but were not working for.js
files