mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 19:21:50 +00:00
improve FilteredConnection filter types (#63672)
This gives a bit more type-safety when using FilteredConnection filters. ## Test plan CI
This commit is contained in:
parent
73881aef18
commit
b0f3ba5f35
@ -8,8 +8,13 @@ import styles from './FilterControl.module.scss'
|
||||
|
||||
/**
|
||||
* A filter to display next to the search input field.
|
||||
* @template K The IDs of all filters ({@link Filter.id} values).
|
||||
* @template A The type of option args ({@link Filter.options} {@link FilterOption.args} values).
|
||||
*/
|
||||
export interface Filter {
|
||||
export interface Filter<
|
||||
K extends string = string,
|
||||
A extends Record<string, string | number | boolean | null> = Record<string, string | number | boolean | null>
|
||||
> {
|
||||
/** The UI label for the filter. */
|
||||
label: string
|
||||
|
||||
@ -20,7 +25,7 @@ export interface Filter {
|
||||
* The URL query parameter name for this filter (conventionally the label, lowercased and
|
||||
* without spaces and punctuation).
|
||||
*/
|
||||
id: string
|
||||
id: K
|
||||
|
||||
/** An optional tooltip to display for this filter. */
|
||||
tooltip?: string
|
||||
@ -28,13 +33,16 @@ export interface Filter {
|
||||
/**
|
||||
* All of the possible values for this filter that the user can select.
|
||||
*/
|
||||
options: FilterOption[]
|
||||
options: FilterOption<A>[]
|
||||
}
|
||||
|
||||
/**
|
||||
* An option that the user can select for a filter ({@link Filter}).
|
||||
* @template A The type of option args ({@link Filter.options} {@link FilterOption.args} values).
|
||||
*/
|
||||
export interface FilterOption {
|
||||
export interface FilterOption<
|
||||
A extends Record<string, string | number | boolean | null> = Record<string, string | number | boolean | null>
|
||||
> {
|
||||
/**
|
||||
* The value (corresponding to the key in {@link Filter.id}) if this option is chosen. For
|
||||
* example, if a filter has {@link Filter.id} of `sort` and the user selects a
|
||||
@ -44,13 +52,14 @@ export interface FilterOption {
|
||||
value: string
|
||||
label: string
|
||||
tooltip?: string
|
||||
args: { [name: string]: string | number | boolean }
|
||||
args: A
|
||||
}
|
||||
|
||||
/**
|
||||
* The values of all filters, keyed by the filter ID ({@link Filter.id}).
|
||||
* @template K The IDs of all filters ({@link Filter.id} values).
|
||||
*/
|
||||
export interface FilterValues extends Record<string, FilterOption['value'] | null> {}
|
||||
export type FilterValues<K extends string = string> = Record<K, FilterOption['value'] | null>
|
||||
|
||||
interface FilterControlProps {
|
||||
/** All filters. */
|
||||
|
||||
@ -113,7 +113,11 @@ interface FilteredConnectionProps<C extends Connection<N>, N, NP = {}, HP = {}>
|
||||
queryConnection: (args: FilteredConnectionQueryArguments) => Observable<C>
|
||||
|
||||
/** Called when the queryConnection Observable emits. */
|
||||
onUpdate?: (value: C | ErrorLike | undefined, query: string, activeValues: FilteredConnectionArgs) => void
|
||||
onUpdate?: (
|
||||
value: C | ErrorLike | undefined,
|
||||
query: string,
|
||||
activeValues: Record<string, string | number | boolean | null>
|
||||
) => void
|
||||
|
||||
/**
|
||||
* Set to true when the GraphQL response is expected to emit an `PageInfo.endCursor` value when
|
||||
@ -660,8 +664,15 @@ class InnerFilteredConnection<N, NP = {}, HP = {}, C extends Connection<N> = Con
|
||||
private buildArgs = buildFilterArgs
|
||||
}
|
||||
|
||||
export const buildFilterArgs = (filters: Filter[], filterValues: FilterValues): FilteredConnectionArgs => {
|
||||
let args: FilteredConnectionArgs = {}
|
||||
/**
|
||||
* @template K The IDs of all filters ({@link Filter.id} values).
|
||||
* @template A The type of option args ({@link Filter.options} {@link FilterOption.args} values).
|
||||
*/
|
||||
export function buildFilterArgs<
|
||||
K extends string = string,
|
||||
A extends Record<string, string | number | boolean | null> = Record<string, string | number | boolean | null>
|
||||
>(filters: Filter<K, A>[], filterValues: FilterValues<K>): A {
|
||||
let args = {} as unknown as A
|
||||
for (const [filterID, value] of Object.entries(filterValues)) {
|
||||
if (value === undefined) {
|
||||
continue
|
||||
@ -684,7 +695,3 @@ export const resetFilteredConnectionURLQuery = (parameters: URLSearchParams): vo
|
||||
parameters.delete('first')
|
||||
parameters.delete('after')
|
||||
}
|
||||
|
||||
export interface FilteredConnectionArgs {
|
||||
[name: string]: string | number | boolean
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { useCallback, useMemo } from 'react'
|
||||
|
||||
import type { ApolloError, WatchQueryFetchPolicy } from '@apollo/client'
|
||||
import { useNavigate, useLocation } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
|
||||
import { type GraphQLResult, useQuery } from '@sourcegraph/http-client'
|
||||
import { useQuery, type GraphQLResult } from '@sourcegraph/http-client'
|
||||
|
||||
import { asGraphQLResult } from '../utils'
|
||||
|
||||
@ -59,9 +59,11 @@ interface UsePaginatedConnectionConfig<TResult> {
|
||||
pollInterval?: number
|
||||
}
|
||||
|
||||
export type PaginationKeys = 'first' | 'last' | 'before' | 'after'
|
||||
|
||||
interface UsePaginatedConnectionParameters<TResult, TVariables extends PaginatedConnectionQueryArguments, TNode> {
|
||||
query: string
|
||||
variables: Omit<TVariables, 'first' | 'last' | 'before' | 'after'>
|
||||
variables: Omit<TVariables, PaginationKeys>
|
||||
getConnection: (result: GraphQLResult<TResult>) => PaginatedConnection<TNode> | undefined
|
||||
options?: UsePaginatedConnectionConfig<TResult>
|
||||
}
|
||||
@ -71,7 +73,6 @@ const DEFAULT_PAGE_SIZE = 20
|
||||
/**
|
||||
* Request a GraphQL connection query and handle pagination options.
|
||||
* Valid queries should follow the connection specification at https://relay.dev/graphql/connections.htm
|
||||
*
|
||||
* @param query The GraphQL connection query
|
||||
* @param variables The GraphQL connection variables
|
||||
* @param getConnection A function that filters and returns the relevant data from the connection response.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user