11import * as React from "react" ;
22import { useTranslation } from "react-i18next" ;
3- import { useForm } from "react-hook-form" ;
3+ import { useForm , useWatch , UseFormReturn } from "react-hook-form" ;
44import * as yup from "yup" ;
55import { yupResolver } from "@hookform/resolvers/yup" ;
66
@@ -13,6 +13,7 @@ import { HookFormPFGroupController } from "@app/components/HookFormPFFields";
1313import { jsonSchemaToYupSchema } from "@app/components/schema-defined-fields/utils" ;
1414
1515interface FiltersFormValues {
16+ filterRequired : boolean ;
1617 schema ?: TargetedSchema ;
1718 document ?: JsonDocument ;
1819}
@@ -24,10 +25,40 @@ export interface FilterState {
2425 isValid : boolean ;
2526}
2627
28+ const useFilterStateChangeHandler = (
29+ form : UseFormReturn < FiltersFormValues > ,
30+ onFiltersChanged : ( filterState : FilterState ) => void
31+ ) => {
32+ const {
33+ control,
34+ formState : { isValid } ,
35+ } = form ;
36+
37+ const watchedValues = useWatch ( {
38+ control,
39+ name : [ "schema" , "document" , "filterRequired" ] ,
40+ } ) ;
41+
42+ const filterState = React . useMemo ( ( ) : FilterState => {
43+ const [ schema , document , filterRequired ] = watchedValues ;
44+ return {
45+ filterRequired,
46+ schema,
47+ document,
48+ isValid,
49+ } ;
50+ } , [ watchedValues , isValid ] ) ;
51+
52+ React . useEffect ( ( ) => {
53+ onFiltersChanged ( filterState ) ;
54+ } , [ onFiltersChanged , filterState ] ) ;
55+ } ;
56+
2757export const FilterInput : React . FC < {
2858 platform : SourcePlatform ;
2959 onFiltersChanged : ( filterState : FilterState ) => void ;
30- } > = ( { platform, onFiltersChanged } ) => {
60+ initialFilters ?: FilterState ;
61+ } > = ( { platform, onFiltersChanged, initialFilters } ) => {
3162 const { t } = useTranslation ( ) ;
3263
3364 const validationSchema = yup . object ( ) . shape ( {
@@ -41,54 +72,35 @@ export const FilterInput: React.FC<{
4172 } ) ,
4273 } ) ;
4374
44- const {
45- control,
46- reset,
47- getValues,
48- watch,
49- formState : { isValid } ,
50- } = useForm < FiltersFormValues > ( {
75+ const form = useForm < FiltersFormValues > ( {
5176 defaultValues : {
52- schema : undefined ,
53- document : { } ,
77+ filterRequired : initialFilters ?. filterRequired ?? true ,
78+ schema : initialFilters ?. schema ?? undefined ,
79+ document : initialFilters ?. document ?? { } ,
5480 } ,
5581 resolver : yupResolver ( validationSchema ) ,
5682 mode : "all" ,
5783 } ) ;
84+ const { setValue, control } = form ;
5885
59- // Fetch the discovery filters schema for the platform and put it in the form
86+ // Fetch the discovery filter schema for the platform
6087 const { filtersSchema } = useFetchPlatformDiscoveryFilterSchema (
6188 platform ?. kind
6289 ) ;
90+
91+ // Update form values that react to schema changes
6392 React . useEffect ( ( ) => {
93+ // TODO: If the schema is undefined, it could be a 404 and we should not require a filter
6494 if ( filtersSchema ) {
65- reset ( {
66- ...getValues ( ) ,
67- schema : filtersSchema ,
68- document : { } ,
69- } ) ;
95+ setValue ( "schema" , filtersSchema ) ;
96+ setValue ( "filterRequired" , true ) ;
7097 } else {
71- reset ( {
72- ...getValues ( ) ,
73- schema : undefined ,
74- document : undefined ,
75- } ) ;
98+ setValue ( "schema" , undefined ) ;
99+ setValue ( "filterRequired" , false ) ;
76100 }
77- } , [ filtersSchema , reset , getValues ] ) ;
101+ } , [ filtersSchema , setValue ] ) ;
78102
79- // Relay form state changes to parent component
80- const watchedValues = watch ( ) ;
81- React . useEffect ( ( ) => {
82- // TODO: Track the filter loading state -- 404 = no filter needed, !!data = filter needed
83- const filterRequired = ! ! filtersSchema ;
84-
85- onFiltersChanged ( {
86- filterRequired,
87- schema : watchedValues . schema ,
88- document : watchedValues . document ,
89- isValid : isValid ,
90- } ) ;
91- } , [ onFiltersChanged , watchedValues , isValid , filtersSchema ] ) ;
103+ useFilterStateChangeHandler ( form , onFiltersChanged ) ;
92104
93105 return (
94106 < div >
0 commit comments