Skip to content
Open
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
Expand Up @@ -17,6 +17,9 @@ import com.woocommerce.android.extensions.navigateBackWithNotice
import com.woocommerce.android.extensions.navigateSafely
import com.woocommerce.android.model.Order
import com.woocommerce.android.ui.base.BaseFragment
import com.woocommerce.android.ui.filters.FilterHistoryType
import com.woocommerce.android.ui.filters.FilterHistoryViewModel
import com.woocommerce.android.ui.filters.SavedFilter
import com.woocommerce.android.ui.main.AppBarStatus
import com.woocommerce.android.ui.main.MainActivity.Companion.BackPressListener
import com.woocommerce.android.ui.orders.creation.customerlist.OrderCustomerListFragment.Companion.KEY_CUSTOMER_RESULT
Expand All @@ -25,6 +28,7 @@ import com.woocommerce.android.ui.orders.filters.data.OrderListFilterCategory.CU
import com.woocommerce.android.ui.orders.filters.data.OrderListFilterCategory.PRODUCT
import com.woocommerce.android.ui.orders.filters.model.OrderFilterCategoryUiModel
import com.woocommerce.android.ui.orders.filters.model.OrderFilterEvent.OnShowOrders
import com.woocommerce.android.ui.orders.filters.model.OrderFilterEvent.OpenFilterHistory
import com.woocommerce.android.ui.orders.filters.model.OrderFilterEvent.ShowFilterOptionsForCategory
import com.woocommerce.android.ui.orders.list.OrderListFragment
import com.woocommerce.android.ui.products.selector.ProductSelectorFragment
Expand Down Expand Up @@ -78,6 +82,7 @@ class OrderFilterCategoriesFragment :

override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_clear, menu)
inflater.inflate(R.menu.menu_filter_history, menu)
}

private fun handleResults() {
Expand All @@ -96,10 +101,15 @@ class OrderFilterCategoriesFragment :
handleResult<Order.Customer>(KEY_CUSTOMER_RESULT) {
viewModel.onCustomerSelected(it)
}

handleResult<SavedFilter>(FilterHistoryViewModel.FILTER_HISTORY_RESULT_KEY) {
viewModel.onPastFilterSelected(it)
}
}

override fun onPrepareMenu(menu: Menu) {
updateClearButtonVisibility(menu.findItem(R.id.menu_clear))
menu.findItem(R.id.menu_filter_history).isVisible = viewModel.isFilterHistoryEnabled
}

override fun onMenuItemSelected(item: MenuItem): Boolean {
Expand All @@ -110,6 +120,11 @@ class OrderFilterCategoriesFragment :
true
}

R.id.menu_filter_history -> {
viewModel.onFilterHistoryButtonClicked()
true
}

else -> false
}
}
Expand Down Expand Up @@ -160,6 +175,13 @@ class OrderFilterCategoriesFragment :
findNavController().navigateSafely(action)
}

private fun navigateToFilterHistory() {
findNavController().navigateSafely(
OrderFilterCategoriesFragmentDirections
.actionOrderFilterCategoriesFragmentToFilterHistoryFragment(FilterHistoryType.ORDERS)
)
}

private fun setUpObservers(viewModel: OrderFilterCategoriesViewModel) {
viewModel.categories.observe(viewLifecycleOwner) { _, newValue ->
showOrderFilters(newValue.list)
Expand All @@ -175,6 +197,7 @@ class OrderFilterCategoriesFragment :
OrderListFragment.FILTER_CHANGE_NOTICE_KEY
)

is OpenFilterHistory -> navigateToFilterHistory()
is Exit -> findNavController().navigateUp()
else -> event.isHandled = false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.woocommerce.android.analytics.AnalyticsTracker
import com.woocommerce.android.analytics.AnalyticsTrackerWrapper
import com.woocommerce.android.model.Order
import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.ui.filters.SavedFilter
import com.woocommerce.android.ui.orders.filters.data.OrderFiltersRepository
import com.woocommerce.android.ui.orders.filters.data.OrderListFilterCategory
import com.woocommerce.android.ui.orders.filters.data.OrderListFilterCategory.CUSTOMER
Expand All @@ -21,9 +22,11 @@ import com.woocommerce.android.ui.orders.filters.domain.GetDateRangeFilterOption
import com.woocommerce.android.ui.orders.filters.domain.GetOrderStatusFilterOptions
import com.woocommerce.android.ui.orders.filters.domain.GetTrackingForFilterSelection
import com.woocommerce.android.ui.orders.filters.domain.IsSalesChannelFilterSupported
import com.woocommerce.android.ui.orders.filters.domain.SaveOrderFilterToHistory
import com.woocommerce.android.ui.orders.filters.model.OrderFilterCategoryListViewState
import com.woocommerce.android.ui.orders.filters.model.OrderFilterCategoryUiModel
import com.woocommerce.android.ui.orders.filters.model.OrderFilterEvent.OnShowOrders
import com.woocommerce.android.ui.orders.filters.model.OrderFilterEvent.OpenFilterHistory
import com.woocommerce.android.ui.orders.filters.model.OrderFilterEvent.ShowFilterOptionsForCategory
import com.woocommerce.android.ui.orders.filters.model.OrderFilterOptionUiModel
import com.woocommerce.android.ui.orders.filters.model.addFilterOptionAll
Expand All @@ -34,6 +37,8 @@ import com.woocommerce.android.ui.orders.filters.model.markOptionAllIfNothingSel
import com.woocommerce.android.ui.orders.filters.model.toOrderFilterOptionUiModel
import com.woocommerce.android.ui.products.list.ProductListRepository
import com.woocommerce.android.util.DateUtils
import com.woocommerce.android.util.FeatureFlag
import com.woocommerce.android.util.FeatureFlagRepository
import com.woocommerce.android.viewmodel.LiveDataDelegate
import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.Exit
import com.woocommerce.android.viewmodel.MultiLiveEvent.Event.ShowDialog
Expand All @@ -58,12 +63,17 @@ class OrderFilterCategoriesViewModel @Inject constructor(
private val productRepository: ProductListRepository,
private val customerStore: WCCustomerStore,
private val selectedSite: SelectedSite,
private val isSalesChannelFilterSupported: IsSalesChannelFilterSupported
private val isSalesChannelFilterSupported: IsSalesChannelFilterSupported,
private val saveOrderFilterToHistory: SaveOrderFilterToHistory,
private val orderFilterHistoryMapper: OrderFilterHistoryMapper,
featureFlagRepository: FeatureFlagRepository
) : ScopedViewModel(savedState) {
companion object {
const val OLD_FILTER_SELECTION_KEY = "old_filter_selection_key"
}

val isFilterHistoryEnabled: Boolean = featureFlagRepository.isEnabled(FeatureFlag.FILTER_HISTORY)

private var oldFilterSelection: List<OrderFilterCategoryUiModel> =
savedState[OLD_FILTER_SELECTION_KEY] ?: emptyList()

Expand Down Expand Up @@ -100,9 +110,29 @@ class OrderFilterCategoriesViewModel @Inject constructor(
fun onShowOrdersClicked() {
saveFiltersSelection(_categories.list)
trackFilterSelection()
saveOrderFilterToHistory()
triggerEvent(OnShowOrders)
}

fun onFilterHistoryButtonClicked() {
analyticsTraWrapper.track(
AnalyticsEvent.FILTER_HISTORY_BUTTON_TAPPED,
mapOf(AnalyticsTracker.KEY_SOURCE to AnalyticsTracker.VALUE_FILTER_HISTORY_SOURCE_ORDERS)
)
triggerEvent(OpenFilterHistory)
}

fun onPastFilterSelected(savedFilter: SavedFilter) {
val historyData = orderFilterHistoryMapper.fromPayload(savedFilter.payload) ?: return
launch {
OrderListFilterCategory.entries.forEach { category ->
orderFilterRepository.setSelectedFilters(category, historyData.selections[category.name] ?: emptyList())
}
orderFilterRepository.setCustomDateRange(historyData.customDateRangeStart, historyData.customDateRangeEnd)
_categories = OrderFilterCategories(buildFilterListUiModel())
}
}

fun onClearFilters() {
analyticsTraWrapper.track(AnalyticsEvent.ORDER_FILTER_LIST_CLEAR_MENU_BUTTON_TAPPED)
_categories = OrderFilterCategories(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.woocommerce.android.ui.orders.filters

import com.google.gson.Gson
import com.google.gson.annotations.SerializedName
import com.woocommerce.android.ui.orders.filters.model.OrderFilterCategoryUiModel
import com.woocommerce.android.ui.orders.filters.model.OrderFilterOptionUiModel
import com.woocommerce.android.ui.orders.filters.model.OrderFilterOptionUiModel.Companion.DEFAULT_ALL_KEY
import javax.inject.Inject

/**
* Encodes/decodes the order filter selection to and from the opaque `payload` string persisted in the
* filter history table, and builds the human-readable label shown in the history list.
*
* The payload is a canonical JSON serialization of the active selection (categories and option keys
* sorted) so that logically-identical selections dedup reliably. Decoding tolerates missing/unknown
* fields, and applying a decoded selection silently drops option keys that no longer exist because the
* filter screen only marks options selected when their key matches an available option.
*/
class OrderFilterHistoryMapper @Inject constructor(
private val gson: Gson
) {
fun toReadableString(categories: List<OrderFilterCategoryUiModel>): String =
categories
.flatMap { it.orderFilterOptions }
.filter { it.isSelected && it.key != DEFAULT_ALL_KEY }
.joinToString(separator = ", ") { it.readableLabel() }

// Prefer displayValue when present so a custom date range shows its dates rather than the static
// "Custom Range" label; other options have no displayValue and fall back to displayName.
private fun OrderFilterOptionUiModel.readableLabel(): String =
displayValue?.takeIf { it.isNotBlank() } ?: displayName

fun toPayload(
categories: List<OrderFilterCategoryUiModel>,
customDateRangeStart: Long,
customDateRangeEnd: Long
): String {
val selections = categories
.associate { category ->
category.categoryKey.name to category.orderFilterOptions
.filter { it.isSelected && it.key != DEFAULT_ALL_KEY }
.map { it.key }
.sorted()
}
.filterValues { it.isNotEmpty() }
.toSortedMap()
return gson.toJson(
OrderFilterHistoryData(
selections = selections,
customDateRangeStart = customDateRangeStart,
customDateRangeEnd = customDateRangeEnd
)
)
}

fun fromPayload(payload: String): OrderFilterHistoryData? =
runCatching { gson.fromJson(payload, OrderFilterHistoryData::class.java) }.getOrNull()

data class OrderFilterHistoryData(
@SerializedName("selections") val selections: Map<String, List<String>> = emptyMap(),
@SerializedName("custom_date_range_start") val customDateRangeStart: Long = 0,
@SerializedName("custom_date_range_end") val customDateRangeEnd: Long = 0
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.woocommerce.android.ui.orders.filters.data.OrderListFilterCategory.OR
import com.woocommerce.android.ui.orders.filters.data.OrderListFilterCategory.PRODUCT
import com.woocommerce.android.ui.orders.filters.data.OrderListFilterCategory.SALES_CHANNEL
import com.woocommerce.android.ui.orders.filters.domain.GetTrackingForFilterSelection
import com.woocommerce.android.ui.orders.filters.domain.SaveOrderFilterToHistory
import com.woocommerce.android.ui.orders.filters.model.OrderFilterEvent.OnFilterOptionsSelectionUpdated
import com.woocommerce.android.ui.orders.filters.model.OrderFilterEvent.OnShowOrders
import com.woocommerce.android.ui.orders.filters.model.OrderFilterEvent.ShowCustomDateRangePicker
Expand All @@ -40,6 +41,7 @@ class OrderFilterOptionsViewModel @Inject constructor(
private val resourceProvider: ResourceProvider,
private val orderFilterRepository: OrderFiltersRepository,
private val getTrackingForFilterSelection: GetTrackingForFilterSelection,
private val saveOrderFilterToHistory: SaveOrderFilterToHistory,
private val dateUtils: DateUtils
) : ScopedViewModel(savedState) {
private val arguments: OrderFilterOptionsFragmentArgs by savedState.navArgs()
Expand Down Expand Up @@ -73,6 +75,7 @@ class OrderFilterOptionsViewModel @Inject constructor(
fun onShowOrdersClicked() {
saveFiltersSelection()
trackFilterSelection()
saveOrderFilterToHistory()
triggerEvent(OnShowOrders)
}

Expand Down
Loading
Loading