Skip to content

TableBody Server Side Filter/Sort Loading Indicator #2452

Open
@jpgilchrist

Description

@jpgilchrist

🙋 Feature Request

I was looking through the code and the TableBody only enters the loading state when loading and loading more. I'd like to optionally control the isLoading state of the TableBody for server side filtering/sorting.

🤔 Expected Behavior

I setup a SearchField that updates a useAsyncList filterText which subsequently calls the load function and thus an api call.

😯 Current Behavior

Only shows loading in loading and loadingMore

💁 Possible Solution

Expose an isLoading prop?

<TableBody 
  loadingState={list.loadingState} 
  isLoading={['loading', 'loadingMore', 'filtering', 'sorting'].includes(list.loadingState)}
  >
    ...
</TableBody>

🔦 Context

💻 Examples

<Flex direction='column' gap='size-200' marginTop='size-200'>
            <Flex direction={{base: 'column', M: 'row'}} gap='size-200'>
                <SearchField
                    label='Search'
                    placeholder='Username, Name, Email'
                    onChange={(value) => updateFilter('search', value)}
                    width={{base: '100%', M: '50%'}}
                />
                <LocationSearch
                    onSelectionChange={(value) => updateFilter('locationId', value)}
                    label='Location'
                    placeholder='Location Name'
                    width={{base: '100%', M: '25%'}}
                />
                <TeamSearch
                    onSelectionChange={(value) => updateFilter('teamId', value)}
                    label='Team'
                    placeholder='Team Name'
                    width={{base: '100%', M: '25%'}}
                />
            </Flex>
            <TableView
                aria-label='Manage Users'
                density='spacious'
                height='size-6000'
                renderEmptyState={renderEmptyState}
            >
                <TableHeader columns={columns}>
                    {(column) => (
                        <Column
                            align={column.align}
                            allowsSorting={column.allowsSorting}
                            width={column.width}
                            minWidth={column.minWidth}
                            maxWidth={column.maxWidth}
                            hideHeader={column.hideHeader}
                        >
                            {column.name}
                        </Column>
                    )}
                </TableHeader>

                <TableBody
                    items={list.items}
                    loadingState={list.loadingState}
                    onLoadMore={list.loadMore}
                >
                    {(item) => (
                        <Row key={item.UserID}>
                            {(columnKey) => <Cell>{renderCellContents(columnKey, item)}</Cell>}
                        </Row>
                    )}
                </TableBody>
            </TableView>
        </Flex>

Unrelated, but that function there for updateFilter('search', value) is an interesting way I got around passing in multiple filters into useAsyncList.

    const [filters, setFilters] = useState({
        search: '',
        locationId: '',
        teamId: ''
    });

    const [debouncedFilters] = useDebounce(filters, 500);

    useEffect(() => {
        list.setFilterText(JSON.stringify(debouncedFilters));
    }, [debouncedFilters])

  let list = useAsyncList({
        initialFilterText: JSON.stringify(filters),
        async load({cursor, filterText, signal, items}) {
            const filters = JSON.parse(filterText);
            // call api with filters.search, filters.teamId, filters.locationId
           ....
      }
  })

🧢 Your Company/Team

Testimonial Tree

🎁 Tracking Ticket (optional)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions