-
Notifications
You must be signed in to change notification settings - Fork 386
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
fix: site theme not initialized correctly from storage #19170
fix: site theme not initialized correctly from storage #19170
Conversation
- Use `config.context[THEME_CONTEXT_ID]` as a default theme ID - No longer fetch a "custom theme" from the backend, but use `config.context[THEME_CONTEXT_ID]` instead (which could have been loaded from backend by the `SiteContextConfigService`, but didn't have to) - Use other configured themes (`config.siteTheme.siteThemes`) as as optional themes - removed from default config of optional themes the default theme object placeholder - thanks to above, the validation of theme (on setActive) is now synchronous
…t's now derived synchronously from configs `config.context[SITE_THEME_ID]` and `config.siteTheme.siteThemes`
…se now by convention the first item in the array is the default one
…s class one from DOM, but just don't apply new (empty) class
…e they are really expected to be defined)
…alues (except undefined)
…ther themes configs into one list
projects/core/src/site-context/config/config-loader/site-context-config-initializer.ts
Outdated
Show resolved
Hide resolved
…xt-config-initializer.ts
projects/core/src/site-theme/services/site-theme-initializer.ts
Outdated
Show resolved
Hide resolved
if (this.featureConfigService.isEnabled('useNewSiteThemeSwitcher')) { | ||
if (this.existingTheme) { | ||
this.renderer.removeClass(element, this.existingTheme); | ||
} | ||
if (theme) { | ||
this.renderer.addClass(element, theme); | ||
this.existingTheme = theme; | ||
} |
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.
New code accounts for the fact that either existingTheme
or the new theme
can be an empty string ''
. But the native DOM API throws an error when we try to add a CSS class ''
.
Moreover, if the old class was non-empty, but the new one is ''
, then we want to just unset the previous one.
…spartacus into feat/CXSPA-7604--fix-race-condition
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.
LGTM. As we discussed offline, unit test adjustments are going to be provided separately
@Platonn
Also, we can no longer switch back to the default theme after selecting a different one |
Good catch. It seems to me that both problems are caused by the lack of a default value of |
…-7604--fix-race-condition
BEFORE:
Elaborating more:
When we attempted to set a value from storage on page start, we encountered an ASYNC mechanism of validation (which in the background called the OCC endpoint /basesites). Unfortunately, then we immediately expected the value to have been set (despite it was delayed by an async validation) - we checked synchronously the value of the
isInitialized()
. This race condition led to setting improper value to ngrx on the page start.Besides this problem, we also forced all customers to make in an APP_INITIALIZER an obligatory render-blocking http call to OCC endpount /basesites, (even regardless if they used CMS-driven theming or not). Please note that we already had a different generic mechanism (
SiteContextConfigInitializer
) which performs such a render-blocking call, but customers only if customers decide to load site context data from CMS (alternatively they can configure site context statically in Spartacus config). It's a tradeoff each customer need to make - to have dynamic CMS-driven site context, Spartacus needs to make a http roundtrip.AFTER:
SiteContextConfigInitializer
to possibly fetch the theme from CMS - only if a customer decides to load site context data from CMS. Alternatively, a customer can configure the theme statically in Spartacus configconfig.context
.Side changes that needed to be made:
config.context[THEME_CONTEXT_ID]: string
config.siteTheme.siteThemes
toconfig.siteTheme.optionalThemes
.config.context[THEME_CONTEXT_ID]: string
defines the default theme ID (which can be configured manually in Spartacus config OR it can be populated dynamically by theSiteContextConfigInitializer
if a customers decides so. So we preserve the old behavior.config.siteTheme.optionalThemes: SiteTheme[]
defines ONLY the optional themes (like high contrast ones), with their IDs (class names) and a11y labelsconfig.context[THEME_CONTEXT_ID]: string
is left undefined, we use an empty string''
as the default theme ID - resulting in storing''
in thelocalStorage
and setting NO css class in DOM in case when this theme is activatedStatePersistenceService
(the functionpersistToStorage
to be precise) to allow for storing an empty string''
- which, to my surprise, was previously impossible (due to a conditionif(value)...
). Now only theundefined
values are prevented. For more, see the JSDoc comment with explanation inpersistToStorage()
functionconfig.context.theme
) and when they don't enable fetching a theme from CMS (viaStatePersistenceService
), then we we use a fallback value - an empty string''
- as the css class / ID of the default theme. This matches the original behavior on thedevelop
branch - to not set any css class when config.context.theme is not defined.QA steps:
Prerequisites:
storefront-component.module.ts
line 29, add an import of the moduleThemeSwitcherModule
(from'../../cms-components/misc/theme-switcher/theme-switcher.module';
)storefront.component.html
line 1, add<cx-theme-switcher />
TEST CASES:
config.context.theme
is undefinedspartacus⚿⚿siteTheme
, if exists.spartacus⚿⚿siteTheme
has a value''
(empty string)[...document.querySelector('cx-storefront').classList]
, the list doesn't contain any class related to themingHC-dark
spartacus⚿⚿siteTheme
has a value'cx-theme-high-contrast-dark'
[...document.querySelector('cx-storefront').classList]
, the list contains'cx-theme-high-contrast-dark'
spartacus⚿⚿siteTheme
has a value'cx-theme-high-contrast-dark'
[...document.querySelector('cx-storefront').classList]
, the list contains'cx-theme-high-contrast-dark'
Default
spartacus⚿⚿siteTheme
has a value''
(empty string)[...document.querySelector('cx-storefront').classList]
, the list doesn't contain any class related to theming (e.g. it DOES NOT contain anymore'cx-theme-high-contrast-dark'
)config.context.theme
is definedspartacus-b2c-configuration.module.ts
in line 40, in thecontext
config, add a new key:theme: ['spike']
''
you should seespike
config.context.theme
is populated by theSiteContextConfigInitializer
spartacus-b2c-configuration.module.ts
comment-out lines 36-40, effectively removing the staticcontext
config. (This will trigger loading loading this config from CMS Basesites. For more see docs)''
you should seesantorini
closes https://jira.tools.sap/browse/CXSPA-8153