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

     1  import { createContext, PropsWithChildren, useContext, useMemo } from "react"
     2  import { useSessionState } from "./BrowserStorage"
     3  
     4  /**
     5   * The ResourceListOptions state keeps track of filters and sorting
     6   * that are applied to resource lists and used across views (with exceptions).
     7   *
     8   * As the persistent options for resource listing change, this context may
     9   * need to be refactored or reconsidered.
    10   */
    11  
    12  // Note: this state was renamed from `SidebarOptions` to `ResourceListOptions`,
    13  // but the local storage key was kept the same
    14  export const RESOURCE_LIST_OPTIONS_KEY = "sidebar_options"
    15  
    16  export type ResourceListOptions = {
    17    alertsOnTop: boolean // Note: this is only used/implemented in OverviewSidebar
    18    resourceNameFilter: string
    19    showDisabledResources: boolean
    20  }
    21  
    22  type ResourceListOptionsContext = {
    23    options: ResourceListOptions
    24    setOptions: (options: Partial<ResourceListOptions>) => void
    25  }
    26  
    27  export const DEFAULT_OPTIONS: ResourceListOptions = {
    28    alertsOnTop: false,
    29    resourceNameFilter: "",
    30    showDisabledResources: false,
    31  }
    32  
    33  const ResourceListOptionsContext = createContext<ResourceListOptionsContext>({
    34    options: { ...DEFAULT_OPTIONS },
    35    setOptions: () => {
    36      console.warn("Resource list options context is not set.")
    37    },
    38  })
    39  
    40  // Note: non-nullable fields added to `ResourceListOptions` (formerly `SidebarOptions`)
    41  // after its initial release need to have default values filled in here
    42  function maybeUpgradeSavedOptions(savedOptions: ResourceListOptions) {
    43    return {
    44      ...savedOptions,
    45      resourceNameFilter: savedOptions.resourceNameFilter ?? "",
    46      showDisabledResources: savedOptions.showDisabledResources ?? false,
    47    }
    48  }
    49  
    50  export function useResourceListOptions(): ResourceListOptionsContext {
    51    return useContext(ResourceListOptionsContext)
    52  }
    53  
    54  export function ResourceListOptionsProvider(
    55    props: PropsWithChildren<{ initialValuesForTesting?: ResourceListOptions }>
    56  ) {
    57    const defaultPersistentValue = props.initialValuesForTesting ?? {
    58      ...DEFAULT_OPTIONS,
    59    }
    60    const [options, setResourceListOptions] =
    61      useSessionState<ResourceListOptions>(
    62        RESOURCE_LIST_OPTIONS_KEY,
    63        defaultPersistentValue,
    64        maybeUpgradeSavedOptions
    65      )
    66  
    67    const defaultValue: ResourceListOptionsContext = useMemo(() => {
    68      function setOptions(options: Partial<ResourceListOptions>) {
    69        setResourceListOptions((previousOptions) => ({
    70          ...previousOptions,
    71          ...options,
    72        }))
    73      }
    74  
    75      return {
    76        options,
    77        setOptions,
    78      }
    79    }, [options, setResourceListOptions])
    80  
    81    return (
    82      <ResourceListOptionsContext.Provider value={defaultValue}>
    83        {props.children}
    84      </ResourceListOptionsContext.Provider>
    85    )
    86  }