Skip to content
Open
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
3 changes: 2 additions & 1 deletion src/APIUtils/APIUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,7 @@ let useGetURL = () => {
| SDK_EVENT_LOGS => `analytics/v1/profile/sdk_event_logs`

| WEBHOOK_EVENTS => `events/profile/list`
| WEBHOOK_EVENTS_FILTERS => `events/profile/filter`
| WEBHOOK_EVENTS_ATTEMPTS =>
switch id {
| Some(id) => `events/${merchantId}/${id}/attempts`
Expand Down Expand Up @@ -1195,7 +1196,7 @@ let useGetURL = () => {
switch queryParameters {
| Some(queryParams) => `${reconBaseURL}/audit_trail?${queryParams}`
| None => `${reconBaseURL}/audit_trail`
}
}
| _ => ""
}
| #PROCESSING_ENTRY_RESOLUTIONS =>
Expand Down
1 change: 1 addition & 0 deletions src/APIUtils/APIUtilsTypes.res
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type entityName =
| DEFAULT_FALLBACK
| SDK_EVENT_LOGS
| WEBHOOK_EVENTS
| WEBHOOK_EVENTS_FILTERS
| WEBHOOK_EVENTS_ATTEMPTS
| WEBHOOKS_EVENTS_RETRY
| WEBHOOKS_EVENT_LOGS
Expand Down
76 changes: 75 additions & 1 deletion src/screens/Developer/Webhooks/Webhooks.res
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ let make = () => {
open LogicUtils
let getURL = useGetURL()
let updateDetails = useUpdateMethod()
let fetchDetails = useGetMethod()
let {userHasAccess} = GroupACLHooks.useUserGroupACLHook()
let (webhooksData, setWebhooksData) = React.useState(_ => [])
let defaultValue: LoadedTable.pageDetails = {offset: 0, resultsPerPage: 20}
Expand Down Expand Up @@ -73,6 +74,15 @@ let make = () => {
}
}

// Helper function to convert UI delivery status to backend boolean
let mapDeliveryStatusToBackend = (status: string) => {
switch status {
| "delivered" => Some(true)
| "failed" => Some(false)
| _ => None
}
}

let fetchWebhooks = async (~searchType=?) => {
try {
setScreenState(_ => PageLoaderWrapper.Loading)
Expand All @@ -88,6 +98,23 @@ let make = () => {
payload->Dict.set("offset", offset->Int.toFloat->JSON.Encode.float)
payload->Dict.set("created_after", start_time->JSON.Encode.string)
payload->Dict.set("created_before", end_time->JSON.Encode.string)

// Add optional filters if present
let eventClasses = filterValueJson->getArrayFromDict("event_classes", [])
if eventClasses->Array.length > 0 {
payload->Dict.set("event_classes", eventClasses->JSON.Encode.array)
}

let eventTypes = filterValueJson->getArrayFromDict("event_types", [])
if eventTypes->Array.length > 0 {
payload->Dict.set("event_types", eventTypes->JSON.Encode.array)
}

let deliveryStatus = filterValueJson->getString("delivery_status", "")
switch mapDeliveryStatusToBackend(deliveryStatus) {
| Some(isDelivered) => payload->Dict.set("is_delivered", isDelivered->JSON.Encode.bool)
| None => ()
}
}

let url = getURL(~entityName=V1(WEBHOOK_EVENTS), ~methodType=Post)
Expand All @@ -102,6 +129,53 @@ let make = () => {
}
}

// Fetch filter options for dropdowns
let (filterOptions, setFilterOptions) = React.useState(_ => {
eventClasses: [],
eventTypes: [],
deliveryStatusOptions: [
{"label": "Delivered", "value": "delivered"},
{"label": "Failed", "value": "failed"},
],
})

let fetchFilterOptions = async () => {
try {
let url = getURL(~entityName=V1(WEBHOOK_EVENTS_FILTERS), ~methodType=Get)
let response = await fetchDetails(url)
let responseDict = response->getDictFromJsonObject

let eventClasses =
responseDict
->getArrayFromDict("event_classes", [])
->Array.map(item => {
let str = item->JSON.Decode.string->Option.getOr("")
{"label": str, "value": str}
})

let eventTypes =
responseDict
->getArrayFromDict("event_types", [])
->Array.map(item => {
let str = item->JSON.Decode.string->Option.getOr("")
{"label": str, "value": str}
})

setFilterOptions(prev => {
...prev,
eventClasses: eventClasses,
eventTypes: eventTypes,
})
} catch {
| _ => ()
}
}

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

React.useEffect(() => {
let currentFilterState = {
let filterDict = Dict.make()
Expand Down Expand Up @@ -149,7 +223,7 @@ let make = () => {
key="0"
title="Webhooks"
defaultFilters={""->JSON.Encode.string}
fixedFilters={initialFixedFilter()}
fixedFilters={initialFixedFilter(~filterOptions)}
requiredSearchFieldsList=[]
localFilters=[]
localOptions=[]
Expand Down
58 changes: 57 additions & 1 deletion src/screens/Developer/Webhooks/WebhooksUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,14 @@ let getAllowedDateRange = {
dateObject
}

let initialFixedFilter = () => [
// Type for filter options
type filterOptions = {
eventClasses: array<dict<string>>,
eventTypes: array<dict<string>>,
deliveryStatusOptions: array<dict<string>>,
}

let initialFixedFilter = (~filterOptions: filterOptions) => [
(
{
localFilter: None,
Expand Down Expand Up @@ -112,4 +119,53 @@ let initialFixedFilter = () => [
),
}: EntityType.initialFilters<'t>
),
// Event Class filter
(
{
localFilter: None,
field: FormRenderer.makeFieldInfo(
~label="Event Class",
~name="event_classes",
~customInput=InputFields.multiSelectInput(
~options=filterOptions.eventClasses,
~showSelectionAsChips=true,
~searchable=true,
~showClearAll=true,
(),
),
),
}: EntityType.initialFilters<'t>
),
// Event Type filter
(
{
localFilter: None,
field: FormRenderer.makeFieldInfo(
~label="Event Type",
~name="event_types",
~customInput=InputFields.multiSelectInput(
~options=filterOptions.eventTypes,
~showSelectionAsChips=true,
~searchable=true,
~showClearAll=true,
(),
),
),
}: EntityType.initialFilters<'t>
),
// Delivery Status filter
(
{
localFilter: None,
field: FormRenderer.makeFieldInfo(
~label="Delivery Status",
~name="delivery_status",
~customInput=InputFields.singleSelectInput(
~options=filterOptions.deliveryStatusOptions,
~showClearSelection=true,
(),
),
),
}: EntityType.initialFilters<'t>
),
]
Loading