site-kit-wp
site-kit-wp copied to clipboard
Add the Selection Panel happy path view (Storybook)
Feature Description
Create the Selection Panel component, implementing the happy path view, and add it to Storybook.
This should include the CTAs but not the behaviour for saving the selection, this will be handled separately via https://github.com/google/site-kit-wp/issues/8158.
Additionally it should not include the loading state, the Audience Creation Notice or the Selection Panel Info Notice, these will be also handled separately via https://github.com/google/site-kit-wp/issues/8162, https://github.com/google/site-kit-wp/issues/8164 and https://github.com/google/site-kit-wp/issues/8159.
It should include the logic/behaviour described in the selection panel > available audiences section.
See selection panel in the design doc.
Do not alter or remove anything below. The following sections will be managed by moderators only.
Acceptance criteria
- The Audience Segmentation Selection Panel component should be created and stories for it added to Storybook.
- It should follow the Figma design, and should also be based on the Key Metrics selection panel.
- The generic components extracted from the KM Selection Panel should be reused (see google/site-kit-wp#8652), with changes to the design for Audience Segmentation applied back to the KM panel (notably the footer layout in the mobile view as mentioned in the design doc).
- The Selection Panel should display the list of available audiences that is cached in the DB (i.e. stored in the
availableAudiences
setting). Their display names and descriptions should be displayed directly, with the exception of the "All users" default audience which should be shown as "All visitors". - The “Purchasers” default audience should only be listed if it’s had any users in it since the associated Analytics property was created.
- Audiences should be selectable via checkboxes and, when there is a currently saved selection, grouped into "Current selection" (the currently saved selection) and "Additional groups" groups.
- The user count for an audience should be displayed on the right hand side of it.
- The Selection Panel should display the header text including the link to the Admin Settings tab on the Settings screen.
- If the Audience Segmentation Settings section is available at implementation time this link should ensure the section is scrolled into view when navigating to the Settings screen. Otherwise, a small followup issue should be created to update the link when the section is available.
- The bottom part of the Selection Panel should include:
- The "Learn more" text including the Analytics link pointing to the introduction to audiences in Google Analytics article.
- The footer which includes the selection count and Cancel / Save selection CTAs.
- As alluded to in the Feature Description, the CTAs don't need to be hooked up here, this will be done via google/site-kit-wp#8158.
- Note that the special case for retrieving reports using the newVsReturning dimension to avoid the “partial data” state as discussed in the design doc's selection panel > available audiences section should not be implemented here, this will be handled separately via google/site-kit-wp#8160.
- Note too that the specific ordering of audiences within the selection panel will be handled via the subsequent issue #8519.
Implementation Brief
Please refer POC PR: https://github.com/google/site-kit-wp/pull/8676. Also, this implementation will be done once #8652 is merged.
- [ ] Create directory
AudiencesSelectionPanel
insideassets/js/modules/analytics-4/components/AudienceSegmentation/
- [ ] Create
constants.js
inside new directory. Add the following constants in it similar to key metrics component.- [ ] Add
AUDIENCES_SELECTION_PANEL_OPENED_KEY
,AUDIENCES_SELECTION_FORM
,AUDIENCES_SELECTED
,MIN_SELECTED_AUDIENCES_COUNT
andMAX_SELECTED_AUDIENCES_COUNT
.
- [ ] Add
- [ ] Create
index.js
which will haveAudiencesSelectionPanel
component in it.- [ ] It should use the
SelectionPanel
component and pass the relevant props to it. - [ ] Make use of
AUDIENCE_SELECTION_PANEL_OPENED_KEY
constant to passisOpen
prop toSelectionPanel
. - [ ]
onOpen
prop should accept a callback function where the callback should add the list of saved audiences toAUDIENCES_SELECTED
. List of saved audiences can be retrieved usinggetConfiguredAudiences
selector. - [ ]
closePanel
prop should be a callback to setAUDIENCES_SELECTION_PANEL_OPENED_KEY
value tofalse
. This callback will also be passed to header component to be triggered on close button's click added in header. - [ ] Within the
SelectionPanel
component. Following components needs to be rendered, which would be passed aschildren
to theSelectionPanel
component.-
Header
-
AudienceItems
-
Footer
-
- [ ] It should use the
- [ ] Create
Header
component insideAudiencesSelectionPanel
directory.- [ ] It should make use of
SelectionPanelHeader
and pass following props to it.- [ ]
title
- Heading text for the selection panel. - [ ]
onCloseClick
- Callback to trigger when selection panel is closed. This can be same callback passed toSelectionPanel
. - [ ]
children
This should display the text under the main heading with the settings link. This is a component created withcreateInterpolateElement
. Refer the figma design for the copy.
- [ ]
- [ ] It should make use of
- [ ] Create
AudienceItems
component insideAudiencesSelectionPanel
directory.- [ ] It should leverage the
SelectionPanelItems
component and pass the necessary props to it. - [ ] Pass current selection title and available selection title according to figma designs.
- [ ]
availableSavedItems
andavailableUnsavedItems
should be calculated by fetching available audiences usinggetAvailableAudiences
selector which returns the available audiences in property andgetConfiguredAudiences
which returns the saved audiences in DB. - [ ]
getAvailableAudiences
should be modified to check if "Purchasers" audience has had any data. This can be checked withgetResourceDataAvailabilityDate
from the partial data infra. If there is any data available for the "Purchasers" i.e.getResourceDataAvailabilityDate
does not return 0 orundefined
, we should keep "Purchasers" ingetAvailableAudiences
response. - [ ] If there has never been any data for "Purchasers", filter out the "Purchasers" from
getAvailableAudiences
response as we do not want to show "Purchasers" audience in this case. - [ ] While passing the
availableSavedItems
andavailableUnsavedItems
props, they must be mapped to includetitle
,description
,subtitle
anduserCount
properties.- [ ]
title
would bedisplayName
from audiences response. - [ ]
description
belongs todescription
property. - [ ]
subtitle
is the text which appears below description. As seen in the figma designs, it will beCreated by ....
text.- [ ] If the audience is "All users" or "Purchasers",
subtitle
would be "Created by default by Google Analytics" - [ ] If the audience is "New visitors" or "Returning visitors",
subtitle
would be "Created by Site Kit". - [ ] For all other audience types,
subtitle
should be "Already exists in your Analytics property".
- [ ] If the audience is "All users" or "Purchasers",
- [ ]
userCount
would be the total number of users in audience for the selected period. This should use thegetReport
selector from analytics module where the metric would betotalUsers
and dimension isaudienceResourceName
.
const options = { startDate: "2024-05-09", endDate: "2024-05-15", metrics: "totalUsers", dimensions: [ 'audienceResourceName' ] }; const result = googlesitekit.data.select('modules/analytics-4').getReport( options );
- [ ]
- [ ] Purchasers audience should only be listed if it’s had any users in it since the associated Analytics property was created. For the same, we can use the
isResourcePartialData
selector to check if there "Purchasers" has had any audience. - [ ] For
savedItemSlugs
pass the value returned bygetConfiguredAudiences
which is array ofname
in audience response. - [ ]
ItemComponent
should beAudiencesItem
which will be responsible to render individual selection item in the panel.- [ ] This component will receive
title
,description
,subtitle
anduserCount
props as mentioned above. - [ ] Note that we need to pass
userCount
assuffix
into (maybe wrapped into some JSX)SelectionPanelItem
component.suffix
prop is described in below point.
- [ ] This component will receive
- [ ] It should leverage the
- [ ] Add an additional prop
suffix
to the componentSelectionPanelItem
. This should be a react component which should be rendered after the SelectionBox component.- [ ] Default value of
suffix
can be a function which returnsfalse
(suffix = () => false
), so that if nothing is passed, it should not render anything. This is particularly useful in case of KM panel.
- [ ] Default value of
- [ ] Create
AudiencesItem
component insideAudiencesSelectionPanel
directory.- [ ] It should leverage the
SelectionPanelItem
component and pass the necessary props to it. All these props should already be passed bySelectionPanelItems
component down to this component. - [ ] We can pass
description
as react component which encompasses ofdescription
of the audience andcreated by
subtitle.
- [ ] It should leverage the
- [ ] Create
Footer
component insideAudiencesSelectionPanel
directory.- [ ] This component should use
SelectionPanelFooter
component to return the new composed component for audience segmentation selection panel footer. - [ ]
savedItemSlugs
- These are the items returned fromgetConfiguredAudiences
. - [ ]
selectedItemSlugs
- This can be retrieved fromAUDIENCES_SELECTED
insideAUDIENCES_SELECTION_FORM
. Please refer this example here. - [ ] Refer other props in
SelectionPanelFooter
and pass them accordingly. A reference ofMetricsFooter
component can be taken to build other props.
- [ ] This component should use
- [ ] It's worth noting that generic components extracted from the KM Selection Panel should be reused in audience selection panel. Note that footer changes in audience selection panel should also be applied to the KM panel.
- [ ] In
assets/sass/components/global/_googlesitekit-selection-panel.scss
, target.googlesitekit-selection-panel-footer__content
and make it display block. - [ ]
.googlesitekit-selection-panel-footer__item-count
should be text aligned left and.googlesitekit-selection-panel-footer__actions
should be text aligned right with display block. - [ ] It's essential that both audience selection panel and KM panel should reflect this change.
- [ ] In
- [ ] Create
Test Coverage
-
Add the
AudiencesSelectionPanel
in storybook with the following scenarios.-
Default
- Where it should show the flat list of all the audiences. -
SavedSelection
- Where it should show theCurrent selection
andAdditional groups
.Current selection
will show the saved items. -
View-only user
- With view only context.
-
-
Write the test for
AudienceSegmentation/AudienceSelectionPanel
component. Take reference of KM component tests. Not all of the tests in theMetricsSelectionPanel
suite will apply to theAudienceSelectionPanel
, so copy/modify the tests which are applicable and add any additional tests as needed.
QA Brief
Changelog entry
Hey @hussain-t, just a heads up that I've amended the Feature Description here to make it clear that we do want to include the logic described in available audiences as part of this issue.
I've also tweaked that section in the design doc to point out that the implementation can leverage the "partial data" infrastructure, and as a result I've added https://github.com/google/site-kit-wp/issues/8141 to the dependencies for this issue. Cc @ivonac4
Hi @hussain-t, just a heads up that I've made a small tweak to the AC to make it clear that we should be leveraging the audience cache here, as opposed to retrieving the audiences directly from the audiences API.
Hi @hussain-t, I've also added a point to the AC to make it clear we don't need to address the specific details of audience ordering in this issue, this will be handled via #8519. This shouldn't actually have any impact on this issue, just want to give a heads up for clarity.
@ankitrox, could you set an estimate?
@hussain-t Added the estimate. Thank you.
Hi @ankitrox, thanks for drafting this IB. Here are some points to consider:
- Using the single
SELECTION_PANEL_OPENED_KEY
key to control the panel's open state is likely to cause problems when there are more than one version of the panel. I can imagine the sharedSELECTION_PANEL_HEADING
andSELECTION_PANEL_SELECTED_ITEMS
potentially being problematic too. I think we should keep separate state for each version of the panel. This could be achieved by passing different key values into the component via props, or potentially via context to facilitate their use in child components. We might want to simplify things a bit by keeping all these values within their own form slice, so we effectively just need to pass a unique value for what's currentlySELECTION_PANEL_FORM
. - Additionally the
MIN_SELECTED_COUNT
andMAX_SELECTED_COUNT
values will differ for the audiences selection panel which has a min of 1 and max 3 selected items, so these values will also need to be passed via props/context. - The passing of a
children
property inselectedItems
andavailableItems
doesn't look right. Rather we should pass a prop likeItemComponent={Label}
which would be the component function rather than a JSX rendered instance. Then we can render the component for each item, passing the item to it via props e.g.<ItemComponent item={item} />
. - Additionally, the shape of the selectable items will be different for each instance - i.e. Key Metrics objects have a different shape to cached audience objects. We'll probably want to map these to a common shape so we'd want to effectively define an interface for a selectable item and map the specific items to it. I also think
selectedItems
should be a simple array of slugs, whileavailableItems
should most likely be an array of mapped, common objects. I imagine these objects should have a shape along the lines of{ slug, title, subtitle, description }
(considering the commonalities between the KM selection panel and the audiences selection panel):- KM panel:
- Audiences panel:
- KM panel:
- In fact, taking these commonalities into consideration maybe we don't even need
ItemComponent
and it should rather be an optional component for rendering a "suffix", e.g.ItemSuffixComponent
, orItemDetailComponent
or something, which can then be used just to show the user count for the audiences panel. - There are a number of Key Metric specific aspects that have been glossed over/missed and will need extracting/abstracting from the appropriate components, for example the saving state, subheader text and behaviour in the
Header
component are all KM-specific, and there are similar things across all the child components. It's worth considering that by lifting this logic out of the child components we might find ourselves with an overly complex parent so it could be appropriate to extract some reusable "base" child components which we then create instance-specific wrappers in which can encapsulate the logic for those components. E.g. we extract a commonHeader
but also create, say, aMetricsSelectionPanel/Header
which contains the KM-specific logic for the header and renders the commonHeader
within it. We don't necessarily need to get too detailed about these aspects in the IB, and we could make a general point about them for awareness rather than defining each and every prop. - CSS classnames should be renamed to remove/replace the
km
substrings so as to be generic. We should avoid passingclassName
in unless we actually need it, a key thing we want to get out of this refactor is to keep the styling common as much as possible. - The IB implies that we'd need to wait for #8158 to be merged in order to retrieve the list of selected widgets. However, #8158 is a dependant of this issue so this issue needs to be merged first. We can simply specify that the list of selected widgets can be retrieved via the
configuredAudiences
settings for the purpose of this issue. - There are some minor formatting issues where backticks haven't been applied to variable names, for example
selectedItems
at the start of point A.3.i and similar. Also it looks like the code snippet in point C.3.i should be using the triple-backtick formatting. There's also a typo that has crept into the IB and POC, "metricss", should obviously be "metrics". - As a general point it's worth bearing in mind this is quite a complex issue for you to have picked up for IB quite early into your time on the project. It's commendable to be keen to get stuck in, but it might be worth ramping up a bit more slowly, going for some easier issues and building up progressively, if possible. I know we are a bit limited in terms of what's available to be picked up so it might be difficult to apply this so well in practice.
Note that since my previous comment we've decided to split this issue into two, with https://github.com/google/site-kit-wp/issues/8652 being created for the initial KM Selection Panel refactor.
Thank you @techanvil for breaking this task into refactoring and audience segmentation panel. This is helpful to better handle the overall requirement.
I have updated the IB considering the fact that we have a separate task for refactoring and key metrics panel. This IB take reference of your POC PR, but I think that should be fine because we are composing the components using extracted components.
Assigning this to you for review.
Thanks again!