diff --git a/src/pbi_cli/core/pbir_models.py b/src/pbi_cli/core/pbir_models.py index 70cee71..9bafd93 100644 --- a/src/pbi_cli/core/pbir_models.py +++ b/src/pbi_cli/core/pbir_models.py @@ -76,6 +76,8 @@ SUPPORTED_VISUAL_TYPES: frozenset[str] = frozenset({ "textbox", "pageNavigator", "advancedSlicerVisual", + # v3.8.0 additions + "azureMap", }) # Mapping from user-friendly names to PBIR visualType identifiers @@ -136,6 +138,9 @@ VISUAL_TYPE_ALIASES: dict[str, str] = { "advanced_slicer": "advancedSlicerVisual", "adv_slicer": "advancedSlicerVisual", "tile_slicer": "advancedSlicerVisual", + # v3.8.0 additions + "azure_map": "azureMap", + "map": "azureMap", } diff --git a/src/pbi_cli/core/visual_backend.py b/src/pbi_cli/core/visual_backend.py index f7214fe..e87ccdf 100644 --- a/src/pbi_cli/core/visual_backend.py +++ b/src/pbi_cli/core/visual_backend.py @@ -82,6 +82,8 @@ VISUAL_DATA_ROLES: dict[str, list[str]] = { "textbox": [], "pageNavigator": [], "advancedSlicerVisual": ["Values"], + # v3.8.0 additions + "azureMap": ["Category", "Size"], } # Roles that should default to Measure references (not Column) @@ -154,6 +156,8 @@ ROLE_ALIASES: dict[str, dict[str, str]] = { "textbox": {}, "pageNavigator": {}, "advancedSlicerVisual": {"value": "Values", "field": "Values"}, + # v3.8.0 additions + "azureMap": {"category": "Category", "value": "Size", "size": "Size"}, } @@ -241,6 +245,8 @@ DEFAULT_SIZES: dict[str, tuple[float, float]] = { "textbox": (300, 100), "pageNavigator": (120, 400), "advancedSlicerVisual": (280, 280), + # v3.8.0 additions + "azureMap": (500, 400), } diff --git a/src/pbi_cli/preview/renderer.py b/src/pbi_cli/preview/renderer.py index 7dfcad0..4a94f72 100644 --- a/src/pbi_cli/preview/renderer.py +++ b/src/pbi_cli/preview/renderer.py @@ -85,6 +85,8 @@ _VISUAL_COLORS: dict[str, str] = { "textbox": "#404040", "pageNavigator": "#00B0F0", "advancedSlicerVisual": "#FFC000", + # v3.8.0 additions + "azureMap": "#0078D4", } _VISUAL_ICONS: dict[str, str] = { @@ -124,6 +126,8 @@ _VISUAL_ICONS: dict[str, str] = { "textbox": "◻", "pageNavigator": "►", "advancedSlicerVisual": "☰", + # v3.8.0 additions + "azureMap": "◆", } diff --git a/src/pbi_cli/templates/visuals/azureMap.json b/src/pbi_cli/templates/visuals/azureMap.json new file mode 100644 index 0000000..2c85ee3 --- /dev/null +++ b/src/pbi_cli/templates/visuals/azureMap.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/fabric/item/report/definition/visualContainer/2.7.0/schema.json", + "name": "__VISUAL_NAME__", + "position": { + "x": __X__, + "y": __Y__, + "z": __Z__, + "height": __HEIGHT__, + "width": __WIDTH__, + "tabOrder": __TAB_ORDER__ + }, + "visual": { + "visualType": "azureMap", + "query": { + "queryState": { + "Category": { + "projections": [] + }, + "Size": { + "projections": [] + } + } + }, + "objects": {}, + "drillFilterOtherVisuals": true + } +} diff --git a/tests/test_visual_backend.py b/tests/test_visual_backend.py index f0db36f..0460dde 100644 --- a/tests/test_visual_backend.py +++ b/tests/test_visual_backend.py @@ -1042,4 +1042,26 @@ def test_gauge_bind_max_value_produces_measure_projection(report_with_page: Path data = json.loads(vfile.read_text(encoding="utf-8")) proj = data["visual"]["query"]["queryState"]["MaxValue"]["projections"][0] assert "Measure" in proj["field"] - assert "Column" not in proj["field"] + + +# --- v3.8.0 azureMap tests --- + + +@pytest.mark.parametrize("alias", ["azureMap", "azure_map", "map"]) +def test_azure_map_aliases(report_with_page: Path, alias: str) -> None: + r = visual_add(report_with_page, "test_page", alias, x=0, y=0) + assert r["visual_type"] == "azureMap" + + +def test_azure_map_has_category_and_size_roles(report_with_page: Path) -> None: + r = visual_add(report_with_page, "test_page", "azureMap", x=0, y=0) + vfile = ( + report_with_page / "pages" / "test_page" / "visuals" / r["name"] / "visual.json" + ) + data = json.loads(vfile.read_text(encoding="utf-8")) + qs = data["visual"]["query"]["queryState"] + assert "Category" in qs + assert "Size" in qs + assert isinstance(qs["Category"], dict) + assert isinstance(qs["Size"], dict) + assert data["$schema"].endswith("2.7.0/schema.json")