From cbf2d2a05322629b9f8ed50e06045924866ddaa0 Mon Sep 17 00:00:00 2001 From: Ondrej Ruttkay Date: Mon, 20 May 2024 21:39:05 +0200 Subject: [PATCH 1/5] Make orders clickable --- .../dashboard/orders/DashboardOrdersCard.kt | 32 ++++++++++++++++--- .../orders/DashboardOrdersViewModel.kt | 7 ++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/orders/DashboardOrdersCard.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/orders/DashboardOrdersCard.kt index 55d64facefd..f0b7eae9de5 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/orders/DashboardOrdersCard.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/orders/DashboardOrdersCard.kt @@ -1,5 +1,7 @@ package com.woocommerce.android.ui.dashboard.orders +import androidx.compose.foundation.clickable +import androidx.compose.foundation.focusable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -33,12 +35,14 @@ import com.woocommerce.android.ui.dashboard.DashboardFilterableCardHeader import com.woocommerce.android.ui.dashboard.DashboardViewModel import com.woocommerce.android.ui.dashboard.WidgetCard import com.woocommerce.android.ui.dashboard.WidgetError +import com.woocommerce.android.ui.dashboard.orders.DashboardOrdersViewModel.NavigateToOrderDetails import com.woocommerce.android.ui.dashboard.orders.DashboardOrdersViewModel.NavigateToOrders import com.woocommerce.android.ui.dashboard.orders.DashboardOrdersViewModel.ViewState.Content import com.woocommerce.android.ui.dashboard.orders.DashboardOrdersViewModel.ViewState.Error import com.woocommerce.android.ui.dashboard.orders.DashboardOrdersViewModel.ViewState.Loading import com.woocommerce.android.ui.dashboard.orders.DashboardOrdersViewModel.ViewState.OrderItem import com.woocommerce.android.ui.orders.filters.data.OrderStatusOption +import com.woocommerce.android.ui.orders.list.OrderListFragmentArgs import com.woocommerce.android.viewmodel.MultiLiveEvent.Event @Composable @@ -63,7 +67,8 @@ fun DashboardOrdersCard( selectedFilter = state.selectedFilter, filterOptions = state.filterOptions, onFilterSelected = viewModel::onFilterSelected, - orders = state.orders + orders = state.orders, + onOrderClicked = { order -> viewModel.onOrderClicked(order.id) } ) } is Error -> WidgetError( @@ -98,6 +103,17 @@ private fun HandleEvents( } ) } + is NavigateToOrderDetails -> { + navController.navigateSafely( + resId = R.id.orders, + navOptions = navOptions { + popUpTo(navController.graph.findStartDestination().id) { + saveState = true + } + }, + bundle = OrderListFragmentArgs(orderId = event.orderId).toBundle() + ) + } } } @@ -134,7 +150,8 @@ fun TopOrders( selectedFilter: OrderStatusOption, filterOptions: List, onFilterSelected: (OrderStatusOption) -> Unit, - orders: List + orders: List, + onOrderClicked: (OrderItem) -> Unit ) { Column { Header( @@ -143,7 +160,7 @@ fun TopOrders( onFilterSelected = onFilterSelected ) orders.forEach { order -> - OrderListItem(order) + OrderListItem(order, onOrderClicked) Divider( modifier = Modifier @@ -234,10 +251,12 @@ private fun LoadingItem() { @Suppress("DestructuringDeclarationWithTooManyEntries") @Composable -private fun OrderListItem(order: OrderItem) { +private fun OrderListItem(order: OrderItem, onOrderClicked: (OrderItem) -> Unit) { ConstraintLayout( modifier = Modifier .fillMaxWidth() + .focusable(true) + .clickable(onClick = { onOrderClicked(order) }) .padding(16.dp) ) { val (number, date, name, status, total) = createRefs() @@ -306,6 +325,7 @@ fun PreviewTopOrders() { TopOrders( orders = listOf( OrderItem( + id = 0L, number = "123", date = "2021-09-01", customerName = "John Doe", @@ -314,6 +334,7 @@ fun PreviewTopOrders() { totalPrice = "$100.00" ), OrderItem( + id = 0L, number = "124", date = "2021-09-02", customerName = "Jane Doe", @@ -342,7 +363,8 @@ fun PreviewTopOrders() { isSelected = false ) ), - onFilterSelected = {} + onFilterSelected = {}, + onOrderClicked = {} ) } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/orders/DashboardOrdersViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/orders/DashboardOrdersViewModel.kt index e97941860da..839b5e70f32 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/orders/DashboardOrdersViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/orders/DashboardOrdersViewModel.kt @@ -114,6 +114,7 @@ class DashboardOrdersViewModel @AssistedInject constructor( .first { option -> option.key == order.status.value }.label ViewState.OrderItem( + id = order.id, number = "#${order.number}", date = order.dateCreated.formatToMMMdd(), customerName = order.billingName.ifEmpty { @@ -175,6 +176,10 @@ class DashboardOrdersViewModel @AssistedInject constructor( selectedFilter.value = filter.key } + fun onOrderClicked(orderId: Long) { + triggerEvent(NavigateToOrderDetails(orderId)) + } + sealed class ViewState { data object Loading : ViewState() data class Error(val message: String) : ViewState() @@ -187,6 +192,7 @@ class DashboardOrdersViewModel @AssistedInject constructor( @StringRes val title: Int = ORDERS.titleResource data class OrderItem( + val id: Long, val number: String, val date: String, val customerName: String, @@ -202,4 +208,5 @@ class DashboardOrdersViewModel @AssistedInject constructor( } data object NavigateToOrders : MultiLiveEvent.Event() + data class NavigateToOrderDetails(val orderId: Long) : MultiLiveEvent.Event() } From 7bbfbad5249056f4bc311ca9b6e45d870ec6ed19 Mon Sep 17 00:00:00 2001 From: Ondrej Ruttkay Date: Mon, 20 May 2024 21:39:22 +0200 Subject: [PATCH 2/5] Filter trashed orders to prevent a crash --- .../woocommerce/android/ui/orders/list/OrderListRepository.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListRepository.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListRepository.kt index b9d07a8b4b7..6eeac878046 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListRepository.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListRepository.kt @@ -39,6 +39,7 @@ class OrderListRepository @Inject constructor( ) { companion object { private const val TAG = "OrderListRepository" + private const val ORDER_STATUS_TRASH = "trash" } private var isFetchingOrderStatusOptions = false @@ -134,7 +135,7 @@ class OrderListRepository @Inject constructor( if (!isForced) { orderStore.getOrdersForSite(selectedSite.get()) .asSequence() - .filter { statusFilter == null || it.status == statusFilter.value } + .filter { it.status != ORDER_STATUS_TRASH && (statusFilter == null || it.status == statusFilter.value) } .sortedByDescending { it.dateCreated } .take(count) .map { orderMapper.toAppModel(it) } From 6812b945bab036380457e44d22f13ff18039f943 Mon Sep 17 00:00:00 2001 From: Ondrej Ruttkay Date: Mon, 20 May 2024 21:39:55 +0200 Subject: [PATCH 3/5] Open order list and then order details when order clicked in the dashboard --- .../android/ui/orders/list/OrderListFragment.kt | 8 ++++++++ .../android/ui/orders/list/OrderListViewModel.kt | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt index 9bb317e8c5e..0d19c184940 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt @@ -567,6 +567,14 @@ class OrderListFragment : openBarcodeScanningFragment() } + is OrderListViewModel.OrderListEvent.OpenOrder -> { + findNavController().navigateSafely( + directions = OrderListFragmentDirections + .actionOrderListFragmentToOrderDetailFragment(event.orderId, longArrayOf()), + skipThrottling = true + ) + } + is MultiLiveEvent.Event.ShowDialog -> event.showDialog() is MultiLiveEvent.Event.ShowActionSnackbar -> uiMessageResolver.showActionSnack( message = event.message, diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListViewModel.kt index 89b068edbbf..a37b5c36609 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListViewModel.kt @@ -50,6 +50,7 @@ import com.woocommerce.android.ui.orders.filters.domain.GetSelectedOrderFiltersC import com.woocommerce.android.ui.orders.filters.domain.GetWCOrderListDescriptorWithFilters import com.woocommerce.android.ui.orders.filters.domain.GetWCOrderListDescriptorWithFiltersAndSearchQuery import com.woocommerce.android.ui.orders.filters.domain.ShouldShowCreateTestOrderScreen +import com.woocommerce.android.ui.orders.list.OrderListViewModel.OrderListEvent.OpenOrder import com.woocommerce.android.ui.orders.list.OrderListViewModel.OrderListEvent.RetryLoadingOrders import com.woocommerce.android.ui.orders.list.OrderListViewModel.OrderListEvent.ShowErrorSnack import com.woocommerce.android.ui.orders.list.OrderListViewModel.OrderListEvent.ShowOrderFilters @@ -230,6 +231,10 @@ class OrderListViewModel @Inject constructor( // stay on the screen } } + + if (navArgs.orderId != -1L) { + triggerEvent(OpenOrder(navArgs.orderId)) + } } fun loadOrders() { @@ -896,6 +901,8 @@ class OrderListViewModel @Inject constructor( data object RetryLoadingOrders : OrderListEvent() data object OpenOrderCreationWithSimplePaymentsMigration : OrderListEvent() + + data class OpenOrder(val orderId: Long) : OrderListEvent() } @Parcelize From 04b14d8dd302f6930307ec1a174c097586cebe3c Mon Sep 17 00:00:00 2001 From: Ondrej Ruttkay Date: Mon, 20 May 2024 22:00:40 +0200 Subject: [PATCH 4/5] Simplify navigation --- .../dashboard/orders/DashboardOrdersCard.kt | 34 ++++++++++--------- .../ui/orders/list/OrderListFragment.kt | 8 ----- .../ui/orders/list/OrderListViewModel.kt | 6 ---- 3 files changed, 18 insertions(+), 30 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/orders/DashboardOrdersCard.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/orders/DashboardOrdersCard.kt index f0b7eae9de5..d2f2e8485ee 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/orders/DashboardOrdersCard.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/orders/DashboardOrdersCard.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.unit.dp import androidx.constraintlayout.compose.ConstraintLayout import androidx.lifecycle.LiveData import androidx.lifecycle.Observer +import androidx.navigation.NavController import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.navOptions import com.woocommerce.android.R @@ -42,7 +43,7 @@ import com.woocommerce.android.ui.dashboard.orders.DashboardOrdersViewModel.View import com.woocommerce.android.ui.dashboard.orders.DashboardOrdersViewModel.ViewState.Loading import com.woocommerce.android.ui.dashboard.orders.DashboardOrdersViewModel.ViewState.OrderItem import com.woocommerce.android.ui.orders.filters.data.OrderStatusOption -import com.woocommerce.android.ui.orders.list.OrderListFragmentArgs +import com.woocommerce.android.ui.orders.list.OrderListFragmentDirections import com.woocommerce.android.viewmodel.MultiLiveEvent.Event @Composable @@ -87,6 +88,17 @@ fun DashboardOrdersCard( private fun HandleEvents( event: LiveData ) { + fun NavController.navigateToOrders() { + navigateSafely( + resId = R.id.orders, + navOptions = navOptions { + popUpTo(graph.findStartDestination().id) { + saveState = true + } + } + ) + } + val navController = rememberNavController() val lifecycleOwner = LocalLifecycleOwner.current @@ -94,24 +106,14 @@ private fun HandleEvents( val observer = Observer { event: Event -> when (event) { is NavigateToOrders -> { - navController.navigateSafely( - resId = R.id.orders, - navOptions = navOptions { - popUpTo(navController.graph.findStartDestination().id) { - saveState = true - } - } - ) + navController.navigateToOrders() } is NavigateToOrderDetails -> { + navController.navigateToOrders() navController.navigateSafely( - resId = R.id.orders, - navOptions = navOptions { - popUpTo(navController.graph.findStartDestination().id) { - saveState = true - } - }, - bundle = OrderListFragmentArgs(orderId = event.orderId).toBundle() + directions = OrderListFragmentDirections + .actionOrderListFragmentToOrderDetailFragment(event.orderId, longArrayOf()), + skipThrottling = true ) } } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt index 0d19c184940..9bb317e8c5e 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListFragment.kt @@ -567,14 +567,6 @@ class OrderListFragment : openBarcodeScanningFragment() } - is OrderListViewModel.OrderListEvent.OpenOrder -> { - findNavController().navigateSafely( - directions = OrderListFragmentDirections - .actionOrderListFragmentToOrderDetailFragment(event.orderId, longArrayOf()), - skipThrottling = true - ) - } - is MultiLiveEvent.Event.ShowDialog -> event.showDialog() is MultiLiveEvent.Event.ShowActionSnackbar -> uiMessageResolver.showActionSnack( message = event.message, diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListViewModel.kt index a37b5c36609..0724aa532b3 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListViewModel.kt @@ -231,10 +231,6 @@ class OrderListViewModel @Inject constructor( // stay on the screen } } - - if (navArgs.orderId != -1L) { - triggerEvent(OpenOrder(navArgs.orderId)) - } } fun loadOrders() { @@ -901,8 +897,6 @@ class OrderListViewModel @Inject constructor( data object RetryLoadingOrders : OrderListEvent() data object OpenOrderCreationWithSimplePaymentsMigration : OrderListEvent() - - data class OpenOrder(val orderId: Long) : OrderListEvent() } @Parcelize From adb175bc73bb27eb1fa07de9eae52ec0fb9ce107 Mon Sep 17 00:00:00 2001 From: Ondrej Ruttkay Date: Mon, 20 May 2024 22:04:59 +0200 Subject: [PATCH 5/5] Fix the build --- .../com/woocommerce/android/ui/orders/list/OrderListViewModel.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListViewModel.kt index 0724aa532b3..89b068edbbf 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/list/OrderListViewModel.kt @@ -50,7 +50,6 @@ import com.woocommerce.android.ui.orders.filters.domain.GetSelectedOrderFiltersC import com.woocommerce.android.ui.orders.filters.domain.GetWCOrderListDescriptorWithFilters import com.woocommerce.android.ui.orders.filters.domain.GetWCOrderListDescriptorWithFiltersAndSearchQuery import com.woocommerce.android.ui.orders.filters.domain.ShouldShowCreateTestOrderScreen -import com.woocommerce.android.ui.orders.list.OrderListViewModel.OrderListEvent.OpenOrder import com.woocommerce.android.ui.orders.list.OrderListViewModel.OrderListEvent.RetryLoadingOrders import com.woocommerce.android.ui.orders.list.OrderListViewModel.OrderListEvent.ShowErrorSnack import com.woocommerce.android.ui.orders.list.OrderListViewModel.OrderListEvent.ShowOrderFilters