Skip to content

Commit aa2cf06

Browse files
authored
Merge pull request #14604 from woocommerce/woomob-1146-woo-poshistorical-orders-orders-searching
[WOOMOB-1146][Woo POS][Orders] Add search functionality to Woo POS orders
2 parents 2d6be84 + d6e4bc4 commit aa2cf06

File tree

7 files changed

+470
-51
lines changed

7 files changed

+470
-51
lines changed

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/orders/WooPosOrdersDataSource.kt

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ sealed class LoadOrdersResult {
1616
data class Error(val message: String) : LoadOrdersResult()
1717
}
1818

19+
sealed class SearchOrdersResult {
20+
data class Success(val orders: List<Order>) : SearchOrdersResult()
21+
data class Error(val message: String) : SearchOrdersResult()
22+
}
23+
1924
class WooPosOrdersDataSource @Inject constructor(
2025
private val restClient: OrderRestClient,
2126
private val selectedSite: SelectedSite,
@@ -25,31 +30,48 @@ class WooPosOrdersDataSource @Inject constructor(
2530
companion object {
2631
const val POS_ORDERS_PAGE_SIZE = 25
2732
}
33+
2834
fun loadOrders(): Flow<LoadOrdersResult> = flow {
2935
val cached = ordersCache.getAll()
3036
if (cached.isNotEmpty()) {
3137
emit(LoadOrdersResult.SuccessCache(cached))
3238
}
3339

34-
val result = restClient.fetchOrders(
35-
site = selectedSite.get(),
36-
count = POS_ORDERS_PAGE_SIZE,
37-
page = 1,
38-
orderBy = OrderBy.DATE,
39-
sortOrder = OrderRestClient.SortOrder.DESCENDING,
40-
statusFilter = null,
41-
createdVia = "pos-rest-api"
42-
)
40+
val result = fetchOrdersFromRemote(searchQuery = null, page = 1)
4341

4442
if (result.isError) {
45-
emit(LoadOrdersResult.Error(result.error.message))
43+
emit(LoadOrdersResult.Error(result.error?.message ?: "Unknown error"))
4644
} else {
4745
val mapped = result.orders.toAppModels()
4846
ordersCache.setAll(mapped)
49-
emit(LoadOrdersResult.SuccessRemote(result.orders.toAppModels()))
47+
emit(LoadOrdersResult.SuccessRemote(mapped))
5048
}
5149
}
5250

51+
suspend fun searchOrders(searchQuery: String): SearchOrdersResult {
52+
val result = fetchOrdersFromRemote(searchQuery = searchQuery, page = 1)
53+
54+
return if (result.isError) {
55+
SearchOrdersResult.Error(result.error?.message ?: "Unknown error")
56+
} else {
57+
SearchOrdersResult.Success(result.orders.toAppModels())
58+
}
59+
}
60+
61+
private suspend fun fetchOrdersFromRemote(
62+
page: Int,
63+
searchQuery: String?
64+
) = restClient.fetchOrders(
65+
site = selectedSite.get(),
66+
count = POS_ORDERS_PAGE_SIZE,
67+
page = page,
68+
orderBy = OrderBy.DATE,
69+
sortOrder = OrderRestClient.SortOrder.DESCENDING,
70+
statusFilter = null,
71+
createdVia = "pos-rest-api",
72+
searchQuery = searchQuery,
73+
)
74+
5375
fun clearCache() = ordersCache.clear()
5476

5577
private suspend fun List<OrderEntity>.toAppModels(): List<Order> = map {

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/orders/WooPosOrdersScreen.kt

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ import androidx.compose.foundation.layout.Spacer
1212
import androidx.compose.foundation.layout.fillMaxHeight
1313
import androidx.compose.foundation.layout.fillMaxSize
1414
import androidx.compose.foundation.layout.fillMaxWidth
15+
import androidx.compose.foundation.layout.height
16+
import androidx.compose.foundation.layout.heightIn
1517
import androidx.compose.foundation.layout.padding
18+
import androidx.compose.foundation.layout.statusBarsPadding
1619
import androidx.compose.foundation.lazy.LazyColumn
1720
import androidx.compose.foundation.lazy.items
1821
import androidx.compose.material.ExperimentalMaterialApi
@@ -30,9 +33,14 @@ import androidx.compose.ui.res.stringResource
3033
import androidx.compose.ui.semantics.selected
3134
import androidx.compose.ui.semantics.semantics
3235
import androidx.compose.ui.text.font.FontWeight
36+
import androidx.compose.ui.unit.dp
37+
import androidx.constraintlayout.compose.ConstraintLayout
3338
import androidx.hilt.navigation.compose.hiltViewModel
3439
import com.woocommerce.android.R
3540
import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview
41+
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosSearchInput
42+
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosSearchInputState
43+
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosSearchUIEvent
3644
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosText
3745
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosToolbar
3846
import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosSpacing
@@ -41,6 +49,8 @@ import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosTyp
4149
import com.woocommerce.android.ui.woopos.home.items.WooPosPullToRefreshState
4250
import com.woocommerce.android.ui.woopos.root.navigation.WooPosNavigationEvent
4351

52+
private val WOO_POS_ORDERS_TOOLBAR_HEIGHT = 56.dp
53+
4454
@OptIn(ExperimentalMaterialApi::class)
4555
@Composable
4656
fun WooPosOrdersScreen(
@@ -59,6 +69,7 @@ fun WooPosOrdersScreen(
5969
onRefresh = viewModel::onRefresh,
6070
isRefreshing = state.pullToRefreshState == WooPosPullToRefreshState.Refreshing,
6171
onOrderSelected = viewModel::onOrderSelected,
72+
onSearchEvent = viewModel::onSearchEvent,
6273
modifier = Modifier
6374
.weight(0.3f)
6475
.fillMaxHeight()
@@ -83,13 +94,48 @@ private fun OrdersList(
8394
onRefresh: () -> Unit,
8495
isRefreshing: Boolean,
8596
onOrderSelected: (Long) -> Unit,
97+
onSearchEvent: (WooPosSearchUIEvent) -> Unit,
8698
modifier: Modifier = Modifier
8799
) {
88100
Column(modifier = modifier) {
89-
WooPosToolbar(
90-
titleText = stringResource(R.string.woopos_orders_title),
91-
onBackClicked = onBackClicked,
92-
)
101+
ConstraintLayout(
102+
modifier = Modifier
103+
.fillMaxWidth()
104+
.heightIn(min = WOO_POS_ORDERS_TOOLBAR_HEIGHT),
105+
) {
106+
val (toolbar, searchInput) = createRefs()
107+
108+
if (state.searchInputState is WooPosSearchInputState.Closed) {
109+
WooPosToolbar(
110+
titleText = stringResource(R.string.woopos_orders_title),
111+
onBackClicked = onBackClicked,
112+
modifier = Modifier.constrainAs(toolbar) {
113+
start.linkTo(parent.start)
114+
top.linkTo(parent.top)
115+
bottom.linkTo(parent.bottom)
116+
}
117+
)
118+
}
119+
WooPosSearchInput(
120+
state = state.searchInputState,
121+
onEvent = onSearchEvent,
122+
modifier = Modifier
123+
.statusBarsPadding()
124+
.constrainAs(searchInput) {
125+
if (state.searchInputState is WooPosSearchInputState.Open) {
126+
start.linkTo(parent.start)
127+
end.linkTo(parent.end)
128+
width = androidx.constraintlayout.compose.Dimension.fillToConstraints
129+
} else {
130+
end.linkTo(parent.end)
131+
}
132+
top.linkTo(parent.top)
133+
bottom.linkTo(parent.bottom)
134+
}
135+
)
136+
}
137+
138+
Spacer(modifier = Modifier.height(WooPosSpacing.Small.value))
93139

94140
val pullRefreshState = rememberPullRefreshState(
95141
refreshing = isRefreshing,

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/orders/WooPosOrdersState.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.woocommerce.android.ui.woopos.orders
22

33
import androidx.compose.runtime.Immutable
4+
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosSearchInputState
45
import com.woocommerce.android.ui.woopos.home.items.WooPosPaginationState
56
import com.woocommerce.android.ui.woopos.home.items.WooPosPullToRefreshState
67

@@ -16,30 +17,33 @@ data class OrderItemViewState(
1617
@Immutable
1718
sealed class WooPosOrdersState {
1819
abstract val pullToRefreshState: WooPosPullToRefreshState
20+
abstract val searchInputState: WooPosSearchInputState
1921

2022
@Immutable
2123
data class Content(
2224
val items: List<OrderItemViewState>,
2325
override val pullToRefreshState: WooPosPullToRefreshState,
26+
override val searchInputState: WooPosSearchInputState,
2427
val paginationState: WooPosPaginationState,
2528
val selectedOrderId: Long?
2629
) : WooPosOrdersState()
2730

2831
@Immutable
2932
data class Error(
3033
val message: String,
34+
override val searchInputState: WooPosSearchInputState
3135
) : WooPosOrdersState() {
3236
override val pullToRefreshState: WooPosPullToRefreshState = WooPosPullToRefreshState.Disabled
3337
}
3438

3539
@Immutable
36-
data object Loading : WooPosOrdersState() {
40+
data class Loading(override val searchInputState: WooPosSearchInputState) : WooPosOrdersState() {
3741
override val pullToRefreshState: WooPosPullToRefreshState = WooPosPullToRefreshState.Disabled
3842
}
3943

4044
@Immutable
4145
data class Empty(
42-
override val pullToRefreshState: WooPosPullToRefreshState =
43-
WooPosPullToRefreshState.Enabled
46+
override val pullToRefreshState: WooPosPullToRefreshState = WooPosPullToRefreshState.Enabled,
47+
override val searchInputState: WooPosSearchInputState,
4448
) : WooPosOrdersState()
4549
}

0 commit comments

Comments
 (0)