Antd Nested Table : How to render parent rows dynamically depending on data after a search?

Viewed 12

I'm trying to render the parent columns dynamically when a search is executed in the Package ID column. Here's a nested table with Packages nested by Customers.

When there's a search done, if a Customer doesn't have a package ID with the search one, I would like it not to be shown.

So searching for a unique package, I would like to only get 1 row for the Customer, and 1 row for the package Id and its details.

As you can see on this screenshot: enter image description here

I would only like to show the customer that has the Package with the Id searched for (in this case: ID ....7bb4). Incidentally, I am getting this ID from the query params. But searching for 1 package still shows all the rows for the parent Customer.

I followed Antd's docs for the Table's search by column and the Nested table component.

And I can't seem to simply filter the customer's list because there are no packageId inside a Customer's data type. But a package has a customerId.

data is a list of packages, and customersList as its name says, both fetched from 2 different APIs.

Here's my code:

type PackagestableDataIndex = keyof PackagesTableData;

type CustomColumnType = ColumnsType<UserData> & {
    isHidden?: boolean,
};

const PackagesTable: React.FC<PackagesTableProps> = ({ data, isLoading, title, customersList }) => {

    const router = useRouter();

    const { pckg } = router.query;

    const { showModal } = useContext(SettingsModalContext);

    const [packageId, setPackageId] = useState<string | undefined>('');

    const [searchText, setSearchText] = useState('');
    const [searchedColumn, setSearchedColumn] = useState('');
    const searchInput = useRef<InputRef>(null);

    useEffect(() => {
        console.log('pckg in pckg table', pckg);
        setPackageId(pckg as string);
    }, [pckg]);


    const handleSearch = (
        selectedKeys: string[],
        confirm: (param?: FilterConfirmProps) => void,
        dataIndex: PackagestableDataIndex,
    ) => {
        confirm();
        setSearchText(selectedKeys[0]);
        setSearchedColumn(dataIndex);
    };


    const handleReset = (clearFilters: () => void) => {
        clearFilters();
        setSearchText('');
    };


    const getColumnSearchProps = (dataIndex: PackagestableDataIndex): ColumnType<PackagesTableData> => ({
        filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
            <div style={{ padding: 8 }}>
                <Input
                    ref={searchInput}
                    placeholder={`Search ${dataIndex}`}
                    value={selectedKeys[0]}
                    onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
                    onPressEnter={() => handleSearch(selectedKeys as string[], confirm, dataIndex)}
                    style={{ marginBottom: 8, display: 'block' }}
                />
                <Space>
                    <Button
                        type="primary"
                        onClick={() => handleSearch(selectedKeys as string[], confirm, dataIndex)}
                        icon={<SearchOutlined />}
                        size="small"
                        style={{ width: 90 }}
                    >
                        Search
                    </Button>
                    <Button
                        onClick={() => clearFilters && handleReset(clearFilters)}
                        size="small"
                        style={{ width: 90 }}
                    >
                        Reset
                    </Button>
                </Space>
            </div>
        ),
        filterIcon: (filtered: boolean) => (
            <SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />
        ),
        onFilter: (value, record) => (
            record[dataIndex]
                .toString()
                .toLowerCase()
                .includes((value as string).toLowerCase())
        ),
        onFilterDropdownVisibleChange: (visible: any) => {
            if (visible) {
                setTimeout(() => searchInput.current?.select(), 100);
            }
        },
        render: text => text

    });

    const customersColumn: ColumnsType<UserData> = [
        {
            title: 'Customer ID',
            dataIndex: '_id',
            key: '_id',
            // isHidden: record('_id') === packageId,

        },
    ];

    const packagesColumns: ColumnsType<PackagesTableData> = [
        {
            title: 'Package ID',
            dataIndex: '_id',
            key: '_id',
            defaultFilteredValue: [`${packageId ? packageId : ''}`],
            // render: text => <a>{text}</a>,
            ...getColumnSearchProps('_id'),
            // isHidden: false
        },
        {
            title: 'Received On',
            dataIndex: 'receivedOn',
            key: 'receivedOn',
            render(value: any, record: any, index: any) {
                return moment(value).format('MM/DD/YYYY');
            },
            defaultSortOrder: 'ascend',
            sorter: (a, b) => moment(b.receivedOn).valueOf() - moment(a.receivedOn).valueOf(),
        },
        // {
        //     title: 'Customer ID',
        //     dataIndex: 'customerId',
        //     key: 'customerID',
        //     // isHidden: searchId !== ''
        // },
        {
            title: 'Warehouse',
            dataIndex: 'warehouse',
            key: 'warehouse',
        },
        {
            title: 'Carrier',
            dataIndex: 'carrier',
            key: 'carrier',
        },
        {
            title: 'Tracking',
            dataIndex: 'tracking',
            key: 'tracking',
        },
        {
            title: 'Action',
            key: 'action',
            render: (_, record) => (
                <Space size="middle">
                    {/* <div className={styles.action_button}> */}
                    <Button type="primary">
                        <RouterLink to={`/packages/createShipment?pckg=${record._id}&wrhs=${record.warehouse}&ctmr=${record.customerId}`}>
                            <a>Create Shipment</a>
                        </RouterLink>
                    </Button>
                    {/* </div> */}
                    {/* <div className={styles.update_button}> */}
                    <Button
                        type="default"
                        onClick={() => showModal('packages', record._id, 'update')}>
                        Update Info
                    </Button>
                    {/* </div> */}
                    {/* <div className={styles.delete_button}> */}
                    <Button
                        type="primary"
                        danger
                        onClick={() => showModal('packages', record._id, 'delete')}>
                        Delete
                    </Button>
                    {/* </div> */}
                </Space>
            ),
        },
    ]
        // .filter(column => !column.isHidden)
        ;

    const expandedRowRender = (record: UserData) => {

        return (
            <Table
                rowKey={record => record._id}
                columns={packagesColumns}
                dataSource={data.filter(pckg => pckg.customerId === record._id)}
                pagination={{
                    defaultPageSize: 10,
                    showSizeChanger: true,
                    pageSizeOptions: ['10', '20', '30'],
                    position: ['topLeft'],
                }}
            />
        );
    };

    const TableTitle = () => <TableHeader title="Packages" />;

    return (
        <div style={{ paddingTop: '20px' }}>
            {/* {packageId === '' || packageId === undefined
                ? */}
            <Table
                rowKey={record => record._id}
                columns={customersColumn}
                row
                expandable={{ expandedRowRender, defaultExpandedRowKeys: ['_id'] }}
                dataSource={customersList/* .filter(customer => customer._id === pac) */}
                title={title ? title : undefined}
                loading={isLoading}
                pagination={{
                    defaultPageSize: 10,
                    showSizeChanger: true,
                    pageSizeOptions: ['10', '20', '30'],
                    position: ['topLeft'],
                }}
            />
            {/* :
                <Table
                    rowKey={record => record._id}
                    columns={packagesColumns}
                    dataSource={data.filter(pckg => pckg._id === packageId)}
                    title={() => <TableHeader title="New Package" />}
                    loading={isLoading}
                    pagination={{
                        // defaultPageSize: 10,
                        // showSizeChanger: true,
                        // pageSizeOptions: ['10', '20', '30'],
                        position: ['topLeft'],
                    }}
                />
            } */}
        </div>
    );
};

export default PackagesTable;

0 Answers
Related