Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug/222 popup action update #223

Merged
merged 4 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
@page "/click-to-add"
<PageTitle>Click to Add Points</PageTitle>
<h1>Click To Add Points</h1>
<div class="links-div">
<a class="btn btn-primary" target="_blank" href="https://www.arcgis.com/home/item.html?id=1e126e7520f9466c9ca28b8f28b5e500">World Ocean Basemap</a>
</div>

<p class="instructions">
Click anywhere to see a point added to the map. Click on the point again to see a popup. Click on the popup action to add the point to the list below.
</p>

<MapView Class="map-view" OnClick="OnClick" Zoom="4">
<Map>
<Basemap>
<TileLayer>
<PortalItem Id="1e126e7520f9466c9ca28b8f28b5e500" />
</TileLayer>
</Basemap>
<GraphicsLayer @ref="_graphicsLayer" />
</Map>
</MapView>

<div>
<h2>Points Clicked</h2>
@foreach (Point point in _points)
{
<p>Long: @point.Longitude!.Value.ToString("N2") Lat: @point.Latitude!.Value.ToString("N2")</p>
}
</div>

@code {
private async Task OnClick(ClickEvent arg)
{
Point point = arg.MapPoint;
if (_graphic is null)
{
_graphic = new Graphic(point);
await _graphicsLayer!.Add(_graphic);
}

SimpleMarkerSymbol symbol = new SimpleMarkerSymbol(new Outline(new MapColor("blue")),
new MapColor("yellow"), 10);

ActionButton actionButton = new ActionButton("Click to Add to List",
"./_content/dymaptic.GeoBlazor.Core.Sample.Shared/images/dymaptic_logo.png", "test-1", AddPoint);
PopupTemplate popupTemplate = new PopupTemplate(
$"New Point at Long: {point.Longitude!.Value:N2} Lat: {point.Latitude!.Value:N2}",
actions: new[]{ actionButton });

await _graphic.SetPopupTemplate(popupTemplate);
await _graphic.SetSymbol(symbol);
await _graphic.SetGeometry(point);
}

private async Task AddPoint()
{
_points.Add(((Point)_graphic!.Geometry!).Clone());
await InvokeAsync(StateHasChanged);
}

private Graphic? _graphic;
private GraphicsLayer? _graphicsLayer;
private readonly List<Point> _points = new();
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
new("", "Home", "oi-home"),
new("navigation", "Navigation", "oi-compass"),
new("drawing", "Drawing", "oi-pencil"),
new("click-to-add", "Click to Add Point", "oi-map-marker"),
new("many-graphics", "Many Graphics", "oi-calculator"),
new("scene", "Scene & Attributes", "oi-globe"),
new("widgets", "Widgets", "oi-location"),
Expand Down
95 changes: 95 additions & 0 deletions src/dymaptic.GeoBlazor.Core/Components/ActionBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,56 @@ internal record ActionBaseSerializationRecord([property: JsonIgnore(Condition =
/// </summary>
public class ActionButton : ActionBase
{
/// <summary>
/// Parameterless constructor for use as a razor component.
/// </summary>
public ActionButton()
{
}

/// <summary>
/// Constructor for use in code.
/// </summary>
/// <param name="title">
/// The title of the action.
/// </param>
/// <param name="image">
/// The URL to an image that will be used to represent the action. This property will be used as a background image
/// </param>
/// <param name="id">
/// The name of the ID assigned to this action.
/// </param>
/// <param name="callbackFunction">
/// The action function to perform on click.
/// </param>
/// <param name="className">
/// This adds a CSS class to the ActionButton's node.
/// </param>
/// <param name="active">
/// Set this property to true to display a spinner icon.
/// </param>
/// <param name="disabled">
/// Indicates whether this action is disabled.
/// </param>
/// <param name="visible">
/// Indicates if the action is visible.
/// </param>
public ActionButton(string? title = null, string? image = null, string? id = null,
Func<Task>? callbackFunction = null, string? className = null, bool? active = null, bool? disabled = null,
bool? visible = null)
{
#pragma warning disable BL0005
Title = title;
Image = image;
Id = id;
CallbackFunction = callbackFunction;
ClassName = className;
Active = active;
Disabled = disabled;
Visible = visible;
#pragma warning restore BL0005
}

/// <inheritdoc />
public override string Type => "button";

Expand Down Expand Up @@ -141,6 +191,51 @@ internal override ActionBaseSerializationRecord ToSerializationRecord()
/// </summary>
public class ActionToggle : ActionBase
{
/// <summary>
/// Parameterless constructor for use as a razor component.
/// </summary>
public ActionToggle()
{
}

/// <summary>
/// Constructor for use in code.
/// </summary>
/// <param name="title">
/// The title of the action.
/// </param>
/// <param name="id">
/// The name of the ID assigned to this action.
/// </param>
/// <param name="callbackFunction">
/// The action function to perform on click.
/// </param>
/// <param name="value">
/// Indicates the value of whether the action is toggled on/off.
/// </param>
/// <param name="active">
/// Set this property to true to display a spinner icon.
/// </param>
/// <param name="disabled">
/// Indicates whether this action is disabled.
/// </param>
/// <param name="visible">
/// Indicates if the action is visible.
/// </param>
public ActionToggle(string? title = null, string? id = null, Func<Task>? callbackFunction = null,
bool? value = null, bool? active = null, bool? disabled = null, bool? visible = null)
{
#pragma warning disable BL0005
Title = title;
Id = id;
CallbackFunction = callbackFunction;
Value = value;
Active = active;
Disabled = disabled;
Visible = visible;
#pragma warning restore BL0005
}

/// <inheritdoc />
public override string Type => "toggle";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ internal PopupTemplateSerializationRecord ToSerializationRecord()
FieldInfos?.Select(f => f.ToSerializationRecord()),
Content.Select(c => c.ToSerializationRecord()),
ExpressionInfos?.Select(e => e.ToSerializationRecord()), OverwriteActions,
ReturnGeometry, Actions?.Select(a => a.ToSerializationRecord()));
ReturnGeometry, Actions?.Select(a => a.ToSerializationRecord()), Id.ToString());
}
}

Expand Down Expand Up @@ -362,5 +362,8 @@ internal record PopupTemplateSerializationRecord([property: JsonIgnore(Condition
bool? ReturnGeometry = null,
[property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[property: ProtoMember(9)]
IEnumerable<ActionBaseSerializationRecord>? Actions = null)
IEnumerable<ActionBaseSerializationRecord>? Actions = null,
[property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[property: ProtoMember(10)]
string? id = null)
: MapComponentSerializationRecord;
45 changes: 45 additions & 0 deletions src/dymaptic.GeoBlazor.Core/Components/Views/MapView.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,51 @@ public async Task OnJavascriptLayerViewCreateError(LayerViewCreateErrorEvent err
/// </summary>
[Parameter]
public int? GraphicSerializationChunkSize { get; set; }

/// <summary>
/// For internal use only, this looks up a missing <see cref="DotNetObjectReference"/> for a <see cref="PopupTemplate"/>
/// and returns it to JavaScript.
/// </summary>
[JSInvokable]
public DotNetObjectReference<PopupTemplate>? GetDotNetPopupTemplateObjectReference(Guid popupTemplateId)
{
foreach (Graphic graphic in Graphics)
{
if (graphic.PopupTemplate?.Id == popupTemplateId)
{
return graphic.PopupTemplate.DotNetPopupTemplateReference;
}
}

foreach (Layer layer in Map!.Layers)
{
switch (layer)
{
case FeatureLayer { Source: not null } featureLayer:
foreach (Graphic graphic in featureLayer.Source)
{
if (graphic.PopupTemplate?.Id == popupTemplateId)
{
return graphic.PopupTemplate.DotNetPopupTemplateReference;
}
}

break;
case GraphicsLayer graphicsLayer:
foreach (Graphic graphic in graphicsLayer.Graphics)
{
if (graphic.PopupTemplate?.Id == popupTemplateId)
{
return graphic.PopupTemplate.DotNetPopupTemplateReference;
}
}

break;
}
}

return null;
}

#endregion

Expand Down
1 change: 1 addition & 0 deletions src/dymaptic.GeoBlazor.Core/Scripts/definitions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ export interface DotNetPopupTemplate {
overwriteActions: boolean;
returnGeometry: boolean;
dotNetPopupTemplateReference: any;
id: string;

actions: any[];
}
Expand Down
13 changes: 12 additions & 1 deletion src/dymaptic.GeoBlazor.Core/Scripts/jsBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import Extent from "@arcgis/core/geometry/Extent";
import Graphic from "@arcgis/core/Graphic";
import PopupTemplate from "@arcgis/core/PopupTemplate";
import { arcGisObjectRefs, triggerActionHandler } from "./arcGisJsInterop";
import {arcGisObjectRefs, dotNetRefs, triggerActionHandler} from "./arcGisJsInterop";
import Geometry from "@arcgis/core/geometry/Geometry";
import Point from "@arcgis/core/geometry/Point";
import Polyline from "@arcgis/core/geometry/Polyline";
Expand Down Expand Up @@ -227,6 +227,7 @@ export function buildJsPopupTemplate(popupTemplateObject: DotNetPopupTemplate, v
} else {
content = async (featureSelection) => {
try {
await lookupDotNetRefForPopupTemplate(popupTemplateObject, viewId as string);
let results: DotNetPopupContent[] | null = await popupTemplateObject.dotNetPopupTemplateReference
.invokeMethodAsync("OnContentFunction", buildDotNetGraphic(featureSelection.graphic));
return results?.map(r => buildJsPopupContent(r));
Expand Down Expand Up @@ -272,11 +273,13 @@ export function buildJsPopupTemplate(popupTemplateObject: DotNetPopupTemplate, v
reactiveUtils.once(() => view.popup.on !== undefined)
.then(() => {
templateTriggerActionHandler = view.popup.on("trigger-action", async (event: PopupTriggerActionEvent) => {
await lookupDotNetRefForPopupTemplate(popupTemplateObject, viewId as string);
await popupTemplateObject.dotNetPopupTemplateReference.invokeMethodAsync("OnTriggerAction", event.action.id);
});
})
} else {
templateTriggerActionHandler = view.popup.on("trigger-action", async (event: PopupTriggerActionEvent) => {
await lookupDotNetRefForPopupTemplate(popupTemplateObject, viewId as string);
await popupTemplateObject.dotNetPopupTemplateReference.invokeMethodAsync("OnTriggerAction", event.action.id);
});
}
Expand All @@ -290,6 +293,14 @@ export function buildJsPopupTemplate(popupTemplateObject: DotNetPopupTemplate, v
return template;
}

async function lookupDotNetRefForPopupTemplate(popupTemplateObject: DotNetPopupTemplate, viewId: string) {
if (!hasValue(popupTemplateObject.dotNetPopupTemplateReference)) {
let viewRef = dotNetRefs[viewId];
popupTemplateObject.dotNetPopupTemplateReference =
await viewRef.invokeMethodAsync('GetDotNetPopupTemplateObjectReference', popupTemplateObject.id);
}
}

export let templateTriggerActionHandler: IHandle;

export function buildJsPopupContent(popupContentObject: DotNetPopupContent): ContentProperties | null {
Expand Down
4 changes: 2 additions & 2 deletions src/dymaptic.GeoBlazor.Core/dymaptic.GeoBlazor.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
</Description>
<Title>GeoBlazor</Title>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageVersion>2.3.0</PackageVersion>
<Version>2.3.0</Version>
<PackageVersion>2.3.1-beta-1</PackageVersion>
<Version>2.3.1-beta-1</Version>
<Authors>Tim Purdum, Christopher Moravec, Mara Stoica, Tim Rawson</Authors>
<Company>dymaptic</Company>
<Copyright>©2023 by dymaptic</Copyright>
Expand Down
2 changes: 1 addition & 1 deletion src/dymaptic.GeoBlazor.Core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dymaptic.GeoBlazor.Core",
"version": "2.3.0",
"version": "2.3.1-beta-1",
"description": "https://www.geoblazor.com",
"main": "arcGisInterop.js",
"scripts": {
Expand Down
4 changes: 4 additions & 0 deletions src/dymaptic.GeoBlazor.Core/wwwroot/graphic.json
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@
"rule": "repeated",
"type": "Action",
"id": 9
},
"id": {
"type": "string",
"id": 10
}
}
},
Expand Down