Skip to content

Commit

Permalink
Merge branch 'main' into package-json-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
PritishBudhiraja authored Oct 28, 2024
2 parents 1be7930 + e166495 commit ab3d315
Show file tree
Hide file tree
Showing 20 changed files with 389 additions and 60 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [conven

- - -

## 2024.10.25.0

### Bug Fixes

- Auto retry bug ([#1639](https://github.com/juspay/hyperswitch-control-center/pull/1639)) ([`46f4de6`](https://github.com/juspay/hyperswitch-control-center/commit/46f4de64f0c68e587a62c876b56e94a5e25ec26d))
- Merchant account credentials not shown in profile view ([#1626](https://github.com/juspay/hyperswitch-control-center/pull/1626)) ([`9108801`](https://github.com/juspay/hyperswitch-control-center/commit/9108801555d2e3e03908dbe33f4a52ce9c0503a3))

### Miscellaneous Tasks

- TwoFa restriction after multiple failed attempts before login ([#1594](https://github.com/juspay/hyperswitch-control-center/pull/1594)) ([`9ff488b`](https://github.com/juspay/hyperswitch-control-center/commit/9ff488b8edc99af45fc8f77ab1f56e6cef34a838))
- Add merchant specific config ([#1643](https://github.com/juspay/hyperswitch-control-center/pull/1643)) ([`aac4ada`](https://github.com/juspay/hyperswitch-control-center/commit/aac4adabf17e96ef7d02fe91048fca8b668030a8))

**Full Changelog:** [`2024.10.24.0...2024.10.25.0`](https://github.com/juspay/hyperswitch-control-center/compare/2024.10.24.0...2024.10.25.0)

- - -

## 2024.10.24.0

### Testing
Expand Down
6 changes: 5 additions & 1 deletion src/screens/NewAnalytics/NewAnalyticsContainerUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ let getPageFromIndex = index => {
}
}

let (startTimeFilterKey, endTimeFilterKey) = ("startTime", "endTime")
let (startTimeFilterKey, endTimeFilterKey, smartRetryKey) = (
"startTime",
"endTime",
"is_smart_retry_enabled",
)

let initialFixedFilterFields = () => {
let newArr = [
Expand Down
41 changes: 41 additions & 0 deletions src/screens/NewAnalytics/NewAnalyticsHelper.res
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,44 @@ module GraphHeader = {
</div>
}
}

module SmartRetryToggle = {
open LogicUtils
open NewAnalyticsContainerUtils
@react.component
let make = () => {
let {updateExistingKeys, filterValue, filterValueJson} = React.useContext(
FilterContext.filterContext,
)
let (isEnabled, setIsEnabled) = React.useState(_ => false)

React.useEffect(() => {
let value = filterValueJson->getString(smartRetryKey, "true")->getBoolFromString(true)
setIsEnabled(_ => value)
None
}, [filterValueJson])

let onClick = _ => {
let updatedValue = !isEnabled
let newValue = filterValue->Dict.copy
newValue->Dict.set(smartRetryKey, updatedValue->getStringFromBool)
newValue->updateExistingKeys
}

<div
className="w-full py-3 -mb-5 -mt-2 px-4 border rounded-lg bg-white flex gap-2 items-center">
<BoolInput.BaseComponent
isSelected={isEnabled}
setIsSelected={onClick}
isDisabled=false
boolCustomClass="rounded-lg !bg-blue-500"
/>
<p className="!text-base text-grey-700 ml-2">
<span className="font-semibold"> {"Include Payment Retries data: "->React.string} </span>
<span>
{"Your data will consist of all the payment retries that contributed to the success rate"->React.string}
</span>
</p>
</div>
}
}
4 changes: 4 additions & 0 deletions src/screens/NewAnalytics/NewAnalyticsTypes.res
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,7 @@ type valueType =
| Latency
| LatencyMs
| No_Type

type metricType =
| Smart_Retry
| Default
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,27 @@ open NewAnalyticsHelper
open NewPaymentAnalyticsEntity
open BarGraphTypes
open FailedPaymentsDistributionUtils

open NewPaymentAnalyticsUtils
module TableModule = {
@react.component
let make = (~data, ~className="", ~selectedTab: string) => {
open LogicUtils

let (offset, setOffset) = React.useState(_ => 0)
let {filterValueJson} = React.useContext(FilterContext.filterContext)
let isSmartRetryEnabled =
filterValueJson
->getString("is_smart_retry_enabled", "true")
->getBoolFromString(true)
->getSmartRetryMetricType
let defaultSort: Table.sortedObject = {
key: "",
order: Table.INC,
}
let tableBorderClass = "border-2 border-solid border-jp-gray-940 border-collapse border-opacity-30 dark:border-jp-gray-dark_table_border_color dark:border-opacity-30"
let visibleColumns = visibleColumns->Array.concat([selectedTab->getColumn])

let defaultCol = isSmartRetryEnbldForFailedPmtDist(isSmartRetryEnabled)
let visibleColumns = [defaultCol]->Array.concat([selectedTab->getColumn])
let tableData = getTableData(data)

<div className>
Expand Down Expand Up @@ -78,23 +88,29 @@ let make = (
let (groupBy, setGroupBy) = React.useState(_ => defaulGroupBy)
let startTimeVal = filterValueJson->getString("startTime", "")
let endTimeVal = filterValueJson->getString("endTime", "")
let isSmartRetryEnabled =
filterValueJson
->getString("is_smart_retry_enabled", "true")
->getBoolFromString(true)
->getSmartRetryMetricType

let getFailedPaymentsDistribution = async () => {
try {
setScreenState(_ => PageLoaderWrapper.Loading)
let url = getURL(
~entityName=ANALYTICS_PAYMENTS,
~entityName=isSmartRetryEnabled->getEntityForSmartRetry,
~methodType=Post,
~id=Some((entity.domain: domain :> string)),
)
let metrics = isSmartRetryEnabled->getMetricsForSmartRetry

let body = NewAnalyticsUtils.requestBody(
~dimensions=[],
~startTime=startTimeVal,
~endTime=endTimeVal,
~delta=entity.requestBodyConfig.delta,
~filters=entity.requestBodyConfig.filters,
~metrics=entity.requestBodyConfig.metrics,
~metrics,
~groupByNames=[groupBy.value]->Some,
~customFilter=entity.requestBodyConfig.customFilter,
~applyFilterFor=entity.requestBodyConfig.applyFilterFor,
Expand Down Expand Up @@ -123,7 +139,7 @@ let make = (
getFailedPaymentsDistribution()->ignore
}
None
}, [startTimeVal, endTimeVal, groupBy.value])
}, [startTimeVal, endTimeVal, groupBy.value, (isSmartRetryEnabled :> string)])

<div>
<ModuleHeader title={entity.title} />
Expand All @@ -138,7 +154,7 @@ let make = (
entity={chartEntity}
object={chartEntity.getObjects(
~data=failedPaymentsDistribution,
~xKey=Payments_Failure_Rate_Distribution->getStringFromVariant,
~xKey=Payments_Failure_Rate_Distribution->getKeyForModule(~isSmartRetryEnabled),
~yKey=groupBy.value,
)}
className="mr-3"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ let failedPaymentsDistributionMapper = (
}

open NewAnalyticsTypes
let visibleColumns = [Payments_Failure_Rate_Distribution]

let tableItemToObjMapper: Dict.t<JSON.t> => failedPaymentsDistributionObject = dict => {
{
Expand Down Expand Up @@ -153,3 +152,25 @@ let defaulGroupBy = {
label: "Connector",
value: Connector->getStringFromVariant,
}

let getKeyForModule = (field, ~isSmartRetryEnabled) => {
switch (field, isSmartRetryEnabled) {
| (Payments_Failure_Rate_Distribution, Smart_Retry) => Payments_Failure_Rate_Distribution
| (Payments_Failure_Rate_Distribution, Default) | _ =>
Payments_Failure_Rate_Distribution_Without_Smart_Retries
}->getStringFromVariant
}

let isSmartRetryEnbldForFailedPmtDist = isEnabled => {
switch isEnabled {
| Smart_Retry => Payments_Failure_Rate_Distribution
| Default => Payments_Failure_Rate_Distribution_Without_Smart_Retries
}
}

let getMetricsForSmartRetry = isEnabled => {
switch isEnabled {
| Smart_Retry => [#payments_distribution]
| Default => [#sessionized_payments_distribution]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ let make = () => {
open NewPaymentAnalyticsEntity

<div className="flex flex-col gap-14 mt-5 pt-7">
<NewAnalyticsHelper.SmartRetryToggle />
<NewPaymentsOverviewSection entity={overviewSectionEntity} />
<PaymentsLifeCycle
entity={paymentsLifeCycleEntity} chartEntity={paymentsLifeCycleChartEntity}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ let successfulPaymentsDistributionTableEntity = {
~uri=``,
~getObjects,
~dataKey="queryData",
~defaultColumns=visibleColumns,
~defaultColumns=[],
~requiredSearchFieldsList=[],
~allColumns=visibleColumns,
~allColumns=[],
~getCell,
~getHeading,
)
Expand Down Expand Up @@ -138,9 +138,9 @@ let failedPaymentsDistributionTableEntity = {
~uri=``,
~getObjects,
~dataKey="queryData",
~defaultColumns=visibleColumns,
~defaultColumns=[],
~requiredSearchFieldsList=[],
~allColumns=visibleColumns,
~allColumns=[],
~getCell,
~getHeading,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,20 @@ let tooltipFormatter = (~secondaryCategories, ~title, ~metricType) => {
}
)->asTooltipPointFormatter
}

let getSmartRetryMetricType = isSmartRetryEnabled => {
open NewAnalyticsTypes
switch isSmartRetryEnabled {
| true => Smart_Retry
| false => Default
}
}

let getEntityForSmartRetry = isEnabled => {
open NewAnalyticsTypes
open APIUtilsTypes
switch isEnabled {
| Smart_Retry => ANALYTICS_PAYMENTS
| Default => ANALYTICS_PAYMENTS_V2
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ let make = (
let {filterValueJson} = React.useContext(FilterContext.filterContext)
let startTimeVal = filterValueJson->getString("startTime", "")
let endTimeVal = filterValueJson->getString("endTime", "")
let isSmartRetryEnabled = filterValueJson->getString("is_smart_retry_enabled", "true")

let getPaymentLieCycleData = async () => {
try {
let url = getURL(~entityName=ANALYTICS_SANKEY, ~methodType=Post)
Expand Down Expand Up @@ -61,14 +63,29 @@ let make = (
}
None
}, (startTimeVal, endTimeVal))

let mockDelay = async () => {
if data != JSON.Encode.null->PaymentsLifeCycleUtils.paymentLifeCycleResponseMapper {
setScreenState(_ => Loading)
await HyperSwitchUtils.delay(300)
setScreenState(_ => Success)
}
}

React.useEffect(() => {
mockDelay()->ignore
None
}, [isSmartRetryEnabled])

<div>
<ModuleHeader title={entity.title} />
<Card>
<PageLoaderWrapper
screenState customLoader={<Shimmer layoutId=entity.title />} customUI={<NoData />}>
<div className="mr-3 my-10">
<SankeyGraph
entity={chartEntity} data={chartEntity.getObjects(~data, ~xKey="", ~yKey="")}
entity={chartEntity}
data={chartEntity.getObjects(~data, ~xKey=isSmartRetryEnabled, ~yKey="")}
/>
</div>
</PageLoaderWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ let paymentLifeCycleResponseMapper = (json: JSON.t) => {

let paymentsLifeCycleMapper = (
~data: paymentLifeCycle,
~xKey as _,
~xKey,
~yKey as _,
): SankeyGraphTypes.sankeyPayload => {
let success = data.normalSuccess + data.smartRetriedSuccess
let failure = data.normalFailure + data.smartRetriedFailure
let isSmartRetryEnabled =
xKey->getBoolFromString(true)->NewPaymentAnalyticsUtils.getSmartRetryMetricType
let success =
data.normalSuccess + (isSmartRetryEnabled === Smart_Retry ? data.smartRetriedSuccess : 0)
let failure =
data.normalFailure + (isSmartRetryEnabled === Smart_Retry ? data.smartRetriedFailure : 0)
let refunded = data.refunded
let pending = data.pending // Attempted Pending
let cancelled = data.cancelled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ let make = (~entity: moduleEntity) => {
let (screenState, setScreenState) = React.useState(_ => PageLoaderWrapper.Loading)
let startTimeVal = filterValueJson->getString("startTime", "")
let endTimeVal = filterValueJson->getString("endTime", "")
let metricType: metricType =
filterValueJson
->getString("is_smart_retry_enabled", "true")
->getBoolFromString(true)
->NewPaymentAnalyticsUtils.getSmartRetryMetricType

let getData = async () => {
setScreenState(_ => PageLoaderWrapper.Loading)
Expand Down Expand Up @@ -159,15 +164,29 @@ let make = (~entity: moduleEntity) => {
None
}, [startTimeVal, endTimeVal])

let mockDelay = async () => {
if data != []->JSON.Encode.array {
setScreenState(_ => Loading)
await HyperSwitchUtils.delay(300)
setScreenState(_ => Success)
}
}

React.useEffect(() => {
mockDelay()->ignore
None
}, [metricType])

<PageLoaderWrapper screenState customLoader={<Shimmer layoutId=entity.title />}>
// Need to modify
<div className="grid grid-cols-3 gap-6">
<SmartRetryCard data responseKey=Total_Smart_Retried_Amount />
<SmartRetryCard data responseKey={Total_Smart_Retried_Amount->getKeyForModule(~metricType)} />
<div className="col-span-2 grid grid-cols-2 grid-rows-2 gap-6">
<OverViewStat data responseKey=Total_Success_Rate />
<OverViewStat data responseKey=Total_Payment_Processed_Amount />
<OverViewStat data responseKey=Refund_Processed_Amount />
<OverViewStat data responseKey=Total_Dispute />
<OverViewStat data responseKey={Total_Success_Rate->getKeyForModule(~metricType)} />
<OverViewStat
data responseKey={Total_Payment_Processed_Amount->getKeyForModule(~metricType)}
/>
<OverViewStat data responseKey={Refund_Processed_Amount->getKeyForModule(~metricType)} />
<OverViewStat data responseKey={Total_Dispute->getKeyForModule(~metricType)} />
</div>
</div>
</PageLoaderWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,17 @@ let getValueFromObj = (data, index, responseKey) => {
->getDictFromJsonObject
->getFloat(responseKey, 0.0)
}

let getKeyForModule = (field, ~metricType) => {
switch (field, metricType) {
| (Total_Smart_Retried_Amount, Smart_Retry) => Total_Smart_Retried_Amount
| (Total_Payment_Processed_Amount, Smart_Retry) => Total_Payment_Processed_Amount
| (Total_Success_Rate, Smart_Retry) => Total_Success_Rate
| (Total_Smart_Retried_Amount, Default) => Total_Smart_Retried_Amount_Without_Smart_Retries
| (Total_Success_Rate, Default) => Total_Success_Rate_Without_Smart_Retries
| (Total_Payment_Processed_Amount, Default) =>
Total_Payment_Processed_Amount_Without_Smart_Retries
| (Refund_Processed_Amount, _) => Refund_Processed_Amount
| (Total_Dispute, _) | _ => Total_Dispute
}
}
Loading

0 comments on commit ab3d315

Please sign in to comment.