diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5dc051fa9..3555b2371 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,31 @@ All notable changes to this project will be documented in this file. See [conven
- - -
+## 1.26.0 (2024-01-18)
+
+### Features
+
+- Add new user ([#237](https://github.com/juspay/hyperswitch-control-center/pull/237)) ([`3749e32`](https://github.com/juspay/hyperswitch-control-center/commit/3749e3278602c2ad514079db3d6d78226cfa9391))
+- Access added for Button ([#274](https://github.com/juspay/hyperswitch-control-center/pull/274)) ([`d5ecee6`](https://github.com/juspay/hyperswitch-control-center/commit/d5ecee626d3da87f6bda8495b7539ba8660a7618))
+
+### Bug Fixes
+
+- Floating point value fix for test payment ([#270](https://github.com/juspay/hyperswitch-control-center/pull/270)) ([`038a714`](https://github.com/juspay/hyperswitch-control-center/commit/038a71492de22f1a1a51b6de9f68f010bf872268))
+
+### Refactors
+
+- Routing types and utils ([#254](https://github.com/juspay/hyperswitch-control-center/pull/254)) ([`b8b5034`](https://github.com/juspay/hyperswitch-control-center/commit/b8b5034fbae6974e34c799e6f9333e3663247f7f))
+
+### Miscellaneous Tasks
+
+- Added Access Type & Remove the Read & ReadWrite Type ([#267](https://github.com/juspay/hyperswitch-control-center/pull/267)) ([`49e3eae`](https://github.com/juspay/hyperswitch-control-center/commit/49e3eaeb9bd14a3c788649b81cf561386a5ce006))
+- Refactor invite users ([#273](https://github.com/juspay/hyperswitch-control-center/pull/273)) ([`85b07d0`](https://github.com/juspay/hyperswitch-control-center/commit/85b07d0cf058dd0842b11acb7714cd85f8d9d6c6))
+
+**Full Changelog:** [`v1.25.1...v1.26.0`](https://github.com/juspay/hyperswitch-control-center/compare/v1.25.1...v1.26.0)
+
+- - -
+
+
## 1.25.1 (2024-01-17)
### Miscellaneous Tasks
diff --git a/src/components/Button.res b/src/components/Button.res
index 59b89f0a2..dc91ab56f 100644
--- a/src/components/Button.res
+++ b/src/components/Button.res
@@ -360,6 +360,7 @@ let make = (
~customBackColor=?,
~isPhoneDropdown=false,
~showBtnTextToolTip=false,
+ ~access=AuthTypes.Access,
) => {
let parentRef = React.useRef(Js.Nullable.null)
let dummyRef = React.useRef(Js.Nullable.null)
@@ -695,110 +696,109 @@ let make = (
: ""} ${customBackColor->Belt.Option.getWithDefault(
backColor,
)} ${customRoundedClass->Belt.Option.getWithDefault(roundedClass)}`
-
- let newThemeGap = ""
-
-
-
-
+ }}
+
+
+
}
diff --git a/src/components/Button.resi b/src/components/Button.resi
index 53bb21c2f..5d9c12918 100644
--- a/src/components/Button.resi
+++ b/src/components/Button.resi
@@ -75,7 +75,7 @@ let useGetTextColor: (
) => string
@react.component
let make: (
- ~buttonFor: Js.String2.t=?,
+ ~buttonFor: string=?,
~loadingText: string=?,
~buttonState: buttonState=?,
~text: Js.String2.t=?,
@@ -101,7 +101,7 @@ let make: (
~textWeight: string=?,
~fullLength: bool=?,
~disableRipple: bool=?,
- ~customButtonStyle: Js.String2.t=?,
+ ~customButtonStyle: string=?,
~textStyleClass: string=?,
~customTextPaddingClass: string=?,
~allowButtonTextMinWidth: bool=?,
@@ -115,4 +115,5 @@ let make: (
~customBackColor: string=?,
~isPhoneDropdown: bool=?,
~showBtnTextToolTip: bool=?,
+ ~access: AuthTypes.authorization=?,
) => React.element
diff --git a/src/components/EntityScaffold.res b/src/components/EntityScaffold.res
index d9d048b33..68afbe809 100644
--- a/src/components/EntityScaffold.res
+++ b/src/components/EntityScaffold.res
@@ -1,85 +1,32 @@
-module ComingSoon = {
- @react.component
- let make = (~title) => {
-
-
{React.string(title)}
-
{React.string("Coming soon...")}
-
- }
-}
-
-module ShowPage = {
- @react.component
- let make = (~entityName, ~id) => {
-
-
- {React.string(`Show ${entityName} `)}
- {React.string(`#${id}`)}
-
-
{React.string("Coming soon...")}
-
- }
-}
-
-module UnauthorizedPage = {
- @react.component
- let make = (~entityName) => {
-
-
{React.string(entityName)}
-
{React.string("You don't have access to this module. Contact admin for access")}
-
- }
-}
-
@react.component
let make = (
~entityName="",
~remainingPath,
~isAdminAccount=false,
- ~access: AuthTypes.authorization=ReadWrite,
- ~renderList=() => ,
- ~renderNewForm=() => ,
+ ~access: AuthTypes.authorization=Access,
+ ~renderList,
+ ~renderNewForm=?,
~renderShow=?,
- ~renderOrder=?,
- ~renderEdit=_id => ,
- ~renderEditWithMultiId=(_id1, _id2) => ,
- ~renderClone=_id => ,
) => {
if access === NoAccess {
-
+
} else {
switch remainingPath {
| list{"new"} =>
switch access {
- | ReadWrite => renderNewForm()
- | _ =>
- }
- | list{id, "clone"} =>
- switch access {
- | ReadWrite => renderClone(id)
- | _ =>
+ | Access =>
+ switch renderNewForm {
+ | Some(element) => element()
+ | None => React.null
+ }
+ | NoAccess =>
}
| list{id} =>
let page = switch renderShow {
| Some(fn) => fn(id)
- | None =>
+ | None => React.null
}
page
- | list{id, "edit"} =>
- switch access {
- | ReadWrite => renderEdit(id)
- | _ =>
- }
- | list{id1, id2, "edit"} =>
- switch access {
- | ReadWrite => renderEditWithMultiId(id1, id2)
- | _ =>
- }
- | list{"order", id} =>
- switch renderOrder {
- | Some(fn) => fn(id)
- | None =>
- }
| list{} => renderList()
| _ =>
}
diff --git a/src/components/HyperSwitchAuthWrapper.res b/src/components/HyperSwitchAuthWrapper.res
index ee0d30017..9f0c21dbd 100644
--- a/src/components/HyperSwitchAuthWrapper.res
+++ b/src/components/HyperSwitchAuthWrapper.res
@@ -23,7 +23,7 @@ let make = (~children) => {
| _ =>
switch LocalStorage.getItem("login")->Js.Nullable.toOption {
| Some(token) =>
- if !(token->HSwitchUtils.isEmptyString) {
+ if !(token->LogicUtils.isEmptyString) {
setAuthStatus(LoggedIn(HyperSwitchAuthTypes.getDummyAuthInfoForToken(token)))
} else {
setAuthStatus(LoggedOut)
diff --git a/src/components/UnauthorizedPage.res b/src/components/UnauthorizedPage.res
new file mode 100644
index 000000000..55bddadc9
--- /dev/null
+++ b/src/components/UnauthorizedPage.res
@@ -0,0 +1,19 @@
+@react.component
+let make = (~message="You don't have access to this module. Contact admin for access") => {
+ let {setDashboardPageState} = React.useContext(GlobalProvider.defaultContext)
+ React.useEffect0(() => {
+ RescriptReactRouter.replace("/unauthorized")
+ None
+ })
+
+ {
+ setDashboardPageState(_ => #HOME)
+ RescriptReactRouter.replace("/home")
+ }}
+ customButtonStyle="mt-4 !p-2"
+ />
+
+}
diff --git a/src/components/form/BoolInput.res b/src/components/form/BoolInput.res
index 64ec789f0..8ada7a9aa 100644
--- a/src/components/form/BoolInput.res
+++ b/src/components/form/BoolInput.res
@@ -114,7 +114,6 @@ let make = (
~boolCustomClass="",
~addAttributeId="",
) => {
- let accessLevel = React.useContext(FormAuthContext.formAuthContext)
let boolInput = baseInput->ffInputToBoolInput
let boolValue: Js.Json.t = boolInput.value
@@ -126,14 +125,8 @@ let make = (
let setIsSelected = boolInput.onChange
isCheckBox
- ?
+ ?
:
}
diff --git a/src/components/priority-logics/PriorityLogicUtils.res b/src/components/priority-logics/PriorityLogicUtils.res
deleted file mode 100644
index e516b8d6c..000000000
--- a/src/components/priority-logics/PriorityLogicUtils.res
+++ /dev/null
@@ -1,7 +0,0 @@
-type gateway = {
- gateway_name: string,
- distribution: int,
- disableFallback: bool,
-}
-
-type formState = CreateConfig | EditConfig | ViewConfig
diff --git a/src/context/FilterContext.res b/src/context/FilterContext.res
index 355099271..03c1d5646 100644
--- a/src/context/FilterContext.res
+++ b/src/context/FilterContext.res
@@ -33,7 +33,7 @@ module Provider = {
@react.component
let make = (~index: string, ~children, ~disableSessionStorage=false) => {
open FilterUtils
- open HSwitchUtils
+ open LogicUtils
let query = React.useMemo0(() => {ref("")})
let searcParamsToDict = query.contents->parseFilterString
let (filterDict, setfilterDict) = React.useState(_ => searcParamsToDict)
diff --git a/src/context/FormAuthContext.res b/src/context/FormAuthContext.res
index e59430a3d..6d87a6061 100644
--- a/src/context/FormAuthContext.res
+++ b/src/context/FormAuthContext.res
@@ -1,3 +1,3 @@
-let formAuthContext = React.createContext(AuthTypes.ReadWrite)
+let formAuthContext = React.createContext(AuthTypes.Access)
let make = React.Context.provider(formAuthContext)
diff --git a/src/entryPoints/hyperswitch/HyperSwitchApp.res b/src/entryPoints/hyperswitch/HyperSwitchApp.res
index 210af2a7c..f8d8e2979 100644
--- a/src/entryPoints/hyperswitch/HyperSwitchApp.res
+++ b/src/entryPoints/hyperswitch/HyperSwitchApp.res
@@ -240,7 +240,7 @@ let make = () => {
}
renderShow={id => }
/>
@@ -250,7 +250,7 @@ let make = () => {
}
renderShow={id => }
/>
@@ -259,7 +259,7 @@ let make = () => {
}
renderShow={id => }
/>
@@ -268,7 +268,7 @@ let make = () => {
}
renderShow={id => }
/>
@@ -285,7 +285,7 @@ let make = () => {
}
renderShow={_ => }
/>
@@ -350,7 +350,7 @@ let make = () => {
| list{"quick-start"} => determineQuickStartPageState()
| list{"woocommerce"} => determineWooCommerce()
| list{"stripe-plus-paypal"} => determineStripePlusPayPal()
-
+ | list{"unauthorized"} =>
| _ =>
RescriptReactRouter.replace(`${hyperSwitchFEPrefix}/home`)
diff --git a/src/entryPoints/hyperswitch/SidebarValues.res b/src/entryPoints/hyperswitch/SidebarValues.res
index 3717fc222..648d74cde 100644
--- a/src/entryPoints/hyperswitch/SidebarValues.res
+++ b/src/entryPoints/hyperswitch/SidebarValues.res
@@ -54,35 +54,35 @@ let home = isHomeEnabled =>
name: "Home",
icon: "hswitch-home",
link: "/home",
- access: ReadWrite,
+ access: Access,
})
: emptyComponent
let payments = SubLevelLink({
name: "Payments",
link: `/payments`,
- access: ReadWrite,
+ access: Access,
searchOptions: [("View payment operations", "")],
})
let refunds = SubLevelLink({
name: "Refunds",
link: `/refunds`,
- access: ReadWrite,
+ access: Access,
searchOptions: [("View refund operations", "")],
})
let disputes = SubLevelLink({
name: "Disputes",
link: `/disputes`,
- access: ReadWrite,
+ access: Access,
searchOptions: [("View dispute operations", "")],
})
let customers = SubLevelLink({
name: "Customers",
link: `/customers`,
- access: ReadWrite,
+ access: Access,
searchOptions: [("View customers", "")],
})
@@ -105,7 +105,7 @@ let connectors = (isConnectorsEnabled, isLiveMode) => {
name: "Processors",
link: `/connectors`,
icon: "connectors",
- access: ReadWrite,
+ access: Access,
searchOptions: HSwitchUtils.getSearchOptionsForProcessors(
~processorList=isLiveMode
? ConnectorUtils.connectorListForLive
@@ -119,21 +119,21 @@ let connectors = (isConnectorsEnabled, isLiveMode) => {
let paymentAnalytcis = SubLevelLink({
name: "Payments",
link: `/analytics-payments`,
- access: ReadWrite,
+ access: Access,
searchOptions: [("View analytics", "")],
})
let refundAnalytics = SubLevelLink({
name: "Refunds",
link: `/analytics-refunds`,
- access: ReadWrite,
+ access: Access,
searchOptions: [("View analytics", "")],
})
let userJourneyAnalytics = SubLevelLink({
name: "User Journey",
link: `/analytics-user-journey`,
- access: ReadWrite,
+ access: Access,
iconTag: "betaTag",
searchOptions: [("View analytics", "")],
})
@@ -153,7 +153,7 @@ let analytics = (isAnalyticsEnabled, userJourneyAnalyticsFlag) =>
let routing = SubLevelLink({
name: "Routing",
link: `/routing`,
- access: ReadWrite,
+ access: Access,
searchOptions: [
("Manage default routing configuration", "/default"),
("Create new volume based routing", "/volume"),
@@ -165,14 +165,14 @@ let routing = SubLevelLink({
let threeDs = SubLevelLink({
name: "3DS Decision Manager",
link: `/3ds`,
- access: ReadWrite,
+ access: Access,
searchOptions: [("Configure 3ds", "")],
})
let surcharge = SubLevelLink({
name: "Surcharge",
link: `/surcharge`,
- access: ReadWrite,
+ access: Access,
searchOptions: [("Add Surcharge", "")],
})
@@ -189,14 +189,14 @@ let workflow = (isWorkflowEnabled, isSurchargeEnabled) =>
let userManagement = SubLevelLink({
name: "Team",
link: `/users`,
- access: ReadWrite,
+ access: Access,
searchOptions: [("View team management", "")],
})
let accountSettings = SubLevelLink({
name: "Account Settings",
link: `/account-settings`,
- access: ReadWrite,
+ access: Access,
searchOptions: [
("View profile", "/profile"),
("Change password", "/profile"),
@@ -207,14 +207,14 @@ let accountSettings = SubLevelLink({
let businessDetails = SubLevelLink({
name: "Business Details",
link: `/business-details`,
- access: ReadWrite,
+ access: Access,
searchOptions: [("Configure business details", "")],
})
let businessProfiles = SubLevelLink({
name: "Business Profiles",
link: `/business-profiles`,
- access: ReadWrite,
+ access: Access,
searchOptions: [("Configure business profiles", "")],
})
@@ -242,14 +242,14 @@ let settings = (~isSampleDataEnabled, ~isUserManagementEnabled, ~isBusinessProfi
let apiKeys = SubLevelLink({
name: "API Keys",
link: `/developer-api-keys`,
- access: ReadWrite,
+ access: Access,
searchOptions: [("View API Keys", "")],
})
let systemMetric = SubLevelLink({
name: "System Metrics",
link: `/developer-system-metrics`,
- access: ReadWrite,
+ access: Access,
iconTag: "betaTag",
searchOptions: [("View System Metrics", "")],
})
@@ -257,7 +257,7 @@ let systemMetric = SubLevelLink({
let paymentSettings = SubLevelLink({
name: "Payment Settings",
link: `/payment-settings`,
- access: ReadWrite,
+ access: Access,
searchOptions: [("View payment settings", ""), ("View webhooks", ""), ("View return url", "")],
})
@@ -282,7 +282,7 @@ let fraudAndRisk = isfraudAndRiskEnabled =>
name: "Fraud & Risk",
icon: "shield-alt",
link: `/fraud-risk-management`,
- access: isfraudAndRiskEnabled ? ReadWrite : NoAccess,
+ access: isfraudAndRiskEnabled ? Access : NoAccess,
searchOptions: [],
})
: emptyComponent
@@ -293,7 +293,7 @@ let payoutConnectors = isPayoutConnectorsEnabled =>
name: "Payout Processors",
link: `/payoutconnectors`,
icon: "connectors",
- access: ReadWrite,
+ access: Access,
searchOptions: HSwitchUtils.getSearchOptionsForProcessors(
~processorList=ConnectorUtils.payoutConnectorList,
~getNameFromString=ConnectorUtils.getConnectorNameString,
@@ -307,7 +307,7 @@ let reconTag = (recon, isReconEnabled) =>
name: "Reconcilation",
icon: isReconEnabled ? "recon" : "recon-lock",
link: `/recon`,
- access: ReadWrite,
+ access: Access,
})
: emptyComponent
diff --git a/src/screens/HyperSwitch/HSwitchUtils.res b/src/screens/HyperSwitch/HSwitchUtils.res
index deb4836e0..41963eec0 100644
--- a/src/screens/HyperSwitch/HSwitchUtils.res
+++ b/src/screens/HyperSwitch/HSwitchUtils.res
@@ -272,8 +272,6 @@ let constructOnboardingBody = (
])->Js.Json.object_
}
-let isEmptyString = str => str->String.length <= 0
-
type textVariantType =
| H1
| H2
diff --git a/src/screens/HyperSwitch/Order/Orders.res b/src/screens/HyperSwitch/Order/Orders.res
index 57adea0d9..db76eca36 100644
--- a/src/screens/HyperSwitch/Order/Orders.res
+++ b/src/screens/HyperSwitch/Order/Orders.res
@@ -2,8 +2,8 @@
let make = (~previewOnly=false) => {
open APIUtils
open HSwitchRemoteFilter
- open HSwitchUtils
open OrderUIUtils
+ open LogicUtils
let updateDetails = useUpdateMethod()
let (screenState, setScreenState) = React.useState(_ => PageLoaderWrapper.Loading)
let (orderData, setOrdersData) = React.useState(_ => [])
@@ -14,8 +14,8 @@ let make = (~previewOnly=false) => {
let connectorList =
HyperswitchAtom.connectorListAtom
->Recoil.useRecoilValueFromAtom
- ->LogicUtils.safeParse
- ->LogicUtils.getObjectArrayFromJson
+ ->safeParse
+ ->getObjectArrayFromJson
let isConfigureConnector = connectorList->Array.length > 0
let (widthClass, heightClass) = React.useMemo1(() => {
diff --git a/src/screens/HyperSwitch/Refunds/Refund.res b/src/screens/HyperSwitch/Refunds/Refund.res
index 88f575dc4..5ee0b3d02 100644
--- a/src/screens/HyperSwitch/Refunds/Refund.res
+++ b/src/screens/HyperSwitch/Refunds/Refund.res
@@ -2,7 +2,7 @@
let make = () => {
open APIUtils
open HSwitchRemoteFilter
- open HSwitchUtils
+ open LogicUtils
open RefundUtils
let updateDetails = useUpdateMethod()
let (screenState, setScreenState) = React.useState(_ => PageLoaderWrapper.Loading)
diff --git a/src/screens/HyperSwitch/Routing/AdvancedRouting/RoutingPreviewer.res b/src/screens/HyperSwitch/Routing/AdvancedRouting/RoutingPreviewer.res
index 578ca6eb4..95f691b4a 100644
--- a/src/screens/HyperSwitch/Routing/AdvancedRouting/RoutingPreviewer.res
+++ b/src/screens/HyperSwitch/Routing/AdvancedRouting/RoutingPreviewer.res
@@ -1,5 +1,4 @@
open RoutingTypes
-open RoutingUtils
module SimplePreview = {
@react.component
@@ -26,6 +25,7 @@ module SimplePreview = {
}
}
+
module GatewayView = {
@react.component
let make = (~gateways, ~connectorList=?) => {
@@ -56,126 +56,3 @@ module GatewayView = {
}
}
-module RulePreviewer = {
- @react.component
- let make = (~ruleInfo: ruleInfoType, ~isFrom3ds=false) => {
- open LogicUtils
-
-
-
- {ruleInfo.rules
- ->Array.mapWithIndex((rule, index) => {
- let headingText = `Rule ${string_of_int(index + 1)}`
- let marginStyle = index === ruleInfo.rules->Array.length - 1 ? "mt-2" : "my-2"
- let threeDsType =
- rule.routingOutput->Belt.Option.getWithDefault(defaultThreeDsObjectValue)
-
-
- {headingText->React.string}
-
-
-
- {rule.conditions
- ->RoutingUtils.filterEmptyValues
- ->Array.mapWithIndex((condition, index) => {
- let logical = logicalOperatorTypeToStringMapper(condition.logicalOperator)
- let operator = operatorTypeToStringMapper(condition.operator)
- let field = condition.field->String.length > 0 ? condition.field : ""
-
- let value = switch condition.value {
- | StringArray(arr) => arr->Array.joinWith(", ")
- | String(str) => str
- | Int(int) => int->Belt.Int.toString
- }
- let metadataKey = switch condition.metadata {
- | Some(json) => json->getDictFromJsonObject->getOptionString("key")
- | _ => None
- }
-
-
-
-
-
-
- {switch metadataKey {
- | Some(key) =>
- | None => React.null
- }}
-
-
-
- })
- ->React.array}
-
-
Array.length > 0}>
-
-
-
-
- {threeDsType.override_3ds->LogicUtils.capitalizeString->React.string}
-
-
-
-
-
-
-
- })
- ->React.array}
-
-
-
-
-
()}
- />
-
- {React.string("Default Processors")}
- {React.string(" *")}
-
-
-
- {ruleInfo.default_gateways
- ->Array.mapWithIndex((gateway, index) => {
-
-
- {React.string(string_of_int(index + 1))}
-
-
{gateway->React.string}
-
Array.length - 1}>
- ()}
- />
-
-
- })
- ->React.array}
-
-
-
-
-
- }
-}
diff --git a/src/screens/HyperSwitch/Routing/HistoryEntity.res b/src/screens/HyperSwitch/Routing/HistoryEntity.res
index e90fb16d2..47ecffdd9 100644
--- a/src/screens/HyperSwitch/Routing/HistoryEntity.res
+++ b/src/screens/HyperSwitch/Routing/HistoryEntity.res
@@ -2,7 +2,17 @@ open LogicUtils
open RoutingUtils
open RoutingTypes
-let allColumns = [Name, Type, ProfileId, ProfileName, Description, Created, LastUpdated, Status]
+let allColumns: array = [
+ Name,
+ Type,
+ ProfileId,
+ ProfileName,
+ Description,
+ Created,
+ LastUpdated,
+ Status,
+]
+
let itemToObjMapper = dict => {
{
id: getString(dict, "id", ""),
@@ -14,9 +24,17 @@ let itemToObjMapper = dict => {
created_at: getString(dict, "created_at", ""),
}
}
-let defaultColumns = [Name, ProfileId, ProfileName, Type, Description, Status]
-let getHeading = colType => {
+let defaultColumns: array = [
+ Name,
+ ProfileId,
+ ProfileName,
+ Type,
+ Description,
+ Status,
+]
+
+let getHeading: historyColType => Table.header = colType => {
switch colType {
| Name => Table.makeHeaderInfo(~key="name", ~title="Name of Control", ~showSort=true, ())
| Type => Table.makeHeaderInfo(~key="kind", ~title="Type of Control", ~showSort=true, ())
@@ -32,7 +50,7 @@ let getHeading = colType => {
}
}
let getTableCell = activeRoutingIds => {
- let getCell = (historyData, colType): Table.cell => {
+ let getCell = (historyData, colType: historyColType): Table.cell => {
switch colType {
| Name => Text(historyData.name)
| Type =>
diff --git a/src/screens/HyperSwitch/Routing/PriorityRouting.res b/src/screens/HyperSwitch/Routing/PriorityRouting.res
index 20592a4a4..7533a3f18 100644
--- a/src/screens/HyperSwitch/Routing/PriorityRouting.res
+++ b/src/screens/HyperSwitch/Routing/PriorityRouting.res
@@ -1,7 +1,6 @@
open RoutingUtils
open APIUtils
open RoutingTypes
-open PriorityLogicUtils
open RoutingPreviewer
module SimpleRoutingView = {
@react.component
diff --git a/src/screens/HyperSwitch/Routing/RoutingTypes.res b/src/screens/HyperSwitch/Routing/RoutingTypes.res
index bd0b6c90d..4b0a522fa 100644
--- a/src/screens/HyperSwitch/Routing/RoutingTypes.res
+++ b/src/screens/HyperSwitch/Routing/RoutingTypes.res
@@ -1,7 +1,21 @@
type routingType = SINGLE | PRIORITY | VOLUME_SPLIT | ADVANCED | COST | DEFAULTFALLBACK | NO_ROUTING
-type modalValue = {conType: string, conText: React.element}
-type routingValueType = {heading: string, subHeading: string}
-type modalObj = (routingType, string) => modalValue
+type formState = CreateConfig | EditConfig | ViewConfig
+type status = ACTIVE | APPROVED | PENDING | REJECTED
+type pageState = Preview | Create | Edit
+type variantType = Number | Enum_variant | Metadata_value | String_value | UnknownVariant(string)
+type logicalOperator = AND | OR | UnknownLogicalOperator(string)
+type val = StringArray(array) | String(string) | Int(int)
+
+type historyColType =
+ | Name
+ | Type
+ | ProfileId
+ | ProfileName
+ | Description
+ | Created
+ | LastUpdated
+ | Status
+
type colType =
| Name
| Description
@@ -10,8 +24,6 @@ type colType =
| DateCreated
| LastUpdated
-type status = ACTIVE | APPROVED | PENDING | REJECTED
-type configType = RuleBased | CodeBased
type operator =
| IS
| IS_NOT
@@ -22,75 +34,30 @@ type operator =
| NOT_CONTAINS
| NOT_EQUAL_TO
| UnknownOperator(string)
-type variantType = Number | Enum_variant | Metadata_value | String_value | UnknownVariant(string)
-type logicalOperator = AND | OR | UnknownLogicalOperator(string)
-type val = StringArray(array) | String(string) | Int(int)
-type logic = {
- id: string,
- name: string,
- description: string,
- isActiveLogic: bool,
- status: status,
- configType: configType,
- version: string,
- priorityLogic: string,
- priorityLogicRules: string,
- dateCreated: string,
- lastUpdated: string,
-}
-type response = {
- useCode: bool,
- gatewayPriority: string,
- gatewayPriorityLogic: string,
- logics: array,
-}
+
+type modalValue = {conType: string, conText: React.element}
+type routingValueType = {heading: string, subHeading: string}
+type modalObj = (routingType, string) => modalValue
+
type wasmModule = {
getAllKeys: unit => array,
getKeyType: string => string,
getAllConnectors: unit => array,
getVariantValues: string => array,
}
+
type gateway = {
distribution: int,
disableFallback: bool,
gateway_name: string,
}
+
type volumeDistribution = {
connector: string,
split: int,
}
-type pageState = Preview | Create | Edit
-type condition = {
- field: string,
- metadata?: Js.Json.t,
- operator: operator,
- value: val,
- logicalOperator: logicalOperator,
-}
-type routingOutputType = {override_3ds: string}
-type rule = {
- gateways: array,
- conditions: array,
- routingOutput?: routingOutputType,
-}
-type ruleInfoType = {
- rules: array,
- default_gateways: array,
-}
-
-type gateWAY = {gateways: array}
-type volumeDistributionType = {volumeBasedDistribution: gateWAY}
-type ruleDict = {json: volumeDistributionType}
-type historyColType =
- | Name
- | Type
- | ProfileId
- | ProfileName
- | Description
- | Created
- | LastUpdated
- | Status
+type routingOutputType = {override_3ds: string}
type historyData = {
id: string,
@@ -103,9 +70,3 @@ type historyData = {
}
type value = {"type": Js.Json.t, "value": Js.Json.t}
-type payloadCondition = {
- lhs: string,
- comparison: string,
- value: value,
- metadata: Js.Json.t,
-}
diff --git a/src/screens/HyperSwitch/Routing/RoutingUtils.res b/src/screens/HyperSwitch/Routing/RoutingUtils.res
index 0a4f4067a..a1528303a 100644
--- a/src/screens/HyperSwitch/Routing/RoutingUtils.res
+++ b/src/screens/HyperSwitch/Routing/RoutingUtils.res
@@ -1,9 +1,7 @@
open RoutingTypes
open LogicUtils
external toWasm: Js.Dict.t => wasmModule = "%identity"
-let getObjects = (_: Js.Json.t) => {
- []
-}
+
let defaultThreeDsObjectValue: routingOutputType = {
override_3ds: "three_ds",
}
@@ -19,38 +17,6 @@ let getCurrentUTCTime = () => {
`${currYear}-${currMonth}-${currDay}`
}
-let operatorMapper = value => {
- switch value {
- | "CONTAINS" => CONTAINS
- | "NOT_CONTAINS" => NOT_CONTAINS
- | "IS" => IS
- | "IS_NOT" => IS_NOT
- | "GREATER THAN" => GREATER_THAN
- | "LESS THAN" => LESS_THAN
- | "EQUAL TO" => EQUAL_TO
- | "NOT EQUAL_TO" => NOT_EQUAL_TO
- | _ => UnknownOperator("")
- }
-}
-
-let variantTypeMapper = variantType => {
- switch variantType {
- | "number" => Number
- | "enum_variant" => Enum_variant
- | "metadata_value" => Metadata_value
- | "str_value" => String_value
- | _ => UnknownVariant("")
- }
-}
-
-let logicalOperatorMapper = logical => {
- switch logical {
- | "AND" => AND
- | "OR" => OR
- | _ => UnknownLogicalOperator("")
- }
-}
-
let routingTypeMapper = routingType => {
switch routingType {
| "single" => SINGLE
@@ -75,75 +41,6 @@ let routingTypeName = routingType => {
}
}
-let logicalOperatorTypeToStringMapper = logicalOperator => {
- switch logicalOperator {
- | AND => "AND"
- | OR => "OR"
- | UnknownLogicalOperator(str) => str
- }
-}
-let operatorTypeToStringMapper = operator => {
- switch operator {
- | IS => "IS"
- | CONTAINS => "CONTAINS"
- | IS_NOT => "IS_NOT"
- | NOT_CONTAINS => "NOT_CONTAINS"
- | GREATER_THAN => "GREATER THAN"
- | LESS_THAN => "LESS THAN"
- | EQUAL_TO => "EQUAL TO"
- | NOT_EQUAL_TO => "NOT EQUAL_TO"
- | UnknownOperator(str) => str
- }
-}
-
-let itemGateWayObjMapper = (
- dict,
- _connectorList: option>,
-) => {
- let connectorId = dict->getDictfromDict("connector")->getString("merchant_connector_id", "")
- [
- ("distribution", dict->getFloat("split", 0.00)->Js.Json.number),
- ("disableFallback", dict->getBool("disableFallback", false)->Js.Json.boolean),
- ("gateway_name", connectorId->Js.Json.string),
- ]->Dict.fromArray
-}
-
-let itemBodyGateWayObjMapper = (
- dict,
- connectorList: option>,
-) => {
- let merchantConnectorId =
- dict->getDictfromDict("connector")->getString("merchant_connector_id", "")
- let name =
- connectorList
- ->Belt.Option.getWithDefault([Dict.make()->ConnectorTableUtils.getProcessorPayloadType])
- ->ConnectorTableUtils.getConnectorNameViaId(merchantConnectorId)
- let newDict =
- [
- ("connector", name.connector_name->Js.Json.string),
- ("merchant_connector_id", merchantConnectorId->Js.Json.string),
- ]
- ->Dict.fromArray
- ->Js.Json.object_
- [("split", dict->getFloat("split", 0.00)->Js.Json.number), ("connector", newDict)]->Dict.fromArray
-}
-
-let connectorPayload = (routingType, arr) => {
- switch routingType->routingTypeMapper {
- | VOLUME_SPLIT => {
- let connectorData = arr->Array.reduce([], (acc, routingObj) => {
- let routingDict = routingObj->getDictFromJsonObject
- acc->Array.push(getString(routingDict, "connector", ""))
- acc
- })
- connectorData
- }
-
- | PRIORITY => arr->Js.Json.array->getStrArryFromJson
- | _ => []
- }
-}
-
let getRoutingPayload = (data, routingType, name, description, profileId) => {
let connectorsOrder =
[("data", data->Js.Json.array), ("type", routingType->Js.Json.string)]->Dict.fromArray
@@ -156,210 +53,6 @@ let getRoutingPayload = (data, routingType, name, description, profileId) => {
]->Dict.fromArray
}
-let getWasmKeyType = (wasm, value) => {
- try {
- switch wasm {
- | Some(res) => res.getKeyType(value)
- | None => ""
- }
- } catch {
- | _ => ""
- }
-}
-
-let getWasmVariantValues = (wasm, value) => {
- try {
- switch wasm {
- | Some(res) => res.getVariantValues(value)
- | None => []
- }
- } catch {
- | _ => []
- }
-}
-
-let getWasmGateway = wasm => {
- try {
- switch wasm {
- | Some(res) => res.getAllConnectors()
- | None => []
- }
- } catch {
- | _ => []
- }
-}
-
-let advanceRoutingConditionMapper = (dict, wasm) => {
- let variantType = wasm->getWasmKeyType(dict->getString("field", ""))
- let obj = {
- lhs: dict->getString("field", ""),
- comparison: switch dict->getString("operator", "")->operatorMapper {
- | IS => "equal"
- | IS_NOT => "not_equal"
- | CONTAINS => "equal"
- | NOT_CONTAINS => "not_equal"
- | EQUAL_TO => "equal"
- | GREATER_THAN => "greater_than"
- | LESS_THAN => "less_than"
- | NOT_EQUAL_TO => "not_equal"
- | UnknownOperator(str) => str
- },
- value: {
- "type": switch variantType->variantTypeMapper {
- | Number => "number"
- | Enum_variant =>
- switch dict->getString("operator", "")->operatorMapper {
- | IS => "enum_variant"
- | CONTAINS => "enum_variant_array"
- | IS_NOT => "enum_variant"
- | NOT_CONTAINS => "enum_variant_array"
- | _ => ""
- }
- | Metadata_value => "metadata_variant"
- | String_value => "str_value"
- | _ => ""
- }->Js.Json.string,
- "value": switch variantType->variantTypeMapper {
- | Number => (dict->getString("value", "")->float_of_string *. 100.00)->Js.Json.number
- | Enum_variant =>
- switch dict->getString("operator", "")->operatorMapper {
- | IS => dict->getString("value", "")->Js.Json.string
- | CONTAINS => dict->getArrayFromDict("value", [])->Js.Json.array
- | IS_NOT => dict->getString("value", "")->Js.Json.string
- | NOT_CONTAINS => dict->getArrayFromDict("value", [])->Js.Json.array
-
- | _ => ""->Js.Json.string
- }
- | Metadata_value => {
- let key =
- dict->getDictfromDict("metadata")->getString("key", "")->String.trim->Js.Json.string
- let value = dict->getString("value", "")->String.trim->Js.Json.string
- Dict.fromArray([("key", key), ("value", value)])->Js.Json.object_
- }
- | String_value => dict->getString("value", "")->Js.Json.string
- | _ => ""->Js.Json.string
- },
- },
- metadata: Dict.make()->Js.Json.object_,
- }
- let value = [("value", obj.value["value"]), ("type", obj.value["type"])]->Dict.fromArray
- let dict =
- [
- ("lhs", obj.lhs->Js.Json.string),
- ("comparison", obj.comparison->Js.Json.string),
- ("value", value->Js.Json.object_),
- ("metadata", obj.metadata),
- ]->Dict.fromArray
-
- dict->Js.Json.object_
-}
-
-let getVolumeSplit = (
- dict_arr,
- objMapper,
- connectorList: option>,
-) => {
- dict_arr->Array.reduce([], (acc, routingObj) => {
- let value = [routingObj->getDictFromJsonObject->objMapper(connectorList)->Js.Json.object_]
- acc->Array.concat(value)->Array.map(value => value)
- })
-}
-
-let checkIfValuePresesent = valueRes => {
- // to check if the value is present only then add to the statement
- let conditionMatched = switch Js.Json.classify(valueRes) {
- | JSONArray(arr) => arr->Array.length > 0
- | JSONString(str) => str->String.length > 0
- | JSONNumber(num) => num > Belt.Int.toFloat(0)
- | _ => false
- }
- conditionMatched
-}
-
-let generateStatement = (arr, wasm) => {
- let conditionDict = Dict.make()
- let statementDict = Dict.make()
- arr->Array.forEachWithIndex((item, index) => {
- let valueRes =
- item->getDictFromJsonObject->Dict.get("value")->Belt.Option.getWithDefault([]->Js.Json.array)
-
- if valueRes->checkIfValuePresesent {
- let value = item->getDictFromJsonObject->advanceRoutingConditionMapper(wasm)
- let logical = item->getDictFromJsonObject->getString("logical.operator", "")
-
- switch logical->logicalOperatorMapper {
- | OR => {
- let copyDict = Js.Dict.map((. val) => val, conditionDict)
- Dict.set(statementDict, Belt.Int.toString(index), copyDict)
- conditionDict->Dict.set("condition", []->Js.Json.array)
- let val =
- conditionDict->Dict.get("condition")->Belt.Option.getWithDefault([]->Js.Json.array)
- let arr = switch Js.Json.classify(val) {
- | JSONArray(arr) => {
- arr->Array.push(value)
- arr
- }
- | _ => []
- }
- conditionDict->Dict.set("condition", arr->Js.Json.array)
- }
-
- | _ =>
- let val =
- conditionDict->Dict.get("condition")->Belt.Option.getWithDefault([]->Js.Json.array)
- let arr = switch Js.Json.classify(val) {
- | JSONArray(arr) => {
- arr->Array.push(value)
- arr
- }
-
- | _ => []
- }
- conditionDict->Dict.set("condition", arr->Js.Json.array)
- }
- }
- })
-
- let copyDict = Js.Dict.map((. val) => val, conditionDict)
- Dict.set(statementDict, Belt.Int.toString(arr->Array.length), copyDict)
- statementDict
- ->Dict.keysToArray
- ->Array.map(val => {
- switch statementDict->Dict.get(val) {
- | Some(dt) => dt->Js.Json.object_
- | _ => Dict.make()->Js.Json.object_
- }
- })
-}
-
-let getDefaultSelection = dict => {
- [
- ("data", dict->getArrayFromDict("default_gateways", [])->Js.Json.array),
- ("type", "priority"->Js.Json.string),
- ]->Dict.fromArray
-}
-let generateRuleObject = (index, connectorSelection, statement) => {
- let ruleObj = Dict.fromArray([
- ("name", `rule_${string_of_int(index + 1)}`->Js.Json.string),
- ("statements", statement->Js.Json.array),
- ("connectorSelection", connectorSelection->Js.Json.object_),
- ])
- ruleObj
-}
-let constuctAlgorithm = (dict, rules, metadata) => {
- let body =
- [
- ("defaultSelection", getDefaultSelection(dict)->Js.Json.object_),
- ("rules", rules->Js.Json.array),
- ("metadata", metadata->Js.Json.object_),
- ]->Dict.fromArray
-
- let algorithm =
- [("type", "advanced"->Js.Json.string), ("data", body->Js.Json.object_)]->Dict.fromArray
-
- algorithm
-}
-
let getModalObj = (routingType, text) => {
switch routingType {
| ADVANCED => {
@@ -453,21 +146,6 @@ let valueTypeMapper = dict => {
value
}
-let conditionTypeMapper = (conditionArr: array) => {
- let conditionArray = []
- conditionArr->Array.forEach(value => {
- let val = value->getDictFromJsonObject
- let tempval = {
- field: val->getString("field", ""),
- metadata: val->getDictfromDict("metadata")->Js.Json.object_,
- operator: val->getString("operator", "")->operatorMapper,
- value: val->valueTypeMapper,
- logicalOperator: val->getString("logical.operator", "")->logicalOperatorMapper,
- }
- conditionArray->Array.push(tempval)
- })
- conditionArray
-}
let threeDsTypeMapper = dict => {
let getRoutingOutputval = dict->getString("override_3ds", "three_ds")
let val = {
@@ -490,78 +168,8 @@ let constructNameDescription = routingType => {
])
}
-let manipulateInitialValueJson = initialValueJson => {
- let manipulatedJson = ADVANCED->constructNameDescription
- manipulatedJson->Dict.set("code", initialValueJson->getString("code", "")->Js.Json.string)
- manipulatedJson->Dict.set("json", initialValueJson->getObj("json", Dict.make())->Js.Json.object_)
- manipulatedJson
-}
let currentTabNameRecoilAtom = Recoil.atom(. "currentTabName", "ActiveTab")
-module SaveAndActivateButton = {
- @react.component
- let make = (
- ~onSubmit: (Js.Json.t, 'a) => promise>,
- ~handleActivateConfiguration,
- ) => {
- let formState: ReactFinalForm.formState = ReactFinalForm.useFormState(
- ReactFinalForm.useFormSubscription(["values"])->Js.Nullable.return,
- )
-
- let handleSaveAndActivate = async _ev => {
- try {
- let onSubmitResponse = await onSubmit(formState.values, false)
- let currentActivatedFromJson =
- onSubmitResponse->Js.Nullable.toOption->Belt.Option.getWithDefault(Js.Json.null)
- let currentActivatedId =
- currentActivatedFromJson->LogicUtils.getDictFromJsonObject->LogicUtils.getString("id", "")
- let _ = await handleActivateConfiguration(Some(currentActivatedId))
- } catch {
- | Js.Exn.Error(e) =>
- let _err =
- Js.Exn.message(e)->Belt.Option.getWithDefault(
- "Failed to save and activate configuration!",
- )
- }
- }
- {
- handleSaveAndActivate()->ignore
- }}
- customButtonStyle="w-1/5 rounded-sm"
- />
- }
-}
-module ConfigureRuleButton = {
- @react.component
- let make = (~setShowModal, ~isConfigButtonEnabled) => {
- let formState: ReactFinalForm.formState = ReactFinalForm.useFormState(
- ReactFinalForm.useFormSubscription(["values"])->Js.Nullable.return,
- )
-
- {
- setShowModal(_ => true)
- }}
- customButtonStyle="w-1/5"
- />
- }
-}
-
-let validateNameAndDescription = (~dict, ~errors) => {
- ["name", "description"]->Array.forEach(field => {
- if dict->LogicUtils.getString(field, "")->String.trim === "" {
- errors->Dict.set(field, `Please provide ${field} field`->Js.Json.string)
- }
- })
-}
-
let checkIfValuePresent = dict => {
let valueFromObject = dict->getDictfromDict("value")
@@ -593,16 +201,6 @@ let validateConditionsFor3ds = dict => {
})
}
-let filterEmptyValues = (arr: array) => {
- arr->Array.filter(item => {
- switch item.value {
- | StringArray(arr) => arr->Array.length > 0
- | String(str) => str->String.length > 0
- | Int(int) => int > 0
- }
- })
-}
-
let getRecordsObject = json => {
switch Js.Json.classify(json) {
| JSONObject(jsonDict) => jsonDict->getArrayFromDict("records", [])
diff --git a/src/screens/HyperSwitch/Routing/VolumeSplitRouting.res b/src/screens/HyperSwitch/Routing/VolumeSplitRouting.res
index 53554b9e8..af4abf049 100644
--- a/src/screens/HyperSwitch/Routing/VolumeSplitRouting.res
+++ b/src/screens/HyperSwitch/Routing/VolumeSplitRouting.res
@@ -1,7 +1,6 @@
open APIUtils
open RoutingTypes
open RoutingPreviewer
-
open LogicUtils
module VolumeRoutingView = {
@@ -129,7 +128,7 @@ module VolumeRoutingView = {
dropDownButtonText="Add Processors"
connectorList
/>
-
+
}
- submitButton={}
+ submitButton={}
headingText="Activate Current Configuration?"
subHeadingText="Activating the current configuration will override the current active configuration. Alternatively, save this configuration to access / activate it later from the configuration history. Please confirm."
leftIcon="hswitch-warning"
diff --git a/src/screens/HyperSwitch/RoutingRevamp/AdvancedRouting.res b/src/screens/HyperSwitch/RoutingRevamp/AdvancedRouting.res
index d1c0d0fd7..6eb45ca3a 100644
--- a/src/screens/HyperSwitch/RoutingRevamp/AdvancedRouting.res
+++ b/src/screens/HyperSwitch/RoutingRevamp/AdvancedRouting.res
@@ -469,7 +469,7 @@ let make = (~routingRuleId, ~isActive, ~setCurrentRouting) => {
let errors = Dict.make()
- RoutingUtils.validateNameAndDescription(~dict, ~errors)
+ AdvancedRoutingUtils.validateNameAndDescription(~dict, ~errors)
let validateGateways = (connectorData: array) => {
if connectorData->Array.length === 0 {
@@ -705,7 +705,9 @@ let make = (~routingRuleId, ~isActive, ~setCurrentRouting) => {
| Create =>
-
+
| _ => React.null
}}
@@ -720,7 +722,7 @@ let make = (~routingRuleId, ~isActive, ~setCurrentRouting) => {
customSumbitButtonStyle="w-1/5 rounded-lg"
tooltipWidthClass="w-48"
/>}
- submitButton={}
headingText="Activate Current Configuration?"
diff --git a/src/screens/HyperSwitch/RoutingRevamp/AdvancedRoutingUIUtils.res b/src/screens/HyperSwitch/RoutingRevamp/AdvancedRoutingUIUtils.res
index af5e2a54c..c3f1853b0 100644
--- a/src/screens/HyperSwitch/RoutingRevamp/AdvancedRoutingUIUtils.res
+++ b/src/screens/HyperSwitch/RoutingRevamp/AdvancedRoutingUIUtils.res
@@ -496,3 +496,60 @@ let descriptionInput = makeFieldInfo(
),
(),
)
+
+module ConfigureRuleButton = {
+ @react.component
+ let make = (~setShowModal, ~isConfigButtonEnabled) => {
+ let formState: ReactFinalForm.formState = ReactFinalForm.useFormState(
+ ReactFinalForm.useFormSubscription(["values"])->Js.Nullable.return,
+ )
+
+ {
+ setShowModal(_ => true)
+ }}
+ customButtonStyle="w-1/5"
+ />
+ }
+}
+
+module SaveAndActivateButton = {
+ @react.component
+ let make = (
+ ~onSubmit: (Js.Json.t, 'a) => promise>,
+ ~handleActivateConfiguration,
+ ) => {
+ let formState: ReactFinalForm.formState = ReactFinalForm.useFormState(
+ ReactFinalForm.useFormSubscription(["values"])->Js.Nullable.return,
+ )
+
+ let handleSaveAndActivate = async _ev => {
+ try {
+ let onSubmitResponse = await onSubmit(formState.values, false)
+ let currentActivatedFromJson =
+ onSubmitResponse->Js.Nullable.toOption->Belt.Option.getWithDefault(Js.Json.null)
+ let currentActivatedId =
+ currentActivatedFromJson->LogicUtils.getDictFromJsonObject->LogicUtils.getString("id", "")
+ let _ = await handleActivateConfiguration(Some(currentActivatedId))
+ } catch {
+ | Js.Exn.Error(e) =>
+ let _err =
+ Js.Exn.message(e)->Belt.Option.getWithDefault(
+ "Failed to save and activate configuration!",
+ )
+ }
+ }
+ {
+ handleSaveAndActivate()->ignore
+ }}
+ customButtonStyle="w-1/5 rounded-sm"
+ />
+ }
+}
diff --git a/src/screens/HyperSwitch/RoutingRevamp/AdvancedRoutingUtils.res b/src/screens/HyperSwitch/RoutingRevamp/AdvancedRoutingUtils.res
index 9acf9b330..03912bb24 100644
--- a/src/screens/HyperSwitch/RoutingRevamp/AdvancedRoutingUtils.res
+++ b/src/screens/HyperSwitch/RoutingRevamp/AdvancedRoutingUtils.res
@@ -400,3 +400,11 @@ let initialValues: AdvancedRoutingTypes.advancedRouting = {
\"type": "",
},
}
+
+let validateNameAndDescription = (~dict, ~errors) => {
+ ["name", "description"]->Array.forEach(field => {
+ if dict->LogicUtils.getString(field, "")->String.trim === "" {
+ errors->Dict.set(field, `Please provide ${field} field`->Js.Json.string)
+ }
+ })
+}
diff --git a/src/screens/HyperSwitch/SDKPayment/SDKPage.res b/src/screens/HyperSwitch/SDKPayment/SDKPage.res
index 7d87fe11f..6542b3032 100644
--- a/src/screens/HyperSwitch/SDKPayment/SDKPage.res
+++ b/src/screens/HyperSwitch/SDKPayment/SDKPage.res
@@ -49,13 +49,13 @@ module SDKConfiguarationFields = {
InputFields.numericTextInput(
~input={
...input,
- value: (initialValues.amount / 100)->string_of_int->Js.Json.string,
+ value: (initialValues.amount /. 100.00)->Js.Float.toString->Js.Json.string,
onChange: {
ev => {
- let eventValueToInt =
- ev->Identity.formReactEventToString->LogicUtils.getIntFromString(0)
+ let eventValueToFloat =
+ ev->Identity.formReactEventToString->LogicUtils.getFloatFromString(0.00)
let valInCents =
- (eventValueToInt * 100)->string_of_int->Identity.stringToFormReactEvent
+ (eventValueToFloat *. 100.00)->Js.Float.toString->Identity.stringToFormReactEvent
input.onChange(valInCents)
}
},
@@ -63,6 +63,7 @@ module SDKConfiguarationFields = {
~isDisabled=false,
~customStyle="w-full",
~placeholder="Enter amount",
+ ~precision=2,
(),
),
(),
diff --git a/src/screens/HyperSwitch/SDKPayment/SDKPaymentTypes.res b/src/screens/HyperSwitch/SDKPayment/SDKPaymentTypes.res
index 631956251..2b1b8e2f2 100644
--- a/src/screens/HyperSwitch/SDKPayment/SDKPaymentTypes.res
+++ b/src/screens/HyperSwitch/SDKPayment/SDKPaymentTypes.res
@@ -27,7 +27,7 @@ type billing = {
type orderDetails = {
product_name: string,
quantity: int,
- amount: int,
+ amount: float,
}
type metadata = {order_details: orderDetails}
@@ -55,13 +55,13 @@ type mandateData = {
}
type paymentType = {
- amount: int,
+ amount: float,
mutable currency: string,
profile_id: string,
customer_id: string,
description: string,
capture_method: string,
- amount_to_capture: Js.Nullable.t,
+ amount_to_capture: Js.Nullable.t,
email: string,
name: string,
phone: string,
diff --git a/src/screens/HyperSwitch/SDKPayment/SDKPaymentUtils.res b/src/screens/HyperSwitch/SDKPayment/SDKPaymentUtils.res
index 31e35445a..39bcc56f0 100644
--- a/src/screens/HyperSwitch/SDKPayment/SDKPaymentUtils.res
+++ b/src/screens/HyperSwitch/SDKPayment/SDKPaymentUtils.res
@@ -1,6 +1,6 @@
let initialValueForForm: HSwitchSettingTypes.profileEntity => SDKPaymentTypes.paymentType = defaultBusinessProfile => {
{
- amount: 10000,
+ amount: 10000.00,
currency: "United States-USD",
profile_id: defaultBusinessProfile.profile_id,
description: "Default value",
@@ -48,11 +48,11 @@ let initialValueForForm: HSwitchSettingTypes.profileEntity => SDKPaymentTypes.pa
order_details: {
product_name: "Apple iphone 15",
quantity: 1,
- amount: 100,
+ amount: 100.00,
},
},
capture_method: "automatic",
- amount_to_capture: Js.Nullable.return(100),
+ amount_to_capture: Js.Nullable.return(100.00),
return_url: `${Window.Location.origin}${Window.Location.pathName}`,
}
}
@@ -95,7 +95,7 @@ let getTypedValueForPayment: Js.Json.t => SDKPaymentTypes.paymentType = values =
},
},
}
- let amount = dictOfValues->getInt("amount", 100)
+ let amount = dictOfValues->getFloat("amount", 100.00)
{
amount,
@@ -150,10 +150,10 @@ let getTypedValueForPayment: Js.Json.t => SDKPaymentTypes.paymentType = values =
},
},
capture_method: "automatic",
- amount_to_capture: amount === 0 ? Js.Nullable.null : Js.Nullable.return(amount),
+ amount_to_capture: amount === 0.00 ? Js.Nullable.null : Js.Nullable.return(amount),
return_url: dictOfValues->getString("return_url", ""),
- payment_type: amount === 0 ? Js.Nullable.return("setup_mandate") : Js.Nullable.null,
- setup_future_usage: amount === 0 ? Js.Nullable.return("off_session") : Js.Nullable.null,
- mandate_data: amount === 0 ? Js.Nullable.return(mandateData) : Js.Nullable.null,
+ payment_type: amount === 0.00 ? Js.Nullable.return("setup_mandate") : Js.Nullable.null,
+ setup_future_usage: amount === 0.00 ? Js.Nullable.return("off_session") : Js.Nullable.null,
+ mandate_data: amount === 0.00 ? Js.Nullable.return(mandateData) : Js.Nullable.null,
}
}
diff --git a/src/screens/HyperSwitch/SDKPayment/WebSDK.res b/src/screens/HyperSwitch/SDKPayment/WebSDK.res
index 170873f83..505a32eaf 100644
--- a/src/screens/HyperSwitch/SDKPayment/WebSDK.res
+++ b/src/screens/HyperSwitch/SDKPayment/WebSDK.res
@@ -232,7 +232,7 @@ module CheckoutForm = {
| WIDGET =>
}}
Belt.Int.toString}`}
+ text={`Pay ${currency} ${(amount /. 100.00)->Belt.Float.toString}`}
loadingText="Please wait..."
buttonState=btnState
buttonType={Primary}
@@ -282,7 +282,7 @@ let make = (
~methodsOrder=[],
~saveViewToSdk=false,
~isSpaceAccordion=false,
- ~amount=65400,
+ ~amount=65400.00,
~setClientSecret,
) => {
let (screenState, setScreenState) = React.useState(_ => PageLoaderWrapper.Loading)
diff --git a/src/screens/HyperSwitch/SelfServe/HSwitchSandboxOnboarding/UserOnboardingUIUtils.res b/src/screens/HyperSwitch/SelfServe/HSwitchSandboxOnboarding/UserOnboardingUIUtils.res
index 0bfebfccb..6e846a84c 100644
--- a/src/screens/HyperSwitch/SelfServe/HSwitchSandboxOnboarding/UserOnboardingUIUtils.res
+++ b/src/screens/HyperSwitch/SelfServe/HSwitchSandboxOnboarding/UserOnboardingUIUtils.res
@@ -862,63 +862,6 @@ let getTabsForIntegration = (
,
},
- // {
- // title: "3. Manage",
- // renderContent: () => {
- // let skipAndContinue = async () => {
- // try {
- // let url = APIUtils.getURL(~entityName=INTEGRATION_DETAILS, ~methodType=Post, ())
- // let metaDataDict =
- // Dict.fromArray([("is_skip", true->Js.Json.boolean)])->Js.Json.object_
- // let body = HSwitchUtils.constructOnboardingBody(
- // ~dashboardPageState,
- // ~integrationDetails,
- // ~is_done=false,
- // ~metadata=metaDataDict,
- // (),
- // )
- // let _ = await updateDetails(url, body, Post)
- // setIntegrationDetails(_ => body->ProviderHelper.getIntegrationDetails)
- // } catch {
- // | _ => ()
- // }
- // }
- // let skipOnboarding = async path => {
- // let _ = await skipAndContinue()
- // Window._open(path)
- // }
- //
- //
- // skipOnboarding(`/connectors`)->ignore} className="cursor-pointer">
- //
- //
- //
- //
- //
- //
- // skipOnboarding(`/routing`)->ignore} className="cursor-pointer">
- //
- //
- //
- //
- //
- //
- // skipOnboarding(`/payments`)->ignore} className="cursor-pointer">
- //
- //
- //
- //
- //
- // //
- //
- // },
- // },
]
| _ => []
}
diff --git a/src/screens/HyperSwitch/Surcharge/Surcharge.res b/src/screens/HyperSwitch/Surcharge/Surcharge.res
index 7adf8b665..df2ea619d 100644
--- a/src/screens/HyperSwitch/Surcharge/Surcharge.res
+++ b/src/screens/HyperSwitch/Surcharge/Surcharge.res
@@ -188,7 +188,7 @@ let make = () => {
let errors = Dict.make()
- RoutingUtils.validateNameAndDescription(~dict, ~errors)
+ AdvancedRoutingUtils.validateNameAndDescription(~dict, ~errors)
switch dict->Dict.get("algorithm")->Belt.Option.flatMap(Js.Json.decodeObject) {
| Some(jsonDict) => {
diff --git a/src/screens/HyperSwitch/ThreeDSFlow/HSwitchThreeDS.res b/src/screens/HyperSwitch/ThreeDSFlow/HSwitchThreeDS.res
index c6e897dce..62b7e68e8 100644
--- a/src/screens/HyperSwitch/ThreeDSFlow/HSwitchThreeDS.res
+++ b/src/screens/HyperSwitch/ThreeDSFlow/HSwitchThreeDS.res
@@ -206,7 +206,7 @@ let make = () => {
let errors = Dict.make()
- RoutingUtils.validateNameAndDescription(~dict, ~errors)
+ AdvancedRoutingUtils.validateNameAndDescription(~dict, ~errors)
switch dict->Dict.get("algorithm")->Belt.Option.flatMap(Js.Json.decodeObject) {
| Some(jsonDict) => {
diff --git a/src/screens/HyperSwitch/UserManagement/InviteUsers.res b/src/screens/HyperSwitch/UserManagement/InviteUsers.res
index f8e9b5375..5405a75e7 100644
--- a/src/screens/HyperSwitch/UserManagement/InviteUsers.res
+++ b/src/screens/HyperSwitch/UserManagement/InviteUsers.res
@@ -13,7 +13,7 @@ module InviteEmailForm = {
let role =
ReactFinalForm.useField(`roleType`).input.value
->getArrayFromJson([])
- ->LogicUtils.getValueFromArray(0, ""->Js.Json.string)
+ ->getValueFromArray(0, ""->Js.Json.string)
->getStringFromJson("")
let getRolesList = async () => {
@@ -26,7 +26,7 @@ module InviteEmailForm = {
)
let response = await fetchDetails(roleListUrl)
let typedResponse: array =
- response->LogicUtils.getArrayDataFromJson(roleListResponseMapper)
+ response->getArrayDataFromJson(roleListResponseMapper)
setRoleListData(_ => typedResponse)
} catch {
| _ => ()
@@ -99,36 +99,46 @@ let make = () => {
setLoaderForInviteUsers(_ => true)
}
let valDict = values->getDictFromJsonObject
- let role = valDict->getStrArray("roleType")->LogicUtils.getValueFromArray(0, "")
+ let role = valDict->getStrArray("roleType")->getValueFromArray(0, "")
let emailList = valDict->getStrArray("emailList")
- let emailPasswordsArray = []
- let arrayOfPromises = emailList->Array.map(ele => {
+ let promisesOfInvitedUsers = emailList->Array.map(ele => {
let body =
[
("email", ele->String.toLowerCase->Js.Json.string),
("name", ele->getNameFromEmail->Js.Json.string),
("role_id", role->Js.Json.string),
- ]->LogicUtils.getJsonFromArrayOfJson
+ ]->getJsonFromArrayOfJson
inviteUserReq(body)
})
- let response = await PromiseUtils.allSettledPolyfill(arrayOfPromises)
+ let response = await PromiseUtils.allSettledPolyfill(promisesOfInvitedUsers)
if !magicLink {
- response->Array.forEachWithIndex((ele, index) => {
+ let invitedUserData = response->Array.mapWithIndex((ele, index) => {
switch Js.Json.classify(ele) {
| Js.Json.JSONObject(jsonDict) => {
let passwordFromResponse = jsonDict->getString("password", "")
- emailPasswordsArray->Array.push(
- [
- ("email", emailList[index]->Option.getWithDefault("")->Js.Json.string),
- ("password", passwordFromResponse->Js.Json.string),
- ]->LogicUtils.getJsonFromArrayOfJson,
- )
+ [
+ ("email", emailList[index]->Option.getWithDefault("")->Js.Json.string),
+ ("password", passwordFromResponse->Js.Json.string),
+ ]->getJsonFromArrayOfJson
}
- | _ => ()
+ | _ => Js.Json.null
}
})
+
+ setLoaderForInviteUsers(_ => false)
+
+ if invitedUserData->Array.length > 0 {
+ DownloadUtils.download(
+ ~fileName=`invited-users.txt`,
+ ~content=invitedUserData
+ ->Array.filter(ele => ele !== Js.Json.null)
+ ->Js.Json.array
+ ->Js.Json.stringifyWithSpace(3),
+ ~fileType="application/json",
+ )
+ }
}
showToast(
@@ -138,20 +148,6 @@ let make = () => {
~toastType=ToastSuccess,
(),
)
-
- if !magicLink && emailPasswordsArray->Array.length > 0 {
- DownloadUtils.download(
- ~fileName=`invited-users.txt`,
- ~content=emailPasswordsArray->Js.Json.array->Js.Json.stringifyWithSpace(3),
- ~fileType="application/json",
- )
- }
-
- if !magicLink {
- setLoaderForInviteUsers(_ => false)
- } else {
- await HyperSwitchUtils.delay(400)
- }
RescriptReactRouter.push("/users")
Js.Nullable.null
}
diff --git a/src/screens/HyperSwitch/UserManagement/PermissionUtils.res b/src/screens/HyperSwitch/UserManagement/PermissionUtils.res
index d75e19b33..bf529ff77 100644
--- a/src/screens/HyperSwitch/UserManagement/PermissionUtils.res
+++ b/src/screens/HyperSwitch/UserManagement/PermissionUtils.res
@@ -103,5 +103,5 @@ let getAccessValue = (~permissionValue: permissionType, permissionList) => {
ele === permissionValue
})
- isPermissionFound->Option.isSome ? Read : NoAccess
+ isPermissionFound->Option.isSome ? Access : NoAccess
}
diff --git a/src/screens/login/AuthTypes.res b/src/screens/login/AuthTypes.res
index a28e0757d..1bb419c39 100644
--- a/src/screens/login/AuthTypes.res
+++ b/src/screens/login/AuthTypes.res
@@ -1 +1 @@
-type authorization = NoAccess | Read | ReadWrite
+type authorization = NoAccess | Access
diff --git a/src/screens/login/HSwitchLoginFlow/HyperSwitchAuth.res b/src/screens/login/HSwitchLoginFlow/HyperSwitchAuth.res
index 84c29b58e..edb0b3520 100644
--- a/src/screens/login/HSwitchLoginFlow/HyperSwitchAuth.res
+++ b/src/screens/login/HSwitchLoginFlow/HyperSwitchAuth.res
@@ -57,7 +57,7 @@ let make = (~setAuthStatus: HyperSwitchAuthTypes.authStatus => unit, ~authType,
let token = parseResponseJson(~json=res, ~email)
// home
- if !(token->HSwitchUtils.isEmptyString) {
+ if !(token->isEmptyString) {
setAuthStatus(LoggedIn(HyperSwitchAuthTypes.getDummyAuthInfoForToken(token)))
} else {
showToast(~message="Failed to sign in, Try again", ~toastType=ToastError, ())
diff --git a/src/screens/login/HSwitchLoginFlow/HyperSwitchEmailVerifyScreen.res b/src/screens/login/HSwitchLoginFlow/HyperSwitchEmailVerifyScreen.res
index dc412e9b3..be70ff263 100644
--- a/src/screens/login/HSwitchLoginFlow/HyperSwitchEmailVerifyScreen.res
+++ b/src/screens/login/HSwitchLoginFlow/HyperSwitchEmailVerifyScreen.res
@@ -14,7 +14,7 @@ let generateBody = (url: RescriptReactRouter.url) => {
let make = (~setAuthType, ~setAuthStatus, ~authType) => {
open HyperSwitchAuthTypes
open APIUtils
- open HSwitchUtils
+ open LogicUtils
let url = RescriptReactRouter.useUrl()
let updateDetails = useUpdateMethod()
let (errorMessage, setErrorMessage) = React.useState(_ => "")
@@ -26,10 +26,7 @@ let make = (~setAuthType, ~setAuthStatus, ~authType) => {
let url = getURL(~entityName=USERS, ~methodType=Post, ~userType, ())
let res = await updateDetails(url, body, Post)
let email =
- res
- ->Js.Json.decodeObject
- ->Belt.Option.getWithDefault(Dict.make())
- ->LogicUtils.getString("email", "")
+ res->Js.Json.decodeObject->Belt.Option.getWithDefault(Dict.make())->getString("email", "")
let token = HyperSwitchAuthUtils.parseResponseJson(~json=res, ~email)
if !(token->isEmptyString) && !(email->isEmptyString) {
setAuthStatus(LoggedIn(HyperSwitchAuthTypes.getDummyAuthInfoForToken(token)))
diff --git a/src/utils/LogicUtils.res b/src/utils/LogicUtils.res
index a90dfe236..c22aa8f68 100644
--- a/src/utils/LogicUtils.res
+++ b/src/utils/LogicUtils.res
@@ -498,6 +498,9 @@ let numericArraySortComperator = (a, b) => {
let isEmptyDict = dict => {
dict->Dict.keysToArray->Array.length === 0
}
+
+let isEmptyString = str => str->String.length === 0
+
let stringReplaceAll = (str, old, new) => {
str->String.split(old)->Array.joinWith(new)
}