Shopify / polaris

Shopify’s design system to help us work together to build a great experience for all of our merchants.
https://polaris.shopify.com
Other
5.81k stars 1.17k forks source link

ResourceList BulkAction Header Selection not seleting all rows #3144

Closed jamieroyce closed 2 years ago

jamieroyce commented 4 years ago

Issue summary

BulkAction Checkbox does not select all rows in ResourceList

image

Expected behavior

When clicking the checkbox at the top, all rows should get selected.

Actual behavior

I have a ResourceList that is getting data from a GraphQL query. I pass the data.products.edges to the "items" variable of the ResourceList table but then the header checkbox does not select all items in ResourceList. If I switch the "items" back to a sample data set it works fine. I haven't found any documentation covering what this "ItemType" input type actually is and if I can't use the Query output, there should be something clearly stating this.

        <ResourceList
            resourceName={resourceName}
            items={data.products.edges}
            renderItem={renderItem}
            selectedItems={selectedItems}
            onSelectionChange={setSelectedItems}
            promotedBulkActions={promotedBulkActions}
            bulkActions={bulkActions}
        />

Call Stack:

Unhandled Runtime Error
Error: Error in translation for key 'Polaris.ResourceList.a11yCheckboxSelectAllMultiple'. No replacement found for key 'itemsLength'. The following replacements were passed: '{"resourceNamePlural":"products"}'

Call Stack
eval
node_modules/@shopify/polaris/index.es.js (586:0)
String.replace
<anonymous>
I18n.translate
node_modules/@shopify/polaris/index.es.js (581:0)
bulkActionsAccessibilityLabel
node_modules/@shopify/polaris/index.es.js (16782:0)
ResourceList
node_modules/@shopify/polaris/index.es.js (16973:0)
renderWithHooks
file:///mnt/c/Users/jamie/projects/shopify/shopify-integration/.next/static/development/dll/dll_f9de5cbc314a1e41f91e.js (15055:18)
mountIndeterminateComponent
/_next/static/development/dll/dll_f9de5cbc314a1e41f91e.js (17734:13)
beginWork
file:///mnt/c/Users/jamie/projects/shopify/shopify-integration/.next/static/development/dll/dll_f9de5cbc314a1e41f91e.js (18848:16)
HTMLUnknownElement.callCallback
/_next/static/development/dll/dll_f9de5cbc314a1e41f91e.js (440:14)
Object.invokeGuardedCallbackDev
file:///mnt/c/Users/jamie/projects/shopify/shopify-integration/.next/static/development/dll/dll_f9de5cbc314a1e41f91e.js (489:16)

Steps to reproduce the problem

  1. Set your "items" in a ResourceList to the data output from a GraphQL query

Specifications

ghost commented 4 years ago

👋 Thanks for opening your first issue. A contributor should give feedback soon. If you haven’t already, please check out the contributing guidelines.

jamieroyce commented 4 years ago

I stripped my code down to bare bones, got a working example in codesandbox and then applied piece by piece until the issue was found. I changed my ResourceList as follows with a map to iterate over and assign each variable that I wanted to use in the RenderItem laster.

       <ResourceList
        showHeader
        items={data.products.edges.map((product, index) => 
          ({ 
              id: product.node.variants.edges[0].node.id,
              price: product.node.variants.edges[0].node.price,
              title: product.node.title,
              type: product.node.productType,
              description: product.node.description,
              taxCode: product.node.variants.edges[0].node.taxCode,
              taxable: product.node.variants.edges[0].node.taxable,
              source: product.node.images.edges[0]
                ? product.node.images.edges[0].node.originalSrc
                : '',
              alt: product.node.images.edges[0]
              ? product.node.images.edges[0].node.altText
              : '',
              key: product,
            }))} 
        promotedBulkActions={promotedBulkActions}
        resourceName={resourceName}
        renderItem={renderItem} 
        selectedItems={selectedItems}
        onSelectionChange={setSelectedItems}
      />

Here is my RenderItem function:

  function renderItem(item) {

    const media = (
      <Thumbnail
        source={item.source}
        alt={item.alt}
        />
    );

    return (
      <ResourceList.Item 
        id={item.id}
        media={media}
        >
        <Stack>
          <Stack.Item fill>
            <h3>
            <Tooltip light content={item.description} dismissOnMouseOut>
              <TextStyle variation="strong">{item.title}
              </TextStyle>
            </Tooltip>
            </h3>
            <h3>({item.type})</h3>
          </Stack.Item>
          <Stack.Item>
            <h3>
              <TextStyle variation="strong">${item.price}</TextStyle>
            </h3>
          </Stack.Item>
          <Stack.Item>
            <h3>
              {!item.taxCode ? (
                <Badge status="attention">No Tax Code</Badge>
              ) : (
              <Badge status="success">Tax Code: {item.taxCode}</Badge>
              )}
            </h3>
          </Stack.Item>
          <Stack.Item>
            <h3>
              {!item.taxable ? (
                <Badge status="info">Exempt</Badge>
              ) : (
                <Badge status="warning">Taxable</Badge>
              )}
            </h3>
          </Stack.Item>
        </Stack>
      </ResourceList.Item>
    );
  }

Still curious why exactly that made it work and whether or not this is a bug or the expected result.

alex-page commented 2 years ago

Hey @jamieroyce unsure why that happened for you. I am unable to replicate this issue. I am going to close this but feel free to reopen it if needed.