Skip to content

Commit 7643640

Browse files
tpellissierclaude
andcommitted
Remove AssociatedMenuConfiguration for minimal API surface
Remove the AssociatedMenuConfiguration class and related parameters from relationship metadata types. This is a niche UI customization that most users don't need, and can still be achieved via additional_properties. Changes: - Remove AssociatedMenuConfiguration class from metadata.py - Remove associated_menu_configuration from OneToManyRelationshipMetadata - Remove entity1/2_associated_menu_configuration from ManyToManyRelationshipMetadata - Update example and tests accordingly Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 22d3f6e commit 7643640

3 files changed

Lines changed: 0 additions & 161 deletions

File tree

examples/advanced/relationships.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
Label,
2828
LocalizedLabel,
2929
CascadeConfiguration,
30-
AssociatedMenuConfiguration,
3130
)
3231

3332

@@ -221,12 +220,6 @@ def main():
221220
assign="NoCascade",
222221
merge="NoCascade",
223222
),
224-
associated_menu_configuration=AssociatedMenuConfiguration(
225-
behavior="UseLabel",
226-
group="Details",
227-
label=Label(localized_labels=[LocalizedLabel(label="Employees", language_code=1033)]),
228-
order=10000,
229-
),
230223
)
231224

232225
# Create the relationship
@@ -285,16 +278,6 @@ def main():
285278
schema_name="new_employee_project",
286279
entity1_logical_name=emp_table["table_logical_name"],
287280
entity2_logical_name=proj_table["table_logical_name"],
288-
entity1_associated_menu_configuration=AssociatedMenuConfiguration(
289-
behavior="UseLabel",
290-
group="Details",
291-
label=Label(localized_labels=[LocalizedLabel(label="Projects", language_code=1033)]),
292-
),
293-
entity2_associated_menu_configuration=AssociatedMenuConfiguration(
294-
behavior="UseLabel",
295-
group="Details",
296-
label=Label(localized_labels=[LocalizedLabel(label="Team Members", language_code=1033)]),
297-
),
298281
)
299282

