# SyncMenuWidgets - Advanced Documentation ## Model Shape ``` SyncMenuWidgets(long ClaimTypeID, MenuItemInfo Menu) -> MenuItemInfo ``` WidgetInfo (BaBackOffice.Model): ``` ID: long Title: string WidthPercentage: int SortOrder: int Type: WidgetTypeInfo Fields: FieldInfo[] SystemWidgetID: long ClaimDesignerOptionsJson: string IsActive: bool ``` FieldInfo is a base class with several sealed subclasses (ClaimFieldInfo, ContactTypeFieldInfo, ContactFieldInfo, EventFieldInfo, LedgerTypeFieldInfo, ListItemFieldInfo) - Format is required on all of them. ## Traps - Menu.ID must already exist (created via SyncClaimTypeMenus first). Passing a Menu.ID that does not exist throws a raw NullReferenceException, not a clean validation error - there is no friendly check here. - This replaces the COMPLETE set of widgets (and each widget's Fields) for that one menu. Any widget whose ID is not in Menu.Widgets gets deleted, and any field omitted from a widget's Fields gets deleted with it. - Save failure throws: "There was a problem saving the widgets for [{Menu.Text}]. {ge.LastError}" - Widget.ClaimDesignerOptionsJson is validated by a handler specific to Widget.Type. Invalid JSON throws: "The provided Widget.ClaimDesignerOptionsJson could not be serialized in the expected model[{ModelType}]." - ClaimTypeID ownership is validated internally against the same lookup GetClaimTypeByID uses - a ClaimTypeID that does not belong to the menu's claim type is rejected. - Always fetch the current Widgets[].Fields[] via GetClaimTypeByID first and send back the full set with only your intended changes - never construct Menu.Widgets from scratch or you will delete every other widget on that menu. ## Script Example ```javascript var claimType = await CallEndpoint("SecureApi", "GetClaimTypeByID", { ClaimTypeID: claimTypeID }); var menu = claimType.Menus.find(m => m.ID === menuID); menu.Widgets.push({ ID: 0, Title: "New Field Section", WidthPercentage: 100, SortOrder: menu.Widgets.length, Type: widgetType, Fields: [], SystemWidgetID: 0, ClaimDesignerOptionsJson: "{}", IsActive: true }); var updated = await CallEndpoint("SecureApi", "SyncMenuWidgets", { ClaimTypeID: claimTypeID, Menu: menu }); ``` ## Cross-References | Endpoint | Relationship | |---|---| | GetClaimTypeByID | Fetch the current Widgets[].Fields[] for a menu before syncing | | SyncClaimTypeMenus | Creates/updates the menu itself - Menu.ID must exist here before calling SyncMenuWidgets | | CopyMenuToClaimType | Calls SyncClaimTypeMenus and SyncMenuWidgets together to clone a menu onto a claim type | ---