Refactor the Key Metrics Selection Panel, extracting components for reuse in the Audience Segmentation Selection Panel.
Feature Description
In order to efficiently reuse the KM Selection Panel's markup, styling and presentation-related logic, we should extract a set of generic, presentational components from the Key Metrics Selection Panel, refactoring the panel to use these components in the process.
Do not alter or remove anything below. The following sections will be managed by moderators only.
Acceptance criteria
- The KM Selection Panel should be refactored such that its markup rendering is extracted to a set of generic presentational components.
- Generic presentation-related logic should be extracted along with the markup where appropriate.
- CSS classes used by these generic components should be renamed to remove references to Key Metrics.
- The generic components and styling should be suitable for building additional Selection Panels, with the Audience Segmentation Selection Panel the first additional consumer.
- The KM Selection Panel should be unchanged from the user's perspective.
Implementation Brief
Please refer the POC PR: https://github.com/google/site-kit-wp/pull/8676
Extracting components.
- [ ] Create a directory
SelectionPanelinassets/js/components/and extract following components into it.- [ ]
SelectionPanel.jsthis is the main component which will wrap theSideSheetcomponent into it with the following props.- [ ]
isOpen= Flag to tell whether panel is open or not. - [ ]
onOpen- A function which gets executed once the panel is opened. - [ ]
closeFn- A function which gets executed once the panel is closes. - [ ]
children- This is useful to insert/display other components within the panel.
- [ ]
- [ ]
SelectionPanelHeader.js, it will display the panel heading and optionally the settings link. It will accept the following props.- [ ]
onCloseClick- Callback when the panel closes. - [ ]
title- Title/heading for the panel. - [ ]
children- Component/content to display in the panel header.
- [ ]
- [ ]
SelectionPanelFooter.jsplease refer the component in POC PR. It will be responsible for displaying the error, footer content, cancel button and save button. This component will accept the following props.- [ ]
savedItemSlugs- Array of slugs for the saved items in database. - [ ]
selectedItemSlugs- Array of slugs for the selected items in the selection form insideCORE_FORMSstore. - [ ]
saveSettings- Callback to save selections. - [ ]
saveError- Any error that may have occurred while saving the settings insaveSettingscallback. - [ ]
itemLimitError- Error to display when less/more than minimum/maximum allowable items are selected respectively. - [ ]
minSelectedItemCount- Minimum items to be selected. - [ ]
maxSelectedItemCount- Maximum allowable items to be selected. - [ ]
isBusy- Flag to tell whether panel CTAs should be disabled because some other operation like saving the settings is in progress. - [ ]
onSaveSuccess- Callback function to call when settings are saved successfully. This can be utilised to reset the dirty form status. - [ ]
onCancel- Callback function to call when cancel button is clicked. - [ ]
isOpen- Flag to tell if the selection panel is open. - [ ]
closeFn- Callback function to call when closing the panel. It will be called on click of cancel button. It should reset any selections in selection form inCORE_FORMSstore.
- [ ]
- [ ]
SelectionPanelItems.js- Component is used to render the currently selected items and other available items for selection.- [ ] It will also accept the
ItemComponentprop, which is the component responsible for displaying the individual item. By default, this should beSelectionPanelItemcomponent in case it is not passed.
- [ ] It will also accept the
- [ ]
SelectionPanelItem.jsthis component should expect the props sent by theSelectionPanelItemscomponent which areid,slug,title,description,onChange,disabled,checkedandchildren.- [ ]
id- This will be used as key prop for item component as well as the id attribute for item in html. - [ ]
slug- It will be used as checkbox value. - [ ]
title- title for checkbox. - [ ]
description- Description of the item, will appear below the title. This will be a react component and will be rendered as is. - [ ]
onChange- Callback for checkbox selection. Will be called when item is selected/deselected. - [ ]
checked- Flag to tell whether the item should be selected or not. - [ ]
disabled- Whether the checkbox should be disabled. - [ ]
children- Any additional children component that needs to be displayed afterdescription.
- [ ]
- [ ]
Updating Key Metrics components.
- [ ] Key Metrics components should utilize the extracted generic components so that we have a concrete key metrics component. The concrete components should pass props to the extracted components.
- [ ] Update
assets/js/components/KeyMetrics/MetricsSelectionPanel/index.js, useSelectionPanelcomponent and pass the relevant props to it. - [ ] Add
MetricsHeader,Metrics,CustomDimensionsNoticeandMetricsFootercomponent as children to theSelectionPanelcomponent. - [ ] Update
MetricsHeadercomponent. Pass the following props toSelectionPanelHeadercomponent.- [ ]
title- Heading text for the selection panel. - [ ]
onCloseClick- Callback to trigger when selection panel is closed. - [ ]
children- This should display the text under the main heading with thesettingslink. This is a component created withcreateInterpolateElement.
- [ ]
- [ ] Update
Metricscomponent so that it usesSelectionPanelItemscomponent for selected items and otherPanelItemscomponent for available items.- [ ] Pass the title for current selection and available selections.
- [ ] Pass the currently saved items and unsaved items as props. Logic for this should already be there in the
Metricscomponent.
- [ ] Update
MetricsFootercomponent, it should useSelectionPanelFooterto compose the concrete component.- [ ] Please note that we need to evaluate the necessary props inside the component and pass it to generic component to make use of it.
- [ ] Update
MetricItemcomponent to useSelectionPanelItemcomponent. Pass other props as mentioned in theSelectionPanelItemcomponent.
- [ ] Update
Updating CSS class names to more generic ones.
- [ ] Rename all instances of
googlesitekit-km-selection-panel-*and replace withgooglesitekit-selection-panel-. - [ ] Also, remove any references to
metricsormetricin classname. For example:googlesitekit-km-selection-panel-metrics__metric-itemshould be replaced bygooglesitekit-selection-panel-item. - [ ] Create a directory
selection-panelinsideassets/sass/components/.- [ ] Move
assets/sass/components/key-metrics/_googlesitekit-km-selection-panel.scssinside new directory. - [ ] Rename file to
_googlesitekit-selection-panel.scss. - [ ] Change class names to the generic ones as we changed above.
- [ ] Move
Test Coverage
- Update the e2e tests for the key metrics selection panel.
- Update the stories for the key metrics selection panel.
- Add the stories for generic selection panel component.
- There should be no failing VRT ideally as we are not modifying anything visually, but fix any failing tests.
QA Brief
- Open the Key Metrics selection panel and verify that it is absolutely unchanged.
- In Storybook, check out the
Components > Selection Panelstory variants and verify that their behaviour and styling is aligned with the key metrics selection panel (there might be a few features not implemented but generally it should behave similarly).
Changelog entry
- Enhance Key Metrics selection panel by introducing and reusing generic selection panel components.
Hi @ankitrox, thanks for drafting the IB/POC. It's definitely heading in the right direction, however there are a number of aspects I would like to see addressed.
- We should be aiming to reuse the CSS classes more than your POC demonstrates.
- We should also look to share more common logic and structure, while keeping the refactor as simple as we can.
- I think we can avoid the
savedflag in the items and we don't need asuffixat this point either.
I figured it would be easiest to show you what I mean in more detail by putting together a POC myself: https://github.com/google/site-kit-wp/pull/8676/. I think this is most of the way there and the main thing remaining to do is to genericise the CSS class names.
Please take a look at my POC, consider my feedback, let me know your thoughts if you wish to discuss this, and/or update the IB accordingly.
Thanks @ankitrox, nice work here so far on the IB.
I've made a few tweaks, to fix a couple of minor errors and remove some duplication, which you can see in the edit history.
Additionally - although I did mention you could take the approach of not listing all the props for each item and instead refer to the POC, where you have listed the props (which is totally fine), you've missed most of them for the SelectionPanelFooter component. Please can you provide the full list of props for this component too, for consistency?
Thanks @techanvil for fixing typos and formatting.
I have expanded on SelectionPanelFooter component props as suggested. I haven't provided too much info on MetricsFooter because it would be repetitive.
Assigning you for review.
Thanks again!
Thanks @ankitrox, that's great. IB LGTM! :white_check_mark:
QA Status ⚠️
This is tested good overall:
-
CSS classes used by these generic components have been renamed to remove references to Key Metrics. ✅
-
The KM Selection Panel is unchanged from the user's perspective. Compared prod and develop and the panels are consistent with each other. ✅
-
In Storybook, the Components > Selection Panel story variants, their behaviour and styling is aligned with the key metrics selection panel ✅
-
Layout, margin, padding, font family , font sizes are consistent with Key Metrics panel ✅
-
Verified on Mobile, tablet and other browsers too and results are consistent across. ✅
-
The only behaviour that I noticed is different is when clicking a checkbox. Refer to the detailed video below ⚠️
https://github.com/google/site-kit-wp/assets/125576926/c24303cc-ab2a-4388-92e8-81dc82b1168b
Thank you for sharing your observation, @kelvinballoo!
- The only behaviour that I noticed is different is when clicking a checkbox. Refer to the detailed video below ⚠️
Interesting observation. However, as long as the focus behaviour is unchanged in the actual application, we should be good to go here, which I just checked and ensured that it is.
See screen recording
https://github.com/google/site-kit-wp/assets/20284937/f676887b-2a22-4fef-89a4-9d60fd5e9292
The Storybook story for SelectionPanel uses a custom set of made-up items and relies on the local state to store the selection. The focus gets lost there most likely due to re-rendering events. I believe we can overlook that.
Please let me know if you have any other concerns, thank you, Kelvin!
QA Updates ✅
Thanks for the explanation @nfmohit . That makes sense. Moving this ticket to Approval.