import React, { useMemo, useState } from 'react' import { __ } from '@wordpress/i18n' import { Spinner } from '@wordpress/components' import { handleUnknownError } from '../../../utils/errors' import { SubmitButton } from '../SubmitButton' import { TablePagination } from './TablePagination' import type { ListTableAction, ListTableNavProps } from './ListTable' import type { TablePaginationProps } from './TablePagination' import type { Dispatch, Key, MouseEventHandler, PropsWithChildren, SetStateAction } from 'react' const isBulkAction = (value: string, actions: ListTableAction[]): value is A => actions.some(action => action.key === value) interface BulkActionSelectOptionsProps { actions: ListTableAction[] } const BulkActionSelectOptions = ({ actions }: BulkActionSelectOptionsProps) => { const [options, optionGroups] = useMemo(() => { const ungroupedActions: ListTableAction[] = [] const groupedActions = new Map[]>() for (const action of actions) { if (action.group === undefined) { ungroupedActions.push(action) } else { groupedActions.set(action.group, [...groupedActions.get(action.group) ?? [], action]) } } return [ungroupedActions, Array.from(groupedActions.entries())] }, [actions]) return ( <> {options.map(action => )} {optionGroups.map(([groupLabel, groupActions]) => {groupActions.map(action => )} )} ) } interface BulkActionSelectProps { which: 'top' | 'bottom' actions: ListTableAction[] selectedAction: A | undefined setSelectedAction: Dispatch> label: string } const BulkActionSelect = ({ which, actions, selectedAction, setSelectedAction, label }: BulkActionSelectProps) => interface BulkActionsProps extends Required, 'which' | 'actions' | 'doAction'>> { onActionSuccess?: VoidFunction disabled?: boolean selected: Set selectLabel?: string } const BulkActions = function BulkActions({ which, actions, selected, doAction, onActionSuccess, disabled, selectLabel }: BulkActionsProps) { const [selectedAction, setSelectedAction] = useState() const [isPerformingAction, setIsPerformingAction] = useState(false) const handleSubmit: MouseEventHandler = event => { event.preventDefault() if (selectedAction) { setIsPerformingAction(true) doAction(selectedAction, selected) .then(() => { onActionSuccess?.() }) .catch(handleUnknownError) .finally(() => setIsPerformingAction(false)) } } return (
{isPerformingAction ? : null}
) } export interface SelectAllControlProps { keys: K[] selected: Set setSelected: Dispatch>> } export const SelectAllControl = ({ keys, selected, setSelected }: SelectAllControlProps) => export interface TableNavProps extends TableNavigationProps { which: 'top' | 'bottom' } export const TableNav = ({ which, actions, doAction, selected, setSelected, totalItems, totalPages = 0, extraTableNav, endTableNav, selectAllKeys, ...paginationProps }: TableNavProps) => { const isTop = 'top' === which const hasBulkActions = 0 < totalItems && Boolean(actions) return isTop && Boolean(extraTableNav ?? endTableNav) || hasBulkActions || 0 < totalPages ?
{0 < totalItems && actions && doAction && ( setSelected(new Set())} />)} {isTop && selectAllKeys ? : null} {isTop ? extraTableNav?.(which) : null} {0 < totalPages || isTop && endTableNav ?
{0 < totalPages && } {isTop ? endTableNav?.(which) : null}
: null}
: null } export interface TableNavigationProps extends ListTableNavProps, Omit { selected: Set setSelected: Dispatch>> totalItems: number totalPages: number | undefined selectAllKeys?: K[] } export const TableNavigation = ({ children, ...props }: PropsWithChildren>) => <> {children}