77import click
88import requests
99
10- from .universal_handlers import UniversalResponseHandler
10+ from .universal_handlers import UniversalResponseHandler , FilteredResponse
1111from .utils import (
1212 ExitCodes ,
1313 get_base_url ,
@@ -158,6 +158,139 @@ def validate_field_type(field_type: str) -> None:
158158 )
159159
160160
161+ def _query_all_groups (workspace_filter : Optional [str ] = None , workspace_map : Optional [dict ] = None ):
162+ """Query all DFF groups using continuation token pagination.
163+
164+ Args:
165+ workspace_filter: Optional workspace ID or name to filter by
166+ workspace_map: Optional workspace mapping to avoid repeated lookups
167+
168+ Returns:
169+ List of all groups, optionally filtered by workspace
170+ """
171+ url = f"{ get_base_url ()} /nidynamicformfields/v1/groups"
172+ all_groups = []
173+ continuation_token = None
174+
175+ while True :
176+ # Build parameters for the request
177+ params = {"Take" : 100 } # Use smaller page size for efficient pagination
178+ if continuation_token :
179+ params ["ContinuationToken" ] = continuation_token
180+
181+ # Build query string
182+ query_string = "&" .join ([f"{ k } ={ v } " for k , v in params .items ()])
183+ full_url = f"{ url } ?{ query_string } "
184+
185+ resp = make_api_request ("GET" , full_url )
186+ data = resp .json ()
187+
188+ # Extract groups from this page
189+ groups = data .get ("groups" , [])
190+ all_groups .extend (groups )
191+
192+ # Check if there are more pages
193+ continuation_token = data .get ("continuationToken" )
194+ if not continuation_token :
195+ break
196+
197+ # Filter by workspace if specified
198+ if workspace_filter and workspace_map :
199+ all_groups = filter_by_workspace (all_groups , workspace_filter , workspace_map )
200+
201+ return all_groups
202+
203+
204+ def _query_all_fields (workspace_filter : Optional [str ] = None , workspace_map : Optional [dict ] = None ):
205+ """Query all DFF fields using continuation token pagination.
206+
207+ Args:
208+ workspace_filter: Optional workspace ID or name to filter by
209+ workspace_map: Optional workspace mapping to avoid repeated lookups
210+
211+ Returns:
212+ List of all fields, optionally filtered by workspace
213+ """
214+ url = f"{ get_base_url ()} /nidynamicformfields/v1/fields"
215+ all_fields = []
216+ continuation_token = None
217+
218+ while True :
219+ # Build parameters for the request
220+ params = {"Take" : 500 } # Use smaller page size for efficient pagination
221+ if continuation_token :
222+ params ["ContinuationToken" ] = continuation_token
223+
224+ # Build query string
225+ query_string = "&" .join ([f"{ k } ={ v } " for k , v in params .items ()])
226+ full_url = f"{ url } ?{ query_string } "
227+
228+ resp = make_api_request ("GET" , full_url )
229+ data = resp .json ()
230+
231+ # Extract fields from this page
232+ fields = data .get ("fields" , [])
233+ all_fields .extend (fields )
234+
235+ # Check if there are more pages
236+ continuation_token = data .get ("continuationToken" )
237+ if not continuation_token :
238+ break
239+
240+ # Filter by workspace if specified
241+ if workspace_filter and workspace_map :
242+ all_fields = filter_by_workspace (all_fields , workspace_filter , workspace_map )
243+
244+ return all_fields
245+
246+
247+ def _query_all_configurations (
248+ workspace_filter : Optional [str ] = None , workspace_map : Optional [dict ] = None
249+ ):
250+ """Query all configurations using continuation token pagination.
251+
252+ Args:
253+ workspace_filter: Optional workspace ID or name to filter by
254+ workspace_map: Optional workspace mapping to avoid repeated lookups
255+
256+ Returns:
257+ List of all configurations, optionally filtered by workspace
258+ """
259+ url = f"{ get_base_url ()} /nidynamicformfields/v1/configurations"
260+ all_configurations = []
261+ continuation_token = None
262+
263+ while True :
264+ # Build parameters for the request
265+ params = {"Take" : 100 } # Use smaller page size for efficient pagination
266+ if continuation_token :
267+ params ["ContinuationToken" ] = continuation_token
268+
269+ # Build query string
270+ query_string = "&" .join ([f"{ k } ={ v } " for k , v in params .items ()])
271+ full_url = f"{ url } ?{ query_string } "
272+
273+ resp = make_api_request ("GET" , full_url )
274+ data = resp .json ()
275+
276+ # Extract configurations from this page
277+ configurations = data .get ("configurations" , [])
278+ all_configurations .extend (configurations )
279+
280+ # Check if there are more pages
281+ continuation_token = data .get ("continuationToken" )
282+ if not continuation_token :
283+ break
284+
285+ # Filter by workspace if specified
286+ if workspace_filter and workspace_map :
287+ all_configurations = filter_by_workspace (
288+ all_configurations , workspace_filter , workspace_map
289+ )
290+
291+ return all_configurations
292+
293+
161294def register_dff_commands (cli ):
162295 """Register the 'dff' command group and its subcommands."""
163296
@@ -190,43 +323,21 @@ def config():
190323 )
191324 def list_configurations (workspace : Optional [str ] = None , take : int = 25 , format : str = "table" ):
192325 """List dynamic form field configurations."""
193- url = f"{ get_base_url ()} /nidynamicformfields/v1/configurations"
194-
195326 try :
196- params = {"Take" : 1000 } # Fetch more data for pagination
197- query_string = "&" .join ([f"{ k } ={ v } " for k , v in params .items ()])
198- full_url = f"{ url } ?{ query_string } "
199-
200- resp = make_api_request ("GET" , full_url )
201- data = resp .json ()
202- configurations = data .get ("configurations" , [])
203-
204327 # Get workspace map once and reuse it
205328 workspace_map = get_workspace_map ()
206329
207- # Filter by workspace if specified
208- if workspace :
209- configurations = filter_by_workspace (configurations , workspace , workspace_map )
210-
211330 # Use the workspace formatter for consistent formatting
212331 format_config_row = WorkspaceFormatter .create_config_row_formatter (workspace_map )
213332
333+ # Use continuation token pagination following user_click.py pattern
334+ all_configurations = _query_all_configurations (workspace , workspace_map )
335+
214336 # Use UniversalResponseHandler for consistent pagination
215337 from typing import Any
216338
217- # Create a mock response with filtered data
218- class FilteredResponse :
219- def __init__ (self , filtered_data ):
220- self ._data = {"configurations" : filtered_data }
221-
222- def json (self ):
223- return self ._data
224-
225- @property
226- def status_code (self ):
227- return 200
228-
229- filtered_resp : Any = FilteredResponse (configurations )
339+ # Create a mock response with all data
340+ filtered_resp : Any = FilteredResponse ({"configurations" : all_configurations })
230341
231342 handler = UniversalResponseHandler ()
232343 handler .handle_list_response (
@@ -757,43 +868,21 @@ def groups():
757868 )
758869 def list_groups (workspace : Optional [str ] = None , take : int = 25 , format : str = "table" ):
759870 """List dynamic form field groups."""
760- url = f"{ get_base_url ()} /nidynamicformfields/v1/groups"
761-
762871 try :
763- params = {"Take" : 1000 } # Fetch more data for pagination
764- query_string = "&" .join ([f"{ k } ={ v } " for k , v in params .items ()])
765- full_url = f"{ url } ?{ query_string } "
766-
767- resp = make_api_request ("GET" , full_url )
768- data = resp .json ()
769- groups = data .get ("groups" , [])
770-
771872 # Get workspace map once and reuse it
772873 workspace_map = get_workspace_map ()
773874
774- # Filter by workspace if specified
775- if workspace :
776- groups = filter_by_workspace (groups , workspace , workspace_map )
875+ # Use continuation token pagination following the pattern
876+ all_groups = _query_all_groups (workspace , workspace_map )
777877
778878 # Use the workspace formatter for consistent formatting
779879 format_group_row = WorkspaceFormatter .create_group_field_row_formatter (workspace_map )
780880
781881 # Use UniversalResponseHandler for consistent pagination
782882 from typing import Any
783883
784- # Create a mock response with filtered data
785- class FilteredResponse :
786- def __init__ (self , filtered_data ):
787- self ._data = {"groups" : filtered_data }
788-
789- def json (self ):
790- return self ._data
791-
792- @property
793- def status_code (self ):
794- return 200
795-
796- filtered_resp : Any = FilteredResponse (groups )
884+ # Create a mock response with all data
885+ filtered_resp : Any = FilteredResponse ({"groups" : all_groups })
797886
798887 handler = UniversalResponseHandler ()
799888 handler .handle_list_response (
@@ -835,43 +924,21 @@ def fields():
835924 )
836925 def list_fields (workspace : Optional [str ] = None , take : int = 25 , format : str = "table" ):
837926 """List dynamic form fields."""
838- url = f"{ get_base_url ()} /nidynamicformfields/v1/fields"
839-
840927 try :
841- params = {"Take" : 1000 } # Fetch more data for pagination
842- query_string = "&" .join ([f"{ k } ={ v } " for k , v in params .items ()])
843- full_url = f"{ url } ?{ query_string } "
844-
845- resp = make_api_request ("GET" , full_url )
846- data = resp .json ()
847- fields = data .get ("fields" , [])
848-
849928 # Get workspace map once and reuse it
850929 workspace_map = get_workspace_map ()
851930
852- # Filter by workspace if specified
853- if workspace :
854- fields = filter_by_workspace (fields , workspace , workspace_map )
931+ # Use continuation token pagination following the pattern
932+ all_fields = _query_all_fields (workspace , workspace_map )
855933
856934 # Use the workspace formatter for consistent formatting
857935 format_field_row = WorkspaceFormatter .create_group_field_row_formatter (workspace_map )
858936
859937 # Use UniversalResponseHandler for consistent pagination
860938 from typing import Any
861939
862- # Create a mock response with filtered data
863- class FilteredResponse :
864- def __init__ (self , filtered_data ):
865- self ._data = {"fields" : filtered_data }
866-
867- def json (self ):
868- return self ._data
869-
870- @property
871- def status_code (self ):
872- return 200
873-
874- filtered_resp : Any = FilteredResponse (fields )
940+ # Create a mock response with all data
941+ filtered_resp : Any = FilteredResponse ({"fields" : all_fields })
875942
876943 handler = UniversalResponseHandler ()
877944 handler .handle_list_response (
@@ -971,7 +1038,7 @@ def query_tables(
9711038 "workspace" : workspace_id ,
9721039 "resourceType" : resource_type ,
9731040 "resourceId" : resource_id ,
974- "take" : 1000 , # Fetch more data for pagination
1041+ "take" : take ,
9751042 "returnCount" : return_count ,
9761043 }
9771044
@@ -993,18 +1060,7 @@ def query_tables(
9931060 from typing import Any
9941061
9951062 # Create a mock response with filtered data
996- class FilteredResponse :
997- def __init__ (self , filtered_data ):
998- self ._data = {"tables" : filtered_data }
999-
1000- def json (self ):
1001- return self ._data
1002-
1003- @property
1004- def status_code (self ):
1005- return 200
1006-
1007- filtered_resp : Any = FilteredResponse (tables )
1063+ filtered_resp : Any = FilteredResponse ({"tables" : tables })
10081064
10091065 handler = UniversalResponseHandler ()
10101066 handler .handle_list_response (
0 commit comments