Skip to content

Commit

Permalink
fix(masthead): container should respect user's L0 data (#11420)
Browse files Browse the repository at this point in the history
### Related Ticket(s)

Previously fixed in #10986, but that was unwittingly wiped away by #11252

### Description

Fixes an issue where `<c4d-masthead-container>` wipes away user-set L0 data with translations fetched from an API.

This PR takes a different approach from the original fix. The root problem is that the masthead container isn't aware of any `l0Data` passed in before setting that property with translation data. I figured we can make the container a little smarter and handle the logic internally rather than adding another property to the masthead composite and complicating the public API.

In order to facilitate this, I needed the `ConnectMixin` to pass a reference to the class instance into the `mapStateToProps` function it expects classes to define. This empowers the container to first check if it has L0 data before resorting to the translations API data.

As a result, users can reliably set the `l0Data` property on either `<c4d-masthead-container>` or `<c4d-masthead-composite>` and expect the same outcome.

### Changelog

**New**

- `ConnectMixin` passes a class instance reference as an argument in the `mapStateToProps` function.

**Changed**

- `<c4d-masthead-container>` will prefer using L0 data passed by user before resorting to automatically fetched translation data.

<!-- React and Web Component deploy previews are enabled by default. -->
<!-- To enable additional available deploy previews, apply the following -->
<!-- labels for the corresponding package: -->
<!-- *** "test: e2e": Codesandbox examples and e2e integration tests -->
<!-- *** "package: services": Services -->
<!-- *** "package: utilities": Utilities -->
<!-- *** "RTL": React / Web Components (RTL) -->
<!-- *** "feature flag": React / Web Components (experimental) -->
  • Loading branch information
jkaeser authored Feb 1, 2024
1 parent 10037b4 commit cf2f60d
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @license
*
* Copyright IBM Corp. 2020, 2023
* Copyright IBM Corp. 2020, 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
Expand Down Expand Up @@ -29,6 +29,7 @@ import {
mapStateToProps as mapStateToPropsMasthead,
mapDispatchToProps as mapDispatchToPropsMasthead,
} from '../masthead/masthead-container';
import C4DMastheadComposite from '../masthead/masthead-composite';
import C4DDotcomShellComposite from './dotcom-shell-composite';
import { carbonElement as customElement } from '../../internal/vendor/@carbon/web-components/globals/decorators/carbon-element';

