github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/web/src/ResourceSelectionContext.tsx (about)

     1  import {
     2    createContext,
     3    PropsWithChildren,
     4    useContext,
     5    useMemo,
     6    useState,
     7  } from "react"
     8  
     9  /**
    10   * The ResourceSelection state keeps track of what resources are selected for bulk actions to be performed on them.
    11   */
    12  
    13  export type ResourceSelectionContext = {
    14    selected: Set<string>
    15    isSelected: (resourceName: string) => boolean
    16    select: (...resourceNames: string[]) => void
    17    deselect: (...resourceNames: string[]) => void
    18    clearSelections: () => void
    19  }
    20  
    21  const ResourceSelectionContext = createContext<ResourceSelectionContext>({
    22    selected: new Set(),
    23    isSelected: (_resourceName: string) => {
    24      console.warn("Resource selections context is not set.")
    25      return false
    26    },
    27    select: (..._resourceNames: string[]) => {
    28      console.warn("Resource selections context is not set.")
    29    },
    30    deselect: (..._resourceNames: string[]) => {
    31      console.warn("Resource selections context is not set.")
    32    },
    33    clearSelections: () => {
    34      console.warn("Resource selections context is not set.")
    35    },
    36  })
    37  
    38  ResourceSelectionContext.displayName = "ResourceSelectionContext"
    39  
    40  export function useResourceSelection(): ResourceSelectionContext {
    41    return useContext(ResourceSelectionContext)
    42  }
    43  
    44  export function ResourceSelectionProvider(
    45    props: PropsWithChildren<{ initialValuesForTesting?: string[] }>
    46  ) {
    47    const selections = new Set(props.initialValuesForTesting) || new Set()
    48    const [selectedResources, setSelectedResources] = useState(selections)
    49  
    50    const contextValue: ResourceSelectionContext = useMemo(() => {
    51      function isSelected(resourceName: string) {
    52        return selectedResources.has(resourceName)
    53      }
    54  
    55      function select(...resourceNames: string[]) {
    56        const newSelections = new Set<string>(selectedResources)
    57        resourceNames.forEach((name) => newSelections.add(name))
    58        return setSelectedResources(newSelections)
    59      }
    60  
    61      function deselect(...resourceNames: string[]) {
    62        const newSelections = new Set<string>(selectedResources)
    63        resourceNames.forEach((name) => newSelections.delete(name))
    64        return setSelectedResources(newSelections)
    65      }
    66  
    67      function clearSelections() {
    68        setSelectedResources(new Set())
    69      }
    70      return {
    71        selected: selectedResources,
    72        isSelected,
    73        select,
    74        deselect,
    75        clearSelections,
    76      }
    77    }, [selectedResources, setSelectedResources])
    78  
    79    return (
    80      <ResourceSelectionContext.Provider value={contextValue}>
    81        {props.children}
    82      </ResourceSelectionContext.Provider>
    83    )
    84  }