Skip to content
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

Pre setting the selected rows in the IndexTable #12285

Open
aditibpatil opened this issue Jun 19, 2024 · 0 comments
Open

Pre setting the selected rows in the IndexTable #12285

aditibpatil opened this issue Jun 19, 2024 · 0 comments

Comments

@aditibpatil
Copy link

aditibpatil commented Jun 19, 2024

How to set pre selected ids initially in a IndexTable in Polaris component
I have tried using react state which works fine but when I select any other row then the initially set all the records gets deselected. Could anyone please help?

export default function Index() {
  // data coming from loader function
  const { session, dropshipperId, merchantCount, merchant, pagination } = useLoaderData < typeof loader > ()

  const navigate = useNavigate()

  // selection of merchants
  const { selectedResources, allResourcesSelected, handleSelectionChange } = useIndexResourceState(merchant);

  // loading state of save merchants table 
  const [addRemoveLoading, setAddRemoveLoading] = useState < boolean > (false)

  // array to store selected merchants id 
  const [selectedMerchantIds, setSelectedMerchantIds] = useState < string[] > ([])
  const [allMerchantsSelected, setAllMerchantsSelected] = useState < boolean > (false)

  // toast message to show once saved
  const [showToast, setShowToast] = useState < boolean > (false)

  // useEffect to get previously stored merchant ids subscribed by dropshipper
  useEffect(() => {
    const initialMerchantIds = async () => {
      /* Get merchant ids subscribed by dropshipper */
      try {
        const merchantIdsDataResponse = await fetch(`http://localhost:4000/get-merchant`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify({ dropshipperId })
        })
        if (merchantIdsDataResponse.ok) {
          const merchantIdsDataJSON = await merchantIdsDataResponse.json()
          setSelectedMerchantIds(merchantIdsDataJSON.data.merchants)
          if (merchantIdsDataJSON.data.merchants) {
            if (merchantIdsDataJSON.data.merchants.length == merchant.length) {
              setAllMerchantsSelected(true)
            }
          }
        } else {
          throw new Error('Failed to fetch merchant data');
        }
      } catch (error) {
        console.error('Error fetching merchant data:', error);
      }
      /* Get merchant ids subscribed by dropshipper */
    }

    initialMerchantIds()
  }, [])

  // on change selection of merchants update selected merchant ids
  useEffect(() => {
    setSelectedMerchantIds(prevSelectedIds => {
      // return Array.from(new Set([...prevSelectedIds, ...selectedResources]));
      return selectedResources
    })
    setAllMerchantsSelected(allResourcesSelected)
  }, [selectedResources])

  // merchant pagination
  const pagi = useMemo(() => {
    if (!pagination) {
      // Handle case where paginationP is null or undefined
      return null; // or some default value
    }

    const { current, pageSize, total } = pagination
    return {
      previous: {
        disabled: current <= 1,
        link: `/app/?page=${current - 1}&pageSize=${pageSize}`
      },
      next: {
        disabled: current == Math.ceil(total / pageSize),
        link: `/app/?page=${current + 1}&pageSize=${pageSize}`
      }
    }
  }, [pagination])

  // rows and columns of merchant table 
  const rowMarkup = merchant?.map(({ id, shop, name, url }: Merchant, index: number) => (
    <IndexTable.Row id={id} key={id} position={index} selected={selectedMerchantIds?.includes(id)}>
      <IndexTable.Cell>{name}</IndexTable.Cell>
      <IndexTable.Cell>{shop}</IndexTable.Cell>
      <IndexTable.Cell><Link url={url} dataPrimaryLink target="_blank">{url}</Link></IndexTable.Cell>
    </IndexTable.Row>
  ))

  // resource name of merchant
  const resourceNameMerchant = {
    singular: 'merchant',
    plural: 'merchants'
  }

  // empty state to display when no data present
  const emptyStateMarkup = (type: string) => (
    <EmptySearchResult
      title={`No ${type} yet`}
      description={`Try changing the filters or search term`}
      withIllustration
    />
  )

  // toast
  const toggleActive = useCallback(() => setShowToast((showToast) => !showToast), []);
  const toastMarkup = showToast ? (
    <Toast content="Saved" icon={StatusActiveIcon} onDismiss={toggleActive} />
  ) : null;

  // function to add or remove merchants subscribed by dropshipper into the database
  const addRemoveMerchant = async () => {
    try {
      setAddRemoveLoading(true)
      const addRemoveMerchantResponse = await fetch(`http://localhost:4000/add-remove-merchant`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({ dropshipperId, merchants: selectedMerchantIds })
      })
      if (addRemoveMerchantResponse.ok) {
        toggleActive()
        // console.log("merchants saved")
      } else {
        throw new Error(`Failed to save merchants`);
      }
    } catch (error) {
      console.error(`Error saving merchants:`, error);
    } finally {
      setTimeout(() => {
        setAddRemoveLoading(false)
      }, 1000)
    }
  }

  return (
    <Page title="Test App"
      subtitle="">
      <Frame>
        <BlockStack gap="500">
          <Layout>
            <Layout.Section>
              <Card>
                <BlockStack gap="300">
                  <InlineStack align="space-between" gap="500">
                    <Text as="h2" variant="headingMd">
                      Merchants
                    </Text>
                    <Button variant="primary" loading={addRemoveLoading} onClick={() => addRemoveMerchant()}>Save Merchants</Button>
                  </InlineStack>
                  {toastMarkup}
                  <Card padding={`0`}>
                    <BlockStack gap="400">
                      <IndexTable
                        condensed={useBreakpoints().smDown}
                        resourceName={resourceNameMerchant}
                        itemCount={merchant.length}
                        emptyState={emptyStateMarkup('merchants')}
                        headings={[
                          { title: "Shop" },
                          { title: "Name" },
                          { title: "URL" }
                        ]}
                        selectedItemsCount={
                          allMerchantsSelected ? 'All' : selectedMerchantIds?.length
                        }
                        hasMoreItems
                        onSelectionChange={handleSelectionChange}
                        {...(merchantCount > 0 && pagi && {
                          pagination: {
                            hasPrevious: !pagi.previous.disabled,
                            onPrevious: () => navigate(pagi.previous.link),
                            hasNext: !pagi.next.disabled,
                            onNext: () => navigate(pagi.next.link),
                          }
                        })}
                      >
                        {rowMarkup}
                      </IndexTable>
                    </BlockStack>
                  </Card>
                </BlockStack>
              </Card>
            </Layout.Section>
          </Layout>
        </BlockStack>
      </Frame>
    </Page>
  );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant