Skip to content

Commit 5bf254e

Browse files
authored
Merge pull request #10677 from woocommerce/issue/10666-see-report-hub
Add see report button in Analytic Hub
2 parents 1b7105a + 9557832 commit 5bf254e

File tree

14 files changed

+454
-54
lines changed

14 files changed

+454
-54
lines changed

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/analytics/hub/AnalyticsHubFragment.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ import kotlinx.coroutines.launch
2929
import java.util.Date
3030

3131
@AndroidEntryPoint
32-
class AnalyticsHubFragment :
33-
BaseFragment(R.layout.fragment_analytics) {
32+
class AnalyticsHubFragment : BaseFragment(R.layout.fragment_analytics) {
3433
companion object {
3534
const val KEY_DATE_RANGE_SELECTOR_RESULT = "key_order_status_result"
3635
const val DATE_PICKER_FRAGMENT_TAG = "DateRangePicker"
@@ -110,6 +109,9 @@ class AnalyticsHubFragment :
110109
private fun bind(view: View) {
111110
_binding = FragmentAnalyticsBinding.bind(view)
112111
binding.analyticsDateSelectorCard.setOnClickListener { viewModel.onDateRangeSelectorClick() }
112+
binding.analyticsOrdersCard.onSeeReportClickListener = { url -> viewModel.onSeeReport(url) }
113+
binding.analyticsRevenueCard.onSeeReportClickListener = { url -> viewModel.onSeeReport(url) }
114+
binding.analyticsProductsCard.onSeeReportClickListener = { url -> viewModel.onSeeReport(url) }
113115
}
114116

115117
private fun handleStateChange(viewState: AnalyticsViewState) {

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/analytics/hub/AnalyticsHubViewModel.kt

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import com.woocommerce.android.model.OrdersStat
1313
import com.woocommerce.android.model.ProductsStat
1414
import com.woocommerce.android.model.RevenueStat
1515
import com.woocommerce.android.model.SessionStat
16+
import com.woocommerce.android.tools.SelectedSite
1617
import com.woocommerce.android.ui.analytics.hub.RefreshIndicator.NotShowIndicator
1718
import com.woocommerce.android.ui.analytics.hub.RefreshIndicator.ShowIndicator
1819
import com.woocommerce.android.ui.analytics.hub.daterangeselector.AnalyticsHubDateRangeSelectorViewState
@@ -70,6 +71,8 @@ class AnalyticsHubViewModel @Inject constructor(
7071
private val feedbackRepository: FeedbackRepository,
7172
private val tracker: AnalyticsTrackerWrapper,
7273
private val dateUtils: DateUtils,
74+
private val selectedSite: SelectedSite,
75+
private val getReportUrl: GetReportUrl,
7376
savedState: SavedStateHandle
7477
) : ScopedViewModel(savedState) {
7578

@@ -132,6 +135,17 @@ class AnalyticsHubViewModel @Inject constructor(
132135
rangeSelectionState.value = selectionType.generateLocalizedSelectionData()
133136
}
134137

138+
fun onSeeReport(url: String) {
139+
selectedSite.getOrNull()?.let { site ->
140+
val event = if (site.isWpComStore) {
141+
AnalyticsViewEvent.OpenWPComWebView(url)
142+
} else {
143+
AnalyticsViewEvent.OpenUrl(url)
144+
}
145+
triggerEvent(event)
146+
} ?: triggerEvent(AnalyticsViewEvent.OpenUrl(url))
147+
}
148+
135149
fun onCustomRangeSelected(startDate: Date, endDate: Date) {
136150
rangeSelectionState.value = SelectionType.CUSTOM.generateLocalizedSelectionData(
137151
startDate = startDate,
@@ -310,7 +324,8 @@ class AnalyticsHubViewModel @Inject constructor(
310324
stats.conversionRate,
311325
null,
312326
listOf()
313-
)
327+
),
328+
reportUrl = null
314329
)
315330

316331
private fun buildRevenueDataViewState(revenueStat: RevenueStat) =
@@ -328,6 +343,10 @@ class AnalyticsHubViewModel @Inject constructor(
328343
if (revenueStat.netDelta is DeltaPercentage.Value) revenueStat.netDelta.value else null,
329344
revenueStat.netRevenueByInterval.map { it.toFloat() }
330345
),
346+
reportUrl = getReportUrl(
347+
selection = ranges,
348+
card = ReportCard.Revenue
349+
)
331350
)
332351

333352
private fun buildOrdersDataViewState(ordersStats: OrdersStat) =
@@ -352,6 +371,10 @@ class AnalyticsHubViewModel @Inject constructor(
352371
null
353372
},
354373
ordersStats.avgOrderValueByInterval.map { it.toFloat() }
374+
),
375+
reportUrl = getReportUrl(
376+
selection = ranges,
377+
card = ReportCard.Orders
355378
)
356379
)
357380

@@ -379,7 +402,11 @@ class AnalyticsHubViewModel @Inject constructor(
379402
),
380403
index != products.size - 1
381404
)
382-
}
405+
},
406+
reportUrl = getReportUrl(
407+
selection = ranges,
408+
card = ReportCard.Products
409+
)
383410
)
384411
}
385412

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.woocommerce.android.ui.analytics.hub
2+
3+
import com.woocommerce.android.extensions.adminUrlOrDefault
4+
import com.woocommerce.android.extensions.formatToYYYYmmDD
5+
import com.woocommerce.android.tools.SelectedSite
6+
import com.woocommerce.android.ui.analytics.ranges.StatsTimeRangeSelection
7+
import javax.inject.Inject
8+
9+
class GetReportUrl @Inject constructor(
10+
private val selectedSite: SelectedSite
11+
) {
12+
operator fun invoke(
13+
selection: StatsTimeRangeSelection,
14+
card: ReportCard
15+
): String? {
16+
return selectedSite.getOrNull()?.let { siteModel ->
17+
val adminURL = siteModel.adminUrlOrDefault
18+
val page = "page=wc-admin"
19+
val path = when (card) {
20+
ReportCard.Revenue -> "path=%2Fanalytics%2Frevenue"
21+
ReportCard.Orders -> "path=%2Fanalytics%2Forders"
22+
ReportCard.Products -> "path=%2Fanalytics%2Fproducts"
23+
}
24+
val period = getPeriod(selection)
25+
val compare = "compare=previous_period"
26+
"${adminURL}admin.php?$page&$path&$period&$compare"
27+
}
28+
}
29+
30+
private fun getPeriod(selection: StatsTimeRangeSelection): String {
31+
return when (selection.selectionType) {
32+
StatsTimeRangeSelection.SelectionType.TODAY -> "period=today"
33+
StatsTimeRangeSelection.SelectionType.YESTERDAY -> "period=yesterday"
34+
StatsTimeRangeSelection.SelectionType.LAST_WEEK -> "period=last_week"
35+
StatsTimeRangeSelection.SelectionType.LAST_MONTH -> "period=last_month"
36+
StatsTimeRangeSelection.SelectionType.LAST_QUARTER -> "period=last_quarter"
37+
StatsTimeRangeSelection.SelectionType.LAST_YEAR -> "period=last_year"
38+
StatsTimeRangeSelection.SelectionType.WEEK_TO_DATE -> "period=week"
39+
StatsTimeRangeSelection.SelectionType.MONTH_TO_DATE -> "period=month"
40+
StatsTimeRangeSelection.SelectionType.QUARTER_TO_DATE -> "period=quarter"
41+
StatsTimeRangeSelection.SelectionType.YEAR_TO_DATE -> "period=year"
42+
StatsTimeRangeSelection.SelectionType.CUSTOM -> {
43+
val startDate = selection.currentRange.start.formatToYYYYmmDD()
44+
val endDate = selection.currentRange.end.formatToYYYYmmDD()
45+
"period=custom&after=$startDate&before=$endDate"
46+
}
47+
}
48+
}
49+
}
50+
51+
enum class ReportCard { Revenue, Orders, Products }

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/analytics/hub/informationcard/AnalyticsHubInformationCardView.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import com.woocommerce.android.ui.analytics.hub.informationcard.AnalyticsHubInfo
1313
import com.woocommerce.android.ui.analytics.hub.informationcard.AnalyticsHubInformationViewState.NoDataState
1414
import com.woocommerce.android.widgets.SkeletonView
1515

16+
typealias SeeReportClickListener = (url: String) -> Unit
17+
1618
class AnalyticsHubInformationCardView @JvmOverloads constructor(
1719
ctx: Context,
1820
attrs: AttributeSet? = null,
@@ -21,6 +23,8 @@ class AnalyticsHubInformationCardView @JvmOverloads constructor(
2123
val binding = AnalyticsInformationCardViewBinding.inflate(LayoutInflater.from(ctx), this)
2224
private var skeletonView = SkeletonView()
2325

26+
var onSeeReportClickListener: SeeReportClickListener? = null
27+
2428
internal fun updateInformation(viewState: AnalyticsHubInformationViewState) {
2529
visibility = if (viewState is HiddenState) View.GONE else View.VISIBLE
2630
when (viewState) {
@@ -49,6 +53,14 @@ class AnalyticsHubInformationCardView @JvmOverloads constructor(
4953
binding.leftAnalyticsSection.visibility = VISIBLE
5054
binding.rightAnalyticsSection.visibility = VISIBLE
5155
binding.noDataText.visibility = GONE
56+
if (viewState.reportUrl != null) {
57+
binding.reportGroup.visibility = VISIBLE
58+
binding.reportText.setOnClickListener {
59+
onSeeReportClickListener?.let { it(viewState.reportUrl) }
60+
}
61+
} else {
62+
binding.reportGroup.visibility = GONE
63+
}
5264
visibility = VISIBLE
5365
}
5466

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/analytics/hub/informationcard/AnalyticsHubInformationViewState.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ sealed class AnalyticsHubInformationViewState {
77
data class DataViewState(
88
val title: String,
99
val leftSection: AnalyticsHubInformationSectionViewState,
10-
val rightSection: AnalyticsHubInformationSectionViewState
10+
val rightSection: AnalyticsHubInformationSectionViewState,
11+
val reportUrl: String?
1112
) : AnalyticsHubInformationViewState()
1213
}

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/analytics/hub/listcard/AnalyticsHubListCardView.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
1111
import com.google.android.material.card.MaterialCardView
1212
import com.woocommerce.android.R
1313
import com.woocommerce.android.databinding.AnalyticsListCardViewBinding
14+
import com.woocommerce.android.ui.analytics.hub.informationcard.SeeReportClickListener
1415
import com.woocommerce.android.ui.analytics.hub.listcard.AnalyticsHubListViewState.DataViewState
1516
import com.woocommerce.android.ui.analytics.hub.listcard.AnalyticsHubListViewState.LoadingViewState
1617
import com.woocommerce.android.ui.analytics.hub.listcard.AnalyticsHubListViewState.NoDataState
@@ -26,6 +27,7 @@ class AnalyticsHubListCardView @JvmOverloads constructor(
2627
) : MaterialCardView(ctx, attrs, defStyleAttr) {
2728
val binding = AnalyticsListCardViewBinding.inflate(LayoutInflater.from(ctx), this)
2829
private var skeletonView = SkeletonView()
30+
var onSeeReportClickListener: SeeReportClickListener? = null
2931

3032
internal fun updateInformation(viewState: AnalyticsHubListViewState) {
3133
when (viewState) {
@@ -77,6 +79,14 @@ class AnalyticsHubListCardView @JvmOverloads constructor(
7779
binding.analyticsListLeftHeader.visibility = VISIBLE
7880
binding.analyticsListRightHeader.visibility = VISIBLE
7981
binding.noDataText.visibility = GONE
82+
if (viewState.reportUrl != null) {
83+
binding.reportGroup.visibility = VISIBLE
84+
binding.reportText.setOnClickListener {
85+
onSeeReportClickListener?.let { it(viewState.reportUrl) }
86+
}
87+
} else {
88+
binding.reportGroup.visibility = GONE
89+
}
8090
}
8191

8292
private fun setNoDataViewState(viewState: NoDataState) {

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/analytics/hub/listcard/AnalyticsHubListViewState.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ sealed class AnalyticsHubListViewState {
1010
val delta: Int?,
1111
val listLeftHeader: String,
1212
val listRightHeader: String,
13-
val items: List<AnalyticsHubListCardItemViewState>
13+
val items: List<AnalyticsHubListCardItemViewState>,
14+
val reportUrl: String?
1415
) : AnalyticsHubListViewState() {
1516
val sign: String
1617
get() = when {

WooCommerce/src/main/kotlin/com/woocommerce/android/ui/analytics/hub/sync/AnalyticsRepository.kt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.woocommerce.android.ui.analytics.hub.sync
22

3-
import com.woocommerce.android.extensions.adminUrlOrDefault
43
import com.woocommerce.android.extensions.formatToYYYYmmDDhhmmss
54
import com.woocommerce.android.model.DeltaPercentage
65
import com.woocommerce.android.model.OrdersStat
@@ -196,10 +195,6 @@ class AnalyticsRepository @Inject constructor(
196195
)
197196
}
198197

199-
fun getRevenueAdminPanelUrl() = getAdminPanelUrl() + ANALYTICS_REVENUE_PATH
200-
fun getOrdersAdminPanelUrl() = getAdminPanelUrl() + ANALYTICS_ORDERS_PATH
201-
fun getProductsAdminPanelUrl() = getAdminPanelUrl() + ANALYTICS_PRODUCTS_PATH
202-
203198
private suspend fun getCurrentPeriodStats(
204199
rangeSelection: StatsTimeRangeSelection,
205200
fetchStrategy: FetchStrategy
@@ -321,13 +316,8 @@ class AnalyticsRepository @Inject constructor(
321316
}
322317

323318
private fun getCurrencyCode() = wooCommerceStore.getSiteSettings(selectedSite.get())?.currencyCode
324-
private fun getAdminPanelUrl() = selectedSite.getIfExists()?.adminUrlOrDefault
325319

326320
companion object {
327-
const val ANALYTICS_REVENUE_PATH = "admin.php?page=wc-admin&path=%2Fanalytics%2Frevenue"
328-
const val ANALYTICS_ORDERS_PATH = "admin.php?page=wc-admin&path=%2Fanalytics%2Forders"
329-
const val ANALYTICS_PRODUCTS_PATH = "admin.php?page=wc-admin&path=%2Fanalytics%2Fproducts"
330-
331321
const val ZERO_VALUE = 0.0
332322
const val MINUS_ONE = -1
333323
const val ONE_H_PERCENT = 100

WooCommerce/src/main/res/layout/analytics_information_card_view.xml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,47 @@
6464
app:layout_constraintWidth_default="percent"
6565
app:layout_constraintWidth_percent="0.5" />
6666

67+
<com.google.android.material.divider.MaterialDivider
68+
android:id="@+id/reportDivider"
69+
android:layout_width="match_parent"
70+
android:layout_height="1dp"
71+
app:layout_constraintTop_toBottomOf="@+id/leftAnalyticsSection"
72+
app:layout_constraintStart_toStartOf="parent"
73+
app:layout_constraintEnd_toEndOf="parent" />
74+
75+
<com.google.android.material.textview.MaterialTextView
76+
android:id="@+id/reportText"
77+
style="@style/Woo.Card.Title"
78+
android:layout_width="match_parent"
79+
android:layout_height="wrap_content"
80+
android:layout_margin="0dp"
81+
android:textSize="@dimen/text_minor_125"
82+
android:textStyle="bold"
83+
android:text="@string/see_report"
84+
tools:visibility="visible"
85+
app:layout_constraintTop_toBottomOf="@+id/reportDivider"
86+
app:layout_constraintStart_toStartOf="parent"
87+
android:padding="@dimen/major_100"
88+
android:background="?attr/selectableItemBackground"
89+
/>
90+
<ImageView
91+
android:id="@+id/reportIcon"
92+
android:layout_width="@dimen/major_200"
93+
android:layout_height="@dimen/major_200"
94+
android:src="@drawable/ic_arrow_right"
95+
app:layout_constraintTop_toTopOf="@+id/reportText"
96+
app:layout_constraintBottom_toBottomOf="@+id/reportText"
97+
app:layout_constraintEnd_toEndOf="parent"
98+
android:layout_marginEnd="@dimen/minor_100"/>
99+
100+
<androidx.constraintlayout.widget.Group
101+
android:id="@+id/reportGroup"
102+
android:layout_width="wrap_content"
103+
android:layout_height="wrap_content"
104+
app:constraint_referenced_ids="reportDivider,reportText,reportIcon"
105+
android:visibility="gone"
106+
/>
107+
67108
</androidx.constraintlayout.widget.ConstraintLayout>
68109
</merge>
69110

WooCommerce/src/main/res/layout/analytics_list_card_view.xml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,48 @@
132132
tools:itemCount="6"
133133
tools:listitem="@layout/analytics_list_card_item_view"/>
134134

135+
<com.google.android.material.divider.MaterialDivider
136+
android:id="@+id/reportDivider"
137+
android:layout_width="match_parent"
138+
android:layout_height="1dp"
139+
app:layout_constraintTop_toBottomOf="@+id/analyticsItemsList"
140+
app:layout_constraintStart_toStartOf="parent"
141+
app:layout_constraintEnd_toEndOf="parent" />
142+
143+
<com.google.android.material.textview.MaterialTextView
144+
android:id="@+id/reportText"
145+
style="@style/Woo.Card.Title"
146+
android:layout_width="match_parent"
147+
android:layout_height="wrap_content"
148+
android:layout_margin="0dp"
149+
android:textSize="@dimen/text_minor_125"
150+
android:textStyle="bold"
151+
android:text="@string/see_report"
152+
tools:visibility="visible"
153+
app:layout_constraintTop_toBottomOf="@+id/reportDivider"
154+
app:layout_constraintStart_toStartOf="parent"
155+
android:padding="@dimen/major_100"
156+
android:background="?attr/selectableItemBackground"
157+
/>
158+
<ImageView
159+
android:id="@+id/reportIcon"
160+
android:layout_width="@dimen/major_200"
161+
android:layout_height="@dimen/major_200"
162+
android:src="@drawable/ic_arrow_right"
163+
app:layout_constraintTop_toTopOf="@+id/reportText"
164+
app:layout_constraintBottom_toBottomOf="@+id/reportText"
165+
app:layout_constraintEnd_toEndOf="parent"
166+
android:layout_marginEnd="@dimen/minor_100"/>
167+
168+
<androidx.constraintlayout.widget.Group
169+
android:id="@+id/reportGroup"
170+
android:layout_width="wrap_content"
171+
android:layout_height="wrap_content"
172+
app:constraint_referenced_ids="reportDivider,reportText,reportIcon"
173+
android:visibility="gone"
174+
/>
175+
176+
135177
</androidx.constraintlayout.widget.ConstraintLayout>
136178
</merge>
137179

0 commit comments

Comments
 (0)