11"""Native Dashboard API endpoints"""
22
3- import copy
43from typing import Optional , List
54from datetime import timedelta
65
@@ -174,15 +173,12 @@ def duplicate_dashboard(request, dashboard_id: int):
174173
175174 # Create a copy of the dashboard
176175 with transaction .atomic ():
177- # First create new dashboard WITHOUT layout_config and components (we'll update them later)
178176 new_dashboard = Dashboard .objects .create (
179177 title = f"Copy of { original_dashboard .title } " ,
180178 description = original_dashboard .description ,
181179 dashboard_type = original_dashboard .dashboard_type ,
182180 grid_columns = original_dashboard .grid_columns ,
183181 target_screen_size = original_dashboard .target_screen_size ,
184- layout_config = [], # Will be updated after filter duplication
185- components = {}, # Will be updated after filter duplication
186182 created_by = orguser ,
187183 org = orguser .org ,
188184 last_modified_by = orguser ,
@@ -204,47 +200,6 @@ def duplicate_dashboard(request, dashboard_id: int):
204200 )
205201 filter_id_mapping [str (original_filter .id )] = str (new_filter .id )
206202
207- # Now update layout_config and components with new filter IDs
208-
209- # Deep copy the original data to avoid modifying it
210- new_layout_config = copy .deepcopy (original_dashboard .layout_config or [])
211- new_components = copy .deepcopy (original_dashboard .components or {})
212-
213- # Update layout_config: change component IDs from "filter-{old_id}" to "filter-{new_id}"
214- for layout_item in new_layout_config :
215- item_id = layout_item .get ("i" , "" )
216- if item_id .startswith ("filter-" ):
217- # Extract old filter ID and replace with new one
218- old_filter_id = item_id .replace ("filter-" , "" )
219- if old_filter_id in filter_id_mapping :
220- new_filter_id = filter_id_mapping [old_filter_id ]
221- layout_item ["i" ] = f"filter-{ new_filter_id } "
222-
223- # Update components: change component keys and filterId references
224- updated_components = {}
225- for component_id , component_data in new_components .items ():
226- new_component_id = component_id
227- new_component_data = copy .deepcopy (component_data )
228-
229- # If this is a filter component
230- if component_id .startswith ("filter-" ):
231- old_filter_id = component_id .replace ("filter-" , "" )
232- if old_filter_id in filter_id_mapping :
233- new_filter_id = filter_id_mapping [old_filter_id ]
234- new_component_id = f"filter-{ new_filter_id } "
235-
236- # Update the filterId reference in the component config
237- if (
238- "config" in new_component_data
239- and "filterId" in new_component_data ["config" ]
240- ):
241- new_component_data ["config" ]["filterId" ] = int (new_filter_id )
242-
243- updated_components [new_component_id ] = new_component_data
244-
245- # Update the dashboard with the corrected layout_config, components, and tabs
246- new_dashboard .layout_config = new_layout_config
247- new_dashboard .components = updated_components
248203 new_dashboard .tabs = DashboardService .copy_tabs_with_filter_remapping (
249204 original_dashboard .tabs or [], filter_id_mapping
250205 )
@@ -422,8 +377,6 @@ def get_filter_options(
422377 raise HttpError (400 , "No warehouse configured for organization" )
423378
424379 # Get filter options from service
425- from ddpui .services .dashboard_service import DashboardService
426-
427380 options = DashboardService .generate_filter_options (
428381 schema = schema_name ,
429382 table = table_name ,
0 commit comments