Skip to content

Commit

Permalink
Merge pull request #13120 from woocommerce/issue/13114-updated-design…
Browse files Browse the repository at this point in the history
…s-retry-pagination-error

[woo pos][non-simple products]updated designs retry pagination error
  • Loading branch information
samiuelson authored Dec 13, 2024
2 parents cccbfae + 86051f2 commit a19800c
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ fun WooPosButtonLarge(
}

@Composable
fun WooPosOutlinedButton(
fun WooPosOutlinedButtonSmall(
modifier: Modifier = Modifier,
text: String,
shape: RoundedCornerShape = RoundedCornerShape(4.dp),
Expand Down Expand Up @@ -133,6 +133,40 @@ fun WooPosOutlinedButton(
)
}

@Composable
fun WooPosOutlinedButton(
modifier: Modifier = Modifier,
text: String,
onClick: () -> Unit,
) {
Button(
modifier = modifier
.fillMaxWidth()
.height(80.dp),
onClick = onClick,
border = BorderStroke(2.dp, MaterialTheme.colors.onBackground),
shape = RoundedCornerShape(8.dp),
colors = ButtonDefaults.buttonColors(
backgroundColor = MaterialTheme.colors.background,
contentColor = MaterialTheme.colors.onBackground,
),
elevation = ButtonDefaults.elevation(
defaultElevation = 0.dp,
pressedElevation = 0.dp,
disabledElevation = 0.dp,
hoveredElevation = 0.dp,
focusedElevation = 0.dp
)
) {
Text(
text = text,
color = MaterialTheme.colors.onBackground,
style = MaterialTheme.typography.h5,
fontWeight = FontWeight.Bold,
)
}
}

@Composable
@WooPosPreview
fun WooPosButtonsPreview() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.woocommerce.android.ui.woopos.common.composeui.component

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
Expand All @@ -14,7 +18,6 @@ import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.painterResource
Expand All @@ -40,12 +43,14 @@ fun WooPosPaginationErrorIndicator(
modifier: Modifier = Modifier,
icon: Painter = painterResource(id = R.drawable.woo_pos_ic_error),
message: String,
description: String,
primaryButton: Button,
) {
WooPosPaginationErrorIndicatorContent(
modifier = modifier,
icon = icon,
message = message,
description = description,
primaryButton = primaryButton
)
}
Expand All @@ -55,6 +60,7 @@ private fun WooPosPaginationErrorIndicatorContent(
modifier: Modifier,
icon: Painter,
message: String,
description: String,
primaryButton: Button
) {
val itemContentDescription = stringResource(id = R.string.woopos_items_pagination_error_content_description)
Expand All @@ -69,38 +75,50 @@ private fun WooPosPaginationErrorIndicatorContent(
Row(
modifier = Modifier
.height(112.dp)
.fillMaxWidth()
.padding(16.dp),
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.weight(1f)
) {
Icon(
modifier = Modifier.size(24.dp),
painter = icon,
contentDescription = stringResource(R.string.woopos_error_icon_content_description),
tint = Color.Unspecified,
)
Text(
text = message,
style = MaterialTheme.typography.h5,
fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colors.error,
modifier = Modifier.padding(start = 24.dp.toAdaptivePadding())
)
Box(
modifier = Modifier
.size(112.dp)
) {
Icon(
modifier = Modifier
.size(54.dp)
.align(Alignment.Center),
painter = icon,
contentDescription = stringResource(R.string.woopos_error_icon_content_description),
tint = Color.Unspecified,
)
}
Spacer(modifier = Modifier.width(18.dp))
Column {
Text(
text = message,
style = MaterialTheme.typography.h5,
fontWeight = FontWeight.Bold,
)
Text(
text = description,
style = MaterialTheme.typography.h5,
fontWeight = FontWeight.Normal,
modifier = Modifier.padding(top = 8.dp.toAdaptivePadding())
)
}
}

WooPosButton(
WooPosOutlinedButton(
text = primaryButton.text,
onClick = primaryButton.click,
modifier = Modifier
.weight(0.5f)
.height(50.dp)
.clip(RoundedCornerShape(16.dp))
.padding(end = 16.dp.toAdaptivePadding())
.weight(0.25f),
)
}
}
Expand Down Expand Up @@ -152,9 +170,10 @@ fun WooPosPaginationErrorScreenPreview() {
onEndOfProductsListReached = {}
) {
WooPosPaginationErrorIndicator(
message = stringResource(id = R.string.woopos_items_pagination_error),
message = stringResource(id = R.string.woopos_items_pagination_error_title),
description = stringResource(id = R.string.woopos_items_pagination_error_description),
primaryButton = Button(
text = stringResource(id = R.string.woopos_items_pagination_load_more_label),
text = stringResource(id = R.string.woopos_items_pagination_try_again_label),
click = {}
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview
import com.woocommerce.android.ui.woopos.common.composeui.WooPosTheme
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosButton
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosLazyColumn
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosOutlinedButton
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosOutlinedButtonSmall
import com.woocommerce.android.ui.woopos.common.composeui.toAdaptivePadding

@Composable
Expand Down Expand Up @@ -380,7 +380,7 @@ private fun CartToolbar(
}

if (toolbar.isClearAllButtonVisible) {
WooPosOutlinedButton(
WooPosOutlinedButtonSmall(
onClick = { onClearAllClicked() },
modifier = Modifier
.constrainAs(clearAllButton) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,10 @@ fun ProductsError(onRetryClicked: () -> Unit) {
@Composable
private fun ProductsPaginationError(onRetryClicked: () -> Unit) {
WooPosPaginationErrorIndicator(
message = stringResource(id = R.string.woopos_items_pagination_error),
message = stringResource(id = R.string.woopos_items_pagination_error_title),
description = stringResource(id = R.string.woopos_items_pagination_error_description),
primaryButton = Button(
text = stringResource(id = R.string.woopos_items_pagination_load_more_label),
text = stringResource(id = R.string.woopos_items_pagination_try_again_label),
click = onRetryClicked
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class WooPosProductsDataSource @Inject constructor(
val result = handler.loadFromCacheAndFetch(
forceRefresh = forceRefreshProducts,
searchType = ProductListHandler.SearchType.DEFAULT,
includeType = listOf(WCProductStore.IncludeType.Simple),
includeType = listOf(WCProductStore.IncludeType.Simple, WCProductStore.IncludeType.Variable),
filters = mapOf(WCProductStore.ProductFilterOption.STATUS to ProductStatus.PUBLISH.value)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,10 @@ fun VariationsError(modifier: Modifier, onRetryClicked: () -> Unit) {
@Composable
fun VariationsPaginationError(onRetryClicked: () -> Unit) {
WooPosPaginationErrorIndicator(
message = stringResource(id = R.string.woopos_items_pagination_error),
message = stringResource(id = R.string.woopos_items_pagination_error_title),
description = stringResource(id = R.string.woopos_items_pagination_error_description),
primaryButton = Button(
text = stringResource(id = R.string.woopos_items_pagination_load_more_label),
text = stringResource(id = R.string.woopos_items_pagination_try_again_label),
click = onRetryClicked
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ class WooPosVariationsViewModel @Inject constructor(
val variations = result.result.getOrThrow()
if (variations.isNotEmpty()) {
WooPosVariationsViewState.Content(
items = variations.filter { it.price != null }.map {
items = variations.filter {
it.price != null && !it.isVirtual && !it.isDownloadable
}.map {
WooPosItem.Variation(
id = it.remoteVariationId,
name = it.getName(getProductById(productId)),
Expand Down
5 changes: 3 additions & 2 deletions WooCommerce/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4331,8 +4331,9 @@

<string name="woopos_items_list_variable_product_variations">%1$d variations</string>
<string name="woopos_variations_back_content_description">Back</string>
<string name="woopos_items_pagination_load_more_label">Load more</string>
<string name="woopos_items_pagination_error">"Failed to load more items. Please try again."</string>
<string name="woopos_items_pagination_try_again_label">Try again</string>
<string name="woopos_items_pagination_error_title">"Failed to load more items"</string>
<string name="woopos_items_pagination_error_description">"An error occurred while loading products."</string>
<string name="woopos_items_pagination_error_content_description">"Failed to load more items. Double tap to try again."</string>
<string name="woopos_variations_loading_error_title">Error loading variations</string>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ object ProductTestUtils {
productId: Long = 1L,
variationId: Long = 1L,
amount: String = "10.00",
isVirtual: Boolean = false,
isDownloadable: Boolean = false,
): ProductVariation {
return WCProductVariationModel(2).apply {
dateCreated = "2018-01-05T05:14:30Z"
Expand All @@ -127,6 +129,8 @@ object ProductTestUtils {
price = amount
image = ""
attributes = ""
virtual = isVirtual
downloadable = isDownloadable
}.toAppModel().also { it.priceWithCurrency = "$10.00" }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,78 @@ class WooPosVariationsViewModelTest {
}
}

@Test
fun `given variations from data source, when view model created, then filter variations that does not have price`() = runTest {
// GIVEN
val variations = listOf(
ProductTestUtils.generateProductVariation(1, 1, "10.0"),
ProductTestUtils.generateProductVariation(2, 1, "")
)
whenever(variationsDataSource.fetchFirstPage(any(), any())).thenReturn(
flowOf(FetchResult.Remote(Result.success(variations)))
)

// WHEN
val viewModel = createViewModel()
viewModel.init(1L)

viewModel.viewState.test {
// THEN
val state = awaitItem() as WooPosVariationsViewState.Content
assertThat(state.items).hasSize(1)
assertThat(state.items[0].id).isEqualTo(1)
assertThat(state.items[0].price).isEqualTo("$10.0")
}
}

@Test
fun `given variations from data source, when view model created, then filter variations that are virtual`() = runTest {
// GIVEN
val variations = listOf(
ProductTestUtils.generateProductVariation(1, 1, "10.0"),
ProductTestUtils.generateProductVariation(2, 1, "20.0", true)
)
whenever(variationsDataSource.fetchFirstPage(any(), any())).thenReturn(
flowOf(FetchResult.Remote(Result.success(variations)))
)

// WHEN
val viewModel = createViewModel()
viewModel.init(1L)

viewModel.viewState.test {
// THEN
val state = awaitItem() as WooPosVariationsViewState.Content
assertThat(state.items).hasSize(1)
assertThat(state.items[0].id).isEqualTo(1)
assertThat(state.items[0].price).isEqualTo("$10.0")
}
}

@Test
fun `given variations from data source, when view model created, then filter variations that are downloadable`() = runTest {
// GIVEN
val variations = listOf(
ProductTestUtils.generateProductVariation(1, 1, "10.0"),
ProductTestUtils.generateProductVariation(2, 1, "20.0", isDownloadable = true)
)
whenever(variationsDataSource.fetchFirstPage(any(), any())).thenReturn(
flowOf(FetchResult.Remote(Result.success(variations)))
)

// WHEN
val viewModel = createViewModel()
viewModel.init(1L)

viewModel.viewState.test {
// THEN
val state = awaitItem() as WooPosVariationsViewState.Content
assertThat(state.items).hasSize(1)
assertThat(state.items[0].id).isEqualTo(1)
assertThat(state.items[0].price).isEqualTo("$10.0")
}
}

@Test
fun `given empty variations list returned, when view model created, then view state is empty`() = runTest {
// GIVEN
Expand Down

0 comments on commit a19800c

Please sign in to comment.