@@ -95,18 +95,74 @@ export interface SystemTree extends Partial<System> {
9595 subsystems ?: SystemTree [ ] ;
9696}
9797
98- const getSystemTree = async ( parent_id : string ) : Promise < SystemTree [ ] > => {
99- // Fetch the systems at the current level
98+ const getSystemTree = async (
99+ parent_id : string ,
100+ maxSubsystems : number , // Total max subsystems allowed
101+ maxDepth ?: number ,
102+ currentDepth : number = 0 , // Default value
103+ subsystemsCutOffPoint ?: number , // Total cutoff point
104+ totalSubsystems : { count : number } = { count : 0 } , // Shared counter object
105+ catalogueItemCache : Map < string , CatalogueItem > = new Map ( ) // Shared cache for catalogue items
106+ ) : Promise < SystemTree [ ] > => {
107+ // Stop recursion if currentDepth exceeds maxDepth
108+ if ( maxDepth !== undefined && currentDepth >= maxDepth ) {
109+ return [ ] ;
110+ }
100111
112+ // Fetch the root system
101113 const rootSystem = await getSystem ( parent_id ) ;
102114
115+ // Fetch systems at the current level
103116 const systems = await getSystems ( parent_id || 'null' ) ;
104117
118+ // Increment the total count of subsystems
119+ totalSubsystems . count += systems . length ;
120+
121+ // Throw an AxiosError if the total count exceeds maxSubsystems
122+ if ( maxSubsystems !== undefined && totalSubsystems . count > maxSubsystems ) {
123+ throw new AxiosError (
124+ `Total subsystems exceeded the maximum allowed limit of ${ maxSubsystems } . Current count: ${ totalSubsystems . count } ` ,
125+ 'SubsystemLimitExceeded' ,
126+ undefined ,
127+ null ,
128+ {
129+ status : 400 ,
130+ statusText : 'Bad Request' ,
131+ headers : { } ,
132+ // @ts -expect-error: not needed
133+ config : { } ,
134+ data : {
135+ message : `Subsystem limit exceeded. Max: ${ maxSubsystems } , Current: ${ totalSubsystems . count } ` ,
136+ } ,
137+ }
138+ ) ;
139+ }
140+
141+ // Stop recursion if totalSubsystems count exceeds the cutoff point
142+ if (
143+ subsystemsCutOffPoint !== undefined &&
144+ totalSubsystems . count > subsystemsCutOffPoint
145+ ) {
146+ return systems . map ( ( system ) => ( {
147+ ...system ,
148+ subsystems : [ ] ,
149+ catalogueItems : [ ] ,
150+ } ) ) ;
151+ }
152+
105153 // Fetch subsystems and catalogue items for each system recursively
106154 const systemsWithTree : SystemTree [ ] = await Promise . all (
107155 systems . map ( async ( system ) => {
108- // Fetch subsystems recursively
109- const subsystems = await getSystemTree ( system . id ) ;
156+ // Fetch subsystems recursively, increasing the depth
157+ const subsystems = await getSystemTree (
158+ system . id ,
159+ maxSubsystems ,
160+ maxDepth ,
161+ currentDepth + 1 ,
162+ subsystemsCutOffPoint ,
163+ totalSubsystems ,
164+ catalogueItemCache
165+ ) ;
110166
111167 // Fetch all items for the current system
112168 const items = await getItems ( system . id ) ;
@@ -118,7 +174,15 @@ const getSystemTree = async (parent_id: string): Promise<SystemTree[]> => {
118174
119175 const catalogueItems : SystemTree [ 'catalogueItems' ] = await Promise . all (
120176 Array . from ( catalogueItemIdSet ) . map ( async ( id ) => {
121- const catalogueItem = await getCatalogueItem ( id ) ;
177+ // Check if the item exists in the cache
178+ if ( ! catalogueItemCache . has ( id ) ) {
179+ // If not, fetch and store it in the cache
180+ const fetchedCatalogueItem = await getCatalogueItem ( id ) ;
181+ catalogueItemCache . set ( id , fetchedCatalogueItem ) ;
182+ }
183+
184+ // Retrieve the item from the cache
185+ const catalogueItem = catalogueItemCache . get ( id ) ! ;
122186 const categoryItems = items . filter (
123187 ( item ) => item . catalogue_item_id === id
124188 ) ;
@@ -131,7 +195,6 @@ const getSystemTree = async (parent_id: string): Promise<SystemTree[]> => {
131195 ) ;
132196
133197 // Handle the case when there are no systems (leaf nodes or empty levels)
134-
135198 const items = await getItems ( parent_id ) ;
136199
137200 // Group items into catalogue categories and fetch catalogue item details
@@ -141,23 +204,54 @@ const getSystemTree = async (parent_id: string): Promise<SystemTree[]> => {
141204
142205 const catalogueItems : SystemTree [ 'catalogueItems' ] = await Promise . all (
143206 Array . from ( catalogueItemIdSet ) . map ( async ( id ) => {
144- const catalogueItem = await getCatalogueItem ( id ) ;
207+ // Check if the item exists in the cache
208+ if ( ! catalogueItemCache . has ( id ) ) {
209+ // If not, fetch and store it in the cache
210+ const fetchedCatalogueItem = await getCatalogueItem ( id ) ;
211+ catalogueItemCache . set ( id , fetchedCatalogueItem ) ;
212+ }
213+
214+ // Retrieve the item from the cache
215+ const catalogueItem = catalogueItemCache . get ( id ) ! ;
145216 const categoryItems = items . filter (
146217 ( item ) => item . catalogue_item_id === id
147218 ) ;
148219 return { ...catalogueItem , itemsQuantity : categoryItems . length } ;
149220 } )
150221 ) ;
151222
152- return [ { ...rootSystem , catalogueItems, subsystems : systemsWithTree } ] ;
223+ return [
224+ {
225+ ...rootSystem ,
226+ catalogueItems,
227+ subsystems : systemsWithTree ,
228+ } ,
229+ ] ;
153230} ;
154231
155232export const useGetSystemsTree = (
156- parent_id ?: string | null
233+ parent_id ?: string | null ,
234+ maxDepth ?: number ,
235+ subsystemsCutOffPoint ?: number , // Add cutoff point as a parameter
236+ maxSubsystems ?: number
157237) : UseQueryResult < SystemTree [ ] , AxiosError > => {
158238 return useQuery ( {
159- queryKey : [ 'SystemsTree' , parent_id ] ,
160- queryFn : ( ) => getSystemTree ( parent_id ?? '' ) ,
239+ queryKey : [
240+ 'SystemsTree' ,
241+ parent_id ,
242+ maxSubsystems ,
243+ maxDepth ,
244+ subsystemsCutOffPoint ,
245+ ] ,
246+ queryFn : ( ) =>
247+ getSystemTree (
248+ parent_id ?? '' ,
249+ maxSubsystems ?? 150 ,
250+ maxDepth ,
251+ 0 ,
252+ subsystemsCutOffPoint
253+ ) ,
254+ staleTime : 1000 * 60 * 5 ,
161255 } ) ;
162256} ;
163257
0 commit comments