Skip to content

Conversation

puneet-pdx
Copy link
Collaborator

@puneet-pdx puneet-pdx commented Sep 10, 2025

Related to issue: # https://devtopia.esri.com/runtime/apollo/issues/1407

Description:

Add support for UNAssociations in Popups.

Summary of changes:

  • Add PopupState, Add new Popup Composable that takes the State object
  • Update all internal popup elements to not have remember functions and just initialize them using constructors and hold them in the PopupState object
  • Add UtilityAssociationElement(from FeatureForms)
  • Add support for Navigation to enable browsing from one Popup to another based on an association element(from FeatureForms)
  • Add PopupScreen
  • Add ContentAwareTopBar(from FeatureForms)
  • Deprecate stateful PopupComposable
  • Update MicroApp to use the new Composable

Pre-merge Checklist

@puneet-pdx puneet-pdx self-assigned this Sep 11, 2025
@puneet-pdx puneet-pdx marked this pull request as ready for review September 15, 2025 17:25
Copy link
Collaborator

@kaushikrw kaushikrw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@puneet-pdx I wasn't able to load any map to test in the micro-app but here is some initial feedback.

*/
@Deprecated(
message = "Maintained for binary compatibility. Use the overload that uses the PopupState object.",
level = DeprecationLevel.HIDDEN
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason this is hidden? Imo this would be confusing to anyone who upgrades to v300 and is not able to see this function. Not sure what the user story for Popup is but imo having this as a warning with later removal or a full removal in 300.0 might be a better approach.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I vaguely remember Soren mentioning it(I am not 100%). I have changed it to warning for now. Soren can chime in later.

optimize mediaElementState
Copy link
Collaborator

@kaushikrw kaushikrw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! Just a few more comments below.

onBackPressed: () -> Unit,
onClose: () -> Unit,
modifier: Modifier = Modifier,
) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I noticed while running the app is, the popup shows up in an expandable group with an empty title. So I was wondering why the expandable group since there is no group element in popups.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the element types are displayed as an expandable cards with title being the title of the element. This is a requirement coming from the design
A stretch goal is to have the individual view elements be "collapsible". When collapsed, a popup element view just displays the title of the element.
https://devtopia.esri.com/runtime/common-toolkit/blob/main/designs/Popup/Popup.md#miscellaneous

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see. Perhaps it is a design discussion then, because the collapsed elements do have a title. I will leave that up to you..

@puneet-pdx
Copy link
Collaborator Author

@kaushikrw I have addressed your comments here and also enabled the close button in the micro app. I am looking into updating UNAssociationsScreen with the latest changes.

Copy link
Collaborator

@kaushikrw kaushikrw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I just have one comment below.

Comment on lines 71 to 77
LaunchedEffect(scaffoldState.bottomSheetState.currentValue) {
if (scaffoldState.bottomSheetState.currentValue == SheetValue.Hidden) {
unselectFeature(viewModel.geoElement, viewModel.layer)
viewModel.updatePopupState(null)
viewModel.setGeoElement(null)
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These sequence of steps are already happening in the Popup.onDismiss event so it seems redundant to do the same here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Popup.onDismiss does not get invoked if the user manually closes the bottomsheet. If that happens then without this there will be no bottomsheet on the screen and there will be a feature selected on the screen. This makes sure that the behavior is consistent for both the workflows.

@puneet-pdx puneet-pdx requested a review from sorenoid September 23, 2025 22:51
Copy link
Collaborator

@sorenoid sorenoid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow! that's quite an undertaking. I will test it out tomorrow. For now here is my review of the code.

Comment on lines 79 to 81
if (viewModel.popupState != null) {
Popup(
viewModel.popupState!!,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could use smart casting here rather than the !! operator.

Suggested change
if (viewModel.popupState != null) {
Popup(
viewModel.popupState!!,
val state = viewModel.popupState
if (state != null) {
Popup(
state,

// guard against null value
as? UtilityAssociationsElementState ?: return@composable
// Display the association details
UtilityAssociationDetails(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like this function should not be called if the result and filter are null, rather than passing in the state and returning early from a composable function. Could the parameters be

val result = utilityAssociationsElementState.state.selectedAssociationResult
val filter = state.selectedFilterResult?.filter
if (result != null && filter != null) {
    UtilityAssociationDetails(
        result,
        filter,
        modifier = Modifier.fillMaxSize()
    )
}

Comment on lines 49 to 50
val associationResult = state.selectedAssociationResult ?: return
val filter = state.selectedFilterResult?.filter ?: return
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment on this function at the call site

}
associationResult.getFractionAlongEdge()?.let { fraction ->
FractionAlongEdgeControl(
fraction = associationResult.getFractionAlongEdge()!!.toFloat(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fraction = associationResult.getFractionAlongEdge()!!.toFloat(),
fraction = fraction.toFloat(),

Comment on lines 44 to 47
private var _loading: MutableState<Boolean> = mutableStateOf(true)

private var _filters: MutableState<List<UtilityAssociationsFilterResult>> =
mutableStateOf(emptyList())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: normally a backing var is directly above the val that uses it.

Comment on lines 301 to 302
// TODO remove for release
println("encountered element of type ${element::class.java}")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't forget to remove this!

@puneet-pdx puneet-pdx requested a review from sorenoid September 24, 2025 15:55
Copy link
Collaborator

@sorenoid sorenoid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

@puneet-pdx
Copy link
Collaborator Author

Thanks @kaushikrw and @sorenoid for the reviews! Merging this.

@puneet-pdx puneet-pdx merged commit 6a47e29 into v.next Sep 24, 2025
@puneet-pdx puneet-pdx deleted the puneet/6396_UNAssociationsPopup branch September 24, 2025 23:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants