~bigbes/lethe

6971b2d09703b22178c58427be3211f93648eaca — Eugene Blikh a month ago 6322186
web: palette — gate prefetch with enabled+staleTime per plan 4.2
M internal/server/web/dist/index.html => internal/server/web/dist/index.html +1 -1
@@ 13,7 13,7 @@
      href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500;700&display=swap"
      rel="stylesheet"
    />
    <script type="module" crossorigin src="/assets/index-KEoqigJf.js"></script>
    <script type="module" crossorigin src="/assets/index-C9v5ApPX.js"></script>
    <link rel="stylesheet" crossorigin href="/assets/index-D-7MmxJh.css">
  </head>
  <body class="density-compact">

M web/src/features/home/useSessions.ts => web/src/features/home/useSessions.ts +8 -1
@@ 28,7 28,12 @@ function sinceToEpoch(since: string): number {
  }
}

export function useSessions(filters: HomeFilters): UseQueryResult<Session[]> {
export interface UseSessionsOptions {
  enabled?: boolean
  staleTime?: number
}

export function useSessions(filters: HomeFilters, options?: UseSessionsOptions): UseQueryResult<Session[]> {
  const since = filters.since ?? '30d'

  return useQuery({


@@ 54,5 59,7 @@ export function useSessions(filters: HomeFilters): UseQueryResult<Session[]> {
      const data = await apiFetch<SessionsResponse>(url)
      return data.sessions.map(adaptSession)
    },
    enabled: options?.enabled,
    staleTime: options?.staleTime,
  })
}

M web/src/features/projects/useProjects.ts => web/src/features/projects/useProjects.ts +8 -1
@@ 24,7 24,12 @@ function sinceToEpoch(since: string): number {
  }
}

export function useProjects(filters: ProjectFilters): UseQueryResult<Project[]> {
export interface UseProjectsOptions {
  enabled?: boolean
  staleTime?: number
}

export function useProjects(filters: ProjectFilters, options?: UseProjectsOptions): UseQueryResult<Project[]> {
  const since = filters.since ?? '30d'

  return useQuery({


@@ 41,5 46,7 @@ export function useProjects(filters: ProjectFilters): UseQueryResult<Project[]> 
      const data = await apiFetch<ProjectsResponse>(url)
      return data.projects.map(adaptProject)
    },
    enabled: options?.enabled,
    staleTime: options?.staleTime,
  })
}

M web/src/features/settings/useSavedSearches.ts => web/src/features/settings/useSavedSearches.ts +8 -2
@@ 8,14 8,20 @@ interface SavedSearchesResponse {
  saved_searches: SavedSearchDTO[]
}

export function useSavedSearches(): UseQueryResult<SavedSearch[]> {
export interface UseSavedSearchesOptions {
  enabled?: boolean
  staleTime?: number
}

export function useSavedSearches(options?: UseSavedSearchesOptions): UseQueryResult<SavedSearch[]> {
  return useQuery({
    queryKey: ['saved-searches'],
    queryFn: async () => {
      const data = await apiFetch<SavedSearchesResponse>('/api/v1/saved-searches')
      return data.saved_searches.map(adaptSavedSearch)
    },
    staleTime: 30_000,
    enabled: options?.enabled,
    staleTime: options?.staleTime ?? 30_000,
  })
}


M web/src/shell/Palette.tsx => web/src/shell/Palette.tsx +5 -4
@@ 72,10 72,11 @@ export function Palette({ open, onClose }: PaletteProps): React.JSX.Element {
    setCursor(0)
  }, [query])

  // Always call hooks unconditionally (React rules); data is used only when open
  const { data: projects } = useProjects({ since: 'all' })
  const { data: sessions } = useSessions({})
  const { data: savedSearches } = useSavedSearches()
  // Always call hooks unconditionally (React rules); enabled+staleTime gate
  // network activity so closed-palette renders don't trigger refetches.
  const { data: projects } = useProjects({ since: 'all' }, { enabled: open, staleTime: 30_000 })
  const { data: sessions } = useSessions({}, { enabled: open, staleTime: 30_000 })
  const { data: savedSearches } = useSavedSearches({ enabled: open, staleTime: 30_000 })

  if (!open) return <></>