Expand Down Expand Up @@ -60,11 +61,12 @@ export type DotcomShellContainerActions =
* @returns The converted version of the given state, tailored for `<c4d-dotcomshell-container>`.
*/
export function mapStateToProps(
state: MastheadContainerState & FooterContainerState
state: MastheadContainerState & FooterContainerState,
self: C4DMastheadComposite
): MastheadContainerStateProps & FooterContainerStateProps {
const footerProps = mapStateToPropsFooter(state);
return {
...mapStateToPropsMasthead(state),
...mapStateToPropsMasthead(state, self),
...Object.keys(footerProps).reduce((acc, key) => {
acc[key !== 'links' ? key : 'footerLinks'] = footerProps[key];
return acc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export const Default = (args) => {
</style>
${useMock
? html`
<c4d-masthead-composite
<c4d-masthead-container
selected-menu-item="${ifDefined(selectedMenuItem)}"
user-status="${ifDefined(userStatus)}"
searchPlaceholder="${ifDefined(searchPlaceholder)}"
Expand All @@ -117,7 +117,7 @@ export const Default = (args) => {
unauthenticatedProfileItems
)}"
custom-profile-login="${customProfileLogin}"
auth-method="${MASTHEAD_AUTH_METHOD.DEFAULT}"></c4d-masthead-composite>
auth-method="${MASTHEAD_AUTH_METHOD.DEFAULT}"></c4d-masthead-container>
`
: html`
<c4d-masthead-container
Expand Down Expand Up @@ -155,15 +155,15 @@ export const WithCustomTypeahead = (args) => {
</style>
${useMock
? html`
<c4d-masthead-composite
<c4d-masthead-container
.l0Data="${mastheadL0Data}"
.authenticatedProfileItems="${ifNonEmpty(
authenticatedProfileItems
)}"
.unauthenticatedProfileItems="${ifNonEmpty(
unauthenticatedProfileItems
)}"
?custom-typeahead-api=${true}></c4d-masthead-composite>
?custom-typeahead-api=${true}></c4d-masthead-container>
`
: html`
<c4d-masthead-container
Expand Down Expand Up @@ -201,7 +201,7 @@ export const searchOpenOnload = (args) => {
</style>
${useMock
? html`
<c4d-masthead-composite
<c4d-masthead-container
.l0Data="${mastheadL0Data}"
.authenticatedProfileItems="${ifNonEmpty(
authenticatedProfileItems
Expand All @@ -212,7 +212,7 @@ export const searchOpenOnload = (args) => {
activate-search="true"
searchPlaceholder="${ifDefined(
searchPlaceholder
)}"></c4d-masthead-composite>
)}"></c4d-masthead-container>
`
: html`
<c4d-masthead-container
Expand Down Expand Up @@ -247,7 +247,7 @@ export const withPlatform = (args) => {
</style>
${useMock
? html`
<c4d-masthead-composite
<c4d-masthead-container
platform="${ifNonEmpty(platform)}"
.l0Data="${mastheadL0Data}"
.authenticatedProfileItems="${ifNonEmpty(
Expand All @@ -256,7 +256,7 @@ export const withPlatform = (args) => {
.unauthenticatedProfileItems="${ifNonEmpty(
unauthenticatedProfileItems
)}"
.platformUrl="${ifNonEmpty(platformUrl)}"></c4d-masthead-composite>
.platformUrl="${ifNonEmpty(platformUrl)}"></c4d-masthead-container>
`
: html`
<c4d-masthead-container
Expand Down Expand Up @@ -313,7 +313,7 @@ export const withL1 = (args) => {
</style>
${useMock
? html`
<c4d-masthead-composite
<c4d-masthead-container
.l0Data="${mastheadL0Data}"
.authenticatedProfileItems="${ifNonEmpty(
authenticatedProfileItems
Expand All @@ -325,7 +325,7 @@ export const withL1 = (args) => {
selected-menu-item="${ifNonEmpty(selectedMenuItem)}"
selected-menu-item-l1="${ifNonEmpty(
selectedMenuItemL1
)}"></c4d-masthead-composite>
)}"></c4d-masthead-container>
`
: html`
<c4d-masthead-container
Expand Down Expand Up @@ -377,7 +377,7 @@ export const withAlternateLogoAndTooltip = (args) => {
</style>
${useMock
? html`
<c4d-masthead-composite
<c4d-masthead-container
.l0Data="${mastheadL0Data}"
.authenticatedProfileItems="${ifNonEmpty(
authenticatedProfileItems
Expand All @@ -387,7 +387,7 @@ export const withAlternateLogoAndTooltip = (args) => {
)}"
.logoData="${mastheadLogo === 'alternateWithTooltip'
? mastheadLogoData
: null}"></c4d-masthead-composite>
: null}"></c4d-masthead-container>
`
: html`
<c4d-masthead-container
Expand Down Expand Up @@ -437,15 +437,15 @@ export const WithScopedSearch = (args) => {
</style>
${useMock
? html`
<c4d-masthead-composite
<c4d-masthead-container
.l0Data="${mastheadL0Data}"
.authenticatedProfileItems="${ifNonEmpty(
authenticatedProfileItems
)}"
.unauthenticatedProfileItems="${ifNonEmpty(
unauthenticatedProfileItems
)}"
.scopeParameters=${scopeParameters}></c4d-masthead-composite>
.scopeParameters=${scopeParameters}></c4d-masthead-container>
`
: html`
<c4d-masthead-container
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,24 @@ export type MastheadContainerActions =

/**
* @param state The Redux state for masthead.
* @param self A reference to the masthead composite instance.
* @returns The converted version of the given state, tailored for `<c4d-masthead-container>`.
*/
export function mapStateToProps(
state: MastheadContainerState
state: MastheadContainerState,
self: C4DMastheadComposite
): MastheadContainerStateProps {
const { localeAPI, translateAPI, profileAPI } = state;
const { language } = localeAPI ?? {};
const { translations } = translateAPI ?? {};
const { request } = profileAPI ?? {};
const { l0Data: userL0Data } = self;

// Attempt to collect data from current/new and deprecated locations.
let l0Data;
let endpointl0Data;
let profileItems;
if (language) {
l0Data = {
endpointl0Data = {
current: translations?.[language]?.masthead?.nav,
deprecated: translations?.[language]?.mastheadNav?.links,
};
Expand All @@ -118,8 +121,11 @@ export function mapStateToProps(

return pickBy(
{
// Progressively enhance to new L0 data shape.
l0Data: !language ? undefined : l0Data.current || l0Data.deprecated,
// Respect user-set L0 data. Otherwise, progressively enhance to new shape.
l0Data:
!language || userL0Data
? undefined
: endpointl0Data.current || endpointl0Data.deprecated,
// Progressively enhance to new profile items shape.
authenticatedProfileItems: !language
? undefined
Expand Down
8 changes: 4 additions & 4 deletions packages/web-components/src/globals/mixins/connect.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @license
*
* Copyright IBM Corp. 2020, 2023
* Copyright IBM Corp. 2020, 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
Expand All @@ -13,7 +13,7 @@ import Handle from '../internal/handle';

/**
* @param store A redux store.
* @returns A funciton that takes a base class and returns a mix-in that connects the component to Redux store.
* @returns A function that takes a base class and returns a mix-in that connects the component to Redux store.
*/
const ConnectMixin =
<
Expand All @@ -23,7 +23,7 @@ const ConnectMixin =
TDispatchProps = { [name: string]: any }
>(
store: Store<TState, TAction>,
mapStateToProps: (state: TState) => TStateProps,
mapStateToProps: (state: TState, self?: any) => TStateProps,
mapDispatchToProps: (dispatch: Dispatch<TAction>) => TDispatchProps = () =>
({} as TDispatchProps)
) =>
Expand All @@ -35,7 +35,7 @@ const ConnectMixin =
_hStore: Handle | null = null;

_handleChangeStoreState(state: TState) {
const props = mapStateToProps(state);
const props = mapStateToProps(state, this);
Object.keys(props as any).forEach((name) => {
const old = this[name];
const current = props[name];
Expand Down

0 comments on commit cf2f60d

Please sign in to comment.