300283
result3 = backoff(

src/PowerPlatform/Dataverse/models/metadata.py

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -185,58 +185,6 @@ def to_dict(self) -> Dict[str, Any]:
185185
return result
186186

187187

188-
@dataclass
189-
class AssociatedMenuConfiguration:
190-
"""
191-
Configuration for how the relationship appears in the associated menu.
192-
193-
:param behavior: Display behavior in the menu.
194-
:type behavior: str
195-
:param group: The menu group where the item appears.
196-
:type group: str
197-
:param label: Display label for the menu item.
198-
:type label: Optional[Label]
199-
:param order: Display order within the group.
200-
:type order: int
201-
:param additional_properties: Optional dict of additional properties to include
202-
in the Web API payload (e.g., "Icon", "ViewId", "AvailableOffline").
203-
These are merged last and can override default values.
204-
:type additional_properties: Optional[Dict[str, Any]]
205-
206-
Valid behavior values:
207-
- "UseCollectionName": Use the collection name
208-
- "UseLabel": Use the specified label
209-
- "DoNotDisplay": Do not display in the menu
210-
"""
211-
212-
behavior: str = "UseLabel"
213-
group: str = "Details"
214-
label: Optional[Label] = None
215-
order: int = 10000
216-
additional_properties: Optional[Dict[str, Any]] = None
217-
218-
def to_dict(self) -> Dict[str, Any]:
219-
"""
220-
Convert to Web API JSON format.
221-
222-
Example::
223-
224-
>>> menu = AssociatedMenuConfiguration(behavior="UseLabel", group="Details")
225-
>>> menu.to_dict()
226-
{'Behavior': 'UseLabel', 'Group': 'Details', 'Order': 10000}
227-
"""
228-
result = {
229-
"Behavior": self.behavior,
230-
"Group": self.group,
231-
"Order": self.order,
232-
}
233-
if self.label:
234-
result["Label"] = self.label.to_dict()
235-
if self.additional_properties:
236-
result.update(self.additional_properties)
237-
return result
238-
239-
240188
@dataclass
241189
class LookupAttributeMetadata:
242190
"""
@@ -323,8 +271,6 @@ class OneToManyRelationshipMetadata:
323271
:type referenced_attribute: str
324272
:param cascade_configuration: Cascade behavior configuration.
325273
:type cascade_configuration: CascadeConfiguration
326-
:param associated_menu_configuration: Optional menu display configuration.
327-
:type associated_menu_configuration: Optional[AssociatedMenuConfiguration]
328274
:param referencing_attribute: Optional name for the referencing attribute (usually auto-generated).
329275
:type referencing_attribute: Optional[str]
330276
:param additional_properties: Optional dict of additional properties to include
@@ -339,7 +285,6 @@ class OneToManyRelationshipMetadata:
339285
referencing_entity: str
340286
referenced_attribute: str
341287
cascade_configuration: CascadeConfiguration = field(default_factory=CascadeConfiguration)
342-
associated_menu_configuration: Optional[AssociatedMenuConfiguration] = None
343288
referencing_attribute: Optional[str] = None
344289
additional_properties: Optional[Dict[str, Any]] = None
345290

@@ -373,8 +318,6 @@ def to_dict(self) -> Dict[str, Any]:
373318
"ReferencedAttribute": self.referenced_attribute,
374319
"CascadeConfiguration": self.cascade_configuration.to_dict(),
375320
}
376-
if self.associated_menu_configuration:
377-
result["AssociatedMenuConfiguration"] = self.associated_menu_configuration.to_dict()
378321
if self.referencing_attribute:
379322
result["ReferencingAttribute"] = self.referencing_attribute
380323
if self.additional_properties:
@@ -395,10 +338,6 @@ class ManyToManyRelationshipMetadata:
395338
:type entity2_logical_name: str
396339
:param intersect_entity_name: Name for the intersect table (defaults to schema_name if not provided).
397340
:type intersect_entity_name: Optional[str]
398-
:param entity1_associated_menu_configuration: Menu configuration for entity1.
399-
:type entity1_associated_menu_configuration: Optional[AssociatedMenuConfiguration]
400-
:param entity2_associated_menu_configuration: Menu configuration for entity2.
401-
:type entity2_associated_menu_configuration: Optional[AssociatedMenuConfiguration]
402341
:param additional_properties: Optional dict of additional properties to include
403342
in the Web API payload. Useful for setting inherited properties like
404343
"IsValidForAdvancedFind", "IsCustomizable", "SecurityTypes", or direct
@@ -411,8 +350,6 @@ class ManyToManyRelationshipMetadata:
411350
entity1_logical_name: str
412351
entity2_logical_name: str
413352
intersect_entity_name: Optional[str] = None
414-
entity1_associated_menu_configuration: Optional[AssociatedMenuConfiguration] = None
415-
entity2_associated_menu_configuration: Optional[AssociatedMenuConfiguration] = None
416353
additional_properties: Optional[Dict[str, Any]] = None
417354

418355
def to_dict(self) -> Dict[str, Any]:
@@ -444,10 +381,6 @@ def to_dict(self) -> Dict[str, Any]:
444381
"Entity2LogicalName": self.entity2_logical_name,
445382
"IntersectEntityName": intersect_name,
446383
}
447-
if self.entity1_associated_menu_configuration:
448-
result["Entity1AssociatedMenuConfiguration"] = self.entity1_associated_menu_configuration.to_dict()
449-
if self.entity2_associated_menu_configuration:
450-
result["Entity2AssociatedMenuConfiguration"] = self.entity2_associated_menu_configuration.to_dict()
451384
if self.additional_properties:
452385
result.update(self.additional_properties)
453386
return result
@@ -457,7 +390,6 @@ def to_dict(self) -> Dict[str, Any]:
457390
"LocalizedLabel",
458391
"Label",
459392
"CascadeConfiguration",
460-
"AssociatedMenuConfiguration",
461393
"LookupAttributeMetadata",
462394
"OneToManyRelationshipMetadata",
463395
"ManyToManyRelationshipMetadata",

tests/unit/models/test_metadata.py

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
LocalizedLabel,
88
Label,
99
CascadeConfiguration,
10-
AssociatedMenuConfiguration,
1110
LookupAttributeMetadata,
1211
OneToManyRelationshipMetadata,
1312
ManyToManyRelationshipMetadata,
@@ -130,44 +129,6 @@ def test_to_dict_with_additional_properties(self):
130129
assert result["RollupView"] == "NoCascade"
131130

132131

133-
class TestAssociatedMenuConfiguration:
134-
"""Tests for AssociatedMenuConfiguration."""
135-
136-
def test_to_dict_defaults(self):
137-
"""Test default values."""
138-
menu = AssociatedMenuConfiguration()
139-
result = menu.to_dict()
140-
141-
assert result["Behavior"] == "UseLabel"
142-
assert result["Group"] == "Details"
143-
assert result["Order"] == 10000
144-
assert "Label" not in result
145-
146-
def test_to_dict_with_label(self):
147-
"""Test with a label."""
148-
menu = AssociatedMenuConfiguration(
149-
label=Label(localized_labels=[LocalizedLabel(label="Related Items", language_code=1033)])
150-
)
151-
result = menu.to_dict()
152-
153-
assert result["Label"]["LocalizedLabels"][0]["Label"] == "Related Items"
154-
155-
def test_to_dict_with_additional_properties(self):
156-
"""Test additional properties like Icon and ViewId."""
157-
menu = AssociatedMenuConfiguration(
158-
additional_properties={
159-
"Icon": "custom_icon",
160-
"ViewId": "00000000-0000-0000-0000-000000000000",
161-
"AvailableOffline": True,
162-
}
163-
)
164-
result = menu.to_dict()
165-
166-
assert result["Icon"] == "custom_icon"
167-
assert result["ViewId"] == "00000000-0000-0000-0000-000000000000"
168-
assert result["AvailableOffline"] is True
169-
170-
171132
class TestLookupAttributeMetadata:
172133
"""Tests for LookupAttributeMetadata."""
173134

@@ -263,23 +224,6 @@ def test_to_dict_with_custom_cascade(self):
263224
assert result["CascadeConfiguration"]["Delete"] == "Cascade"
264225
assert result["CascadeConfiguration"]["Assign"] == "Cascade"
265226

266-
def test_to_dict_with_menu_configuration(self):
267-
"""Test with associated menu configuration."""
268-
rel = OneToManyRelationshipMetadata(
269-
schema_name="new_account_orders",
270-
referenced_entity="account",
271-
referencing_entity="new_order",
272-
referenced_attribute="accountid",
273-
associated_menu_configuration=AssociatedMenuConfiguration(
274-
behavior="UseLabel",
275-
label=Label(localized_labels=[LocalizedLabel(label="Orders", language_code=1033)]),
276-
),
277-
)
278-
result = rel.to_dict()
279-
280-
assert "AssociatedMenuConfiguration" in result
281-
assert result["AssociatedMenuConfiguration"]["Label"]["LocalizedLabels"][0]["Label"] == "Orders"
282-
283227
def test_to_dict_with_referencing_attribute(self):
284228
"""Test with explicit referencing attribute."""
285229
rel = OneToManyRelationshipMetadata(
@@ -344,26 +288,6 @@ def test_to_dict_with_explicit_intersect_name(self):
344288

345289
assert result["IntersectEntityName"] == "new_account_contact_assoc"
346290

347-
def test_to_dict_with_menu_configurations(self):
348-
"""Test with associated menu configurations for both entities."""
349-
rel = ManyToManyRelationshipMetadata(
350-
schema_name="new_account_contact",
351-
entity1_logical_name="account",
352-
entity2_logical_name="contact",
353-
entity1_associated_menu_configuration=AssociatedMenuConfiguration(
354-
label=Label(localized_labels=[LocalizedLabel(label="Contacts", language_code=1033)])
355-
),
356-
entity2_associated_menu_configuration=AssociatedMenuConfiguration(
357-
label=Label(localized_labels=[LocalizedLabel(label="Accounts", language_code=1033)])
358-
),
359-
)
360-
result = rel.to_dict()
361-
362-
assert "Entity1AssociatedMenuConfiguration" in result
363-
assert "Entity2AssociatedMenuConfiguration" in result
364-
assert result["Entity1AssociatedMenuConfiguration"]["Label"]["LocalizedLabels"][0]["Label"] == "Contacts"
365-
assert result["Entity2AssociatedMenuConfiguration"]["Label"]["LocalizedLabels"][0]["Label"] == "Accounts"
366-
367291
def test_to_dict_with_additional_properties(self):
368292
"""Test additional properties like navigation property names."""
369293
rel = ManyToManyRelationshipMetadata(

0 commit comments

Comments
 (0)