From 848d1618ac7ccc0c734a554a1e22fe17c82e9cb4 Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Thu, 18 Jan 2024 10:42:55 -0800 Subject: [PATCH 1/3] added discard edits api and ui confirmation dialog --- .../featureformsapp/screens/map/MapScreen.kt | 42 ++++++++++++++++++- .../screens/map/MapViewModel.kt | 6 +-- .../app/src/main/res/values/strings.xml | 3 ++ .../toolkit/featureforms/FeatureForm.kt | 2 + 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/microapps/FeatureFormsApp/app/src/main/java/com/arcgismaps/toolkit/featureformsapp/screens/map/MapScreen.kt b/microapps/FeatureFormsApp/app/src/main/java/com/arcgismaps/toolkit/featureformsapp/screens/map/MapScreen.kt index 4442a5e74..028e66a2d 100644 --- a/microapps/FeatureFormsApp/app/src/main/java/com/arcgismaps/toolkit/featureformsapp/screens/map/MapScreen.kt +++ b/microapps/FeatureFormsApp/app/src/main/java/com/arcgismaps/toolkit/featureformsapp/screens/map/MapScreen.kt @@ -13,6 +13,8 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Close +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -22,7 +24,10 @@ import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity @@ -51,6 +56,7 @@ fun MapScreen(mapViewModel: MapViewModel = hiltViewModel(), onBackPressed: () -> val uiState by mapViewModel.uiState val context = LocalContext.current val windowSize = getWindowSize(context) + var showDiscardEditsDialog by remember { mutableStateOf(false) } Scaffold( modifier = Modifier.fillMaxSize(), @@ -62,7 +68,7 @@ fun MapScreen(mapViewModel: MapViewModel = hiltViewModel(), onBackPressed: () -> title = mapViewModel.portalItem.title, editingMode = uiState is UIState.Editing, onClose = { - scope.launch { mapViewModel.rollbackEdits() } + showDiscardEditsDialog = true }, onSave = { scope.launch { @@ -130,6 +136,40 @@ fun MapScreen(mapViewModel: MapViewModel = hiltViewModel(), onBackPressed: () -> } } } + if (showDiscardEditsDialog) { + DiscardEditsDialog( + onConfirm = { + mapViewModel.rollbackEdits() + showDiscardEditsDialog = false + }, + onCancel = { + showDiscardEditsDialog = false + } + ) + } +} + +@Composable +fun DiscardEditsDialog(onConfirm: () -> Unit, onCancel: () -> Unit) { + AlertDialog( + onDismissRequest = onCancel, + confirmButton = { + Button(onClick = onConfirm) { + Text(text = stringResource(R.string.discard)) + } + }, + dismissButton = { + Button(onClick = onCancel) { + Text(text = stringResource(R.string.cancel)) + } + }, + title = { + Text(text = stringResource(R.string.discard_edits)) + }, + text = { + Text(text = stringResource(R.string.all_changes_will_be_lost)) + } + ) } @OptIn(ExperimentalMaterial3Api::class) diff --git a/microapps/FeatureFormsApp/app/src/main/java/com/arcgismaps/toolkit/featureformsapp/screens/map/MapViewModel.kt b/microapps/FeatureFormsApp/app/src/main/java/com/arcgismaps/toolkit/featureformsapp/screens/map/MapViewModel.kt index 1a4bbfa77..00c805005 100644 --- a/microapps/FeatureFormsApp/app/src/main/java/com/arcgismaps/toolkit/featureformsapp/screens/map/MapViewModel.kt +++ b/microapps/FeatureFormsApp/app/src/main/java/com/arcgismaps/toolkit/featureformsapp/screens/map/MapViewModel.kt @@ -93,11 +93,9 @@ class MapViewModel @Inject constructor( } } - suspend fun rollbackEdits(): Result { + fun rollbackEdits(): Result { (_uiState.value as? UIState.Editing)?.let { - val feature = it.featureForm.feature - (feature.featureTable as? ServiceFeatureTable)?.undoLocalEdits() - feature.refresh() + it.featureForm.discardEdits() _uiState.value = UIState.NotEditing return Result.success(Unit) } ?: return Result.failure(IllegalStateException("Not in editing state")) diff --git a/microapps/FeatureFormsApp/app/src/main/res/values/strings.xml b/microapps/FeatureFormsApp/app/src/main/res/values/strings.xml index cde365b56..a64454f32 100644 --- a/microapps/FeatureFormsApp/app/src/main/res/values/strings.xml +++ b/microapps/FeatureFormsApp/app/src/main/res/values/strings.xml @@ -17,4 +17,7 @@ Sign in using built-in Credentials Sign in with ArcGIS Enterprise Skip sign in + Discard + Discard Edits? + All changes made will be lost. diff --git a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt index 4e8111be7..5c7bd6db0 100644 --- a/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt +++ b/toolkit/featureforms/src/main/java/com/arcgismaps/toolkit/featureforms/FeatureForm.kt @@ -29,6 +29,8 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview From 60885c6ecfdcc23ab89866167e589ebbfc38802d Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Thu, 18 Jan 2024 12:18:38 -0800 Subject: [PATCH 2/3] fixes issue 369 --- .../screens/map/MapViewModel.kt | 71 ++++++++++--------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/microapps/FeatureFormsApp/app/src/main/java/com/arcgismaps/toolkit/featureformsapp/screens/map/MapViewModel.kt b/microapps/FeatureFormsApp/app/src/main/java/com/arcgismaps/toolkit/featureformsapp/screens/map/MapViewModel.kt index 00c805005..627bb6e70 100644 --- a/microapps/FeatureFormsApp/app/src/main/java/com/arcgismaps/toolkit/featureformsapp/screens/map/MapViewModel.kt +++ b/microapps/FeatureFormsApp/app/src/main/java/com/arcgismaps/toolkit/featureformsapp/screens/map/MapViewModel.kt @@ -102,47 +102,50 @@ class MapViewModel @Inject constructor( } context(MapView, CoroutineScope) override fun onSingleTapConfirmed(singleTapEvent: SingleTapConfirmedEvent) { - launch { - this@MapView.identifyLayers( - screenCoordinate = singleTapEvent.screenCoordinate, - tolerance = 22.0, - returnPopupsOnly = false - ).onSuccess { results -> - results.firstNotNullOfOrNull { result -> - try { - result.geoElements.filterIsInstance() - .firstOrNull { feature -> - (feature.featureTable?.layer as? FeatureLayer)?.featureFormDefinition != null - } - } catch (e: Exception) { - e.printStackTrace() - Toast.makeText( - context, - "failed to load the FeatureFormDefinition for the feature", - Toast.LENGTH_LONG - ).show() - null - } - }?.let { feature -> - feature.load().onSuccess { + // do not process any taps on a different feature when a feature is being edited + if (_uiState.value is UIState.NotEditing) { + launch { + this@MapView.identifyLayers( + screenCoordinate = singleTapEvent.screenCoordinate, + tolerance = 22.0, + returnPopupsOnly = false + ).onSuccess { results -> + results.firstNotNullOfOrNull { result -> try { - val featureForm = FeatureForm( - feature, - (feature.featureTable?.layer as FeatureLayer).featureFormDefinition!! - ) - // set the UI to an editing state and set the FeatureForm - _uiState.value = UIState.Editing(featureForm) + result.geoElements.filterIsInstance() + .firstOrNull { feature -> + (feature.featureTable?.layer as? FeatureLayer)?.featureFormDefinition != null + } } catch (e: Exception) { - e.printStackTrace() // for debugging core issues + e.printStackTrace() Toast.makeText( context, - "failed to create a FeatureForm for the feature and layer", + "failed to load the FeatureFormDefinition for the feature", Toast.LENGTH_LONG ).show() + null } - }.onFailure { println("failed to load tapped Feature") } - } ?: println("identified features do not have feature forms defined") - }.onFailure { println("tap was not on a feature") } + }?.let { feature -> + feature.load().onSuccess { + try { + val featureForm = FeatureForm( + feature, + (feature.featureTable?.layer as FeatureLayer).featureFormDefinition!! + ) + // set the UI to an editing state and set the FeatureForm + _uiState.value = UIState.Editing(featureForm) + } catch (e: Exception) { + e.printStackTrace() // for debugging core issues + Toast.makeText( + context, + "failed to create a FeatureForm for the feature and layer", + Toast.LENGTH_LONG + ).show() + } + }.onFailure { println("failed to load tapped Feature") } + } ?: println("identified features do not have feature forms defined") + }.onFailure { println("tap was not on a feature") } + } } } } From e8e608525c85c684518bc1678c20800e9a51287a Mon Sep 17 00:00:00 2001 From: Kaushik Meesala Date: Fri, 19 Jan 2024 11:01:36 -0800 Subject: [PATCH 3/3] Update strings.xml --- microapps/FeatureFormsApp/app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microapps/FeatureFormsApp/app/src/main/res/values/strings.xml b/microapps/FeatureFormsApp/app/src/main/res/values/strings.xml index a64454f32..550b5b5f5 100644 --- a/microapps/FeatureFormsApp/app/src/main/res/values/strings.xml +++ b/microapps/FeatureFormsApp/app/src/main/res/values/strings.xml @@ -19,5 +19,5 @@ Skip sign in Discard Discard Edits? - All changes made will be lost. + All changes made within the form will be lost.