Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: dispute filters #1474

Merged
merged 8 commits into from
Sep 30, 2024
Merged
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
16 changes: 9 additions & 7 deletions src/container/TransactionContainer.res
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,15 @@ let make = () => {
</AccessControl>
| list{"disputes", ...remainingPath} =>
<AccessControl permission=userPermissionJson.operationsView>
<EntityScaffold
entityName="Disputes"
remainingPath
access=Access
renderList={() => <Disputes />}
renderShow={(id, key) => <ShowDisputes id profileId={key} />}
/>
<FilterContext key="disputes" index="disputes">
<EntityScaffold
entityName="Disputes"
remainingPath
access=Access
renderList={() => <Disputes />}
renderShow={(id, key) => <ShowDisputes id profileId={key} />}
/>
</FilterContext>
</AccessControl>
| list{"unauthorized"} => <UnauthorizedPage />
| _ => <NotFoundPage />
Expand Down
29 changes: 25 additions & 4 deletions src/screens/APIUtils/APIUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ let useGetURL = () => {
| _ => `payments/v2/filter`
}

| _ => ""
}
| DISPUTE_FILTERS =>
switch methodType {
| Get =>
switch transactionEntity {
| #Profile => `disputes/profile/filter`
| #Merchant
| _ => `disputes/filter`
}

| _ => ""
}
| PAYOUTS_FILTERS =>
Expand Down Expand Up @@ -184,10 +195,20 @@ let useGetURL = () => {
switch id {
| Some(dispute_id) => `disputes/${dispute_id}`
| None =>
switch transactionEntity {
| #Merchant => `disputes/list?limit=10000`
| #Profile => `disputes/profile/list?limit=10000`
| _ => `disputes/list?limit=10000`
switch queryParamerters {
| Some(queryParams) =>
switch transactionEntity {
| #Profile => `disputes/profile/list?${queryParams}&limit=10000`
| #Merchant
| _ =>
`disputes/list?${queryParams}&limit=10000`
}
| None =>
switch transactionEntity {
| #Profile => `disputes/profile/list?limit=10000`
| #Merchant
| _ => `disputes/list?limit=10000`
}
}
}
| _ => ""
Expand Down
1 change: 1 addition & 0 deletions src/screens/APIUtils/APIUtilsTypes.res
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type entityName =
| REFUNDS
| REFUND_FILTERS
| DISPUTES
| DISPUTE_FILTERS
| PAYOUTS
| PAYOUTS_FILTERS
| ANALYTICS_FILTERS
Expand Down
16 changes: 16 additions & 0 deletions src/screens/Disputes/DisputeTypes.res
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,19 @@ type disputeStatus =

type disputeStage = PreDispute | Dispute | PreArbitration | NotFound
type disputeStatusType = Landing | EvidencePresent
type filterTypes = {
connector: array<string>,
currency: array<string>,
connector_label: array<string>,
dispute_status: array<string>,
dispute_stage: array<string>,
}

type filter = [
| #connector
| #currency
| #connector_label
| #dispute_status
| #dispute_stage
| #unknown
]
114 changes: 70 additions & 44 deletions src/screens/Disputes/Disputes.res
Original file line number Diff line number Diff line change
@@ -1,28 +1,54 @@
open APIUtils
open PageLoaderWrapper
@react.component
let make = () => {
open APIUtils
open HSwitchRemoteFilter
open DisputesUtils

let getURL = useGetURL()
let {globalUIConfig: {font: {textColor}, border: {borderColor}}} = React.useContext(
ThemeProvider.themeContext,
)
let {branding} = HyperswitchAtom.featureFlagAtom->Recoil.useRecoilValueFromAtom
let (screenState, setScreenState) = React.useState(_ => Loading)
let fetchDetails = useGetMethod()
let {filterValueJson} = React.useContext(FilterContext.filterContext)
let (screenState, setScreenState) = React.useState(_ => PageLoaderWrapper.Loading)
let (disputesData, setDisputesData) = React.useState(_ => [])
let (searchText, setSearchText) = React.useState(_ => "")
let (offset, setOffset) = React.useState(_ => 0)
let fetchDetails = useGetMethod()
let (filters, setFilters) = React.useState(_ => None)

let {generateReport} = HyperswitchAtom.featureFlagAtom->Recoil.useRecoilValueFromAtom
let {updateTransactionEntity} = OMPSwitchHooks.useUserInfo()
let {userInfo: {transactionEntity}, checkUserEntity} = React.useContext(
UserInfoProvider.defaultContext,
)
let getDisputesList = async () => {
open LogicUtils
try {
setScreenState(_ => Loading)
let disputesUrl = getURL(~entityName=DISPUTES, ~methodType=Get)
if searchText->isNonEmptyString {
filterValueJson->Dict.set("dispute_id", searchText->String.trim->JSON.Encode.string)
filterValueJson->Dict.set("payment_id", searchText->String.trim->JSON.Encode.string)
}
let queryParam =
filterValueJson
->Dict.toArray
->Array.map(item => {
let (key, value) = item
let value = switch value->JSON.Classify.classify {
| String(str) => str
| Array(arr) => {
let valueString = arr->getStrArrayFromJsonArray->Array.joinWith(",")
valueString
}
| _ => ""
}
`${key}=${value}`
})
->Array.joinWith("&")
let disputesUrl = getURL(
~entityName=DISPUTES,
~methodType=Get,
~queryParamerters=Some(queryParam),
)
let response = await fetchDetails(disputesUrl)
let disputesValue = response->LogicUtils.getArrayDataFromJson(DisputesEntity.itemToObjMapper)
let disputesValue = response->getArrayDataFromJson(DisputesEntity.itemToObjMapper)
if disputesValue->Array.length > 0 {
setDisputesData(_ => disputesValue->Array.map(Nullable.make))
setScreenState(_ => Success)
Expand All @@ -40,51 +66,51 @@ let make = () => {
}
}
React.useEffect(() => {
getDisputesList()->ignore
if filters->isNonEmptyValue {
getDisputesList()->ignore
}
None
}, [])
}, (filters, searchText))

gitanjli525 marked this conversation as resolved.
Show resolved Hide resolved
let customUI =
<>
<RenderIf condition={!branding}>
<div
className={`${borderColor.primaryNormal} flex items-start text-sm rounded-md gap-2 px-4 py-3 mt-5`}>
<Icon name="info-vacent" className={`${textColor.primaryNormal} mt-1`} size=18 />
<p>
{"Missing disputes? Disputes might not be supported for your payment processor or might not yet have been integrated with hyperswitch. Please check the"->React.string}
<a
href="https://hyperswitch.io/pm-list"
target="_blank"
className={`${textColor.primaryNormal}`}>
{" feature matrix "->React.string}
</a>
{"for your processor."->React.string}
</p>
</div>
</RenderIf>
<HelperComponents.BluredTableComponent
infoText="No disputes as of now." moduleName=" " showRedirectCTA=false
/>
</>
<NoDataFound
customCssClass={"my-6"} message="There are no disputes as of now" renderType=Painting
/>

let filtersUI =
<RemoteTableFilters
setFilters
endTimeFilterKey
startTimeFilterKey
initialFilters
initialFixedFilter
setOffset
customLeftView={<SearchBarFilter
placeholder="Search disptue id" setSearchVal=setSearchText searchVal=searchText
/>}
entityName=DISPUTE_FILTERS
title="Disputes"
/>

<div>
<div className="flex justify-between items-center">
<PageUtils.PageHeading title="Disputes" subTitle="View and manage all disputes" />
<OMPSwitchHelper.OMPViews
views={OMPSwitchUtils.transactionViewList(~checkUserEntity)}
selectedEntity={transactionEntity}
onChange={updateTransactionEntity}
/>
</div>
<div className="flex w-full justify-end pb-3 gap-3">
<RenderIf condition={generateReport && disputesData->Array.length > 0}>
<GenerateReport entityName={DISPUTE_REPORT} />
</RenderIf>
<div className="flex gap-4">
<OMPSwitchHelper.OMPViews
views={OMPSwitchUtils.transactionViewList(~checkUserEntity)}
selectedEntity={transactionEntity}
onChange={updateTransactionEntity}
/>
<RenderIf condition={generateReport && disputesData->Array.length > 0}>
<GenerateReport entityName={DISPUTE_REPORT} />
</RenderIf>
</div>
</div>
<div className="flex-1"> {filtersUI} </div>
<PageLoaderWrapper screenState customUI>
<div className="flex flex-col gap-4">
<LoadedTableWithCustomColumns
title=" "
title="Disputes"
hideTitle=true
actualData=disputesData
entity={DisputesEntity.disputesEntity}
Expand Down
2 changes: 1 addition & 1 deletion src/screens/Disputes/DisputesEntity.res
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ let allColumns = [
PaymentId,
]

let useGetStatus = dispute => {
let useGetStatus = (dispute: disputes) => {
open DisputesUtils
let {globalUIConfig: {backgroundColor}} = React.useContext(ThemeProvider.themeContext)
let orderStatusLabel = dispute.dispute_status->String.toUpperCase
Expand Down
Loading
Loading