-
Notifications
You must be signed in to change notification settings - Fork 48
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
DO NOT MERGE!!! All changes from last release for Nina #1042
Conversation
…mbining notifications" This reverts commit 8a97a0b.
* TNT-48367 Make SPA view names lowercase
Support for top and bottom of page events. Combine personalization display notifications together.
…t for rendering to complete.
}) => { | ||
return ({ decisionsDeferred, personalizationDetails, event, onResponse }) => { | ||
return ({ cacheUpdate, personalizationDetails, event, onResponse }) => { | ||
if (personalizationDetails.isRenderDecisions()) { | ||
hideContainers(prehidingStyle); |
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 else
clause here to call showContainers
. Customers implementing async
with pre-hiding snippet will have a hidden page till the timeout function from the snippet is called.
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.
Fixed in #1058
@@ -35,10 +35,10 @@ export default ({ | |||
const xdm = { eventType: INTERACT }; | |||
const scope = decisionsMeta[0].scope; | |||
|
|||
if (scope !== PAGE_WIDE_SCOPE) { | |||
if (isNonEmptyString(scope) && scope !== PAGE_WIDE_SCOPE) { |
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.
the scope would never be empty
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.
Fixed in #1056
xdm.web = { | ||
webPageDetails: { | ||
viewName: scope | ||
viewName: scope.toLowerCase() |
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.
scope
is stored lowercase, no need to lowercase again.
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.
Fixed in #1056
} | ||
}, | ||
items: [ | ||
{ |
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.
Default Content Item
schema is used in Target to indicate that user has entered a "control" experience, using it liberally will cause confusion.
@@ -19,6 +19,11 @@ export const mergeDecisionsMeta = ( | |||
eventType, | |||
eventLabel = "" | |||
) => { | |||
// Do not send a display notification with no decisions. Even empty view changes | |||
// should include a proposition. |
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 move this logic where the event is triggered instead, this functions are calling event
API, to merge to an existing event
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.
Fixed in #1061
} | ||
|
||
if (!modules[type]) { | ||
logger.warn("Invalid DOM action data: unknown type.", item.getData()); |
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.
In such cases we should set renderAttempted: false, includeInNotifications:false
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.
Fixed in #1060
const errorMessage = `Failed to execute action ${item.toString()}. ${message} ${stack}`; | ||
logger.error(errorMessage); | ||
} | ||
return false; |
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.
logger level should be warrning
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.
Fixed in #1058
let renderedItems = []; | ||
let nonRenderedItems = []; | ||
let itemRenderers = []; | ||
let atLeastOneWithNotification = false; |
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.
so many flags, a decision diagram would be very helpful for CE engineers debugging an issue.
[schema.HTML_CONTENT_ITEM]: createProcessHtmlContent({ modules, logger }), | ||
[schema.REDIRECT_ITEM]: createProcessRedirect({ | ||
logger, | ||
executeRedirect: url => window.location.replace(url), |
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.
extract this to a function
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.
Fixed in #1061
|
||
const render = () => { | ||
return collect({ decisionsMeta: [item.getMeta()] }).then(() => { | ||
executeRedirect(content); |
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.
Render would be called only when renderDecisions:true
, otherwise it should be just part of the array of propositions returned.
Collect should be called here with documentMayUnload
argument.
You should try/catch errors here and log the error and showContainers.
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 renderDecisions is false, processRedirect isn't even called, and the proposition is just returned as part of the returned propositions. See
if (personalizationDetails.isRenderDecisions()) { |
Changing it to use collect is fixed in #1061
The try/catch is done in
.catch(error => { |
The showContainers is in
showContainers(); |
return "page"; | ||
} | ||
if (scopeType === "view") { | ||
return "view"; |
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.
as this gets part of the proposition design, extract this into an enum of proposition types.
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 fixed in #1056
|
||
export const EMPTY_PROPOSITIONS = { propositions: [] }; | ||
|
||
export default ({ logger, options }) => { | ||
const applyPropositionsOptionsValidator = objectOf({ | ||
propositions: arrayOf(objectOf(anything())).nonEmpty(), | ||
metadata: objectOf(anything()) | ||
propositions: arrayOf(objectOf(anything())), |
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 validator should be oneOf
:
viewName
propositions
&&metadata
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 you don't send in any propositions or a viewName, then this command does nothing. That's not an error. Additionally it is a valid use case to send in propositions without metadata. These could be page_wide_scope propositions that were not rendered automatically.
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.
Generally, I would recommend breaking this into a few smaller PRs, it touches one of the most impactful and feature rich components, Personalization. Mixing the whole component refactoring and adding a big feature on top of that becomes pretty complicated for the PR reviewer to understand the changes and how it will impact the backward compatibility.
The src/components/Personalization/handlers/createProcessPropositions.js
is pretty complex, would be good to break it into smaller descriptive pieces and comments. A design spec would also help CE rotation engineers that will potentially have to debug a related issue.
While testing Target use-cases, have found a few use-cases that needs to be fixed:
- when
renderDecisions: false
the redirect offer should not be executed, the proposition should be returned in the result - the notification should be a
collect
instead ofinteract
call - when
renderDecisions:false
the prehiding snippet should be removed(showContainers
should be called) - when a click from a surface occurs the surface scope should not be sent in a
viewName
,viewName
will be populated only when the propositionscopeType:view
- when something fails, we log warnings, not errors
As improvements:
- the functional tests for AJO should be improved to have the assertions for rendering, click notifications
viewName
I have mentioned above. - add test for
renderDecisions:false
and redirect offer being returned - add a functional test to validate that prehiding style is removed:
-- when no personalization payload is returned
-- whenrenderDecisions
is false
-- when an exception while executing
deduplicateArray | ||
} from "../utils"; | ||
|
||
const getXdmPropositions = xdm => { |
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.
experience.decisioning
is strictly Personalization related. Core should remain Personalization agnostic. Move this logic to Personalization component.
!userXdm.web || | ||
!userXdm.web.webPageDetails || | ||
!userXdm.web.webPageDetails.viewName | ||
) { |
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.
in case viewName
is undefined it will anyways be returned as undefined
. No need for extra condition. Please revert this change.
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.
Fixed in #1061
@@ -63,8 +81,23 @@ export default () => { | |||
return; | |||
} | |||
|
|||
const newPropositions = deduplicateArray( |
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 logic too should be moved to Personalization.
@@ -35,10 +35,10 @@ export default ({ | |||
const xdm = { eventType: INTERACT }; | |||
const scope = decisionsMeta[0].scope; | |||
|
|||
if (scope !== PAGE_WIDE_SCOPE) { | |||
if (isNonEmptyString(scope) && scope !== PAGE_WIDE_SCOPE) { |
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.
the viewName
would be populated only when the proposition was for an SPA view, add to this if
clause another one that checks if scopeType: view
.
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.
Fixed in #1056
I've addressed most of the comments here in these PRs: Outstanding are still these comments:
|
Description
DO NOT MERGE!!! This is all the changes for the new release.
Related Issue
Motivation and Context
Screenshots (if appropriate):
Types of changes
Checklist: