diff --git a/src/screens/Analytics/GlobalSearch/GlobalSearchBar.res b/src/screens/Analytics/GlobalSearch/GlobalSearchBar.res
index 45620c037..6d52ae644 100644
--- a/src/screens/Analytics/GlobalSearch/GlobalSearchBar.res
+++ b/src/screens/Analytics/GlobalSearch/GlobalSearchBar.res
@@ -1,205 +1,9 @@
-module RenderedComponent = {
- @react.component
- let make = (~ele, ~searchText) => {
- open LogicUtils
-
- listOfMatchedText(ele, searchText)
- ->Array.mapWithIndex((item, i) => {
- if (
- String.toLowerCase(item) == String.toLowerCase(searchText) && String.length(searchText) > 0
- ) {
- Int.toString}
- className="border-searched_text_border bg-yellow-searched_text font-medium text-fs-14 text-lightgray_background opacity-50">
- {item->React.string}
-
- } else {
- Int.toString}
- className="font-medium text-fs-14 text-lightgray_background opacity-50">
- {item->React.string}
-
- }
- })
- ->React.array
- }
-}
-
-module SearchBox = {
- @react.component
- let make = (~openModalOnClickHandler) => {
- let shortcutText = Window.Navigator.platform->String.includes("Mac") ? "Cmd + K" : "Ctrl + K"
- let isMobileView = MatchMedia.useMobileChecker()
-
- if isMobileView {
-
- } else {
-
-
-
-
{"Search"->React.string}
-
-
{shortcutText->React.string}
-
- }
- }
-}
-
-module EmptyResult = {
- @react.component
- let make = (~prefix, ~searchText) => {
-
-
-
-
- {`No Results for " ${searchText} "`->React.string}
-
-
-
- }
-}
-
-module OptionsWrapper = {
- open HeadlessUI
- @react.component
- let make = (~children) => {
-
-
- {_ => {children}}
-
-
- }
-}
-
-module OptionWrapper = {
- open HeadlessUI
- @react.component
- let make = (~index, ~value, ~children) => {
- let activeClasses = isActive => {
- let borderClass = isActive ? "bg-gray-100 dark:bg-jp-gray-960" : ""
- `group flex items-center w-full p-2 text-sm rounded-lg ${borderClass}`
- }
-
- Int.toString} value>
- {props => {
- activeClasses}> {children}
- }}
-
- }
-}
-
-module ModalWrapper = {
- @react.component
- let make = (~showModal, ~setShowModal, ~children) => {
-
-
- {children}
-
-
- }
-}
-
-module SearchResultsComponent = {
- open GlobalSearchTypes
- open LogicUtils
-
- @react.component
- let make = (~searchResults, ~searchText, ~setShowModal) => {
- React.useEffect(() => {
- let onKeyPress = event => {
- let keyPressed = event->ReactEvent.Keyboard.key
-
- if keyPressed == "Enter" {
- let redirectLink = `/search?query=${searchText}`
- if redirectLink->isNonEmptyString {
- setShowModal(_ => false)
- GlobalVars.appendDashboardPath(~url=redirectLink)->RescriptReactRouter.push
- }
- }
- }
- Window.addEventListener("keydown", onKeyPress)
- Some(() => Window.removeEventListener("keydown", onKeyPress))
- }, [])
-
-
- {searchResults
- ->Array.mapWithIndex((section: resultType, index) => {
- let borderClass =
- index !== searchResults->Array.length - 1 ? "border-b-1 dark:border-jp-gray-960" : ""
- getSectionHeader}
- className={`px-3 mb-3 py-1 ${borderClass}`}>
- getSectionHeader}-${index->Belt.Int.toString}`}
- className="text-lightgray_background px-2 pb-1 flex justify-between">
-
- {section.section->getSectionHeader->String.toUpperCase->React.string}
-
-
- {setShowModal(_ => false)}}
- textStyleClass="text-xs"
- searchText
- />
-
-
- {section.results
- ->Array.mapWithIndex((item, i) => {
- let elementsArray = item.texts
-
-
- {elementsArray
- ->Array.mapWithIndex(
- (item, index) => {
- let elementValue = item->JSON.Decode.string->Option.getOr("")
- isNonEmptyString} key={index->Int.toString}>
-
- = 0 && index < elementsArray->Array.length - 1}>
-
- {">"->React.string}
-
-
-
- },
- )
- ->React.array}
-
- })
- ->React.array}
-
- })
- ->React.array}
-
- }
-}
-
@react.component
let make = () => {
open GlobalSearchTypes
open GlobalSearchBarUtils
- open HeadlessUI
open LogicUtils
+ open GlobalSearchBarHelper
let getURL = APIUtils.useGetURL()
let prefix = useUrlPrefix()
@@ -208,17 +12,22 @@ let make = () => {
let (state, setState) = React.useState(_ => Idle)
let (showModal, setShowModal) = React.useState(_ => false)
let (searchText, setSearchText) = React.useState(_ => "")
+ let (activeFilter, setActiveFilter) = React.useState(_ => "")
+ let (localSearchText, setLocalSearchText) = React.useState(_ => "")
+ let (selectedOption, setSelectedOption) = React.useState(_ => ""->getDefaultOption)
+ let (allOptions, setAllOptions) = React.useState(_ => [])
+ let (categorieSuggestionResponse, setCategorieSuggestionResponse) = React.useState(_ =>
+ Dict.make()->JSON.Encode.object
+ )
let (searchResults, setSearchResults) = React.useState(_ => [])
let merchentDetails = HSwitchUtils.useMerchantDetailsValue()
let isReconEnabled = merchentDetails.recon_status === Active
let hswitchTabs = SidebarValues.useGetSidebarValues(~isReconEnabled)
- let searchText = searchText->String.trim
let loader = LottieFiles.useLottieJson("loader-circle.json")
let {globalSearch} = HyperswitchAtom.featureFlagAtom->Recoil.useRecoilValueFromAtom
let {userHasAccess} = GroupACLHooks.useUserGroupACLHook()
let isShowRemoteResults = globalSearch && userHasAccess(~groupAccess=OperationsView) === Access
let mixpanelEvent = MixpanelHook.useSendEvent()
- let {userInfo: {merchantId}} = React.useContext(UserInfoProvider.defaultContext)
let redirectOnSelect = element => {
mixpanelEvent(~eventName="global_search_redirect")
@@ -229,13 +38,47 @@ let make = () => {
}
}
+ React.useEffect(() => {
+ let onKeyPress = event => {
+ let keyPressed = event->ReactEvent.Keyboard.key
+
+ if keyPressed == "Enter" {
+ selectedOption->redirectOnSelect
+ }
+ }
+ Window.addEventListener("keydown", onKeyPress)
+ Some(() => Window.removeEventListener("keydown", onKeyPress))
+ }, [])
+
+ let getCategoryOptions = async () => {
+ setState(_ => Loading)
+ try {
+ let paymentsUrl = getURL(
+ ~entityName=ANALYTICS_FILTERS,
+ ~methodType=Post,
+ ~id=Some("payments"),
+ )
+
+ let paymentsResponse = await fetchDetails(
+ paymentsUrl,
+ paymentsGroupByNames->getFilterBody,
+ Post,
+ )
+ setCategorieSuggestionResponse(_ => paymentsResponse)
+
+ setState(_ => Idle)
+ } catch {
+ | _ => setState(_ => Idle)
+ }
+ }
+
let getSearchResults = async results => {
try {
let url = getURL(~entityName=GLOBAL_SEARCH, ~methodType=Post)
- let body = generateSearchBody(~searchText, ~merchant_id={merchantId})
+ let body = searchText->generateQuery
- let response = await fetchDetails(url, body, Post)
+ let response = await fetchDetails(url, body->JSON.Encode.object, Post)
let local_results = []
results->Array.forEach((item: resultType) => {
@@ -258,7 +101,6 @@ let make = () => {
if results->Array.length > 0 {
let defaultItem = searchText->getDefaultResult
-
let arr = [defaultItem]->Array.concat(results)
setSearchResults(_ => arr)
@@ -267,14 +109,21 @@ let make = () => {
}
setState(_ => Loaded)
} catch {
- | _ => setState(_ => Failed)
+ | _ => setState(_ => Loaded)
}
}
+ React.useEffect(() => {
+ let allOptions = searchResults->getAllOptions
+ setAllOptions(_ => allOptions)
+ setSelectedOption(_ => searchText->getDefaultOption)
+ None
+ }, [searchResults])
+
React.useEffect(_ => {
let results = []
- if searchText->String.length > 0 {
+ if searchText->String.length > 0 && activeFilter->LogicUtils.isEmptyString {
setState(_ => Loading)
let localResults: resultType = searchText->getLocalMatchedResults(hswitchTabs)
@@ -287,7 +136,6 @@ let make = () => {
} else {
if results->Array.length > 0 {
let defaultItem = searchText->getDefaultResult
-
let arr = [defaultItem]->Array.concat(results)
setSearchResults(_ => arr)
@@ -306,10 +154,14 @@ let make = () => {
React.useEffect(_ => {
setSearchText(_ => "")
+ setLocalSearchText(_ => "")
+ setActiveFilter(_ => "")
None
}, [showModal])
React.useEffect(() => {
+ getCategoryOptions()->ignore
+
let onKeyPress = event => {
let metaKey = event->ReactEvent.Keyboard.metaKey
let keyPressed = event->ReactEvent.Keyboard.key
@@ -331,12 +183,19 @@ let make = () => {
setShowModal(_ => true)
}
- let borderClass = searchText->String.length > 0 ? "border-b dark:border-jp-gray-960" : ""
-
let setGlobalSearchText = ReactDebounce.useDebounced(value => {
setSearchText(_ => value)
}, ~wait=500)
+ React.useEffect(() => {
+ setGlobalSearchText(localSearchText)
+ None
+ }, [localSearchText])
+
+ let setFilterText = ReactDebounce.useDebounced(value => {
+ setActiveFilter(_ => value)
+ }, ~wait=500)
+
let leftIcon = switch state {
| Loading =>
@@ -350,58 +209,42 @@ let make = () => {
}
- let modalSearchBox =
-
-
- {leftIcon}
-
{
- setGlobalSearchText(event["target"]["value"])
- }}
- />
- {
- setShowModal(_ => false)
- }}>
- {"Esc"->React.string}
-
-
-
-
-
- {
- element->redirectOnSelect
- }}>
- {_ => {
- <>
- {modalSearchBox}
- {switch state {
- | Loading =>
-
-
-
- | _ =>
- if searchText->isNonEmptyString && searchResults->Array.length === 0 {
-
- } else {
-
- }
- }}
- >
+
+
+ {switch getViewType(~state, ~searchResults) {
+ | Load =>
+
+
+
+ | Results =>
+
+ | FiltersSugsestions =>
+
+ | EmptyResult =>
}}
-
+
diff --git a/src/screens/Analytics/GlobalSearch/GlobalSearchBarHelper.res b/src/screens/Analytics/GlobalSearch/GlobalSearchBarHelper.res
new file mode 100644
index 000000000..f71f585a7
--- /dev/null
+++ b/src/screens/Analytics/GlobalSearch/GlobalSearchBarHelper.res
@@ -0,0 +1,474 @@
+open LogicUtils
+open GlobalSearchTypes
+module RenderedComponent = {
+ @react.component
+ let make = (~ele, ~searchText) => {
+ listOfMatchedText(ele, searchText)
+ ->Array.mapWithIndex((item, i) => {
+ if (
+ String.toLowerCase(item) == String.toLowerCase(searchText) && String.length(searchText) > 0
+ ) {
+ Int.toString}
+ className="border-searched_text_border bg-yellow-searched_text font-medium text-fs-14 text-lightgray_background opacity-50">
+ {item->React.string}
+
+ } else {
+ Int.toString}
+ className="font-medium text-fs-14 text-lightgray_background opacity-50">
+ {item->React.string}
+
+ }
+ })
+ ->React.array
+ }
+}
+
+module SearchBox = {
+ @react.component
+ let make = (~openModalOnClickHandler) => {
+ let shortcutText = Window.Navigator.platform->String.includes("Mac") ? "Cmd + K" : "Ctrl + K"
+ let isMobileView = MatchMedia.useMobileChecker()
+
+ if isMobileView {
+
+ } else {
+
+
+
+
{"Search"->React.string}
+
+
{shortcutText->React.string}
+
+ }
+ }
+}
+
+module EmptyResult = {
+ open FramerMotion.Motion
+ @react.component
+ let make = (~prefix, ~searchText) => {
+
+
+
+
+ {`No Results for " ${searchText} "`->React.string}
+
+
+
+ }
+}
+
+module OptionWrapper = {
+ @react.component
+ let make = (~index, ~value, ~children, ~selectedOption, ~redirectOnSelect) => {
+ let activeClass = value == selectedOption ? "bg-gray-100 rounded-lg p-2 group items-center" : ""
+ value->redirectOnSelect}
+ className={`flex ${activeClass} flex-row truncate hover:bg-gray-100 cursor-pointer hover:rounded-lg p-2 group items-center`}
+ key={index->Int.toString}>
+ {children}
+
+ }
+}
+
+module ModalWrapper = {
+ open FramerMotion.Motion
+ @react.component
+ let make = (~showModal, ~setShowModal, ~children) => {
+
+
+ {children}
+
+
+ }
+}
+
+module ShowMoreLink = {
+ @react.component
+ let make = (
+ ~section: resultType,
+ ~cleanUpFunction=() => {()},
+ ~textStyleClass="",
+ ~searchText,
+ ) => {
+ 10}>
+ {
+ let totalCount = section.total_results
+ let suffix = totalCount > 1 ? "s" : ""
+ let linkText = `View ${totalCount->Int.toString} result${suffix}`
+
+ switch section.section {
+ | SessionizerPaymentAttempts
+ | SessionizerPaymentIntents
+ | SessionizerPaymentRefunds
+ | SessionizerPaymentDisputes
+ | PaymentAttempts
+ | PaymentIntents
+ | Refunds
+ | Disputes =>
+ {
+ let link = switch section.section {
+ | PaymentAttempts => `payment-attempts?query=${searchText}&domain=payment_attempts`
+ | SessionizerPaymentAttempts =>
+ `payment-attempts?query=${searchText}&domain=sessionizer_payment_attempts`
+ | PaymentIntents => `payment-intents?query=${searchText}&domain=payment_intents`
+ | SessionizerPaymentIntents =>
+ `payment-intents?query=${searchText}&domain=sessionizer_payment_intents`
+ | Refunds => `refunds-global?query=${searchText}&domain=refunds`
+ | SessionizerPaymentRefunds =>
+ `refunds-global?query=${searchText}&domain=sessionizer_refunds`
+ | Disputes => `dispute-global?query=${searchText}&domain=disputes`
+ | SessionizerPaymentDisputes =>
+ `dispute-global?query=${searchText}&domain=sessionizer_disputes`
+ | Local
+ | Others
+ | Default => ""
+ }
+ GlobalVars.appendDashboardPath(~url=link)->RescriptReactRouter.push
+ cleanUpFunction()
+ }}
+ className={`font-medium cursor-pointer underline underline-offset-2 opacity-50 ${textStyleClass}`}>
+ {linkText->React.string}
+
+ | Local
+ | Default
+ | Others => React.null
+ }
+ }
+
+ }
+}
+
+module SearchResultsComponent = {
+ open FramerMotion.Motion
+ @react.component
+ let make = (~searchResults, ~searchText, ~setShowModal, ~selectedOption, ~redirectOnSelect) => {
+ let borderClass = searchResults->Array.length > 0 ? "border-t dark:border-jp-gray-960" : ""
+
+
+ {searchResults
+ ->Array.mapWithIndex((section: resultType, index) => {
+
getSectionHeader} ${Int.toString(index)}`}
+ className={`px-3 mb-3 py-1`}>
+
getSectionHeader}-${index->Belt.Int.toString}`}
+ className="text-lightgray_background px-2 pb-1 flex justify-between ">
+
+ {section.section->getSectionHeader->String.toUpperCase->React.string}
+
+
{setShowModal(_ => false)}}
+ textStyleClass="text-xs"
+ searchText
+ />
+
+ {section.results
+ ->Array.mapWithIndex((item, i) => {
+ let elementsArray = item.texts
+
+ {elementsArray
+ ->Array.mapWithIndex(
+ (item, index) => {
+ let elementValue = item->JSON.Decode.string->Option.getOr("")
+ isNonEmptyString} key={index->Int.toString}>
+
+ = 0 && index < elementsArray->Array.length - 1}>
+
+ {">"->React.string}
+
+
+
+ },
+ )
+ ->React.array}
+
+ })
+ ->React.array}
+
+ })
+ ->React.array}
+
+ }
+}
+
+let sidebarScrollbarCss = `
+ @supports (-webkit-appearance: none){
+ .sidebar-scrollbar {
+ scrollbar-width: auto;
+ scrollbar-color: #8a8c8f;
+ }
+
+ .sidebar-scrollbar::-webkit-scrollbar {
+ display: block;
+ overflow: scroll;
+ height: 4px;
+ width: 5px;
+ }
+
+ .sidebar-scrollbar::-webkit-scrollbar-thumb {
+ background-color: #8a8c8f;
+ border-radius: 3px;
+ }
+
+ .sidebar-scrollbar::-webkit-scrollbar-track {
+ display: none;
+ }
+}
+ `
+
+module FilterResultsComponent = {
+ open GlobalSearchBarUtils
+ open FramerMotion.Motion
+ @react.component
+ let make = (
+ ~categorySuggestions: array,
+ ~activeFilter,
+ ~setActiveFilter,
+ ~searchText,
+ ~setLocalSearchText,
+ ) => {
+ let filterKey = activeFilter->String.split(":")->getValueFromArray(0, "")
+
+ let filters = categorySuggestions->Array.filter(category => {
+ if !(activeFilter->isEmptyString) {
+ if searchText->String.charAt(searchText->String.length - 1) == ":" {
+ `${category.categoryType->getcategoryFromVariant}:` == `${filterKey}:`
+ } else {
+ category.categoryType
+ ->getcategoryFromVariant
+ ->String.includes(filterKey)
+ }
+ } else {
+ true
+ }
+ })
+
+ let checkFilterKey = list => {
+ switch list->Array.get(0) {
+ | Some(value) =>
+ value.categoryType->getcategoryFromVariant === filterKey && value.options->Array.length > 0
+ | _ => false
+ }
+ }
+
+ Array.length > 0}>
+
+
+ {"Suggested Filters"->String.toUpperCase->React.string}
+
+
+
Array.length === 1 && filters->checkFilterKey}>
+
+
+ {switch filters->Array.get(0) {
+ | Some(value) =>
+ value.options
+ ->Array.map(option => {
+
{
+ let saparater =
+ searchText->String.charAt(searchText->String.length - 1) == ":" ? "" : ":"
+ setLocalSearchText(_ => `${searchText}${saparater}${option}`)
+ setActiveFilter(_ => "")
+ }}>
+
+
+ {`${value.categoryType
+ ->getcategoryFromVariant
+ ->String.toLocaleLowerCase} : ${option}`->React.string}
+
+
+
+ })
+ ->React.array
+ | _ => React.null
+ }}
+
+
+
Array.length === 1 && filters->checkFilterKey)}>
+ {filters
+ ->Array.map(category => {
+ {
+ let newFilter = category.categoryType->getcategoryFromVariant
+ let lastString = searchText->String.charAt(searchText->String.length - 1)
+ if activeFilter->isNonEmptyString && lastString !== ":" {
+ let end = searchText->String.length - activeFilter->String.length
+ let newText = searchText->String.substring(~start=0, ~end)
+ setLocalSearchText(_ => `${newText} ${newFilter}:`)
+ setActiveFilter(_ => newFilter)
+ } else if lastString !== ":" {
+ setLocalSearchText(_ => `${searchText} ${newFilter}:`)
+ setActiveFilter(_ => newFilter)
+ }
+ }}>
+
+
+ {`${category.categoryType
+ ->getcategoryFromVariant
+ ->String.toLocaleLowerCase} : `->React.string}
+
+
+
{category.placeholder->React.string}
+
+ })
+ ->React.array}
+
+
+
+
+ }
+}
+
+module ModalSearchBox = {
+ open FramerMotion.Motion
+ @react.component
+ let make = (
+ ~leftIcon,
+ ~setShowModal,
+ ~setFilterText,
+ ~localSearchText,
+ ~setLocalSearchText,
+ ~allOptions,
+ ~selectedOption,
+ ~setSelectedOption,
+ ~redirectOnSelect,
+ ) => {
+ let (errorMessage, setErrorMessage) = React.useState(_ => "")
+
+ let input: ReactFinalForm.fieldRenderPropsInput = {
+ {
+ name: "global_search",
+ onBlur: _ => (),
+ onChange: ev => {
+ let value = {ev->ReactEvent.Form.target}["value"]
+ setLocalSearchText(_ => value)
+ },
+ onFocus: _ => (),
+ value: localSearchText->JSON.Encode.string,
+ checked: false,
+ }
+ }
+
+ let handleKeyDown = e => {
+ open ReactEvent.Keyboard
+
+ let index = allOptions->Array.findIndex(item => {
+ item == selectedOption
+ })
+
+ if e->keyCode == 40 {
+ let newIndex =
+ index == allOptions->Array.length - 1 ? 0 : Int.mod(index + 1, allOptions->Array.length)
+ switch allOptions->Array.get(newIndex) {
+ | Some(val) => setSelectedOption(_ => val)
+ | _ => ()
+ }
+ } else if e->keyCode == 38 {
+ let newIndex =
+ index === 0 ? allOptions->Array.length - 1 : Int.mod(index - 1, allOptions->Array.length)
+ switch allOptions->Array.get(newIndex) {
+ | Some(val) => setSelectedOption(_ => val)
+ | _ => ()
+ }
+ } else if e->keyCode == 13 {
+ selectedOption->redirectOnSelect
+ }
+
+ if e->keyCode === 32 {
+ setFilterText("")
+ } else {
+ let values = localSearchText->String.split(" ")
+ let filter = values->getValueFromArray(values->Array.length - 1, "")
+ setFilterText(filter)
+ }
+ }
+
+ let validateForm = _values => {
+ let errors = Dict.make()
+ let lastChar = localSearchText->String.charCodeAt(localSearchText->String.length - 1)
+ if localSearchText->GlobalSearchBarUtils.validateQuery && lastChar == 32.0 {
+ setErrorMessage(_ => "Multiple free-text terms found")
+ } else if !(localSearchText->GlobalSearchBarUtils.validateQuery) {
+ setErrorMessage(_ => "")
+ }
+ errors->JSON.Encode.object
+ }
+
+
+ }
+}
diff --git a/src/screens/Analytics/GlobalSearch/GlobalSearchBarUtils.res b/src/screens/Analytics/GlobalSearch/GlobalSearchBarUtils.res
index 17ba6e384..860ebf918 100644
--- a/src/screens/Analytics/GlobalSearch/GlobalSearchBarUtils.res
+++ b/src/screens/Analytics/GlobalSearch/GlobalSearchBarUtils.res
@@ -1,57 +1,7 @@
-module ShowMoreLink = {
- open GlobalSearchTypes
- @react.component
- let make = (
- ~section: resultType,
- ~cleanUpFunction=() => {()},
- ~textStyleClass="",
- ~searchText,
- ) => {
- 10}>
- {
- let linkText = `View ${section.total_results->Int.toString} result${section.total_results > 1
- ? "s"
- : ""}`
-
- switch section.section {
- | Local
- | Default
- | Others
- | SessionizerPaymentAttempts
- | SessionizerPaymentIntents
- | SessionizerPaymentRefunds
- | SessionizerPaymentDisputes => React.null
- | PaymentAttempts | PaymentIntents | Refunds | Disputes =>
- {
- let link = switch section.section {
- | PaymentAttempts => `payment-attempts?query=${searchText}`
- | PaymentIntents => `payment-intents?query=${searchText}`
- | Refunds => `refunds-global?query=${searchText}`
- | Disputes => `dispute-global?query=${searchText}`
- | Local
- | Others
- | Default
- | SessionizerPaymentAttempts
- | SessionizerPaymentIntents
- | SessionizerPaymentRefunds
- | SessionizerPaymentDisputes => ""
- }
- GlobalVars.appendDashboardPath(~url=link)->RescriptReactRouter.push
- cleanUpFunction()
- }}
- className={`font-medium cursor-pointer underline underline-offset-2 ${textStyleClass}`}>
- {linkText->React.string}
-
- }
- }
-
- }
-}
+open GlobalSearchTypes
+open LogicUtils
let matchInSearchOption = (searchOptions, searchText, name, link, ~sectionName) => {
- open GlobalSearchTypes
- open LogicUtils
searchOptions
->Option.getOr([])
->Array.filter(item => {
@@ -73,8 +23,6 @@ let matchInSearchOption = (searchOptions, searchText, name, link, ~sectionName)
}
let getLocalMatchedResults = (searchText, tabs) => {
- open LogicUtils
- open GlobalSearchTypes
open SidebarTypes
let results = tabs->Array.reduce([], (acc, item) => {
switch item {
@@ -160,9 +108,6 @@ let getLocalMatchedResults = (searchText, tabs) => {
}
let getElements = (hits, section) => {
- open GlobalSearchTypes
- open LogicUtils
-
let getAmount = (value, amountKey, currencyKey) =>
`${value->getFloat(amountKey, 0.0)->Belt.Float.toString} ${value->getString(currencyKey, "")}`
@@ -177,7 +122,7 @@ let getElements = (hits, section) => {
}
switch section {
- | PaymentAttempts =>
+ | PaymentAttempts | SessionizerPaymentAttempts =>
hits->Array.map(item => {
let (payId, amount, status, profileId) = item->getValues
@@ -186,7 +131,7 @@ let getElements = (hits, section) => {
redirect_link: `/payments/${payId}/${profileId}`->JSON.Encode.string,
}
})
- | PaymentIntents =>
+ | PaymentIntents | SessionizerPaymentIntents =>
hits->Array.map(item => {
let (payId, amount, status, profileId) = item->getValues
@@ -196,7 +141,7 @@ let getElements = (hits, section) => {
}
})
- | Refunds =>
+ | Refunds | SessionizerPaymentRefunds =>
hits->Array.map(item => {
let value = item->JSON.Decode.object->Option.getOr(Dict.make())
let refId = value->getString("refund_id", "")
@@ -209,7 +154,7 @@ let getElements = (hits, section) => {
redirect_link: `/refunds/${refId}/${profileId}`->JSON.Encode.string,
}
})
- | Disputes =>
+ | Disputes | SessionizerPaymentDisputes =>
hits->Array.map(item => {
let value = item->JSON.Decode.object->Option.getOr(Dict.make())
let disId = value->getString("dispute_id", "")
@@ -224,18 +169,35 @@ let getElements = (hits, section) => {
})
| Local
| Others
- | Default
- | SessionizerPaymentAttempts
- | SessionizerPaymentIntents
- | SessionizerPaymentRefunds
- | SessionizerPaymentDisputes => []
+ | Default => []
+ }
+}
+
+let getItemFromArray = (results, key1, key2, resultsData) => {
+ switch (resultsData->Dict.get(key1), resultsData->Dict.get(key2)) {
+ | (Some(data), Some(sessionizerData)) => {
+ let intentsCount = data.total_results
+ let sessionizerCount = sessionizerData.total_results
+ if intentsCount > 0 && sessionizerCount > 0 {
+ if intentsCount >= sessionizerCount {
+ results->Array.push(data)
+ } else {
+ results->Array.push(sessionizerData)
+ }
+ } else if intentsCount > 0 {
+ results->Array.push(data)
+ } else {
+ results->Array.push(sessionizerData)
+ }
+ }
+ | (None, Some(sessionizerData)) => results->Array.push(sessionizerData)
+ | (Some(data), None) => results->Array.push(data)
+ | _ => ()
}
}
let getRemoteResults = json => {
- open GlobalSearchTypes
- open LogicUtils
- let results = []
+ let data = Dict.make()
json
->JSON.Decode.array
@@ -245,21 +207,46 @@ let getRemoteResults = json => {
let section = value->getString("index", "")->getSectionVariant
let hints = value->getArrayFromDict("hits", [])
let total_results = value->getInt("count", hints->Array.length)
+ let key = value->getString("index", "")
if hints->Array.length > 0 {
- results->Array.push({
- section,
- results: hints->getElements(section),
- total_results,
- })
+ data->Dict.set(
+ key,
+ {
+ section,
+ results: hints->getElements(section),
+ total_results,
+ },
+ )
}
})
+ let results = []
+
+ // intents
+ let key1 = PaymentIntents->getSectionIndex
+ let key2 = SessionizerPaymentIntents->getSectionIndex
+ getItemFromArray(results, key1, key2, data)
+
+ // Attempts
+ let key1 = PaymentAttempts->getSectionIndex
+ let key2 = SessionizerPaymentAttempts->getSectionIndex
+ getItemFromArray(results, key1, key2, data)
+
+ // Refunds
+ let key1 = Refunds->getSectionIndex
+ let key2 = SessionizerPaymentRefunds->getSectionIndex
+ getItemFromArray(results, key1, key2, data)
+
+ // Disputes
+ let key1 = Disputes->getSectionIndex
+ let key2 = SessionizerPaymentDisputes->getSectionIndex
+ getItemFromArray(results, key1, key2, data)
+
results
}
let getDefaultResult = searchText => {
- open GlobalSearchTypes
{
section: Default,
results: [
@@ -272,14 +259,22 @@ let getDefaultResult = searchText => {
}
}
+let getDefaultOption = searchText => {
+ {
+ texts: ["Show all results for"->JSON.Encode.string, searchText->JSON.Encode.string],
+ redirect_link: `/search?query=${searchText}`->JSON.Encode.string,
+ }
+}
+
+let getAllOptions = (results: array) => {
+ results->Array.flatMap(item => item.results)
+}
+
let parseResponse = response => {
- open GlobalSearchTypes
- open LogicUtils
response
->getArrayFromJson([])
->Array.map(json => {
let item = json->getDictFromJsonObject
-
{
count: item->getInt("count", 0),
hits: item->getArrayFromDict("hits", []),
@@ -289,7 +284,6 @@ let parseResponse = response => {
}
let generateSearchBody = (~searchText, ~merchant_id) => {
- open LogicUtils
if !(searchText->CommonAuthUtils.isValidEmail) {
let filters =
[
@@ -300,3 +294,227 @@ let generateSearchBody = (~searchText, ~merchant_id) => {
[("query", searchText->JSON.Encode.string)]->getJsonFromArrayOfJson
}
}
+
+let categoryList = [
+ Payment_Method,
+ Payment_Method_Type,
+ Currency,
+ Connector,
+ Customer_Email,
+ Card_Network,
+ Last_4,
+ Authentication_type,
+ Status,
+ Client_source,
+ Client_version,
+]
+
+let getcategoryFromVariant = category => {
+ switch category {
+ | Payment_Method => "payment_method"
+ | Payment_Method_Type => "payment_method_type"
+ | Currency => "currency"
+ | Connector => "connector"
+ | Customer_Email => "customer_email"
+ | Card_Network => "card_network"
+ | Last_4 => "last_4"
+ | Date => "date"
+ | Authentication_type => "authentication_type"
+ | Status => "status"
+ | Client_source => "client_source"
+ | Client_version => "client_version"
+ }
+}
+
+let getDefaultPlaceholderValue = category => {
+ switch category {
+ | Payment_Method => "payment_method:card"
+ | Payment_Method_Type => "payment_method_type:credit"
+ | Currency => "currency:USD"
+ | Connector => "connector:stripe"
+ | Customer_Email => "customer_email:abc@abc.com"
+ | Card_Network => "card_network:visa"
+ | Last_4 => "last_4:2326"
+ | Date => "date:today"
+ | Authentication_type => "authentication_type:no_three_ds"
+ | Status => "status:charged"
+ | Client_source => "client_source:Payment"
+ | Client_version => "client_version:0.55.0"
+ }
+}
+
+let getCategoryVariantFromString = category => {
+ switch category {
+ | "payment_method" => Payment_Method
+ | "payment_method_type" => Payment_Method_Type
+ | "connector" => Connector
+ | "currency" => Currency
+ | "customer_email" => Customer_Email
+ | "card_network" => Card_Network
+ | "last_4" => Last_4
+ | "authentication_type" => Authentication_type
+ | "status" => Status
+ | "client_source" => Client_source
+ | "client_version" => Client_version
+ | "date" | _ => Date
+ }
+}
+
+let generatePlaceHolderValue = (category, options) => {
+ switch options->Array.get(0) {
+ | Some(value) => `${category->getcategoryFromVariant}:${value}`
+ | _ => category->getDefaultPlaceholderValue
+ }
+}
+
+let getCategorySuggestions = json => {
+ let suggestions = Dict.make()
+
+ json
+ ->getDictFromJsonObject
+ ->getArrayFromDict("queryData", [])
+ ->Array.forEach(item => {
+ let itemDict = item->getDictFromJsonObject
+ let key = itemDict->getString("dimension", "")
+ let value =
+ itemDict
+ ->getArrayFromDict("values", [])
+ ->Array.map(value => {
+ value->JSON.Decode.string->Option.getOr("")
+ })
+ ->Array.filter(item => item->String.length > 0)
+ if key->isNonEmptyString && value->Array.length > 0 {
+ suggestions->Dict.set(key, value)
+ }
+ })
+
+ categoryList->Array.map(category => {
+ let options = suggestions->Dict.get(category->getcategoryFromVariant)->Option.getOr([])
+
+ {
+ categoryType: category,
+ options,
+ placeholder: generatePlaceHolderValue(category, options),
+ }
+ })
+}
+
+let paymentsGroupByNames = [
+ "connector",
+ "payment_method",
+ "payment_method_type",
+ "currency",
+ "authentication_type",
+ "status",
+ "client_source",
+ "client_version",
+ "profile_id",
+ "card_network",
+ "merchant_id",
+]
+
+let refundsGroupByNames = ["currency", "refund_status", "connector", "refund_type", "profile_id"]
+let disputesGroupByNames = ["connector", "dispute_stage"]
+
+let getFilterBody = groupByNames =>
+ {
+ let defaultDate = HSwitchRemoteFilter.getDateFilteredObject(~range=360)
+ let filterBodyEntity: AnalyticsUtils.filterBodyEntity = {
+ startTime: defaultDate.start_time,
+ endTime: defaultDate.end_time,
+ groupByNames,
+ source: "BATCH",
+ }
+ AnalyticsUtils.filterBody(filterBodyEntity)
+ }->Identity.genericTypeToJson
+
+let generateFilter = (queryArray: array) => {
+ let filter = Dict.make()
+ queryArray->Array.forEach(query => {
+ let keyValuePair =
+ query
+ ->String.split(":")
+ ->Array.filter(query => {
+ query->String.trim->isNonEmptyString
+ })
+
+ let key = keyValuePair->getValueFromArray(0, "")
+ let value = keyValuePair->getValueFromArray(1, "")
+
+ switch filter->Dict.get(key) {
+ | Some(prevArr) => filter->Dict.set(key, prevArr->Array.concat([value]))
+ | _ => filter->Dict.set(key, [value])
+ }
+ })
+
+ filter
+ ->Dict.toArray
+ ->Array.map(item => {
+ let (key, value) = item
+ let newValue = value->Array.map(JSON.Encode.string)
+ (key, newValue->JSON.Encode.array)
+ })
+ ->Dict.fromArray
+}
+
+let generateQuery = searchQuery => {
+ let filters = []
+ let queryText = ref("")
+
+ searchQuery
+ ->String.split(" ")
+ ->Array.filter(query => {
+ query->String.trim->isNonEmptyString
+ })
+ ->Array.forEach(query => {
+ if RegExp.test(%re("/^[^:\s]+:[^:\s]+$/"), query) {
+ filters->Array.push(query)
+ } else {
+ queryText := query
+ }
+ })
+
+ let body = {
+ let query = if filters->Array.length > 0 {
+ [("filters", filters->generateFilter->JSON.Encode.object)]
+ } else {
+ []
+ }
+
+ let query = query->Array.concat([("query", queryText.contents->JSON.Encode.string)])
+
+ query->Dict.fromArray
+ }
+
+ body
+}
+
+let validateQuery = searchQuery => {
+ let freeTextCount = ref(0)
+
+ searchQuery
+ ->String.split(" ")
+ ->Array.filter(query => {
+ query->String.trim->isNonEmptyString
+ })
+ ->Array.forEach(query => {
+ if !RegExp.test(%re("/^[^:\s]+:[^:\s]+$/"), query) {
+ freeTextCount := freeTextCount.contents + 1
+ }
+ })
+
+ freeTextCount.contents > 1
+}
+
+let getViewType = (~state, ~searchResults) => {
+ switch state {
+ | Loading => Load
+ | Loaded =>
+ if searchResults->Array.length > 0 {
+ Results
+ } else {
+ EmptyResult
+ }
+ | Idle => FiltersSugsestions
+ }
+}
diff --git a/src/screens/Analytics/GlobalSearch/GlobalSearchTypes.res b/src/screens/Analytics/GlobalSearch/GlobalSearchTypes.res
index 3657bce64..d82ad13a3 100644
--- a/src/screens/Analytics/GlobalSearch/GlobalSearchTypes.res
+++ b/src/screens/Analytics/GlobalSearch/GlobalSearchTypes.res
@@ -3,11 +3,11 @@ type section =
| PaymentIntents
| PaymentAttempts
| Refunds
+ | Disputes
| SessionizerPaymentAttempts
| SessionizerPaymentIntents
| SessionizerPaymentRefunds
| SessionizerPaymentDisputes
- | Disputes
| Others
| Default
@@ -25,16 +25,12 @@ type resultType = {
let getSectionHeader = section => {
switch section {
| Local => "Go To"
- | PaymentIntents => "Payment Intents"
- | PaymentAttempts => "Payment Attempts"
- | Refunds => "Refunds"
+ | PaymentIntents | SessionizerPaymentIntents => "Payment Intents"
+ | PaymentAttempts | SessionizerPaymentAttempts => "Payment Attempts"
+ | Refunds | SessionizerPaymentRefunds => "Refunds"
+ | Disputes | SessionizerPaymentDisputes => "Disputes"
| Others => "Others"
- | Disputes => "Disputes"
- | Default
- | SessionizerPaymentAttempts
- | SessionizerPaymentIntents
- | SessionizerPaymentRefunds
- | SessionizerPaymentDisputes => ""
+ | Default => ""
}
}
@@ -52,6 +48,20 @@ let getSectionVariant = string => {
}
}
+let getSectionIndex = string => {
+ switch string {
+ | PaymentAttempts => "payment_attempts"
+ | PaymentIntents => "payment_intents"
+ | Refunds => "refunds"
+ | Disputes => "disputes"
+ | SessionizerPaymentAttempts => "sessionizer_payment_attempts"
+ | SessionizerPaymentIntents => "sessionizer_payment_intents"
+ | SessionizerPaymentRefunds => "sessionizer_refunds"
+ | SessionizerPaymentDisputes => "sessionizer_disputes"
+ | _ => ""
+ }
+}
+
type remoteResult = {
count: int,
hits: array,
@@ -64,4 +74,30 @@ type defaultResult = {
searchText: string,
}
-type state = Loading | Loaded | Failed | Idle
+type state = Loading | Loaded | Idle
+
+type category =
+ | Payment_Method
+ | Payment_Method_Type
+ | Connector
+ | Customer_Email
+ | Card_Network
+ | Last_4
+ | Date
+ | Currency
+ | Authentication_type
+ | Status
+ | Client_source
+ | Client_version
+
+type categoryOption = {
+ categoryType: category,
+ options: array,
+ placeholder: string,
+}
+
+type viewType =
+ | Load
+ | Results
+ | FiltersSugsestions
+ | EmptyResult
diff --git a/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/Disputes/DisputeTable.res b/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/Disputes/DisputeTable.res
index 656e2e377..3512dc89d 100644
--- a/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/Disputes/DisputeTable.res
+++ b/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/Disputes/DisputeTable.res
@@ -59,6 +59,7 @@ let make = () => {
let setPageDetails = Recoil.useSetRecoilState(LoadedTable.table_pageDetails)
let (offset, setOffset) = React.useState(_ => pageDetail.offset)
let searchText = UrlUtils.useGetFilterDictFromUrl("")->LogicUtils.getString("query", "")
+ let path = UrlUtils.useGetFilterDictFromUrl("")->LogicUtils.getString("domain", "")
let clearPageDetails = () => {
let newDict = pageDetailDict->Dict.toArray->Dict.fromArray
@@ -70,12 +71,7 @@ let make = () => {
setScreenState(_ => PageLoaderWrapper.Loading)
try {
- let (data, total) = await fetchTableData(
- ~updateDetails,
- ~offset,
- ~query={searchText},
- ~path=domain,
- )
+ let (data, total) = await fetchTableData(~updateDetails, ~offset, ~query={searchText}, ~path)
let arr = Array.make(~length=offset, Dict.make())
if total <= offset {
diff --git a/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/PaymentAttempt/PaymentAttemptTable.res b/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/PaymentAttempt/PaymentAttemptTable.res
index 317c04193..7d61f46ac 100644
--- a/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/PaymentAttempt/PaymentAttemptTable.res
+++ b/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/PaymentAttempt/PaymentAttemptTable.res
@@ -59,6 +59,7 @@ let make = () => {
let pageDetail = pageDetailDict->Dict.get(domain)->Option.getOr(defaultValue)
let (offset, setOffset) = React.useState(_ => pageDetail.offset)
let searchText = UrlUtils.useGetFilterDictFromUrl("")->LogicUtils.getString("query", "")
+ let path = UrlUtils.useGetFilterDictFromUrl("")->LogicUtils.getString("domain", "")
let clearPageDetails = () => {
let newDict = pageDetailDict->Dict.toArray->Dict.fromArray
@@ -70,12 +71,7 @@ let make = () => {
setScreenState(_ => PageLoaderWrapper.Loading)
try {
- let (data, total) = await fetchTableData(
- ~updateDetails,
- ~offset,
- ~query={searchText},
- ~path=domain,
- )
+ let (data, total) = await fetchTableData(~updateDetails, ~offset, ~query={searchText}, ~path)
let arr = Array.make(~length=offset, Dict.make())
if total <= offset {
diff --git a/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/PaymentIntent/PaymentIntentTable.res b/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/PaymentIntent/PaymentIntentTable.res
index 48d3daf20..ce633c479 100644
--- a/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/PaymentIntent/PaymentIntentTable.res
+++ b/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/PaymentIntent/PaymentIntentTable.res
@@ -59,6 +59,7 @@ let make = () => {
let pageDetail = pageDetailDict->Dict.get(domain)->Option.getOr(defaultValue)
let (offset, setOffset) = React.useState(_ => pageDetail.offset)
let searchText = UrlUtils.useGetFilterDictFromUrl("")->LogicUtils.getString("query", "")
+ let path = UrlUtils.useGetFilterDictFromUrl("")->LogicUtils.getString("domain", "")
let clearPageDetails = () => {
let newDict = pageDetailDict->Dict.toArray->Dict.fromArray
@@ -70,12 +71,7 @@ let make = () => {
setScreenState(_ => PageLoaderWrapper.Loading)
try {
- let (data, total) = await fetchTableData(
- ~updateDetails,
- ~offset,
- ~query={searchText},
- ~path=domain,
- )
+ let (data, total) = await fetchTableData(~updateDetails, ~offset, ~query={searchText}, ~path)
let arr = Array.make(~length=offset, Dict.make())
if total <= offset {
diff --git a/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/Refunds/RefundsTable.res b/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/Refunds/RefundsTable.res
index fdfd78a95..8aba6af61 100644
--- a/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/Refunds/RefundsTable.res
+++ b/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/Refunds/RefundsTable.res
@@ -59,6 +59,7 @@ let make = () => {
let setPageDetails = Recoil.useSetRecoilState(LoadedTable.table_pageDetails)
let (offset, setOffset) = React.useState(_ => pageDetail.offset)
let searchText = UrlUtils.useGetFilterDictFromUrl("")->LogicUtils.getString("query", "")
+ let path = UrlUtils.useGetFilterDictFromUrl("")->LogicUtils.getString("domain", "")
let clearPageDetails = () => {
let newDict = pageDetailDict->Dict.toArray->Dict.fromArray
@@ -70,12 +71,7 @@ let make = () => {
setScreenState(_ => PageLoaderWrapper.Loading)
try {
- let (data, total) = await fetchTableData(
- ~updateDetails,
- ~offset,
- ~query={searchText},
- ~path=domain,
- )
+ let (data, total) = await fetchTableData(~updateDetails, ~offset, ~query={searchText}, ~path)
let arr = Array.make(~length=offset, Dict.make())
if total <= offset {
diff --git a/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/ResultsTableUtils.res b/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/ResultsTableUtils.res
index f0271bdaf..4db654b32 100644
--- a/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/ResultsTableUtils.res
+++ b/src/screens/Analytics/GlobalSearchResults/GlobalSearchTables/ResultsTableUtils.res
@@ -2,8 +2,6 @@ let tableBorderClass = "border-collapse border border-jp-gray-940 border-solid b
let useGetData = () => {
open LogicUtils
- let body = Dict.make()
- let {userInfo: {merchantId}} = React.useContext(UserInfoProvider.defaultContext)
let getURL = APIUtils.useGetURL()
async (
~updateDetails: (
@@ -18,17 +16,9 @@ let useGetData = () => {
~query,
~path,
) => {
+ let body = query->GlobalSearchBarUtils.generateQuery
body->Dict.set("offset", offset->Int.toFloat->JSON.Encode.float)
body->Dict.set("count", 10->Int.toFloat->JSON.Encode.float)
- body->Dict.set("query", query->JSON.Encode.string)
-
- if !(query->CommonAuthUtils.isValidEmail) {
- let filters = [("customer_email", [query->JSON.Encode.string]->JSON.Encode.array)]
- body->Dict.set("filters", filters->getJsonFromArrayOfJson)
- body->Dict.set("query", merchantId->JSON.Encode.string)
- } else {
- body->Dict.set("query", query->JSON.Encode.string)
- }
try {
let url = getURL(~entityName=GLOBAL_SEARCH, ~methodType=Post, ~id=Some(path))
diff --git a/src/screens/Analytics/GlobalSearchResults/SearchResultsPage.res b/src/screens/Analytics/GlobalSearchResults/SearchResultsPage.res
index 49007092a..7b57545e0 100644
--- a/src/screens/Analytics/GlobalSearchResults/SearchResultsPage.res
+++ b/src/screens/Analytics/GlobalSearchResults/SearchResultsPage.res
@@ -40,16 +40,13 @@ module RenderSearchResultBody = {
})
->React.array
- | PaymentIntents =>
- | PaymentAttempts =>
- | Refunds =>
- | Disputes =>
+ | PaymentIntents | SessionizerPaymentIntents =>
+
+ | PaymentAttempts | SessionizerPaymentAttempts =>
+
+ | Refunds | SessionizerPaymentRefunds =>
+ | Disputes | SessionizerPaymentDisputes =>
| Others | Default => "Not implemented"->React.string
- | SessionizerPaymentAttempts
- | SessionizerPaymentIntents
- | SessionizerPaymentRefunds
- | SessionizerPaymentDisputes =>
- ""->React.string
}
}
}
@@ -66,7 +63,7 @@ module SearchResultsComponent = {
{section.section->getSectionHeader->React.string}
-
@@ -97,14 +94,15 @@ let make = () => {
let query = UrlUtils.useGetFilterDictFromUrl("")->getString("query", "")
let {globalSearch} = HyperswitchAtom.featureFlagAtom->Recoil.useRecoilValueFromAtom
let {userHasAccess} = GroupACLHooks.useUserGroupACLHook()
- let {userInfo: {merchantId}} = React.useContext(UserInfoProvider.defaultContext)
let isShowRemoteResults = globalSearch && userHasAccess(~groupAccess=OperationsView) === Access
+ let fallBackQuery = UrlUtils.useGetFilterDictFromUrl("")->LogicUtils.getString("query", "")
let getSearchResults = async results => {
try {
let url = getURL(~entityName=GLOBAL_SEARCH, ~methodType=Post)
- let body = generateSearchBody(~searchText={query}, ~merchant_id={merchantId})
- let response = await fetchDetails(url, body, Post)
+ let query = searchText->isNonEmptyString ? searchText : fallBackQuery
+ let body = query->generateQuery
+ let response = await fetchDetails(url, body->JSON.Encode.object, Post)
let local_results = []
results->Array.forEach((item: resultType) => {
@@ -129,7 +127,7 @@ let make = () => {
setState(_ => Loaded)
} catch {
- | _ => setState(_ => Failed)
+ | _ => setState(_ => Loaded)
}
}
@@ -165,7 +163,7 @@ let make = () => {
}
None
- }, (query, url.search))
+ }, [query, url.search])
@@ -176,7 +174,7 @@ let make = () => {
| _ =>
if searchResults->Array.length === 0 {
-
+
} else {
}
diff --git a/src/screens/Analytics/GlobalSearchResults/SearchResultsPageUtils.res b/src/screens/Analytics/GlobalSearchResults/SearchResultsPageUtils.res
index dee7b46be..3c4bcbf65 100644
--- a/src/screens/Analytics/GlobalSearchResults/SearchResultsPageUtils.res
+++ b/src/screens/Analytics/GlobalSearchResults/SearchResultsPageUtils.res
@@ -10,6 +10,8 @@ let getSearchresults = (result: GlobalSearchTypes.defaultResult) => {
})
}
+ let data = Dict.make()
+
result.remote_results->Array.forEach(value => {
let remoteResults = value.hits->Array.map(item => {
{
@@ -19,13 +21,37 @@ let getSearchresults = (result: GlobalSearchTypes.defaultResult) => {
})
if remoteResults->Array.length > 0 {
- results->Array.push({
- section: value.index->getSectionVariant,
- results: remoteResults,
- total_results: value.count,
- })
+ data->Dict.set(
+ value.index,
+ {
+ section: value.index->getSectionVariant,
+ results: remoteResults,
+ total_results: value.count,
+ },
+ )
}
})
+ open GlobalSearchBarUtils
+ // intents
+ let key1 = PaymentIntents->getSectionIndex
+ let key2 = SessionizerPaymentIntents->getSectionIndex
+ getItemFromArray(results, key1, key2, data)
+
+ // Attempts
+ let key1 = PaymentAttempts->getSectionIndex
+ let key2 = SessionizerPaymentAttempts->getSectionIndex
+ getItemFromArray(results, key1, key2, data)
+
+ // Refunds
+ let key1 = Refunds->getSectionIndex
+ let key2 = SessionizerPaymentRefunds->getSectionIndex
+ getItemFromArray(results, key1, key2, data)
+
+ // Disputes
+ let key1 = Disputes->getSectionIndex
+ let key2 = SessionizerPaymentDisputes->getSectionIndex
+ getItemFromArray(results, key1, key2, data)
+
(results, result.searchText)
}