Sitecore / Sitecore.Commerce.Headstart.ReactAdmin

This is a basic implementation of Sitecore Commerce using the OrderCloud Javascript SDK. You can use it as a starting point to discover, understand, and learn more about the Sitecore Commerce OrderCloud capabilities.
https://sitecore-commerce-headstart-react-admin.vercel.app/
MIT License
7 stars 33 forks source link

Improve Products list view component anatomy #63

Closed robertsoniv closed 1 year ago

robertsoniv commented 1 year ago

Warning - this is a big task!

Right now the product components are a little all over the place. The product page loads ProductSearch and then ProductSearch loads all of the filters / search / view toggle AND the list/grid components. This isn't very intuitive when just looking at the .src/component/products directory. Let's take the time to revisit the product list view anatomy and see if we can't establish some good patterns that can be repeated elsewhere.

Starting at the NextJS page level and working inward from there. The NextJS page is where we have the opportunity control the layout of the page and the components within it. From my experience, most list views have a similar responsive layout, with some differences in the lower level components that appear at the top of the view.

// .src/pages/products/index.tsx

import { Products } from 'ordercloud-javascript-sdk'
import productListSettings from '../../components/products/ListView/settings'

const Products = () => {
  return (
    <ListView service={Products.List} settings={productListSettings}>
        {(props:ListViewProps) => (
          <>
            <ProductCreate {...props}/>
            <ProductFilters {...props}/>
            <ProductSearch {...props} />
            <Button onClick={props.toggleView}>View Toggle</Button>
          </>
        )}
    </ListView>
  );
}

ListView needs to know what OrderCloud SDK service to use for fetching data. Within ListView we can optionally pass additional "control" components at the top of the page. Using a render function we are able to give our controls access to the information they will need from the ListView, such as callbacks or current state. Without these controls, a simple table is rendered with basic sorting and pagination controls.

Nearly ALL of the heavy lifting will be handled by the HoC ListView component. Maintaining state, mapping initial list options based on URL (optional?), maintaining the selected options in the URL (also optional?), establishing necessary callbacks to allow lower level components some level of control, and finally, rendering the table and/or grid view.

That brings us to the second required parameter: settings. The way I see this working is that these will be the settings that control both the table and grid display options. It would include the column definitions for the table, renderCard callback for the grid, and potentially other necessary settings for list views in general.

robertsoniv commented 1 year ago

settings could include:

{
  columns?: ColumnDefinition[],
  renderCard?: (thing) => React.JSX,
  paramMap?: { [key:string]: string },
  queryMap?: { [key:string]: string }
}
robertsoniv commented 1 year ago

ListView will probably have to be generically typed. So the change here would be that the product page renders <ProductListView/> and that component uses <ListView<IProduct>> under the hood allowing us to strongly type the options for service (promise returning a ListPage<IProduct> result) and the settings (properties available for renderCard & columns).

I think I like this because it means less code in the NextJS page.