@@ -26,11 +26,21 @@ export type GraphRecordRef = {
2626 recordId : string ;
2727} ;
2828
29+ export const GRAPH_DEGREE_OPTIONS = [ 1 , 2 , 3 , 4 , 5 ] as const ;
30+ export type GraphDegree = ( typeof GRAPH_DEGREE_OPTIONS ) [ number ] ;
31+ export const DEFAULT_GRAPH_DEGREES : GraphDegree = 2 ;
32+
33+ export function isGraphDegree ( value : number ) : value is GraphDegree {
34+ return ( GRAPH_DEGREE_OPTIONS as readonly number [ ] ) . includes ( value ) ;
35+ }
36+
2937export type GraphSessionContextValue = {
3038 recordType : string ;
3139 setRecordType : ( value : string ) => void ;
3240 recordId : string ;
3341 setRecordId : ( value : string ) => void ;
42+ degrees : GraphDegree ;
43+ setDegrees : ( value : GraphDegree ) => void ;
3444
3545 graphData : GraphData | null ;
3646 /** Incremented on every fetch; keys the graph subtree so it remounts on new data. */
@@ -76,6 +86,8 @@ export function GraphSessionProvider({
7686
7787 const [ recordType , setRecordType ] = useState ( seed ?. recordType ?? '' ) ;
7888 const [ recordId , setRecordId ] = useState ( seed ?. recordId ?? '' ) ;
89+ const [ degrees , setDegrees ] = useState < GraphDegree > ( DEFAULT_GRAPH_DEGREES ) ;
90+ const [ committedDegrees , setCommittedDegrees ] = useState < GraphDegree > ( DEFAULT_GRAPH_DEGREES ) ;
7991 const [ loadedRecord , setLoadedRecord ] = useState < GraphRecordRef | null > ( seed ) ;
8092 const [ selectedTableNames , setSelectedTableNames ] = useState ( initialTableNames ) ;
8193 /** `null` means "every group", so groups loading in later are included without a sync effect. */
@@ -112,6 +124,7 @@ export function GraphSessionProvider({
112124 {
113125 recordType : loadedRecord ?. recordType ?? '' ,
114126 recordId : loadedRecord ?. recordId ?? '' ,
127+ degrees : committedDegrees ,
115128 ...committedFilterParams ,
116129 } ,
117130 loadedRecord != null ,
@@ -127,15 +140,26 @@ export function GraphSessionProvider({
127140 if ( ! recordType || ! trimmedRecordId ) return ;
128141
129142 const sameFilters = graphFilterParamsEqual ( draftFilterParams , committedFilterParams ) ;
143+ const sameDegrees = degrees === committedDegrees ;
130144 setCommittedFilterParams ( draftFilterParams ) ;
145+ setCommittedDegrees ( degrees ) ;
131146
132147 if ( loadedRecord ?. recordType === recordType && loadedRecord ?. recordId === trimmedRecordId ) {
133- if ( sameFilters ) void refetch ( ) ;
148+ if ( sameFilters && sameDegrees ) void refetch ( ) ;
134149 return ;
135150 }
136151
137152 setLoadedRecord ( { recordType, recordId : trimmedRecordId } ) ;
138- } , [ committedFilterParams , draftFilterParams , loadedRecord , recordId , recordType , refetch ] ) ;
153+ } , [
154+ committedDegrees ,
155+ committedFilterParams ,
156+ degrees ,
157+ draftFilterParams ,
158+ loadedRecord ,
159+ recordId ,
160+ recordType ,
161+ refetch ,
162+ ] ) ;
139163
140164 const refreshGraph = useCallback ( ( ) => {
141165 setCommittedFilterParams ( draftFilterParams ) ;
@@ -180,6 +204,8 @@ export function GraphSessionProvider({
180204 setRecordType,
181205 recordId,
182206 setRecordId,
207+ degrees,
208+ setDegrees,
183209 graphData : data ?? null ,
184210 graphGeneration : dataUpdatedAt ,
185211 isGeneratingGraph : isFetching ,
@@ -196,6 +222,7 @@ export function GraphSessionProvider({
196222 [
197223 recordType ,
198224 recordId ,
225+ degrees ,
199226 data ,
200227 dataUpdatedAt ,
201228 isFetching ,
0 commit comments