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 }