diff --git a/.github/workflows/cypress-test.yml b/.github/workflows/cypress-test.yml index 8e6cebf99..5fd3c41f2 100644 --- a/.github/workflows/cypress-test.yml +++ b/.github/workflows/cypress-test.yml @@ -33,8 +33,8 @@ jobs: - name: Make Curl Request run: | - # Replace the URL with your actual endpoint - response=$(curl --location --request GET 'http://localhost:8080/health') + # Once the service is up, make the actual curl request + response=$(curl --location --request GET 'http://0.0.0.0:8080/health') echo "Response:" echo "$response" diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a21f370f..99659c5fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,149 @@ All notable changes to this project will be documented in this file. See [conven - - - +## 2024.09.23.0 + +### Miscellaneous Tasks + +- Update profile dropdown ([#1434](https://github.com/juspay/hyperswitch-control-center/pull/1434)) ([`e6fe7bc`](https://github.com/juspay/hyperswitch-control-center/commit/e6fe7bcbd3afe6eb62fe85333c78312d782a547f)) + +**Full Changelog:** [`2024.09.20.0...2024.09.23.0`](https://github.com/juspay/hyperswitch-control-center/compare/2024.09.20.0...2024.09.23.0) + +- - - + +## 2024.09.20.0 + +### Features + +- Overview file cleanup and files restructuring ([#1436](https://github.com/juspay/hyperswitch-control-center/pull/1436)) ([`c063e64`](https://github.com/juspay/hyperswitch-control-center/commit/c063e645e3698477f3bea565d0c0e12c1c5442f1)) + +**Full Changelog:** [`2024.09.19.1...2024.09.20.0`](https://github.com/juspay/hyperswitch-control-center/compare/2024.09.19.1...2024.09.20.0) + +- - - + +## 2024.09.19.1 + +### Bug Fixes + +- User management name changes ([#1432](https://github.com/juspay/hyperswitch-control-center/pull/1432)) ([`ff64997`](https://github.com/juspay/hyperswitch-control-center/commit/ff6499771645c096d04e26acbec3efa2b137cf2c)) + +**Full Changelog:** [`2024.09.19.0...2024.09.19.1`](https://github.com/juspay/hyperswitch-control-center/compare/2024.09.19.0...2024.09.19.1) + +- - - + +## 2024.09.19.0 + +### Features + +- New connector deutsche bank ([#1408](https://github.com/juspay/hyperswitch-control-center/pull/1408)) ([`fb7847b`](https://github.com/juspay/hyperswitch-control-center/commit/fb7847bf840e7aa33148f2593558ed533bebad95)) + +### Testing + +- Cypress update ([#1420](https://github.com/juspay/hyperswitch-control-center/pull/1420)) ([`6f59156`](https://github.com/juspay/hyperswitch-control-center/commit/6f59156bae44fe3d80d236c50b6562445bd5e0ee)) + +### Miscellaneous Tasks + +- Merchant name validation added ([#1416](https://github.com/juspay/hyperswitch-control-center/pull/1416)) ([`e143725`](https://github.com/juspay/hyperswitch-control-center/commit/e14372523fc323aaf2c90bc630d73e4bcee9d57b)) +- Update wasm for deutsche ([#1429](https://github.com/juspay/hyperswitch-control-center/pull/1429)) ([`6fc9d63`](https://github.com/juspay/hyperswitch-control-center/commit/6fc9d63757df8ba9fb4e5df1d448de5189903c27)) +- Post login questions page related files removal ([#1427](https://github.com/juspay/hyperswitch-control-center/pull/1427)) ([`93382db`](https://github.com/juspay/hyperswitch-control-center/commit/93382db3ff28d9f0e99af08407c7f9593930466a)) +- UI changes for update connector creds ([#1438](https://github.com/juspay/hyperswitch-control-center/pull/1438)) ([`3101b29`](https://github.com/juspay/hyperswitch-control-center/commit/3101b298e0e4dff45cef5afa23f0f32da1166e92)) + +**Full Changelog:** [`2024.09.18.0...2024.09.19.0`](https://github.com/juspay/hyperswitch-control-center/compare/2024.09.18.0...2024.09.19.0) + +- - - + +## 2024.09.18.0 + +### Features + +- Remove user-management revamp feature flag ([#1394](https://github.com/juspay/hyperswitch-control-center/pull/1394)) ([`6d7123b`](https://github.com/juspay/hyperswitch-control-center/commit/6d7123bd4302193c11291d44fe381e2fcab112e4)) + +### Bug Fixes + +- Bug fixes ui ([#1396](https://github.com/juspay/hyperswitch-control-center/pull/1396)) ([`8e4d2d8`](https://github.com/juspay/hyperswitch-control-center/commit/8e4d2d8cc35b348d43371364c05bed157d8d6062)) + +### Miscellaneous Tasks + +- Home page changes for profile level users ([#1409](https://github.com/juspay/hyperswitch-control-center/pull/1409)) ([`877de7f`](https://github.com/juspay/hyperswitch-control-center/commit/877de7fd8e52c1d46e43653525b77aa26d08dbf9)) + +**Full Changelog:** [`2024.09.17.2...2024.09.18.0`](https://github.com/juspay/hyperswitch-control-center/compare/2024.09.17.2...2024.09.18.0) + +- - - + +## 2024.09.17.2 + +### Features + +- Handle masked api keys ([#1400](https://github.com/juspay/hyperswitch-control-center/pull/1400)) ([`2cc832c`](https://github.com/juspay/hyperswitch-control-center/commit/2cc832ca2d1c8b7689d175e5b0d5d01cc7304d0d)) + +### Miscellaneous Tasks + +- Handle masked api keys ([`91358cb`](https://github.com/juspay/hyperswitch-control-center/commit/91358cb6dcca083e5669b57be4141119ada5635e)) + +**Full Changelog:** [`2024.09.17.1...2024.09.17.2`](https://github.com/juspay/hyperswitch-control-center/compare/2024.09.17.1...2024.09.17.2) + +- - - + +## 2024.09.17.1 + +### Features + +- Tax processor addition and taxjar addition ([#1379](https://github.com/juspay/hyperswitch-control-center/pull/1379)) ([`0b4dad9`](https://github.com/juspay/hyperswitch-control-center/commit/0b4dad9a496d315ac43b26d829f55f6f281050f6)) +- Table view switch to the graph component ([#1381](https://github.com/juspay/hyperswitch-control-center/pull/1381)) ([`70b7a61`](https://github.com/juspay/hyperswitch-control-center/commit/70b7a615fb5c99e409a213102a2987bbca03b855)) + +### Miscellaneous Tasks + +- Analytics entity refactor ([#1377](https://github.com/juspay/hyperswitch-control-center/pull/1377)) ([`52fecda`](https://github.com/juspay/hyperswitch-control-center/commit/52fecdabeb832e938c1f07bd66465f5654aea171)) +- Taxjar icon ([#1403](https://github.com/juspay/hyperswitch-control-center/pull/1403)) ([`af175be`](https://github.com/juspay/hyperswitch-control-center/commit/af175be31897efc133b8ffe8fe020afe55a80216)) +- Tax processor ([#1405](https://github.com/juspay/hyperswitch-control-center/pull/1405)) ([`6fc6374`](https://github.com/juspay/hyperswitch-control-center/commit/6fc6374ad4ed30ee613c13f7bfed5b5f6b666f6a)) + +**Full Changelog:** [`2024.09.17.0...2024.09.17.1`](https://github.com/juspay/hyperswitch-control-center/compare/2024.09.17.0...2024.09.17.1) + +- - - + +## 2024.09.17.0 + +### Features + +- Core file changes for tax processor addition ([#1378](https://github.com/juspay/hyperswitch-control-center/pull/1378)) ([`9aba852`](https://github.com/juspay/hyperswitch-control-center/commit/9aba85242e62c5d723d74992fa389265148ad99d)) +- Payment operation revamp ([#1203](https://github.com/juspay/hyperswitch-control-center/pull/1203)) ([`2fee0ee`](https://github.com/juspay/hyperswitch-control-center/commit/2fee0ee3cc087496604cd65376745cd8c9bd8740)) +- Novalnet connector addition ([#1373](https://github.com/juspay/hyperswitch-control-center/pull/1373)) ([`989b1f6`](https://github.com/juspay/hyperswitch-control-center/commit/989b1f69a1c7cb0fd5e03f3bc10ff6a1cb53950f)) + +### Miscellaneous Tasks + +- Moved user management files from old modules ([#1389](https://github.com/juspay/hyperswitch-control-center/pull/1389)) ([`188a136`](https://github.com/juspay/hyperswitch-control-center/commit/188a13685f6017d32c597b53febf0d0a5b6d2d62)) +- Update wasm for tax processor ([#1391](https://github.com/juspay/hyperswitch-control-center/pull/1391)) ([`7a40f4a`](https://github.com/juspay/hyperswitch-control-center/commit/7a40f4a3ea155e99e4f24009ded9a572f9966866)) +- Unused vars removed ([#1383](https://github.com/juspay/hyperswitch-control-center/pull/1383)) ([`790040d`](https://github.com/juspay/hyperswitch-control-center/commit/790040d4e9c1c3fec1dfab2cc41eb47f3c8a05e8)) + +**Full Changelog:** [`2024.09.16.0...2024.09.17.0`](https://github.com/juspay/hyperswitch-control-center/compare/2024.09.16.0...2024.09.17.0) + +- - - + +## 2024.09.16.0 + +### Miscellaneous Tasks + +- Line graph utils ([#1349](https://github.com/juspay/hyperswitch-control-center/pull/1349)) ([`ba4e885`](https://github.com/juspay/hyperswitch-control-center/commit/ba4e88565818551f1a82bc6c76da6dff1ceb4273)) + +**Full Changelog:** [`2024.09.13.0...2024.09.16.0`](https://github.com/juspay/hyperswitch-control-center/compare/2024.09.13.0...2024.09.16.0) + +- - - + +## 2024.09.13.0 + +### Bug Fixes + +- Volume based routing fix ([#1365](https://github.com/juspay/hyperswitch-control-center/pull/1365)) ([`8bc98e4`](https://github.com/juspay/hyperswitch-control-center/commit/8bc98e4ae0b61001d3ac23a3ddaac16e26dee2c0)) +- Global search fixes ([#1366](https://github.com/juspay/hyperswitch-control-center/pull/1366)) ([`7274021`](https://github.com/juspay/hyperswitch-control-center/commit/727402161be194f636f91f5cb1e416ec6e256596)) + +### Miscellaneous Tasks + +- Add a sankey utils graph ([#1371](https://github.com/juspay/hyperswitch-control-center/pull/1371)) ([`74f5d0c`](https://github.com/juspay/hyperswitch-control-center/commit/74f5d0cc60fa2fd6667f7f0dbbb552d6bd238b1e)) + +**Full Changelog:** [`2024.09.11.1...2024.09.13.0`](https://github.com/juspay/hyperswitch-control-center/compare/2024.09.11.1...2024.09.13.0) + +- - - + ## 2024.09.11.1 ### Bug Fixes @@ -3394,4 +3537,4 @@ All notable changes to this project will be documented in this file. See [conven - - - -Changelog generated by [cocogitto](https://github.com/cocogitto/cocogitto). \ No newline at end of file +Changelog generated by [cocogitto](https://github.com/cocogitto/cocogitto). diff --git a/README.md b/README.md index 600fd1a19..d62c55f06 100644 --- a/README.md +++ b/README.md @@ -419,6 +419,38 @@ Welcome to the standard process for raising a Pull Request (PR) directly from a - Include relevant tests, documentation updates, or screenshots, if applicable. - Collaborate and communicate effectively with other contributors and maintainers throughout the review process. +## Cypress Test Suite + +### Running Tests + +1. + +``` +npm run build:test +npm run test:start +``` + +2. To run tests interactively in Cypress Test Runner: + + ``` + npm run cy:open + + ``` + +3. To run tests in headless mode (CI/CD): + + ``` + npm run cy:run + + ``` + +### Running Tests Locally + +## Prerequisite + +1. Make sure to run the Hyperswitch backend locally by following the instructions at https://github.com/juspay/hyperswitch. +2. Once the backend is running, follow the steps in Running Tests to execute the Cypress test suite. + ## License This project is open-source and available under the Apache 2.0 license. diff --git a/config/config.toml b/config/config.toml index c61b0070f..cec13b7d2 100644 --- a/config/config.toml +++ b/config/config.toml @@ -42,8 +42,8 @@ live_users_counter=false granularity=false custom_webhook_headers=false compliance_certificate=false -user_management_revamp=false pm_authentication_processor=true performance_monitor=false new_analytics=false -down_time=false \ No newline at end of file +down_time=false +tax_processor=true diff --git a/cypress/e2e/auth/auth.cy.js b/cypress/e2e/auth/auth.cy.js index 081c72e0b..d52c4df65 100644 --- a/cypress/e2e/auth/auth.cy.js +++ b/cypress/e2e/auth/auth.cy.js @@ -11,7 +11,7 @@ describe("Auth Module", () => { cy.get("#footer").should("exist"); }); - it("check singup flow", () => { + it("check signup flow", () => { const password = "Cypress98#"; cy.visit("http://localhost:9000/"); cy.get("#card-subtitle").click(); @@ -19,6 +19,7 @@ describe("Auth Module", () => { cy.get("[data-testid=email]").type(username); cy.get("[data-testid=password]").type(password); cy.get('button[type="submit"]').click({ force: true }); + cy.get("[data-testid=skip-now]").click({ force: true }); cy.url().should("eq", "http://localhost:9000/dashboard/home"); }); @@ -57,7 +58,12 @@ describe("Auth Module", () => { sdk_url: "", logo_url: "", favicon_url: "", + agreement_url: "", + agreement_version: "", + apple_pay_certificate_url: "", mixpanel_token: "", + recon_iframe_url: "", + dss_certificate_url: "", }, features: { test_live_toggle: false, @@ -75,12 +81,25 @@ describe("Auth Module", () => { mixpanel: false, generate_report: false, user_journey_analytics: false, + authentication_analytics: false, surcharge: false, - permission_based_module: false, dispute_evidence_upload: false, paypal_automatic_flow: false, - invite_multiple: false, - "accept-invite": false, + threeds_authenticator: false, + global_search: false, + dispute_analytics: false, + configure_pmts: false, + branding: false, + live_users_counter: false, + granularity: false, + custom_webhook_headers: false, + compliance_certificate: false, + user_management_revamp: false, + pm_authentication_processor: true, + performance_monitor: false, + new_analytics: false, + down_time: false, + tax_processor: true, }, }, }).as("getFeatureData"); @@ -90,6 +109,10 @@ describe("Auth Module", () => { cy.url().should("include", "/login"); cy.get("#card-header").should("contain", "Hey there, Welcome back!"); cy.get("#card-subtitle").should("contain", "Sign up"); + cy.get("[data-testid=card-foot-text]") + .should("contain", "sign in using password") + .click(); + cy.get("[data-testid=forgot-password]").click(); cy.url().should("include", "/forget-password"); cy.get("#card-header").should("contain", "Forgot Password?"); @@ -101,6 +124,7 @@ describe("Auth Module", () => { cy.get("[data-testid=email]").type(username); cy.get("[data-testid=password]").type(password); cy.get('button[type="submit"]').click({ force: true }); + cy.get("[data-testid=skip-now]").click({ force: true }); cy.url().should("eq", "http://localhost:9000/dashboard/home"); }); @@ -118,6 +142,7 @@ describe("Auth Module", () => { cy.get("[data-testid=email]").type(` ${username} `); cy.get("[data-testid=password]").type(password); cy.get('button[type="submit"]').click({ force: true }); + cy.get("[data-testid=skip-now]").click({ force: true }); cy.url().should("eq", "http://localhost:9000/dashboard/home"); }); }); diff --git a/cypress/e2e/processors/processores-paypal_test.cy.js b/cypress/e2e/processors/processores-paypal_test.cy.js deleted file mode 100644 index 6ccf1b68f..000000000 --- a/cypress/e2e/processors/processores-paypal_test.cy.js +++ /dev/null @@ -1,101 +0,0 @@ -let username = `cypressprocessores+${Math.round(+new Date() / 1000)}@gmail.com`; -before(() => { - cy.singup_curl(username, "Cypress98#"); -}); -beforeEach(() => { - cy.login_UI(username, "Cypress98#"); -}); -describe("Processors Create Module", () => { - it("should successfully create the paypal test processor", () => { - cy.url().should("eq", "http://localhost:9000/home"); - cy.get('input[name="merchant_name"]').type("paypal_test_cypress_api_key"); - cy.get("[data-button-for=startExploring]").click({ force: true }); - cy.get("[data-testid=connectors]") - .find(".justify-center") - .click({ force: true }); - cy.get("[data-testid=paymentprocessors]").click({ force: true }); - - cy.get("[data-testid=connect_a_test_processor]").contains( - "Connect a test processor", - ); - cy.get("[data-testid=paypal_test]").click({ force: true }); - cy.get('input[name="connector_account_details.api_key"]').clear(); - cy.get('input[name="connector_label"]').clear(); - - cy.get('input[name="connector_account_details.api_key"]').type( - "paypal_test_cypress_api_key", - ); - cy.get('input[name="connector_label"]').type("paypal_test_cypress_label"); - cy.get("[data-button-for=connectAndProceed]").click({ force: true }); - cy.contains( - "NOTE:Please verify if the payment methods are turned on at the processor end as well.", - ).should("be.visible"); - cy.get("[data-testid=credit_mastercard]").click(); - cy.get("[data-testid=debit_select_all]") - .children(".cursor-pointer") - .click({ force: true }); - cy.get("[data-testid=wallet_paypal]").click(); - cy.get("[data-button-for=proceed]").click({ force: true }); - cy.get("[data-testid=connector_status]").should("contain", "ACTIVE"); - cy.get("[data-button-for=done]").click({ force: true }); - cy.get("[data-testid=table-search-filter]").type("VOLT"); - cy.get("[data-component=no-data-available]").should("exist"); - cy.get('input[name="search"]').clear(); - cy.get("[data-testid=table-search-filter]").type("paypal"); - cy.get("[data-table-heading=Processor]").should("exist"); - }); - - it("should successfully delete the paypal test processor", () => { - cy.intercept("/accounts/*").as("getAccount"); - cy.wait("@getAccount").then(() => { - cy.get("[data-testid=connectors]") - .find(".justify-center") - .click({ force: true }); - cy.get("[data-testid=paymentprocessors]").click({ force: true }); - const targetValue = "paypal_test"; - cy.get("table") - .find("td") - .each(($td) => { - // Use .invoke('text') to get the text content of each td - cy.wrap($td) - .invoke("text") - .then((text) => { - // Check if the text content of the current td matches the target value - if (text === targetValue) { - // Perform actions/assertions on the found td - cy.wrap($td) - .should("have.text", targetValue) - .click({ force: true }); - } - }); - }); - - cy.location("pathname").then((pathname) => { - let mca_id = pathname.split("/")[2]; - cy.deleteConnector(mca_id); - cy.visit("http://localhost:9000/connectors"); - }); - }); - }); - - it("should successfully land in the process list page", () => { - cy.get("[data-testid=connectors]") - .find(".justify-center") - .click({ force: true }); - cy.get("[data-testid=paymentprocessors]").click({ force: true }); - cy.url().should("eq", "http://localhost:9000/connectors"); - cy.contains("Processors").should("be.visible"); - cy.contains( - "Connect a test processor and get started with testing your payments", - ).should("be.visible"); - cy.get("[data-testid=connect_a_new_processor]").contains( - "Connect a new processor", - ); - cy.get("[data-testid=search-processor]") - .type("stripe", { force: true }) - .should("have.value", "stripe"); - cy.get("[data-testid=stripe]") - .find("img") - .should("have.attr", "src", "/Gateway/STRIPE.svg"); - }); -}); diff --git a/cypress/e2e/quick-start/prod-quick-start.cy.js b/cypress/e2e/quick-start/prod-quick-start.cy.js deleted file mode 100644 index b9fad60e4..000000000 --- a/cypress/e2e/quick-start/prod-quick-start.cy.js +++ /dev/null @@ -1,126 +0,0 @@ -let username = `cypressquickstart+${Math.round(+new Date() / 1000)}@gmail.com`; -before(() => { - cy.singup_curl(username, "Cypress98#"); -}); -beforeEach(() => { - cy.intercept("GET", "merchant-config?domain=default", { - statusCode: 200, - body: { - theme: { - primary_color: "#006DF9", - primary_hover_color: "#005ED6", - sidebar_color: "#242F48", - }, - endpoints: { - api_url: "http://localhost:8080", - sdk_url: "", - logo_url: "", - favicon_url: "", - mixpanel_token: "", - }, - features: { - test_live_toggle: false, - is_live_mode: true, - email: false, - quick_start: false, - audit_trail: false, - system_metrics: false, - sample_data: false, - frm: false, - payout: true, - recon: false, - test_processors: false, - feedback: false, - mixpanel: false, - generate_report: false, - user_journey_analytics: false, - surcharge: false, - permission_based_module: false, - dispute_evidence_upload: false, - paypal_automatic_flow: false, - invite_multiple: false, - "accept-invite": false, - }, - }, - }).as("getFeatureData"); - cy.intercept("GET", "/agreement/tc-hyperswitch-aug-23.pdf", { - statusCode: 200, - }).as("getPDF"); - cy.visit("http://localhost:9000"); - cy.wait("@getFeatureData"); - cy.login_UI(username, "Cypress98#"); - cy.wait("@getPDF"); -}); -describe("Prod quick start", () => { - it("should successfully accept the agreement", () => { - cy.contains("Hyperswitch Service Agreement").should("be.visible"); - cy.get(".show-scrollbar").scrollTo(0, 300); - cy.get("[data-selected-checkbox=NotSelected]").click({ force: true }); - cy.get("[data-button-for='accept&Proceed']").click({ force: true }); - }); - - it("should successfully setup first processor", () => { - cy.get("[data-button-for='accept&Proceed']").click({ force: true }); - cy.get("[data-testid=adyen]").click(); - cy.get("[data-button-for='proceed']").click({ force: true }); - cy.get('input[name="connector_account_details.api_key"]').type( - "adyen_test_cypress_api_key", - ); - cy.get('input[name="connector_account_details.key1"]').type( - "adyen_test_cypress_account_id", - ); - cy.get('input[name="metadata.endpoint_prefix"]').type("https://adyne.in"); - cy.get('input[name="connector_webhook_details.merchant_secret"]').type( - "adyen_test_cypress_source_verification", - ); - cy.get("[data-selected-checkbox=NotSelected]").click({ force: true }); - cy.get("[data-button-for=back]").should("exist"); - cy.get("[data-button-for=connectAndProceed]").click({ force: true }); - - cy.contains("Setup Webhooks on Adyen"); - cy.contains("Enable relevant webhooks on your Adyen account"); - cy.get("[data-icon=copy]").should("exist"); - cy.get("[data-icon=copy]").click({ force: true }); - cy.get("[data-button-for=connectAndProceed]").click({ force: true }); - cy.contains("Replace API keys & Live Endpoints"); - }); - - it("should successfully configure live endpoints", () => { - cy.get("[data-button-for='accept&Proceed']").click({ force: true }); - cy.contains("Replace API keys & Live Endpoints"); - cy.contains( - "Point your application's client and server to our live environment", - ); - cy.contains("Live Domain"); - cy.contains( - "Configure this base url in your application for all server-server calls", - ); - cy.contains("Publishable Key"); - cy.contains( - "Use this key to authenticate all calls from your application's client to Hyperswitch SDK", - ); - cy.contains("API Key"); - cy.contains( - "Use this key to authenticate all API requests from your application's server to Hyperswitch server", - ); - cy.get("[data-button-for=createAndDownloadAPIKey]").click({ force: true }); - cy.get("[data-button-for=connectAndProceed]").click({ force: true }); - cy.contains("Setup Webhooks On Your End"); - cy.contains( - "Create webhook endpoints to allow us to receive and notify you of payment events", - ); - cy.contains("Merchant Webhook Endpoint"); - cy.contains( - "Provide the endpoint where you would want us to send live payment events", - ); - cy.contains("Payment Response Hash Key"); - cy.contains( - "Download the provided key to authenticate and verify live events sent by Hyperswitch. Learn more", - ); - cy.get('input[name="webhookEndpoint"]').type("https://google.com"); - cy.get("[data-button-for=connectAndProceed]").click({ force: true }); - cy.contains("Basic Account Setup Successful"); - cy.get("[data-button-for=goToDashboard]").click({ force: true }); - cy.url().should("eq", "http://localhost:9000/dashboard/home"); - }); -}); diff --git a/cypress/e2e/quick-start/sbx-quick-start.cy.js b/cypress/e2e/quick-start/sbx-quick-start.cy.js deleted file mode 100644 index c9dc4d2af..000000000 --- a/cypress/e2e/quick-start/sbx-quick-start.cy.js +++ /dev/null @@ -1,159 +0,0 @@ -let username = `cypresssbxquickstart+${Math.round( - +new Date() / 1000, -)}@gmail.com`; -before(() => { - cy.singup_curl(username, "Cypress98#"); -}); -beforeEach(() => { - cy.intercept("GET", "/config/merchant-config?domain=default", { - statusCode: 200, - body: { - theme: { - primary_color: "#006DF9", - primary_hover_color: "#005ED6", - sidebar_color: "#242F48", - }, - endpoints: { - api_url: "http://localhost:8080", - sdk_url: "", - logo_url: "", - favicon_url: "", - mixpanel_token: "", - }, - features: { - test_live_toggle: false, - is_live_mode: false, - email: false, - quick_start: true, - audit_trail: false, - system_metrics: false, - sample_data: false, - frm: false, - payout: true, - recon: false, - test_processors: true, - feedback: false, - mixpanel: false, - generate_report: false, - user_journey_analytics: false, - surcharge: false, - permission_based_module: false, - dispute_evidence_upload: false, - paypal_automatic_flow: false, - invite_multiple: false, - "accept-invite": false, - }, - }, - }).as("getData"); - cy.visit("http://localhost:9000"); - cy.wait("@getData"); - cy.login_UI(username, "Cypress98#"); -}); - -describe("Sandbox quick start", () => { - function clickButton(buttonName) { - cy.get(`[data-button-for=${buttonName}]`).click({ force: true }); - } - - function fillInputFields(inputFieldName, textToFill) { - cy.get(`input[name="${inputFieldName}"]`).type(textToFill); - } - - function customComponentButtonType(componentTestingId) { - cy.get(`[data-testid=${componentTestingId}]`).click({ force: true }); - } - - function selectDropDownOption(dropdownId, dropdownValue) { - cy.get(`[data-dropdown-for="${dropdownId}"]`).click(); - cy.get(`[data-dropdown-value="${dropdownValue}"]`).click(); - } - - it("should successfully setup quickstart flow", () => { - cy.url().should("eq", "http://localhost:9000/home"); - fillInputFields("merchant_name", "quick_start_flow_test"); - cy.contains("Quick Start"); - cy.contains( - "Configure and start using Hyperswitch to get an overview of our offerings and how hyperswitch can help you control your payments", - ); - clickButton("startExploring"); - clickButton("getStartedNow"); - cy.contains("How would you like to configure Hyperswitch?"); - customComponentButtonType("MultipleProcessorWithSmartRouting"); - clickButton("proceed"); - - // to connect stripe - customComponentButtonType("stripe"); - clickButton("proceed"); - customComponentButtonType("ConnectorApiKeys"); - clickButton("proceed"); - fillInputFields( - "connector_account_details.api_key", - "sk_test_stripe_dummy_api_key", - ); - fillInputFields( - "connector_webhook_details.merchant_secret", - "stripe_dummy_source_verification_keys", - ); - clickButton("proceed"); - clickButton("proceed"); - clickButton("proceed"); - clickButton("proceed"); - - // to connect paypal - customComponentButtonType("paypal"); - clickButton("proceed"); - customComponentButtonType("ConnectorApiKeys"); - clickButton("proceed"); - fillInputFields( - "connector_account_details.api_key", - "sk_test_paypal_dummy_api_key", - ); - fillInputFields( - "connector_account_details.key1", - "sk_test_paypal_dummy_client_id", - ); - fillInputFields( - "connector_webhook_details.merchant_secret", - "paypal_dummy_source_verification_keys", - ); - clickButton("proceed"); - clickButton("proceed"); - clickButton("proceed"); - clickButton("proceed"); - - // configure default routing - customComponentButtonType("DefaultFallback"); - clickButton("proceed"); - cy.contains("Preview Checkout page"); - cy.get(`[data-button-for=skipThisStep]`).should("be.visible"); - clickButton("skipThisStep"); - cy.contains( - "Configuration is complete. You can now start integrating with us!", - ); - clickButton("iWantToIntegrateHyperswitchIntoMyApp"); - // integrate to my app flow - customComponentButtonType("MigrateFromStripe"); - clickButton("proceed"); - clickButton("downloadAPIKey"); - clickButton("proceed"); - clickButton("proceed"); - clickButton("proceed"); - clickButton("proceed"); - clickButton("complete"); - - // prod intent form - clickButton("getProductionAccess"); - fillInputFields("legal_business_name", "temp_business_name"); - selectDropDownOption("Select Country", "Albania"); - fillInputFields("business_website", "https://google.com"); - fillInputFields("poc_name", "temp_poc_name"); - fillInputFields( - "poc_email", - `cypressquickstart+${Math.round(+new Date() / 1000)}@gmail.com`, - ); - fillInputFields("comments", "temp_tax_identification_number"); - clickButton("submit"); - clickButton("goToHome"); - cy.url().should("eq", "http://localhost:9000/home"); - }); -}); diff --git a/cypress/start_hyperswitch.sh b/cypress/start_hyperswitch.sh index 7bbdda23d..c1f1e3950 100755 --- a/cypress/start_hyperswitch.sh +++ b/cypress/start_hyperswitch.sh @@ -5,9 +5,27 @@ curl -L "https://github.com/docker/compose/releases/latest/download/docker-compo cd hyperswitch sed 's|juspaydotin/hyperswitch-router:standalone|juspaydotin/hyperswitch-router:nightly-standalone|g' docker-compose.yml > docker-compose.tmp mv docker-compose.tmp docker-compose.yml -docker --version -# chmod +x /usr/local/bin/docker-compose -# docker-compose -# docker-compose --version -# # Start Docker Compose services in detached mode + +#!/bin/bash + +# Specify the correct file path to the TOML file +#!/bin/bash + +# File path of the TOML file +toml_file="config/docker_compose.toml" # Adjust the path if necessary + +# Ensure the file exists +if [[ ! -f "$toml_file" ]]; then + echo "Error: File $toml_file not found!" + exit 1 +fi + +# Use sed to remove the [network_tokenization_service] section and all its keys +sed '/^\[network_tokenization_service\]/,/^\[.*\]/d' "$toml_file" > temp.toml +mv temp.toml "$toml_file" +echo "[network_tokenization_service] section removed from $toml_file." + + +chmod +x /usr/local/bin/docker-compose +# Start Docker Compose services in detached mode docker-compose up -d pg redis-standalone migration_runner hyperswitch-server \ No newline at end of file diff --git a/cypress/support/commands.js b/cypress/support/commands.js index f2a3ff864..0acebd946 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -31,6 +31,7 @@ Cypress.Commands.add("login_UI", (name = "", pass = "") => { cy.get("[data-testid=email]").type(username); cy.get("[data-testid=password]").type(password); cy.get('button[type="submit"]').click({ force: true }); + cy.get("[data-testid=skip-now]").click({ force: true }); }); Cypress.Commands.add("singup_curl", (name = "", pass = "") => { diff --git a/package.json b/package.json index 6edb890b8..a8f7dd6b9 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "postinstall": "git config core.hooksPath .githooks && chmod +x .githooks/commit-msg", "cy:open": "sh cypress/start_hyperswitch.sh && cypress open", "cy:run": "sh cypress/start_hyperswitch.sh && cypress run", + "local:cy:open": "cypress open", "lint:hooks": "eslint src/ --max-warnings 0" }, "husky": { diff --git a/public/hyperswitch/Gateway/DEUTSCHEBANK.svg b/public/hyperswitch/Gateway/DEUTSCHEBANK.svg new file mode 100644 index 000000000..d52e3182d --- /dev/null +++ b/public/hyperswitch/Gateway/DEUTSCHEBANK.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/hyperswitch/Gateway/NOVALNET.svg b/public/hyperswitch/Gateway/NOVALNET.svg new file mode 100644 index 000000000..c34b1549f --- /dev/null +++ b/public/hyperswitch/Gateway/NOVALNET.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/hyperswitch/Gateway/TAXJAR.svg b/public/hyperswitch/Gateway/TAXJAR.svg new file mode 100644 index 000000000..aeb145d4b --- /dev/null +++ b/public/hyperswitch/Gateway/TAXJAR.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/hyperswitch/icons/solid.svg b/public/hyperswitch/icons/solid.svg index c3a1c017c..a6d02b8b9 100644 --- a/public/hyperswitch/icons/solid.svg +++ b/public/hyperswitch/icons/solid.svg @@ -34,6 +34,26 @@ License) fill="#29242E" /> + + + + + + + + + + + + + + + + + + + + void; readonly getPayoutConnectorConfig: (a: number, b: number, c: number) => void; readonly getAuthenticationConnectorConfig: (a: number, b: number, c: number) => void; + readonly getTaxProcessorConfig: (a: number, b: number, c: number) => void; readonly getPMAuthenticationProcessorConfig: (a: number, b: number, c: number) => void; readonly getRequestPayload: (a: number, b: number, c: number) => void; readonly getResponsePayload: (a: number, b: number) => void; @@ -181,18 +187,18 @@ export type SyncInitInput = BufferSource | WebAssembly.Module; * Instantiates the given `module`, which can either be bytes or * a precompiled `WebAssembly.Module`. * -* @param {SyncInitInput} module +* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated. * * @returns {InitOutput} */ -export function initSync(module: SyncInitInput): InitOutput; +export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput; /** * If `module_or_path` is {RequestInfo} or {URL}, makes a request and * for everything else, calls `WebAssembly.instantiate` directly. * -* @param {InitInput | Promise} module_or_path +* @param {{ module_or_path: InitInput | Promise }} module_or_path - Passing `InitInput` directly is deprecated. * * @returns {Promise} */ -export default function __wbg_init (module_or_path?: InitInput | Promise): Promise; +export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise } | InitInput | Promise): Promise; diff --git a/public/hyperswitch/wasm/euclid.js b/public/hyperswitch/wasm/euclid.js index 975bd3d55..c56bc18bc 100644 --- a/public/hyperswitch/wasm/euclid.js +++ b/public/hyperswitch/wasm/euclid.js @@ -4,18 +4,18 @@ const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder( if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; -let cachedUint8Memory0 = null; +let cachedUint8ArrayMemory0 = null; -function getUint8Memory0() { - if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) { - cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); } - return cachedUint8Memory0; + return cachedUint8ArrayMemory0; } function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); } const heap = new Array(128).fill(undefined); @@ -69,7 +69,7 @@ function passStringToWasm0(arg, malloc, realloc) { if (realloc === undefined) { const buf = cachedTextEncoder.encode(arg); const ptr = malloc(buf.length, 1) >>> 0; - getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf); + getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); WASM_VECTOR_LEN = buf.length; return ptr; } @@ -77,7 +77,7 @@ function passStringToWasm0(arg, malloc, realloc) { let len = arg.length; let ptr = malloc(len, 1) >>> 0; - const mem = getUint8Memory0(); + const mem = getUint8ArrayMemory0(); let offset = 0; @@ -92,7 +92,7 @@ function passStringToWasm0(arg, malloc, realloc) { arg = arg.slice(offset); } ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; - const view = getUint8Memory0().subarray(ptr + offset, ptr + len); + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); const ret = encodeString(arg, view); offset += ret.written; @@ -107,31 +107,13 @@ function isLikeNone(x) { return x === undefined || x === null; } -let cachedInt32Memory0 = null; +let cachedDataViewMemory0 = null; -function getInt32Memory0() { - if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) { - cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); } - return cachedInt32Memory0; -} - -let cachedFloat64Memory0 = null; - -function getFloat64Memory0() { - if (cachedFloat64Memory0 === null || cachedFloat64Memory0.byteLength === 0) { - cachedFloat64Memory0 = new Float64Array(wasm.memory.buffer); - } - return cachedFloat64Memory0; -} - -let cachedBigInt64Memory0 = null; - -function getBigInt64Memory0() { - if (cachedBigInt64Memory0 === null || cachedBigInt64Memory0.byteLength === 0) { - cachedBigInt64Memory0 = new BigInt64Array(wasm.memory.buffer); - } - return cachedBigInt64Memory0; + return cachedDataViewMemory0; } function debugString(val) { @@ -209,9 +191,9 @@ export function setForexData(forex) { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.setForexData(retptr, addHeapObject(forex)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -234,9 +216,9 @@ export function convertCurrency(amount, from_currency, to_currency) { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.convertCurrency(retptr, amount, addHeapObject(from_currency), addHeapObject(to_currency)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -257,9 +239,9 @@ export function seedKnowledgeGraph(mcas) { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.seedKnowledgeGraph(retptr, addHeapObject(mcas)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -280,9 +262,9 @@ export function getValidConnectorsForRule(rule) { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.getValidConnectorsForRule(retptr, addHeapObject(rule)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -300,9 +282,9 @@ export function analyzeProgram(js_program) { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.analyzeProgram(retptr, addHeapObject(js_program)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -321,9 +303,9 @@ export function runProgram(program, input) { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.runProgram(retptr, addHeapObject(program), addHeapObject(input)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -340,9 +322,9 @@ export function getAllConnectors() { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.getAllConnectors(retptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -359,9 +341,9 @@ export function getAllKeys() { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.getAllKeys(retptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -383,10 +365,10 @@ export function getKeyType(key) { const ptr0 = passStringToWasm0(key, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); const len0 = WASM_VECTOR_LEN; wasm.getKeyType(retptr, ptr0, len0); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; - var r3 = getInt32Memory0()[retptr / 4 + 3]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); var ptr2 = r0; var len2 = r1; if (r3) { @@ -409,9 +391,9 @@ export function getThreeDsKeys() { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.getThreeDsKeys(retptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -428,9 +410,9 @@ export function getSurchargeKeys() { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.getSurchargeKeys(retptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -452,8 +434,8 @@ export function parseToString(val) { const ptr0 = passStringToWasm0(val, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); const len0 = WASM_VECTOR_LEN; wasm.parse(retptr, ptr0, len0); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); deferred2_0 = r0; deferred2_1 = r1; return getStringFromWasm0(r0, r1); @@ -473,9 +455,9 @@ export function getVariantValues(key) { const ptr0 = passStringToWasm0(key, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); const len0 = WASM_VECTOR_LEN; wasm.getVariantValues(retptr, ptr0, len0); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -502,9 +484,9 @@ export function getDescriptionCategory() { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.getDescriptionCategory(retptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -524,9 +506,9 @@ export function getConnectorConfig(key) { const ptr0 = passStringToWasm0(key, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); const len0 = WASM_VECTOR_LEN; wasm.getConnectorConfig(retptr, ptr0, len0); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -546,9 +528,9 @@ export function getPayoutConnectorConfig(key) { const ptr0 = passStringToWasm0(key, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); const len0 = WASM_VECTOR_LEN; wasm.getPayoutConnectorConfig(retptr, ptr0, len0); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -568,9 +550,31 @@ export function getAuthenticationConnectorConfig(key) { const ptr0 = passStringToWasm0(key, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); const len0 = WASM_VECTOR_LEN; wasm.getAuthenticationConnectorConfig(retptr, ptr0, len0); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** +* @param {string} key +* @returns {any} +*/ +export function getTaxProcessorConfig(key) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(key, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); + const len0 = WASM_VECTOR_LEN; + wasm.getTaxProcessorConfig(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -590,9 +594,9 @@ export function getPMAuthenticationProcessorConfig(key) { const ptr0 = passStringToWasm0(key, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); const len0 = WASM_VECTOR_LEN; wasm.getPMAuthenticationProcessorConfig(retptr, ptr0, len0); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -611,9 +615,9 @@ export function getRequestPayload(input, response) { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.getRequestPayload(retptr, addHeapObject(input), addHeapObject(response)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -631,9 +635,9 @@ export function getResponsePayload(input) { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.getResponsePayload(retptr, addHeapObject(input)); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -650,9 +654,9 @@ export function getAllPayoutKeys() { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.getAllPayoutKeys(retptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -672,9 +676,9 @@ export function getPayoutVariantValues(key) { const ptr0 = passStringToWasm0(key, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); const len0 = WASM_VECTOR_LEN; wasm.getPayoutVariantValues(retptr, ptr0, len0); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -691,9 +695,9 @@ export function getPayoutDescriptionCategory() { try { const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); wasm.getPayoutDescriptionCategory(retptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var r2 = getInt32Memory0()[retptr / 4 + 2]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); if (r2) { throw takeObject(r1); } @@ -725,8 +729,8 @@ export function parse(val) { const ptr0 = passStringToWasm0(val, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); const len0 = WASM_VECTOR_LEN; wasm.parse(retptr, ptr0, len0); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); deferred2_0 = r0; deferred2_1 = r1; return getStringFromWasm0(r0, r1); @@ -777,14 +781,14 @@ function __wbg_get_imports() { imports.wbg.__wbindgen_object_drop_ref = function(arg0) { takeObject(arg0); }; - imports.wbg.__wbg_new_16b304a2cfa7ff4a = function() { + imports.wbg.__wbg_new_a220cf903aa02ca2 = function() { const ret = new Array(); return addHeapObject(ret); }; - imports.wbg.__wbg_set_d4638f722068f043 = function(arg0, arg1, arg2) { + imports.wbg.__wbg_set_673dda6c73d19609 = function(arg0, arg1, arg2) { getObject(arg0)[arg1 >>> 0] = takeObject(arg2); }; - imports.wbg.__wbg_set_8417257aaedc936b = function(arg0, arg1, arg2) { + imports.wbg.__wbg_set_49185437f0ab06f8 = function(arg0, arg1, arg2) { const ret = getObject(arg0).set(getObject(arg1), getObject(arg2)); return addHeapObject(ret); }; @@ -804,8 +808,8 @@ function __wbg_get_imports() { const ret = typeof(obj) === 'string' ? obj : undefined; var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); var len1 = WASM_VECTOR_LEN; - getInt32Memory0()[arg0 / 4 + 1] = len1; - getInt32Memory0()[arg0 / 4 + 0] = ptr1; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); }; imports.wbg.__wbindgen_jsval_loose_eq = function(arg0, arg1) { const ret = getObject(arg0) == getObject(arg1); @@ -828,31 +832,31 @@ function __wbg_get_imports() { const ret = getObject(arg0) in getObject(arg1); return ret; }; - imports.wbg.__wbg_entries_95cc2c823b285a09 = function(arg0) { + imports.wbg.__wbg_entries_7a0e06255456ebcd = function(arg0) { const ret = Object.entries(getObject(arg0)); return addHeapObject(ret); }; - imports.wbg.__wbg_length_cd7af8117672b8b8 = function(arg0) { + imports.wbg.__wbg_length_ae22078168b726f5 = function(arg0) { const ret = getObject(arg0).length; return ret; }; - imports.wbg.__wbg_get_bd8e338fbd5f5cc8 = function(arg0, arg1) { + imports.wbg.__wbg_get_3baa728f9d58d3f6 = function(arg0, arg1) { const ret = getObject(arg0)[arg1 >>> 0]; return addHeapObject(ret); }; - imports.wbg.__wbg_isArray_2ab64d95e09ea0ae = function(arg0) { + imports.wbg.__wbg_isArray_8364a5371e9737d8 = function(arg0) { const ret = Array.isArray(getObject(arg0)); return ret; }; - imports.wbg.__wbg_next_196c84450b364254 = function() { return handleError(function (arg0) { + imports.wbg.__wbg_next_f9cb570345655b9a = function() { return handleError(function (arg0) { const ret = getObject(arg0).next(); return addHeapObject(ret); }, arguments) }; - imports.wbg.__wbg_done_298b57d23c0fc80c = function(arg0) { + imports.wbg.__wbg_done_bfda7aa8f252b39f = function(arg0) { const ret = getObject(arg0).done; return ret; }; - imports.wbg.__wbg_value_d93c65011f51a456 = function(arg0) { + imports.wbg.__wbg_value_6d39332ab4788d86 = function(arg0) { const ret = getObject(arg0).value; return addHeapObject(ret); }; @@ -861,7 +865,7 @@ function __wbg_get_imports() { const ret = typeof(v) === 'boolean' ? (v ? 1 : 0) : 2; return ret; }; - imports.wbg.__wbg_new_72fb9a18b5ae2624 = function() { + imports.wbg.__wbg_new_525245e2b9901204 = function() { const ret = new Object(); return addHeapObject(ret); }; @@ -872,14 +876,14 @@ function __wbg_get_imports() { imports.wbg.__wbindgen_number_get = function(arg0, arg1) { const obj = getObject(arg1); const ret = typeof(obj) === 'number' ? obj : undefined; - getFloat64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? 0 : ret; - getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret); + getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true); }; - imports.wbg.__wbg_iterator_2cee6dadfd956dfa = function() { + imports.wbg.__wbg_iterator_888179a48810a9fe = function() { const ret = Symbol.iterator; return addHeapObject(ret); }; - imports.wbg.__wbg_instanceof_Map_87917e0a7aaf4012 = function(arg0) { + imports.wbg.__wbg_instanceof_Map_763ce0e95960d55e = function(arg0) { let result; try { result = getObject(arg0) instanceof Map; @@ -889,15 +893,15 @@ function __wbg_get_imports() { const ret = result; return ret; }; - imports.wbg.__wbg_isSafeInteger_f7b04ef02296c4d2 = function(arg0) { + imports.wbg.__wbg_isSafeInteger_7f1ed56200d90674 = function(arg0) { const ret = Number.isSafeInteger(getObject(arg0)); return ret; }; imports.wbg.__wbindgen_bigint_get_as_i64 = function(arg0, arg1) { const v = getObject(arg1); const ret = typeof(v) === 'bigint' ? v : undefined; - getBigInt64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? BigInt(0) : ret; - getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret); + getDataViewMemory0().setBigInt64(arg0 + 8 * 1, isLikeNone(ret) ? BigInt(0) : ret, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true); }; imports.wbg.__wbindgen_bigint_from_i64 = function(arg0) { const ret = arg0; @@ -915,7 +919,7 @@ function __wbg_get_imports() { const ret = arg0; return addHeapObject(ret); }; - imports.wbg.__wbg_new_d9bc3a0147634640 = function() { + imports.wbg.__wbg_new_8608a2b51a5f6737 = function() { const ret = new Map(); return addHeapObject(ret); }; @@ -923,14 +927,14 @@ function __wbg_get_imports() { const ret = String(getObject(arg1)); const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); const len1 = WASM_VECTOR_LEN; - getInt32Memory0()[arg0 / 4 + 1] = len1; - getInt32Memory0()[arg0 / 4 + 0] = ptr1; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); }; imports.wbg.__wbindgen_as_number = function(arg0) { const ret = +getObject(arg0); return ret; }; - imports.wbg.__wbg_fromCodePoint_cedd7612a2ff688f = function() { return handleError(function (arg0) { + imports.wbg.__wbg_fromCodePoint_ae875c4ff5f6a86b = function() { return handleError(function (arg0) { const ret = String.fromCodePoint(arg0 >>> 0); return addHeapObject(ret); }, arguments) }; @@ -946,19 +950,19 @@ function __wbg_get_imports() { const ret = wasm.memory; return addHeapObject(ret); }; - imports.wbg.__wbg_buffer_12d079cc21e14bdb = function(arg0) { + imports.wbg.__wbg_buffer_b7b08af79b0b0974 = function(arg0) { const ret = getObject(arg0).buffer; return addHeapObject(ret); }; - imports.wbg.__wbg_newwithbyteoffsetandlength_aa4a17c33a06e5cb = function(arg0, arg1, arg2) { + imports.wbg.__wbg_newwithbyteoffsetandlength_8a2cb9ca96b27ec9 = function(arg0, arg1, arg2) { const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); return addHeapObject(ret); }; - imports.wbg.__wbg_new_63b92bc8671ed464 = function(arg0) { + imports.wbg.__wbg_new_ea1883e1e5e86686 = function(arg0) { const ret = new Uint8Array(getObject(arg0)); return addHeapObject(ret); }; - imports.wbg.__wbg_from_89e3fc3ba5e6fb48 = function(arg0) { + imports.wbg.__wbg_from_0791d740a9d37830 = function(arg0) { const ret = Array.from(getObject(arg0)); return addHeapObject(ret); }; @@ -966,7 +970,7 @@ function __wbg_get_imports() { const ret = getObject(arg0); return addHeapObject(ret); }; - imports.wbg.__wbg_get_e3c254076557e348 = function() { return handleError(function (arg0, arg1) { + imports.wbg.__wbg_get_224d16597dbbfd96 = function() { return handleError(function (arg0, arg1) { const ret = Reflect.get(getObject(arg0), getObject(arg1)); return addHeapObject(ret); }, arguments) }; @@ -974,22 +978,22 @@ function __wbg_get_imports() { const ret = typeof(getObject(arg0)) === 'function'; return ret; }; - imports.wbg.__wbg_call_27c0f87801dedf93 = function() { return handleError(function (arg0, arg1) { + imports.wbg.__wbg_call_1084a111329e68ce = function() { return handleError(function (arg0, arg1) { const ret = getObject(arg0).call(getObject(arg1)); return addHeapObject(ret); }, arguments) }; - imports.wbg.__wbg_next_40fc327bfc8770e6 = function(arg0) { + imports.wbg.__wbg_next_de3e9db4440638b2 = function(arg0) { const ret = getObject(arg0).next; return addHeapObject(ret); }; - imports.wbg.__wbg_length_c20a40f15020d68a = function(arg0) { + imports.wbg.__wbg_length_8339fcf5d8ecd12e = function(arg0) { const ret = getObject(arg0).length; return ret; }; - imports.wbg.__wbg_set_a47bac70306a19a7 = function(arg0, arg1, arg2) { + imports.wbg.__wbg_set_d1e79e2388520f18 = function(arg0, arg1, arg2) { getObject(arg0).set(getObject(arg1), arg2 >>> 0); }; - imports.wbg.__wbg_instanceof_Uint8Array_2b3bbecd033d19f6 = function(arg0) { + imports.wbg.__wbg_instanceof_Uint8Array_247a91427532499e = function(arg0) { let result; try { result = getObject(arg0) instanceof Uint8Array; @@ -999,7 +1003,7 @@ function __wbg_get_imports() { const ret = result; return ret; }; - imports.wbg.__wbg_instanceof_ArrayBuffer_836825be07d4c9d2 = function(arg0) { + imports.wbg.__wbg_instanceof_ArrayBuffer_61dfc3198373c902 = function(arg0) { let result; try { result = getObject(arg0) instanceof ArrayBuffer; @@ -1009,31 +1013,30 @@ function __wbg_get_imports() { const ret = result; return ret; }; + imports.wbg.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; imports.wbg.__wbindgen_debug_string = function(arg0, arg1) { const ret = debugString(getObject(arg1)); const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); const len1 = WASM_VECTOR_LEN; - getInt32Memory0()[arg0 / 4 + 1] = len1; - getInt32Memory0()[arg0 / 4 + 0] = ptr1; - }; - imports.wbg.__wbindgen_throw = function(arg0, arg1) { - throw new Error(getStringFromWasm0(arg0, arg1)); + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); }; return imports; } -function __wbg_init_memory(imports, maybe_memory) { +function __wbg_init_memory(imports, memory) { } function __wbg_finalize_init(instance, module) { wasm = instance.exports; __wbg_init.__wbindgen_wasm_module = module; - cachedBigInt64Memory0 = null; - cachedFloat64Memory0 = null; - cachedInt32Memory0 = null; - cachedUint8Memory0 = null; + cachedDataViewMemory0 = null; + cachedUint8ArrayMemory0 = null; + return wasm; @@ -1042,6 +1045,12 @@ function __wbg_finalize_init(instance, module) { function initSync(module) { if (wasm !== undefined) return wasm; + + if (typeof module !== 'undefined' && Object.getPrototypeOf(module) === Object.prototype) + ({module} = module) + else + console.warn('using deprecated parameters for `initSync()`; pass a single object instead') + const imports = __wbg_get_imports(); __wbg_init_memory(imports); @@ -1055,24 +1064,30 @@ function initSync(module) { return __wbg_finalize_init(instance, module); } -async function __wbg_init(input) { +async function __wbg_init(module_or_path) { if (wasm !== undefined) return wasm; - if (typeof input === 'undefined') { - input = new URL('euclid_bg.wasm', import.meta.url); + + if (typeof module_or_path !== 'undefined' && Object.getPrototypeOf(module_or_path) === Object.prototype) + ({module_or_path} = module_or_path) + else + console.warn('using deprecated parameters for the initialization function; pass a single object instead') + + if (typeof module_or_path === 'undefined') { + module_or_path = new URL('euclid_bg.wasm', import.meta.url); } const imports = __wbg_get_imports(); - if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) { - input = fetch(input); + if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) { + module_or_path = fetch(module_or_path); } __wbg_init_memory(imports); - const { instance, module } = await __wbg_load(await input, imports); + const { instance, module } = await __wbg_load(await module_or_path, imports); return __wbg_finalize_init(instance, module); } -export { initSync } +export { initSync }; export default __wbg_init; diff --git a/public/hyperswitch/wasm/euclid_bg.wasm b/public/hyperswitch/wasm/euclid_bg.wasm index 5d4269299..1cce4fa43 100644 Binary files a/public/hyperswitch/wasm/euclid_bg.wasm and b/public/hyperswitch/wasm/euclid_bg.wasm differ diff --git a/public/hyperswitch/wasm/euclid_bg.wasm.d.ts b/public/hyperswitch/wasm/euclid_bg.wasm.d.ts index 5b658ab7f..e0c546f49 100644 --- a/public/hyperswitch/wasm/euclid_bg.wasm.d.ts +++ b/public/hyperswitch/wasm/euclid_bg.wasm.d.ts @@ -18,6 +18,7 @@ export function getDescriptionCategory(a: number): void; export function getConnectorConfig(a: number, b: number, c: number): void; export function getPayoutConnectorConfig(a: number, b: number, c: number): void; export function getAuthenticationConnectorConfig(a: number, b: number, c: number): void; +export function getTaxProcessorConfig(a: number, b: number, c: number): void; export function getPMAuthenticationProcessorConfig(a: number, b: number, c: number): void; export function getRequestPayload(a: number, b: number, c: number): void; export function getResponsePayload(a: number, b: number): void; diff --git a/src/components/Accordion.res b/src/components/Accordion.res index d5d1f00a7..c0418cb32 100644 --- a/src/components/Accordion.res +++ b/src/components/Accordion.res @@ -87,7 +87,7 @@ module AccordionInfo = { ) => { let (isExpanded, setIsExpanded) = React.useState(() => expanded) - let handleClick = _e => { + let handleClick = _ => { setIsExpanded(prevExpanded => !prevExpanded) } diff --git a/src/components/Calendar.res b/src/components/Calendar.res index e810efb39..d997c106d 100644 --- a/src/components/Calendar.res +++ b/src/components/Calendar.res @@ -116,7 +116,7 @@ module TableRow = { | None => true } - let onClick = _evt => { + let onClick = _ => { let isClickDisabled = (endDate->isEmptyString && !isInLimit) || (isFutureDate ? disableFutureDates : disablePastDates) || @@ -252,7 +252,7 @@ module TableRow = { className={classN} onClick onMouseOver={_ => handleHover()} - onMouseOut={_evt => setHoverdDate(_ => "")}> + onMouseOut={_ => setHoverdDate(_ => "")}> { let {globalUIConfig: {font: {textColor}}} = React.useContext(ThemeProvider.themeContext) - let onCardClick = _ev => { + let onCardClick = _ => { switch onRowClick { | Some(fn) => fn(rowIndex + offset) | None => () @@ -53,7 +53,7 @@ module CardDetails = { let (show, setshow) = React.useState(_ => true) - let showMore = _ev => { + let showMore = _ => { setshow(prev => !prev) } diff --git a/src/components/Chip.res b/src/components/Chip.res index c6b50b3b4..4b1c66bf2 100644 --- a/src/components/Chip.res +++ b/src/components/Chip.res @@ -4,7 +4,7 @@ let make = (~values=[], ~showButton=false, ~onButtonClick=_ => (), ~converterFn=
{values ->Array.map(value => { - let onClick = _evt => { + let onClick = _ => { onButtonClick(value) }
!p) }, ) - let changeVisibility = _ev => { + let changeVisibility = _ => { if !isDisabled { setIsExpanded(p => !p) } diff --git a/src/components/DateRangeField.res b/src/components/DateRangeField.res index aa76198bb..4518cbd47 100644 --- a/src/components/DateRangeField.res +++ b/src/components/DateRangeField.res @@ -400,7 +400,7 @@ module Base = { changeStartDate(str, true, None) } - let handleApply = _ev => { + let handleApply = _ => { setShowOption(_ => false) setCalendarVisibility(p => !p) setIsDropdownExpanded(_ => false) @@ -440,7 +440,7 @@ module Base = { } let startTimeInput: ReactFinalForm.fieldRenderPropsInput = { name: "string", - onBlur: _ev => (), + onBlur: _ => (), onChange: timeValEv => { let startTimeVal = timeValEv->Identity.formReactEventToString let endTime = localEndDate->getTimeStringForValue(isoStringToCustomTimeZone) @@ -457,13 +457,13 @@ module Base = { } } }, - onFocus: _ev => (), + onFocus: _ => (), value: localStartDate->getTimeStringForValue(isoStringToCustomTimeZone)->JSON.Encode.string, checked: false, } let endTimeInput: ReactFinalForm.fieldRenderPropsInput = { name: "string", - onBlur: _ev => (), + onBlur: _ => (), onChange: timeValEv => { let endTimeVal = timeValEv->Identity.formReactEventToString let startTime = localStartDate->getTimeStringForValue(isoStringToCustomTimeZone) @@ -479,7 +479,7 @@ module Base = { } } }, - onFocus: _ev => (), + onFocus: _ => (), value: localEndDate->getTimeStringForValue(isoStringToCustomTimeZone)->JSON.Encode.string, checked: false, } @@ -837,7 +837,7 @@ module Base = { leaveTo="transform opacity-0 scale-95">
ReactDOM.Ref.domRef} - className={`${dropdownVisibilityClass} absolute ${dropdownPosition} z-20 max-h-min max-w-min overflow-auto bg-white dark:bg-jp-gray-950 rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none mt-2`}> + className={`${dropdownVisibilityClass} absolute ${dropdownPosition} z-20 max-h-min max-w-min overflow-auto bg-white dark:bg-jp-gray-950 rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none mt-2 right-0`}> calendarElement
diff --git a/src/components/DateRangePicker.res b/src/components/DateRangePicker.res index 227fc9725..70a32a6a4 100644 --- a/src/components/DateRangePicker.res +++ b/src/components/DateRangePicker.res @@ -403,7 +403,7 @@ module Base = { changeStartDate(str, true, None) } - let handleApply = _ev => { + let handleApply = _ => { setShowOption(_ => false) setCalendarVisibility(p => !p) setIsDropdownExpanded(_ => false) @@ -443,7 +443,7 @@ module Base = { } let startTimeInput: ReactFinalForm.fieldRenderPropsInput = { name: "string", - onBlur: _ev => (), + onBlur: _ => (), onChange: timeValEv => { let startTimeVal = timeValEv->Identity.formReactEventToString let endTime = localEndDate->getTimeStringForValue(isoStringToCustomTimeZone) @@ -460,13 +460,13 @@ module Base = { } } }, - onFocus: _ev => (), + onFocus: _ => (), value: localStartDate->getTimeStringForValue(isoStringToCustomTimeZone)->JSON.Encode.string, checked: false, } let endTimeInput: ReactFinalForm.fieldRenderPropsInput = { name: "string", - onBlur: _ev => (), + onBlur: _ => (), onChange: timeValEv => { let endTimeVal = timeValEv->Identity.formReactEventToString let startTime = localStartDate->getTimeStringForValue(isoStringToCustomTimeZone) @@ -482,7 +482,7 @@ module Base = { } } }, - onFocus: _ev => (), + onFocus: _ => (), value: localEndDate->getTimeStringForValue(isoStringToCustomTimeZone)->JSON.Encode.string, checked: false, } diff --git a/src/components/DynamicChart.res b/src/components/DynamicChart.res index 06e8848d2..313103c4f 100644 --- a/src/components/DynamicChart.res +++ b/src/components/DynamicChart.res @@ -324,7 +324,7 @@ module GranularitySelectBox = { open HeadlessUI <> - {_menuProps => + {_ =>
@@ -352,7 +352,7 @@ module GranularitySelectBox = { leaveTo="transform opacity-0 scale-95"> { - {_props => { + {_ => { <>
{options diff --git a/src/components/DynamicFilter.res b/src/components/DynamicFilter.res index f08056af7..929f361ad 100644 --- a/src/components/DynamicFilter.res +++ b/src/components/DynamicFilter.res @@ -189,7 +189,7 @@ let make = ( buttonSize=Small leftIcon={CustomIcon()} textStyle={`${textColor.primaryNormal}`} - onClick={_ev => setShowModal(_ => true)} + onClick={_ => setShowModal(_ => true)} />
{ + let handleClick = React.useCallback(_ => { handleSelectedTab( ~tabValue={ switch tabNames->Array.get(index) { @@ -171,7 +171,7 @@ module IndicationArrow = { let make = (~iconName, ~side, ~refElement: React.ref>, ~isVisible) => { let isMobileView = MatchMedia.useMobileChecker() let onClick = { - _ev => + _ => refElement.current ->Nullable.toOption ->Option.forEach(input => @@ -399,7 +399,7 @@ let make = ( let scrollRef = React.useRef(Nullable.null) let lastTabRef = React.useRef(Nullable.null) - let onScroll = _ev => { + let onScroll = _ => { setTabScroll( firstTabRef, lastTabRef, @@ -595,7 +595,7 @@ let make = ( buttonSize=Small customButtonStyle=addBtnStyle textStyle=addBtnTextStyle - onClick={_ev => setShowModal(_ => true)} + onClick={_ => setShowModal(_ => true)} />} toolTipPosition=Top tooltipWidthClass="w-fit" diff --git a/src/components/Filter.res b/src/components/Filter.res index 988e42aaa..8267a4f55 100644 --- a/src/components/Filter.res +++ b/src/components/Filter.res @@ -68,7 +68,7 @@ module ClearFilters = { +
} + + ) + ->React.array} +
+ + }} + + +
} + +
{ -
-
- {customLeftView} + {<> +
+
+ {customLeftView} + Array.length > 0}> {allFiltersUI} +
Array.length > 0}> Array.map(item => item.field)} @@ -302,86 +371,15 @@ let make = ( />
-
- Array.length > 0}> - - {_menuProps => -
- - {_buttonProps => { - <> - - {"Add Filters"->React.string} - - }} - - - { - {_props => { - <> -
- {allFilters - ->Array.mapWithIndex((option, i) => - Int.toString}> - {props => -
- -
} -
- ) - ->React.array} -
- - }} -
} -
-
} -
-
-
-
+
0}> 0} />
-
+ } } } diff --git a/src/components/FilterSelectBox.res b/src/components/FilterSelectBox.res index 59c8cc9e8..cd8cc1052 100644 --- a/src/components/FilterSelectBox.res +++ b/src/components/FilterSelectBox.res @@ -539,7 +539,7 @@ module BaseSelect = { setSearchString(_ => str) } - let selectAll = select => _ev => { + let selectAll = select => _ => { let newValues = if select { let newVal = filteredOptions @@ -901,7 +901,7 @@ module BaseSelectButton = { let (itemdata, setItemData) = React.useState(() => "") let (assignButtonState, setAssignButtonState) = React.useState(_ => false) let searchRef = React.useRef(Nullable.null) - let onItemClick = itemData => _ev => { + let onItemClick = itemData => _ => { if !disableSelect { let isSelected = value->JSON.Decode.string->Option.mapOr(false, str => itemData === str) @@ -1212,7 +1212,7 @@ module BaseRadio = { setSearchString(_ => "") }, ) - let onItemClick = (itemData, isDisabled) => _ev => { + let onItemClick = (itemData, isDisabled) => _ => { if !isDisabled { let isSelected = value->JSON.Decode.string->Option.mapOr(false, str => itemData === str) @@ -1612,7 +1612,7 @@ module BaseDropdown = { } } - let removeOption = text => _ev => { + let removeOption = text => _ => { let actualValue = switch Array.find(transformedOptions, option => option.value == text) { | Some(str) => str.value | None => "" @@ -1682,8 +1682,8 @@ module BaseDropdown = { | TopLeft | TopRight => "mb-12" } - let onRadioOptionSelect = _ev => { - newInputRadio.onChange(_ev) + let onRadioOptionSelect = ev => { + newInputRadio.onChange(ev) addButton ? setShowDropDown(_ => true) : setShowDropDown(_ => false) } diff --git a/src/components/HeadlessUISelectBox.res b/src/components/HeadlessUISelectBox.res index ae71801ac..17ba83c8c 100644 --- a/src/components/HeadlessUISelectBox.res +++ b/src/components/HeadlessUISelectBox.res @@ -38,9 +38,9 @@ let make = (
- {_menuProps => + {_ =>
- {_buttonProps => children} + {_ => children} - {_props => + {_ => options ->Array.mapWithIndex((option, index) => { let selected = switch value { @@ -137,7 +137,7 @@ let make = ( } else { - {_props => + {_ => options ->Array.mapWithIndex((option, index) => { let selected = switch value { diff --git a/src/components/InfraCalendar.res b/src/components/InfraCalendar.res index b1105f63c..576663111 100644 --- a/src/components/InfraCalendar.res +++ b/src/components/InfraCalendar.res @@ -68,7 +68,7 @@ module TableRow = { ) let isFutureDate = todayInitial -. date->Date.getTime < 0.0 - let onClick = _evt => { + let onClick = _ => { let isClickDisabled = isFutureDate ? disableFutureDates : disablePastDates switch !isClickDisabled { | true => diff --git a/src/components/InfraCalendarList.res b/src/components/InfraCalendarList.res index 096a8a7af..af2b28184 100644 --- a/src/components/InfraCalendarList.res +++ b/src/components/InfraCalendarList.res @@ -130,8 +130,8 @@ module MonthItem = { open InfraCalendar @react.component let make = ( - ~month as _: option=?, - ~year as _: option=?, + ~month as _, + ~year as _, ~onDateClick=?, ~cellHighlighter=?, ~cellRenderer=?, diff --git a/src/components/NewCalendar.res b/src/components/NewCalendar.res index 74b32e9fc..1506aecd2 100644 --- a/src/components/NewCalendar.res +++ b/src/components/NewCalendar.res @@ -97,7 +97,7 @@ module TableRow = { | None => true } - let onClick = _evt => { + let onClick = _ => { switch setIsDateClicked { | Some(setIsDateClicked) => setIsDateClicked(_ => true) | _ => () @@ -308,7 +308,7 @@ module TableRow = { className={`${classN} ${highlightBgClass} text-sm font-normal`} onClick onMouseOver={_ => handleHover()} - onMouseOut={_evt => setHoverdDate(_ => "")}> + onMouseOut={_ => setHoverdDate(_ => "")}> paginate(Math.Int.max(1, currentPage - 1))} + onClick={_ => paginate(Math.Int.max(1, currentPage - 1))} /> } else { paginate(Math.Int.max(1, currentPage - 1))} + onClick={_ => paginate(Math.Int.max(1, currentPage - 1))} /> }} {pageNumbers @@ -39,7 +39,7 @@ let make = (~resultsPerPage, ~totalResults, ~currentPage, ~paginate, ~btnCount=4
} @@ -74,13 +74,10 @@ module MenuOption = { @react.component let make = ( ~updateStepValue=ConnectorTypes.IntegFields, - ~setCurrentStep, ~disableConnector, ~isConnectorDisabled, ~pageName="connector", - ~connector, ) => { - let mixpanelEvent = MixpanelHook.useSendEvent() let showPopUp = PopUpState.useShowPopUp() let openConfirmationPopUp = _ => { showPopUp({ @@ -101,21 +98,13 @@ module MenuOption = { {_popoverProps => <> - {_buttonProps => } + {_ => } {panelProps => {
+ className="relative flex flex-col bg-white py-1 overflow-hidden rounded ring-1 ring-black ring-opacity-5 w-40"> {<> - { - panelProps["close"]() - mixpanelEvent(~eventName=`processor_update_${connector}`) - setCurrentStep(_ => updateStepValue) - }} - /> { @@ -133,7 +122,6 @@ module MenuOption = { } module ConnectorSummaryGrid = { - open PageLoaderWrapper open CommonAuthHooks @react.component let make = ( @@ -141,7 +129,11 @@ module ConnectorSummaryGrid = { ~connector, ~isPayoutFlow, ~setScreenState, + ~setCurrentStep, + ~updateStepValue=None, + ~getConnectorDetails=None, ) => { + let mixpanelEvent = MixpanelHook.useSendEvent() let businessProfiles = HyperswitchAtom.businessProfilesAtom->Recoil.useRecoilValueFromAtom let defaultBusinessProfile = businessProfiles->MerchantAccountUtils.getValueFromBusinessProfile let currentProfileName = @@ -161,7 +153,7 @@ module ConnectorSummaryGrid = { let dict = isPayoutFlow ? Window.getPayoutConnectorConfig(connector) : Window.getConnectorConfig(connector) - setScreenState(_ => Success) + dict } else { Dict.make()->JSON.Encode.object @@ -210,61 +202,99 @@ module ConnectorSummaryGrid = { {`${currentProfileName.profile_name} - ${connectorInfo.profile_id}`->React.string}
-
-

{"API Keys"->React.string}

+
+
+

{"API Keys"->React.string}

+
- {connectorAccountFields - ->Dict.keysToArray - ->Array.mapWithIndex((field, index) => { - open LogicUtils - let label = connectorAccountFields->getString(field, "") - Int.toString} - label={label} - render={connectorInfo->ConnectorUtils.getConnectorDetailsValue(field)} - /> - }) - ->React.array} +
+
+ {connectorAccountFields + ->Dict.keysToArray + ->Array.mapWithIndex((field, index) => { + open LogicUtils + let label = connectorAccountFields->getString(field, "") + <> + Int.toString} + label={label} + render={connectorInfo->ConnectorUtils.getConnectorDetailsValue(field)} + /> + + }) + ->React.array} +
+ +
+
-
-

{"PMTs"->React.string}

-
-
- -

- {"Improve conversion rate by conditionally managing PMTs visibility on checkout . Visit Settings >"->React.string} - - RescriptReactRouter.push(GlobalVars.appendDashboardPath(~url="/configure-pmts"))} - target="_blank" - className="text-blue-500 underline cursor-pointer"> - {"Configure PMTs at Checkout"->React.string} - -

+ {switch updateStepValue { + | Some(state) => +
+
+

{"PMTs"->React.string}

- {connectorInfo.payment_methods_enabled - ->Array.mapWithIndex((field, index) => { - Int.toString} - label={field.payment_method->LogicUtils.snakeToTitle} - render={Some( - field.payment_method_types - ->Array.map(item => item.payment_method_type->LogicUtils.snakeToTitle) - ->Array.reduce([], (acc, curr) => { - if !(acc->Array.includes(curr)) { - acc->Array.push(curr) - } - acc +
+
+
+ {connectorInfo.payment_methods_enabled + ->Array.mapWithIndex((field, index) => { + Int.toString} + label={field.payment_method->LogicUtils.snakeToTitle} + render={Some( + field.payment_method_types + ->Array.map(item => item.payment_method_type->LogicUtils.snakeToTitle) + ->Array.reduce([], (acc, curr) => { + if !(acc->Array.includes(curr)) { + acc->Array.push(curr) + } + acc + }) + ->Array.joinWith(", "), + )} + /> }) - ->Array.joinWith(", "), - )} - /> - }) - ->React.array} + ->React.array} +
+
{ + mixpanelEvent(~eventName=`processor_update_payment_methods_${connector}`) + + setCurrentStep(_ => state) + }}> + } + toolTipPosition=Top + tooltipWidthClass="w-fit" + /> +
+
+ +
-
+ + | None => React.null + }}
} } @@ -279,6 +309,7 @@ let make = ( ~showMenuOption=true, ~setInitialValues, ~getPayPalStatus, + ~getConnectorDetails=None, ) => { open APIUtils open ConnectorUtils @@ -371,8 +402,7 @@ let make = ( isUpdateFlow setInitialValues /> - | (_, _) => - + | (_, _) => }}
@@ -392,7 +422,15 @@ let make = ( }}
- +
} diff --git a/src/screens/Connectors/ConnectorTypes.res b/src/screens/Connectors/ConnectorTypes.res index 474da4d36..6d39546b4 100644 --- a/src/screens/Connectors/ConnectorTypes.res +++ b/src/screens/Connectors/ConnectorTypes.res @@ -94,6 +94,8 @@ type processorTypes = | PAYBOX | WELLSFARGO | FIUU + | NOVALNET + | DEUTSCHEBANK type threeDsAuthenticatorTypes = THREEDSECUREIO | NETCETERA @@ -103,11 +105,14 @@ type frmTypes = type pmAuthenticationProcessorTypes = PLAID +type taxProcessorTypes = TAXJAR + type connectorTypes = | Processors(processorTypes) | ThreeDsAuthenticator(threeDsAuthenticatorTypes) | FRM(frmTypes) | PMAuthenticationProcessor(pmAuthenticationProcessorTypes) + | TaxProcessor(taxProcessorTypes) | UnknownConnector(string) type paymentMethod = @@ -250,14 +255,26 @@ type connectorPayload = { disabled: bool, payment_methods_enabled: payment_methods_enabled, profile_id: string, - metadata?: JSON.t, + metadata: JSON.t, merchant_connector_id: string, frm_configs?: array, status: string, + connector_webhook_details: JSON.t, + additional_merchant_data: JSON.t, } type connector = - FRMPlayer | Processor | PayoutConnector | ThreeDsAuthenticator | PMAuthenticationProcessor + | FRMPlayer + | Processor + | PayoutConnector + | ThreeDsAuthenticator + | PMAuthenticationProcessor + | TaxProcessor type connectorTypeVariants = - PaymentProcessor | PaymentVas | PayoutProcessor | AuthenticationProcessor | PMAuthProcessor + | PaymentProcessor + | PaymentVas + | PayoutProcessor + | AuthenticationProcessor + | PMAuthProcessor + | TaxProcessor diff --git a/src/screens/Connectors/ConnectorUpdateAuthCreds.res b/src/screens/Connectors/ConnectorUpdateAuthCreds.res new file mode 100644 index 000000000..583b4526f --- /dev/null +++ b/src/screens/Connectors/ConnectorUpdateAuthCreds.res @@ -0,0 +1,160 @@ +@react.component +let make = (~connectorInfo: ConnectorTypes.connectorPayload, ~getConnectorDetails) => { + open ConnectorUtils + open APIUtils + open LogicUtils + open ConnectorAccountDetailsHelper + let mixpanelEvent = MixpanelHook.useSendEvent() + let getURL = useGetURL() + let updateAPIHook = useUpdateMethod(~showErrorToast=false) + let showToast = ToastState.useShowToast() + + let (showModal, setShowFeedbackModal) = React.useState(_ => false) + // Need to remove connector and merge connector and connectorTypeVariants + let (processorType, connectorType) = connectorInfo.connector_type->connectorTypeTuple + let {connector_name: connectorName, merchant_connector_id: connectorId} = connectorInfo + let connectorTypeFromName = connectorName->getConnectorNameTypeFromString(~connectorType) + + React.useEffect(() => { + RescriptReactRouter.replace( + GlobalVars.appendDashboardPath(~url=`/connectors/${connectorId}?name=${connectorName}`), + ) + None + }, []) + + let connectorDetails = React.useMemo(() => { + try { + if connectorName->LogicUtils.isNonEmptyString { + let dict = switch processorType { + | PaymentProcessor => Window.getConnectorConfig(connectorName) + | PayoutProcessor => Window.getPayoutConnectorConfig(connectorName) + | AuthenticationProcessor => Window.getAuthenticationConnectorConfig(connectorName) + | PMAuthProcessor => Window.getPMAuthenticationProcessorConfig(connectorName) + | TaxProcessor => Window.getTaxProcessorConfig(connectorName) + | _ => JSON.Encode.null + } + dict + } else { + JSON.Encode.null + } + } catch { + | Exn.Error(e) => { + Js.log2("FAILED TO LOAD CONNECTOR CONFIG", e) + let _ = Exn.message(e)->Option.getOr("Something went wrong") + JSON.Encode.null + } + } + }, [connectorName]) + let ( + _, + connectorAccountFields, + connectorMetaDataFields, + _, + connectorWebHookDetails, + connectorLabelDetailField, + connectorAdditionalMerchantData, + ) = getConnectorFields(connectorDetails) + + let initialValues = React.useMemo(() => { + [ + ("connector_type", connectorInfo.connector_type->JSON.Encode.string), + ( + "connector_account_details", + [("auth_type", connectorInfo.connector_account_details.auth_type->JSON.Encode.string)] + ->Dict.fromArray + ->JSON.Encode.object, + ), + ("connector_webhook_details", connectorInfo.connector_webhook_details), + ("connector_label", connectorInfo.connector_label->JSON.Encode.string), + ("metadata", connectorInfo.metadata), + ( + "additional_merchant_data", + connectorInfo.additional_merchant_data->checkEmptyJson + ? JSON.Encode.null + : connectorInfo.additional_merchant_data, + ), + ]->LogicUtils.getJsonFromArrayOfJson + }, ( + connectorInfo.connector_webhook_details, + connectorInfo.connector_label, + connectorInfo.metadata, + )) + + let onSubmit = async (values, _) => { + try { + let url = getURL( + ~entityName=CONNECTOR, + ~methodType=Post, + ~id=Some(connectorInfo.merchant_connector_id), + ) + let _ = await updateAPIHook(url, values, Post) + switch getConnectorDetails { + | Some(fun) => fun()->ignore + | _ => () + } + setShowFeedbackModal(_ => false) + } catch { + | _ => showToast(~message="Connector Failed to update", ~toastType=ToastError) + } + + Nullable.null + } + let validateMandatoryField = values => { + let errors = Dict.make() + let valuesFlattenJson = values->JsonFlattenUtils.flattenObject(true) + validateConnectorRequiredFields( + connectorTypeFromName, + valuesFlattenJson, + connectorAccountFields, + connectorMetaDataFields, + connectorWebHookDetails, + connectorLabelDetailField, + errors->JSON.Encode.object, + ) + } + + let selectedConnector = React.useMemo(() => { + connectorTypeFromName->getConnectorInfo + }, [connectorName]) + <> +
{ + mixpanelEvent(~eventName=`processor_update_creds_${connectorName}`) + setShowFeedbackModal(_ => true) + }}> + } + toolTipPosition=Top + tooltipWidthClass="w-fit" + /> +
+ +
+ +
+ +
+ + +
+ +} diff --git a/src/screens/Connectors/ConnectorUtils.res b/src/screens/Connectors/ConnectorUtils.res index b1fa03f5b..9ed5157d4 100644 --- a/src/screens/Connectors/ConnectorUtils.res +++ b/src/screens/Connectors/ConnectorUtils.res @@ -37,6 +37,8 @@ let threedsAuthenticatorListForLive: array = [ThreeDsAuthenticat let pmAuthenticationConnectorList: array = [PMAuthenticationProcessor(PLAID)] +let taxProcessorList: array = [TaxProcessor(TAXJAR)] + let connectorList: array = [ Processors(STRIPE), Processors(PAYPAL), @@ -97,6 +99,8 @@ let connectorList: array = [ Processors(PAYBOX), Processors(FIUU), Processors(WELLSFARGO), + Processors(NOVALNET), + Processors(DEUTSCHEBANK), ] let connectorListForLive: array = [ @@ -477,6 +481,18 @@ let fiuuInfo = { description: "Fiuu has been the premier merchant service provider in Southeast Asia since 2005, connecting international brands to consumers across the region. The company helps its clients establish a foothold in Southeast Asia's market by offering a full range of alternative payment methods, such as online banking, cash at 7-Eleven (Fiuu Cash), e-wallets, and more. Fiuu provides comprehensive payment solutions to facilitate market entry and expansion for businesses looking to reach Southeast Asian consumers.", } +let novalnetInfo = { + description: "Novalnet is a global payment service provider and financial technology company based in Germany. It offers a wide range of payment processing solutions and services to merchants and businesses, enabling them to accept various forms of payments online, in-store, or through mobile platforms.", +} + +let deutscheBankInfo = { + description: "Deutsche Bank is a German multinational investment bank and financial services company.", +} + +let taxJarInfo = { + description: "TaxJar is reimagining how businesses manage sales tax compliance. Its cloud-based platform automates the entire sales tax life cycle across all sales channels — from calculations and nexus tracking to reporting and filing.", +} + let signifydInfo = { description: "One platform to protect the entire shopper journey end-to-end", validate: [ @@ -579,6 +595,8 @@ let getConnectorNameString = (connector: processorTypes) => | WELLSFARGO => "wellsfargo" | FISERVIPG => "fiservemea" | FIUU => "fiuu" + | NOVALNET => "novalnet" + | DEUTSCHEBANK => "deutschebank" } let getThreeDsAuthenticatorNameString = (threeDsAuthenticator: threeDsAuthenticatorTypes) => @@ -602,6 +620,12 @@ let getPMAuthenticationConnectorNameString = ( } } +let getTaxProcessorNameString = (taxProcessor: taxProcessorTypes) => { + switch taxProcessor { + | TAXJAR => "taxjar" + } +} + let getConnectorNameString = (connector: connectorTypes) => { switch connector { | Processors(connector) => connector->getConnectorNameString @@ -610,6 +634,7 @@ let getConnectorNameString = (connector: connectorTypes) => { | FRM(frmConnector) => frmConnector->getFRMNameString | PMAuthenticationProcessor(pmAuthenticationConnector) => pmAuthenticationConnector->getPMAuthenticationConnectorNameString + | TaxProcessor(taxProcessor) => taxProcessor->getTaxProcessorNameString | UnknownConnector(str) => str } } @@ -685,6 +710,8 @@ let getConnectorNameTypeFromString = (connector, ~connectorType=ConnectorTypes.P | "paybox" => Processors(PAYBOX) | "wellsfargo" => Processors(WELLSFARGO) | "fiuu" => Processors(FIUU) + | "novalnet" => Processors(NOVALNET) + | "deutschebank" => Processors(DEUTSCHEBANK) | _ => UnknownConnector("Not known") } | ThreeDsAuthenticator => @@ -704,6 +731,11 @@ let getConnectorNameTypeFromString = (connector, ~connectorType=ConnectorTypes.P | "plaid" => PMAuthenticationProcessor(PLAID) | _ => UnknownConnector("Not known") } + | TaxProcessor => + switch connector { + | "taxjar" => TaxProcessor(TAXJAR) + | _ => UnknownConnector("Not known") + } | _ => UnknownConnector("Not known") } } @@ -777,6 +809,8 @@ let getProcessorInfo = connector => { | PAYBOX => payboxInfo | WELLSFARGO => wellsfargoInfo | FIUU => fiuuInfo + | NOVALNET => novalnetInfo + | DEUTSCHEBANK => deutscheBankInfo } } let getThreedsAuthenticatorInfo = threeDsAuthenticator => @@ -798,6 +832,12 @@ let getOpenBankingProcessorInfo = ( } } +let getTaxProcessorInfo = (taxProcessor: ConnectorTypes.taxProcessorTypes) => { + switch taxProcessor { + | TAXJAR => taxJarInfo + } +} + let getConnectorInfo = connector => { switch connector { | Processors(connector) => connector->getProcessorInfo @@ -805,6 +845,7 @@ let getConnectorInfo = connector => { | FRM(frm) => frm->getFrmInfo | PMAuthenticationProcessor(pmAuthenticationConnector) => pmAuthenticationConnector->getOpenBankingProcessorInfo + | TaxProcessor(taxProcessor) => taxProcessor->getTaxProcessorInfo | UnknownConnector(_) => unknownConnectorInfo } } @@ -864,6 +905,7 @@ let connectorIgnoredField = [ "connector_name", "profile_id", "applepay_verified_domains", + "connector_account_details", ] let configKeysToIgnore = [ @@ -915,6 +957,7 @@ let getConnectorType = (connector: ConnectorTypes.connectorTypes, ~isPayoutFlow) : switch connector { | ThreeDsAuthenticator(_) => "authentication_processor" | PMAuthenticationProcessor(_) => "payment_method_auth" + | TaxProcessor(_) => "tax_processor" | UnknownConnector(str) => str | _ => "payment_processor" } @@ -1499,11 +1542,13 @@ let filterList = (items: array, ~removeFromList let isPayoutConnector = connectorType == "payout_processor" let isThreeDsAuthenticator = connectorType == "authentication_processor" let isPMAuthenticationProcessor = connectorType == "payment_method_auth" + let isTaxProcessor = connectorType == "tax_processor" let isConnector = connectorType !== "payment_vas" && !isPayoutConnector && !isThreeDsAuthenticator && - !isPMAuthenticationProcessor + !isPMAuthenticationProcessor && + !isTaxProcessor switch removeFromList { | Processor => !isConnector @@ -1511,6 +1556,7 @@ let filterList = (items: array, ~removeFromList | PayoutConnector => isPayoutConnector | ThreeDsAuthenticator => isThreeDsAuthenticator | PMAuthenticationProcessor => isPMAuthenticationProcessor + | TaxProcessor => isTaxProcessor } }) } @@ -1591,6 +1637,8 @@ let getDisplayNameForProcessor = connector => | WELLSFARGO => "Wells Fargo" | FISERVIPG => "Fiserv IPG" | FIUU => "Fiuu" + | NOVALNET => "Novalnet" + | DEUTSCHEBANK => "Deutsche Bank" } let getDisplayNameForThreedsAuthenticator = threeDsAuthenticator => @@ -1611,6 +1659,12 @@ let getDisplayNameForOpenBankingProcessor = pmAuthenticationConnector => { } } +let getDisplayNameForTaxProcessor = taxProcessor => { + switch taxProcessor { + | TAXJAR => "Tax Jar" + } +} + let getDisplayNameForConnector = (~connectorType=ConnectorTypes.Processor, connector) => { let connectorType = connector->String.toLowerCase->getConnectorNameTypeFromString(~connectorType) switch connectorType { @@ -1620,6 +1674,7 @@ let getDisplayNameForConnector = (~connectorType=ConnectorTypes.Processor, conne | FRM(frmConnector) => frmConnector->getDisplayNameForFRMConnector | PMAuthenticationProcessor(pmAuthenticationConnector) => pmAuthenticationConnector->getDisplayNameForOpenBankingProcessor + | TaxProcessor(taxProcessor) => taxProcessor->getDisplayNameForTaxProcessor | UnknownConnector(str) => str } } @@ -1632,6 +1687,17 @@ let getConnectorTypeArrayFromListConnectors = ( connectorDetail.connector_name->getConnectorNameTypeFromString(~connectorType) ) } +// Need to remove connector and merge connector and connectorTypeVariants +let connectorTypeTuple = connectorType => { + switch connectorType { + | "payment_processor" => (PaymentProcessor, Processor) + | "payment_vas" => (PaymentVas, FRMPlayer) + | "payout_processor" => (PayoutProcessor, PayoutConnector) + | "authentication_processor" => (AuthenticationProcessor, ThreeDsAuthenticator) + | "payment_method_auth" => (PMAuthProcessor, PMAuthenticationProcessor) + | _ => (PaymentProcessor, Processor) + } +} let connectorTypeStringToTypeMapper = connector_type => { switch connector_type { @@ -1640,6 +1706,7 @@ let connectorTypeStringToTypeMapper = connector_type => { | "payout_processor" => PayoutProcessor | "authentication_processor" => AuthenticationProcessor | "payment_method_auth" => PMAuthProcessor + | "tax_processor" => TaxProcessor | _ => PaymentProcessor } } diff --git a/src/screens/Disputes/Disputes.res b/src/screens/Disputes/Disputes.res index 42abf27ee..b94f1d29f 100644 --- a/src/screens/Disputes/Disputes.res +++ b/src/screens/Disputes/Disputes.res @@ -12,8 +12,7 @@ let make = () => { let (offset, setOffset) = React.useState(_ => 0) let fetchDetails = useGetMethod() - let {generateReport, userManagementRevamp} = - HyperswitchAtom.featureFlagAtom->Recoil.useRecoilValueFromAtom + let {generateReport} = HyperswitchAtom.featureFlagAtom->Recoil.useRecoilValueFromAtom let {updateTransactionEntity} = OMPSwitchHooks.useUserInfo() let {userInfo: {transactionEntity}, checkUserEntity} = React.useContext( UserInfoProvider.defaultContext, @@ -71,13 +70,11 @@ let make = () => {
- - - +
Array.length > 0}> diff --git a/src/screens/FraudAndRisk/FRMConfigure.res b/src/screens/FraudAndRisk/FRMConfigure.res index f55369f46..b6eeda61f 100644 --- a/src/screens/FraudAndRisk/FRMConfigure.res +++ b/src/screens/FraudAndRisk/FRMConfigure.res @@ -98,7 +98,7 @@ let make = () => { /> | SummaryAndTest | Preview => - + | _ => React.null }}
diff --git a/src/screens/FraudAndRisk/FRMIntegrationFields.res b/src/screens/FraudAndRisk/FRMIntegrationFields.res index c1d8bd3eb..ad99e3c3a 100644 --- a/src/screens/FraudAndRisk/FRMIntegrationFields.res +++ b/src/screens/FraudAndRisk/FRMIntegrationFields.res @@ -6,12 +6,12 @@ module AdvanceSettings = { let inputLabel: ReactFinalForm.fieldRenderPropsInput = { name: `input`, - onBlur: _ev => (), + onBlur: _ => (), onChange: ev => { let value = ev->Identity.formReactEventToBool setIsFRMSettings(_ => value) }, - onFocus: _ev => (), + onFocus: _ => (), value: {isFRMSettings->JSON.Encode.bool}, checked: true, } diff --git a/src/screens/FraudAndRisk/FRMSummary.res b/src/screens/FraudAndRisk/FRMSummary.res index 8d4df3cbd..6539186c4 100644 --- a/src/screens/FraudAndRisk/FRMSummary.res +++ b/src/screens/FraudAndRisk/FRMSummary.res @@ -59,7 +59,7 @@ module ConfigInfo = { } @react.component -let make = (~initialValues, ~currentStep, ~setCurrentStep) => { +let make = (~initialValues, ~currentStep) => { open LogicUtils open FRMUtils open APIUtils @@ -108,11 +108,9 @@ let make = (~initialValues, ~currentStep, ~setCurrentStep) => {

LogicUtils.getListHead} - connector={frmInfo.connector_name} />
| _ => diff --git a/src/screens/HSwitchRemoteFilter.res b/src/screens/HSwitchRemoteFilter.res index 9410a895b..066dc1fef 100644 --- a/src/screens/HSwitchRemoteFilter.res +++ b/src/screens/HSwitchRemoteFilter.res @@ -92,9 +92,9 @@ module SearchBarFilter = { let inputSearch: ReactFinalForm.fieldRenderPropsInput = { name: "name", - onBlur: _ev => (), + onBlur: _ => (), onChange, - onFocus: _ev => (), + onFocus: _ => (), value: baseValue->JSON.Encode.string, checked: true, } diff --git a/src/screens/Helpers/TableSearchFilter.res b/src/screens/Helpers/TableSearchFilter.res index f977d9eac..23dc6148d 100644 --- a/src/screens/Helpers/TableSearchFilter.res +++ b/src/screens/Helpers/TableSearchFilter.res @@ -24,9 +24,9 @@ let make = ( let inputSearch: ReactFinalForm.fieldRenderPropsInput = { name: "search", - onBlur: _ev => (), + onBlur: _ => (), onChange, - onFocus: _ev => (), + onFocus: _ => (), value: searchVal->JSON.Encode.string, checked: true, } diff --git a/src/screens/Home/CommonConnectorFlow/QuickStartConnectorFlow.res b/src/screens/Home/CommonConnectorFlow/QuickStartConnectorFlow.res index 4827ca4ee..322eef7e8 100644 --- a/src/screens/Home/CommonConnectorFlow/QuickStartConnectorFlow.res +++ b/src/screens/Home/CommonConnectorFlow/QuickStartConnectorFlow.res @@ -203,6 +203,8 @@ let make = ( connector=connectorName setScreenState={_ => ()} isPayoutFlow=false + updateStepValue=None + setCurrentStep={_ => ()} /> }} diff --git a/src/screens/Home/DelayedVerificationBanner.res b/src/screens/Home/DelayedVerificationBanner.res deleted file mode 100644 index ed2ad6514..000000000 --- a/src/screens/Home/DelayedVerificationBanner.res +++ /dev/null @@ -1,65 +0,0 @@ -open APIUtils - -@react.component -let make = (~merchantId="", ~verificationDays) => { - open CommonAuthHooks - let updateDetails = useUpdateMethod(~showErrorToast=false) - let showToast = ToastState.useShowToast() - let showPopUp = PopUpState.useShowPopUp() - let getURL = useGetURL() - let {email} = useCommonAuthInfo()->Option.getOr(defaultAuthInfo) - let authId = HyperSwitchEntryUtils.getSessionData(~key="auth_id") - - let verificationMessage = `${verificationDays->Int.toString} ${verificationDays === 1 - ? "day" - : "days"} to go!` - - let openVerifiedPopUp = (~heading, ~description, ~isApiFailed, ~retryFunction) => { - showPopUp({ - popUpType: (Primary, WithIcon), - heading, - description: description->React.string, - handleConfirm: { - text: isApiFailed ? "RETRY" : "OK", - onClick: _ => { - isApiFailed ? retryFunction() : () - }, - }, - }) - } - - let rec resendEmailVerify = async () => { - let body = email->CommonAuthUtils.getEmailBody - try { - let url = getURL( - ~entityName=USERS, - ~userType=#VERIFY_EMAIL_REQUEST, - ~methodType=Post, - ~queryParamerters=Some(`auth_id=${authId}`), - ) - let _ = await updateDetails(url, body, Post) - showToast(~message=`Email Send Successfully!`, ~toastType=ToastSuccess) - } catch { - | _ => - openVerifiedPopUp( - ~heading="Failed to send email", - ~description="Please retry sending an email or try again after some time in case the issue persists!", - ~isApiFailed=true, - ~retryFunction={_ => resendEmailVerify()->ignore}, - ) - } - } - -
- {`${verificationMessage}`->React.string} - resendEmailVerify()->ignore}> - {"Verify"->React.string} - - - {"your email address for uninterrupted access. "->React.string} - -
-} diff --git a/src/screens/Home/Home.res b/src/screens/Home/Home.res index e356c37e7..1a28bed7a 100644 --- a/src/screens/Home/Home.res +++ b/src/screens/Home/Home.res @@ -3,7 +3,6 @@ let make = () => { open HomeUtils open PageUtils let greeting = getGreeting() - let featureFlagDetails = HyperswitchAtom.featureFlagAtom->Recoil.useRecoilValueFromAtom let {userInfo: {recoveryCodesLeft}} = React.useContext(UserInfoProvider.defaultContext) let recoveryCode = recoveryCodesLeft->Option.getOr(0) @@ -12,7 +11,7 @@ let make = () => { Option.isSome && recoveryCode < 3}> - {featureFlagDetails.userManagementRevamp ? : } +
{ let merchantDetailsValue = useMerchantDetailsValue() let {isLiveMode} = HyperswitchAtom.featureFlagAtom->Recoil.useRecoilValueFromAtom + let {checkUserEntity} = React.useContext(UserInfoProvider.defaultContext) let isLiveModeEnabledStyles = isLiveMode ? "flex flex-col md:flex-row gap-5 w-full" : "flex flex-col gap-5 md:w-1/2 w-full"
+ + +
- - - - -
- - -
} } diff --git a/src/screens/Home/HomeV2.res b/src/screens/Home/HomeV2.res index a2e321961..53f28b0a1 100644 --- a/src/screens/Home/HomeV2.res +++ b/src/screens/Home/HomeV2.res @@ -409,7 +409,6 @@ let make = () => { let {isProdIntentCompleted} = React.useContext(GlobalProvider.defaultContext) let enumDetails = Recoil.useRecoilValueFromAtom(HyperswitchAtom.enumVariantAtom) let typedEnumValue = enumDetails->LogicUtils.safeParse->QuickStartUtils.getTypedValueFromDict - let featureFlagDetails = HyperswitchAtom.featureFlagAtom->Recoil.useRecoilValueFromAtom let {userInfo: {recoveryCodesLeft}} = React.useContext(UserInfoProvider.defaultContext) let recoveryCode = recoveryCodesLeft->Option.getOr(0) @@ -418,7 +417,7 @@ let make = () => { Option.isSome && recoveryCode < 3}> - {featureFlagDetails.userManagementRevamp ? : } +
diff --git a/src/screens/NewAnalytics/Graphs/LineGraph/LineGraph.res b/src/screens/NewAnalytics/Graphs/LineGraph/LineGraph.res new file mode 100644 index 000000000..04b9957f1 --- /dev/null +++ b/src/screens/NewAnalytics/Graphs/LineGraph/LineGraph.res @@ -0,0 +1,18 @@ +external lineGraphOptionsToJson: LineGraphTypes.lineGraphOptions => JSON.t = "%identity" +@react.component +let make = (~entity, ~data: JSON.t, ~className="") => { + open NewAnalyticsTypes + let data = entity.getObjects(data) + let default = entity.getChatOptions(data)->lineGraphOptionsToJson + let (options, setOptions) = React.useState(_ => default) + + React.useEffect(() => { + // to re-rendor the chart + setOptions(_ => entity.getChatOptions(data)->lineGraphOptionsToJson) + None + }, []) + +
+ +
+} diff --git a/src/screens/NewAnalytics/Graphs/LineGraph/LineGraphTypes.res b/src/screens/NewAnalytics/Graphs/LineGraph/LineGraphTypes.res new file mode 100644 index 000000000..5f7a55b4d --- /dev/null +++ b/src/screens/NewAnalytics/Graphs/LineGraph/LineGraphTypes.res @@ -0,0 +1,84 @@ +type \"type" = string +type spacingLeft = int +type spacingRight = int + +type categories = array +type crosshair = bool +type lineWidth = int +type tickWidth = int +type align = string +type color = string +type y = int +type gridLineWidth = int +type gridLineColor = string +type gridLineDashStyle = string +type tickmarkPlacement = string +type endOnTick = bool +type startOnTick = bool +type min = int +type showInLegend = bool +type name = string + +type title = {text: string} +type style = {color: color} +type enabled = {enabled: bool} +type credits = { + ...enabled, +} +type exporting = { + ...enabled, +} +type marker = { + ...enabled, +} +type line = {marker: marker} +type plotOptions = {line: line} +type labels = { + align: align, + style: style, + y: y, +} +type chart = { + \"type": \"type", + spacingLeft: spacingLeft, + spacingRight: spacingRight, +} +type data = { + showInLegend: showInLegend, + name: name, + data: array, + color: color, +} + +type yAxis = { + title: title, + gridLineWidth: gridLineWidth, + gridLineColor: gridLineColor, + gridLineDashStyle: gridLineDashStyle, + min: min, +} + +type xAxis = { + categories: categories, + crosshair: crosshair, + lineWidth: lineWidth, + tickWidth: tickWidth, + labels: labels, + gridLineWidth: gridLineWidth, + gridLineColor: gridLineColor, + tickmarkPlacement: tickmarkPlacement, + endOnTick: endOnTick, + startOnTick: startOnTick, +} + +type lineGraphOptions = { + chart: chart, + title: title, + xAxis: xAxis, + yAxis: yAxis, + plotOptions: plotOptions, + series: data, + credits: credits, +} + +type lineGraphPayload = {categories: categories, data: data, title: title} diff --git a/src/screens/NewAnalytics/Graphs/LineGraph/LineGraphUtils.res b/src/screens/NewAnalytics/Graphs/LineGraph/LineGraphUtils.res new file mode 100644 index 000000000..a6f75b430 --- /dev/null +++ b/src/screens/NewAnalytics/Graphs/LineGraph/LineGraphUtils.res @@ -0,0 +1,50 @@ +open LineGraphTypes +let getLineGraphOptions = (lineGraphOptions: lineGraphPayload) => { + let {categories, data, title} = lineGraphOptions + { + chart: { + \"type": "line", + spacingLeft: 20, + spacingRight: 20, + }, + title: { + text: "", + }, + xAxis: { + categories, + crosshair: true, + lineWidth: 1, + tickWidth: 1, + labels: { + align: "center", + style: { + color: "#666", + }, + y: 35, + }, + gridLineWidth: 1, + gridLineColor: "#e6e6e6", + tickmarkPlacement: "on", + endOnTick: false, + startOnTick: false, + }, + yAxis: { + title, + gridLineWidth: 1, + gridLineColor: "#e6e6e6", + gridLineDashStyle: "Dash", + min: 0, + }, + plotOptions: { + line: { + marker: { + enabled: false, + }, + }, + }, + series: data, + credits: { + enabled: false, + }, + } +} diff --git a/src/screens/NewAnalytics/Graphs/SankyGraph/SankeyGraph.res b/src/screens/NewAnalytics/Graphs/SankyGraph/SankeyGraph.res new file mode 100644 index 000000000..88d76d9d8 --- /dev/null +++ b/src/screens/NewAnalytics/Graphs/SankyGraph/SankeyGraph.res @@ -0,0 +1,12 @@ +external sankeyGraphOptionsToJson: SankeyGraphTypes.sankeyGraphOptions => JSON.t = "%identity" + +@react.component +let make = (~entity, ~data: JSON.t) => { + open NewAnalyticsTypes + Highcharts.sankeyChartModule(Highcharts.highchartsModule) + let data = entity.getObjects(data) + let options = entity.getChatOptions(data) + sankeyGraphOptionsToJson} highcharts={Highcharts.highcharts} + /> +} diff --git a/src/screens/NewAnalytics/Graphs/SankyGraph/SankeyGraphTypes.res b/src/screens/NewAnalytics/Graphs/SankyGraph/SankeyGraphTypes.res new file mode 100644 index 000000000..a245cb6d6 --- /dev/null +++ b/src/screens/NewAnalytics/Graphs/SankyGraph/SankeyGraphTypes.res @@ -0,0 +1,77 @@ +type point = {sum: string, id: string} +type nodeFormatter = {point: point} + +external asTooltipPointFormatter: Js_OO.Callback.arity1<'a> => nodeFormatter => string = "%identity" + +type enabled = {enabled: bool} +type exporting = { + ...enabled, +} +type credits = {...enabled} +type colors = array +type keys = array +type sankeyGraphData = (string, string, int, string) +type data = array +type \"type" = string +type name = string +type nodePadding = int +type borderRadius = int +type fontWeight = string +type fontSize = string +type color = string +type allowOverlap = bool +type crop = bool +type overflow = string +type align = string +type verticalAlign = string +type x = int +type nodeDataLabels = { + align: align, + x: x, +} + +type node = { + id: string, + dataLabels: nodeDataLabels, +} +type style = { + fontWeight: fontWeight, + fontSize: fontSize, + color: color, +} +type dataLabels = { + style: style, + allowOverlap: allowOverlap, + crop: crop, + overflow: overflow, + align: align, + verticalAlign: verticalAlign, + nodeFormatter: nodeFormatter => string, +} +type nodes = array +type chart = { + spacingLeft: int, + spacingRight: int, +} +type series = { + exporting: exporting, + credits: credits, + colors: colors, + keys: keys, + data: data, + \"type": \"type", + nodePadding: nodePadding, + borderRadius: borderRadius, + dataLabels: dataLabels, + nodes: nodes, +} + +type title = {text: string} +type sankeyGraphOptions = {title: title, series: array, chart: chart} + +type sankeyPayload = { + title: title, + data: data, + nodes: nodes, + colors: colors, +} diff --git a/src/screens/NewAnalytics/Graphs/SankyGraph/SankeyGraphUtils.res b/src/screens/NewAnalytics/Graphs/SankyGraph/SankeyGraphUtils.res new file mode 100644 index 000000000..f6b86b2d4 --- /dev/null +++ b/src/screens/NewAnalytics/Graphs/SankyGraph/SankeyGraphUtils.res @@ -0,0 +1,51 @@ +open SankeyGraphTypes + +let valueFormatter = ( + @this + (this: nodeFormatter) => { + let label = `${this.point.sum}
${this.point.id}` + label + } +)->asTooltipPointFormatter + +let getSankyGraphOptions = (payload: sankeyPayload) => { + let {data, nodes, title, colors} = payload + let options = { + title, + series: [ + { + \"type": "sankey", + exporting: { + enabled: false, + }, + credits: { + enabled: false, + }, + colors, // Payments Initiated // Success // Non-terminal state // Dispute Raised // Refunds Issued // Failed // Drop-offs + keys: ["from", "to", "weight", "color"], + data, + nodePadding: 35, + borderRadius: 0, // Set the border radius of the bars to 0 + dataLabels: { + nodeFormatter: valueFormatter, + style: { + fontWeight: "normal", + fontSize: "13px", + color: "#333333", + }, + allowOverlap: true, // Allow labels to overlap + crop: false, // Prevent labels from being cropped + overflow: "allow", // Allow labels to overflow the chart area + align: "left", + verticalAlign: "middle", + }, + nodes, + }, + ], + chart: { + spacingLeft: 150, + spacingRight: 150, + }, + } + options +} diff --git a/src/screens/NewAnalytics/NewAnalyticsContainerUtils.res b/src/screens/NewAnalytics/NewAnalyticsContainerUtils.res new file mode 100644 index 000000000..131dcfefd --- /dev/null +++ b/src/screens/NewAnalytics/NewAnalyticsContainerUtils.res @@ -0,0 +1,29 @@ +open NewAnalyticsTypes + +let tabs: array = [ + { + title: "Payments", + renderContent: () => +
+ +
, + }, +] + +let getPageVariant = string => { + switch string { + | "new-analytics-payment" | _ => NewAnalyticsPayment + } +} + +let getPageIndex = (url: RescriptReactRouter.url) => { + switch url.path->HSwitchUtils.urlPath { + | list{"new-analytics-payment"} | _ => 0 + } +} + +let getPageFromIndex = index => { + switch index { + | 1 | _ => NewAnalyticsPayment + } +} diff --git a/src/screens/NewAnalytics/NewAnalyticsHelper.res b/src/screens/NewAnalytics/NewAnalyticsHelper.res new file mode 100644 index 000000000..231a3f7c0 --- /dev/null +++ b/src/screens/NewAnalytics/NewAnalyticsHelper.res @@ -0,0 +1,200 @@ +module Card = { + @react.component + let make = (~children) => { +
+ {children} +
+ } +} + +module NoData = { + @react.component + let make = (~height="h-96") => { + +
+ {"No Data"->React.string} +
+
+ } +} + +module TabSwitch = { + @react.component + let make = (~viewType, ~setViewType) => { + open NewAnalyticsTypes + + let (icon1Bg, icon1Color, icon1Name) = switch viewType { + | Graph => ("bg-white", "text-grey-dark", "graph-dark") + | Table => ("bg-grey-light", "", "graph") + } + + let (icon2Bg, icon2Color, icon2Name) = switch viewType { + | Graph => ("bg-grey-light", "text-grey-medium", "table-view") + | Table => ("bg-white", "text-grey-dark", "table-view") + } + +
+
setViewType(_ => Graph)}> + +
+
+
setViewType(_ => Table)}> + +
+
+ } +} + +module Tabs = { + open NewAnalyticsTypes + @react.component + let make = (~option: tab, ~setOption, ~options: array) => { + let getStyle = (value: string, index) => { + let textStyle = + value === option.value + ? "bg-white text-grey-dark font-medium" + : "bg-grey-light text-grey-medium" + + let borderStyle = index === 0 ? "" : "border-l" + + let borderRadius = + index === 0 ? "rounded-l-lg" : index === options->Array.length - 1 ? "rounded-r-lg" : "" + + `${textStyle} ${borderStyle} ${borderRadius}` + } + +
+ {options + ->Array.mapWithIndex((tabValue, index) => +
getStyle(index)}`} + onClick={_ => setOption(_ => tabValue)}> + {tabValue.title->React.string} +
+ ) + ->React.array} +
+ } +} + +module CustomDropDown = { + open NewAnalyticsTypes + @react.component + let make = (~buttonText, ~options: array) => { + open HeadlessUI + let (arrow, setArrow) = React.useState(_ => false) + + {_ => +
+ + {_ => { + <> + {buttonText->React.string} + + + }} + + + { + {props => { + setArrow(_ => props["open"]) + +
+ {options + ->Array.mapWithIndex((option, i) => + Int.toString}> + {props => +
+ +
} +
+ ) + ->React.array} +
+ }} +
} +
+
} +
+ } +} + +module StatisticsCard = { + open NewAnalyticsTypes + @react.component + let make = (~value, ~direction) => { + let (bgColor, textColor) = switch direction { + | Upward => ("bg-green-light", "text-green-dark") + | Downward => ("bg-red-light", "text-red-dark") + } +
+ +
{`${value}%`->React.string}
+
+ } +} + +module NoteSection = { + @react.component + let make = (~text) => { +
+ +

{text->React.string}

+
+ } +} + +module ModuleHeader = { + @react.component + let make = (~title) => { +

{title->React.string}

+ } +} + +module GraphHeader = { + open NewAnalyticsTypes + @react.component + let make = (~title, ~viewType, ~setViewType) => { +
+
+
{title->React.string}
+ +
+
+ +
+
+ } +} diff --git a/src/screens/NewAnalytics/NewAnalyticsTypes.res b/src/screens/NewAnalytics/NewAnalyticsTypes.res index 116c87f79..3db9d024d 100644 --- a/src/screens/NewAnalytics/NewAnalyticsTypes.res +++ b/src/screens/NewAnalytics/NewAnalyticsTypes.res @@ -1,19 +1,49 @@ -type analyticsPages = Overview | Payment +type analyticsPages = Payment +type viewType = Graph | Table +type statisticsDirection = Upward | Downward -type analyticsPagesRoutes = - | @as("new-analytics-overview") NewAnalyticsOverview - | @as("new-analytics-payment") NewAnalyticsPayment +type analyticsPagesRoutes = | @as("new-analytics-payment") NewAnalyticsPayment -let getPageIndex = (url: RescriptReactRouter.url) => { - switch url.path->HSwitchUtils.urlPath { - | list{"new-analytics-payment"} => 1 - | _ => 0 - } +type domain = [#payments] +type dimension = [ + | #connector + | #payment_method + | #payment_method_type + | #card_network + | #authentication_type +] +type status = [#charged | #failure] +type metrics = [#payment_processed_amount | #payment_success_rate] +type granularity = [ + | #hour_wise + | #day_wise + | #week_wise +] +// will change this once we get the api srtcuture +type requestBodyConfig = { + metrics: array, + delta?: bool, + groupBy?: array, + filters?: array, + customFilter?: dimension, + applyFilterFor?: array, + excludeFilterValue?: array, } -let getPageFromIndex = index => { - switch index { - | 1 => NewAnalyticsPayment - | _ => NewAnalyticsOverview - } +type moduleEntity = { + requestBodyConfig: requestBodyConfig, + title: string, + domain: domain, +} + +type chartEntity<'t, 'chatOption> = { + getObjects: JSON.t => 't, + getChatOptions: 't => 'chatOption, +} + +type dropDownOptionType = {label: string} + +type tab = { + title: string, + value: string, } diff --git a/src/screens/NewAnalytics/NewAnalyticsUtils.res b/src/screens/NewAnalytics/NewAnalyticsUtils.res index 1a5c97935..e02a98c78 100644 --- a/src/screens/NewAnalytics/NewAnalyticsUtils.res +++ b/src/screens/NewAnalytics/NewAnalyticsUtils.res @@ -1,10 +1,2 @@ -let tabs: array = [ - { - title: "Overview", - renderContent: () =>
{"Overview page"->React.string}
, - }, - { - title: "Payments", - renderContent: () =>
{"Payments page"->React.string}
, - }, -] +//Logic utils + diff --git a/src/screens/NewAnalytics/OverViewAnalytics/OverViewAnalyticsEntity.res b/src/screens/NewAnalytics/OverViewAnalytics/OverViewAnalyticsEntity.res deleted file mode 100644 index 8b1378917..000000000 --- a/src/screens/NewAnalytics/OverViewAnalytics/OverViewAnalyticsEntity.res +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/screens/NewAnalytics/OverViewAnalytics/OverViewAnalyticsTypes.res b/src/screens/NewAnalytics/OverViewAnalytics/OverViewAnalyticsTypes.res deleted file mode 100644 index 8b1378917..000000000 --- a/src/screens/NewAnalytics/OverViewAnalytics/OverViewAnalyticsTypes.res +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/screens/NewAnalytics/OverViewAnalytics/OverViewAnalyticsUtils.res b/src/screens/NewAnalytics/OverViewAnalytics/OverViewAnalyticsUtils.res deleted file mode 100644 index 8b1378917..000000000 --- a/src/screens/NewAnalytics/OverViewAnalytics/OverViewAnalyticsUtils.res +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/screens/NewAnalytics/PaymentAnalytics/NewPaymentAnalytics.res b/src/screens/NewAnalytics/PaymentAnalytics/NewPaymentAnalytics.res index 95df2b667..4b24c3634 100644 --- a/src/screens/NewAnalytics/PaymentAnalytics/NewPaymentAnalytics.res +++ b/src/screens/NewAnalytics/PaymentAnalytics/NewPaymentAnalytics.res @@ -1,2 +1,13 @@ -// html code comes here +@react.component +let make = () => { + open NewPaymentAnalyticsEntity +
+ + +
+} diff --git a/src/screens/NewAnalytics/PaymentAnalytics/NewPaymentAnalyticsEntity.res b/src/screens/NewAnalytics/PaymentAnalytics/NewPaymentAnalyticsEntity.res index eaca0b423..011fff31b 100644 --- a/src/screens/NewAnalytics/PaymentAnalytics/NewPaymentAnalyticsEntity.res +++ b/src/screens/NewAnalytics/PaymentAnalytics/NewPaymentAnalyticsEntity.res @@ -1,2 +1,48 @@ -// graphs entity defination +open NewAnalyticsTypes +// Payments Lifecycle +let paymentsLifeCycleEntity: moduleEntity = { + requestBodyConfig: { + delta: false, + metrics: [#payment_processed_amount], + }, + title: "Payments Lifecycle", + domain: #payments, +} +let paymentsLifeCycleChartEntity: chartEntity< + SankeyGraphTypes.sankeyPayload, + SankeyGraphTypes.sankeyGraphOptions, +> = { + getObjects: PaymentsLifeCycleUtils.paymentsLifeCycleMapper, + getChatOptions: SankeyGraphUtils.getSankyGraphOptions, +} + +// Payments Processed +open PaymentsProcessedUtils +let paymentsProcessedEntity: moduleEntity = { + requestBodyConfig: { + delta: false, + metrics: [#payment_processed_amount], + }, + title: "Payments Processed", + domain: #payments, +} + +let paymentsProcessedChartEntity: chartEntity< + LineGraphTypes.lineGraphPayload, + LineGraphTypes.lineGraphOptions, +> = { + getObjects: PaymentsProcessedUtils.paymentsProcessedMapper, + getChatOptions: LineGraphUtils.getLineGraphOptions, +} + +let paymentsProcessedTableEntity = EntityType.makeEntity( + ~uri=``, + ~getObjects, + ~dataKey="queryData", + ~defaultColumns=visibleColumns, + ~requiredSearchFieldsList=[], + ~allColumns=visibleColumns, + ~getCell, + ~getHeading, +) diff --git a/src/screens/NewAnalytics/PaymentAnalytics/NewPaymentAnalyticsTypes.res b/src/screens/NewAnalytics/PaymentAnalytics/NewPaymentAnalyticsTypes.res deleted file mode 100644 index 02f5d8a2a..000000000 --- a/src/screens/NewAnalytics/PaymentAnalytics/NewPaymentAnalyticsTypes.res +++ /dev/null @@ -1,2 +0,0 @@ -// types - diff --git a/src/screens/NewAnalytics/PaymentAnalytics/PaymentsLifeCycle/PaymentsLifeCycle.res b/src/screens/NewAnalytics/PaymentAnalytics/PaymentsLifeCycle/PaymentsLifeCycle.res new file mode 100644 index 000000000..cecabfc3a --- /dev/null +++ b/src/screens/NewAnalytics/PaymentAnalytics/PaymentsLifeCycle/PaymentsLifeCycle.res @@ -0,0 +1,29 @@ +open NewAnalyticsTypes +open NewAnalyticsHelper +open SankeyGraphTypes +@react.component +let make = ( + ~entity: moduleEntity, + ~chartEntity: chartEntity, +) => { + let (paymentsLifeCycle, setPaymentsLifeCycle) = React.useState(_ => JSON.Encode.null) + let getPaymentLieCycleData = async () => { + try { + setPaymentsLifeCycle(_ => JSON.Encode.null) + } catch { + | _ => () + } + } + React.useEffect(() => { + getPaymentLieCycleData()->ignore + None + }, []) +
+ + +
+ +
+
+
+} diff --git a/src/screens/NewAnalytics/OverViewAnalytics/OverViewAnalytics.res b/src/screens/NewAnalytics/PaymentAnalytics/PaymentsLifeCycle/PaymentsLifeCycleTypes.res similarity index 100% rename from src/screens/NewAnalytics/OverViewAnalytics/OverViewAnalytics.res rename to src/screens/NewAnalytics/PaymentAnalytics/PaymentsLifeCycle/PaymentsLifeCycleTypes.res diff --git a/src/screens/NewAnalytics/PaymentAnalytics/PaymentsLifeCycle/PaymentsLifeCycleUtils.res b/src/screens/NewAnalytics/PaymentAnalytics/PaymentsLifeCycle/PaymentsLifeCycleUtils.res new file mode 100644 index 000000000..4f6b2285d --- /dev/null +++ b/src/screens/NewAnalytics/PaymentAnalytics/PaymentsLifeCycle/PaymentsLifeCycleUtils.res @@ -0,0 +1,67 @@ +let paymentsLifeCycleMapper = (_json): SankeyGraphTypes.sankeyPayload => { + open SankeyGraphTypes + let processedData = [ + ("Payments Initiated", "Success", 8000, "#E4EFFF"), + ("Payments Initiated", "Non-terminal state", 1200, "#E4EFFF"), + ("Success", "Dispute Raised", 200, "#F7E0E0"), + ("Success", "Refunds Issued", 600, "#E4EFFF"), + ("Payments Initiated", "Failed", 200, "#F7E0E0"), + ("Payments Initiated", "Drop-offs", 600, "#F7E0E0"), + ] + let sankeyNodes = [ + { + id: "Payments Initiated", + dataLabels: { + align: "left", + x: -130, + }, + }, + { + id: "Success", + dataLabels: { + align: "right", + x: -25, + }, + }, + { + id: "Dispute Raised", + dataLabels: { + align: "right", + x: 105, + }, + }, + { + id: "Refunds Issued", + dataLabels: { + align: "right", + x: 110, + }, + }, + { + id: "Non-terminal state", + dataLabels: { + align: "left", + x: 20, + }, + }, + { + id: "Failed", + dataLabels: { + align: "left", + x: 20, + }, + }, + { + id: "Drop-offs", + dataLabels: { + align: "left", + x: 20, + }, + }, + ] + let title = { + text: "Payments Lifecycle", + } + let colors = ["#91B7EE", "#91B7EE", "#91B7EE", "#EC6262", "#91B7EE", "#EC6262", "#BA3535"] + {data: processedData, nodes: sankeyNodes, title, colors} +} diff --git a/src/screens/NewAnalytics/PaymentAnalytics/PaymentsProcessed/PaymentsProcessed.res b/src/screens/NewAnalytics/PaymentAnalytics/PaymentsProcessed/PaymentsProcessed.res new file mode 100644 index 000000000..c5b185a0d --- /dev/null +++ b/src/screens/NewAnalytics/PaymentAnalytics/PaymentsProcessed/PaymentsProcessed.res @@ -0,0 +1,84 @@ +open NewAnalyticsTypes +open NewAnalyticsHelper +open LineGraphTypes +open NewPaymentAnalyticsEntity +open PaymentsProcessedUtils + +module TableModule = { + @react.component + let make = (~data, ~className="") => { + let (offset, setOffset) = React.useState(_ => 0) + let defaultSort: Table.sortedObject = { + key: "", + order: Table.INC, + } + let tableBorderClass = "border-collapse border border-jp-gray-940 border-solid border-2 border-opacity-30 dark:border-jp-gray-dark_table_border_color dark:border-opacity-30" + + let paymentsProcessed = + data + ->LogicUtils.getArrayDataFromJson(tableItemToObjMapper) + ->Array.map(Nullable.make) + +
+ Array.length} + offset + setOffset + defaultSort + currrentFetchCount={paymentsProcessed->Array.length} + tableLocalFilter=false + tableheadingClass=tableBorderClass + tableBorderClass + ignoreHeaderBg=true + tableDataBorderClass=tableBorderClass + isAnalyticsModule=true + /> +
+ } +} + +@react.component +let make = ( + ~entity: moduleEntity, + ~chartEntity: chartEntity, +) => { + let (paymentsProcessed, setpaymentsProcessed) = React.useState(_ => JSON.Encode.array([])) + let (viewType, setViewType) = React.useState(_ => Graph) + + let getPaymentsProcessed = async () => { + try { + let data = + getData + ->LogicUtils.getDictFromJsonObject + ->LogicUtils.getArrayFromDict("queryData", []) + ->JSON.Encode.array + + setpaymentsProcessed(_ => data) + } catch { + | _ => () + } + } + React.useEffect(() => { + getPaymentsProcessed()->ignore + None + }, []) + +
+ + + +
+ {switch viewType { + | Graph => + | Table => + }} +
+
+
+} diff --git a/src/screens/NewAnalytics/PaymentAnalytics/PaymentsProcessed/PaymentsProcessedTypes.res b/src/screens/NewAnalytics/PaymentAnalytics/PaymentsProcessed/PaymentsProcessedTypes.res new file mode 100644 index 000000000..7a07e234c --- /dev/null +++ b/src/screens/NewAnalytics/PaymentAnalytics/PaymentsProcessed/PaymentsProcessedTypes.res @@ -0,0 +1,12 @@ +type paymentsProcessedObject = { + count: int, + amount: float, + currency: string, + time_bucket: string, +} + +type paymentsProcessedCols = + | Count + | Amount + | Currency + | TimeBucket diff --git a/src/screens/NewAnalytics/PaymentAnalytics/PaymentsProcessed/PaymentsProcessedUtils.res b/src/screens/NewAnalytics/PaymentAnalytics/PaymentsProcessed/PaymentsProcessedUtils.res new file mode 100644 index 000000000..9ca5268e3 --- /dev/null +++ b/src/screens/NewAnalytics/PaymentAnalytics/PaymentsProcessed/PaymentsProcessedUtils.res @@ -0,0 +1,121 @@ +open PaymentsProcessedTypes +let paymentsProcessedMapper = (_json): LineGraphTypes.lineGraphPayload => { + open LineGraphTypes + let categories = [ + "01 Aug", + "02 Aug", + "03 Aug", + "04 Aug", + "05 Aug", + "06 Aug", + "07 Aug", + "08 Aug", + "09 Aug", + "10 Aug", + "11 Aug", + ] + let data = { + showInLegend: false, + name: "Series 1", + data: [3000, 5000, 7000, 5360, 4500, 6800, 5400, 3000, 0, 0], + color: "#2f7ed8", + } + let title = { + text: "USD", + } + {categories, data, title} +} + +let visibleColumns = [Count, Amount, Currency, TimeBucket] + +let colMapper = (col: paymentsProcessedCols) => { + switch col { + | Count => "count" + | Amount => "amount" + | Currency => "currency" + | TimeBucket => "time_bucket" + } +} + +let tableItemToObjMapper: Dict.t => paymentsProcessedObject = dict => { + open LogicUtils + { + count: dict->getInt(Count->colMapper, 0), + amount: dict->getFloat(Amount->colMapper, 0.0), + currency: dict->getString(Currency->colMapper, "NA"), + time_bucket: dict->getString(TimeBucket->colMapper, "NA"), + } +} + +let getObjects: JSON.t => array = json => { + open LogicUtils + json + ->LogicUtils.getArrayFromJson([]) + ->Array.map(item => { + tableItemToObjMapper(item->getDictFromJsonObject) + }) +} + +let getHeading = colType => { + let key = colType->colMapper + switch colType { + | Count => Table.makeHeaderInfo(~key, ~title="Count", ~dataType=TextType) + | Amount => Table.makeHeaderInfo(~key, ~title="Amount", ~dataType=TextType) + | Currency => Table.makeHeaderInfo(~key, ~title="Currency", ~dataType=TextType) + | TimeBucket => Table.makeHeaderInfo(~key, ~title="Date", ~dataType=TextType) + } +} + +let getCell = (obj, colType): Table.cell => { + switch colType { + | Count => Text(obj.count->Int.toString) + | Amount => Text(obj.amount->Float.toString) + | Currency => Text(obj.currency) + | TimeBucket => Text(obj.time_bucket) + } +} + +// Remove this +let getData = { + "queryData": [ + {"count": 24, "amount": 952, "currency": "USD", "time_bucket": "2024-08-13 18:30:00"}, + {"count": 28, "amount": 1020, "currency": "USD", "time_bucket": "2024-08-14 18:30:00"}, + {"count": 35, "amount": 1450, "currency": "USD", "time_bucket": "2024-08-15 18:30:00"}, + {"count": 30, "amount": 1150, "currency": "USD", "time_bucket": "2024-08-16 18:30:00"}, + {"count": 40, "amount": 1600, "currency": "USD", "time_bucket": "2024-08-17 18:30:00"}, + {"count": 29, "amount": 1200, "currency": "USD", "time_bucket": "2024-08-18 18:30:00"}, + {"count": 31, "amount": 1300, "currency": "USD", "time_bucket": "2024-08-19 18:30:00"}, + {"count": 56, "amount": 3925, "currency": "EUR", "time_bucket": "2024-08-13 18:30:00"}, + {"count": 50, "amount": 3750, "currency": "EUR", "time_bucket": "2024-08-14 18:30:00"}, + {"count": 42, "amount": 3150, "currency": "EUR", "time_bucket": "2024-08-15 18:30:00"}, + {"count": 38, "amount": 2900, "currency": "EUR", "time_bucket": "2024-08-16 18:30:00"}, + {"count": 44, "amount": 3300, "currency": "EUR", "time_bucket": "2024-08-17 18:30:00"}, + {"count": 50, "amount": 3750, "currency": "EUR", "time_bucket": "2024-08-18 18:30:00"}, + {"count": 60, "amount": 4500, "currency": "EUR", "time_bucket": "2024-08-19 18:30:00"}, + {"count": 48, "amount": 3600, "currency": "GBP", "time_bucket": "2024-08-13 18:30:00"}, + {"count": 45, "amount": 3400, "currency": "GBP", "time_bucket": "2024-08-14 18:30:00"}, + {"count": 40, "amount": 3000, "currency": "GBP", "time_bucket": "2024-08-15 18:30:00"}, + {"count": 43, "amount": 3200, "currency": "GBP", "time_bucket": "2024-08-16 18:30:00"}, + {"count": 46, "amount": 3500, "currency": "GBP", "time_bucket": "2024-08-17 18:30:00"}, + {"count": 50, "amount": 3800, "currency": "GBP", "time_bucket": "2024-08-18 18:30:00"}, + {"count": 52, "amount": 4000, "currency": "GBP", "time_bucket": "2024-08-19 18:30:00"}, + ], + "metaData": [ + {"count": 217, "amount": 8672, "currency": "USD"}, + {"count": 340, "amount": 25575, "currency": "EUR"}, + {"count": 324, "amount": 24500, "currency": "GBP"}, + ], +}->Identity.genericObjectOrRecordToJson + +let getData2 = { + "queryData": [ + {"count": 24, "amount": 952, "time_bucket": "2024-08-13 18:30:00"}, + {"count": 28, "amount": 1020, "time_bucket": "2024-08-14 18:30:00"}, + {"count": 35, "amount": 1450, "time_bucket": "2024-08-15 18:30:00"}, + {"count": 30, "amount": 1150, "time_bucket": "2024-08-16 18:30:00"}, + {"count": 40, "amount": 1600, "time_bucket": "2024-08-17 18:30:00"}, + {"count": 29, "amount": 1200, "time_bucket": "2024-08-18 18:30:00"}, + {"count": 31, "amount": 1300, "time_bucket": "2024-08-19 18:30:00"}, + ], + "metaData": [{"count": 217, "amount": 8672, "currency": "USD"}], +}->Identity.genericObjectOrRecordToJson diff --git a/src/screens/OMPSwitch/MerchantSwitch.res b/src/screens/OMPSwitch/MerchantSwitch.res index 22f3b4031..53184838c 100644 --- a/src/screens/OMPSwitch/MerchantSwitch.res +++ b/src/screens/OMPSwitch/MerchantSwitch.res @@ -35,6 +35,29 @@ module NewAccountCreationModal = { ~isRequired=true, ) + let validateForm = (values: JSON.t) => { + open LogicUtils + let errors = Dict.make() + let companyName = values->getDictFromJsonObject->getString("company_name", "")->String.trim + let regexForCompanyName = "^([a-z]|[A-Z]|[0-9]|_|\\s)+$" + + let errorMessage = if companyName->isEmptyString { + "Merchant name cannot be empty" + } else if companyName->String.length > 64 { + "Merchant name too long" + } else if !RegExp.test(RegExp.fromString(regexForCompanyName), companyName) { + "Merchant name should not contain special characters" + } else { + "" + } + + if errorMessage->isNonEmptyString { + Dict.set(errors, "company_name", errorMessage->JSON.Encode.string) + } + + errors->JSON.Encode.object + } + let modalBody = {
@@ -49,13 +72,14 @@ module NewAccountCreationModal = { />
-
+
diff --git a/src/screens/OMPSwitch/ProfileSwitch.res b/src/screens/OMPSwitch/ProfileSwitch.res index 081403036..0cbfcbf9d 100644 --- a/src/screens/OMPSwitch/ProfileSwitch.res +++ b/src/screens/OMPSwitch/ProfileSwitch.res @@ -3,8 +3,10 @@ module ListBaseCompForProfile = { let make = (~currProfile, ~arrow) => {
-
-

{currProfile->React.string}

+
+

{"Profile"->React.string}

+

{"|"->React.string}

+

{currProfile->React.string}

{ let (profileList, setProfileList) = Recoil.useRecoilState(HyperswitchAtom.profileListAtom) let (showSwitchingProfile, setShowSwitchingProfile) = React.useState(_ => false) let (arrow, setArrow) = React.useState(_ => false) + let businessProfiles = Recoil.useRecoilValueFromAtom(HyperswitchAtom.businessProfilesAtom) let getProfileList = async () => { try { @@ -163,7 +166,7 @@ let make = () => { React.useEffect(() => { getProfileList()->ignore None - }, []) + }, [businessProfiles]) let toggleChevronState = () => { setArrow(prev => !prev) diff --git a/src/screens/Order/OrderUIUtils.res b/src/screens/Order/OrderUIUtils.res index 38fb56d9a..132b60863 100644 --- a/src/screens/Order/OrderUIUtils.res +++ b/src/screens/Order/OrderUIUtils.res @@ -427,7 +427,7 @@ let getOrdersList = async ( try { let ordersUrl = getURL(~entityName=ORDERS, ~methodType=Post) let res = await updateDetails(ordersUrl, filterValueJson->JSON.Encode.object, Post) - let data = res->LogicUtils.getDictFromJsonObject->LogicUtils.getArrayFromDict("data", []) + let data = res->getDictFromJsonObject->getArrayFromDict("data", []) let total = res->getDictFromJsonObject->getInt("total_count", 0) if data->Array.length === 0 && filterValueJson->Dict.get("payment_id")->Option.isSome { @@ -443,7 +443,7 @@ let getOrdersList = async ( filterValueJson->Dict.set("payment_id", newID->JSON.Encode.string) let res = await updateDetails(ordersUrl, filterValueJson->JSON.Encode.object, Post) - let data = res->LogicUtils.getDictFromJsonObject->LogicUtils.getArrayFromDict("data", []) + let data = res->getDictFromJsonObject->getArrayFromDict("data", []) let total = res->getDictFromJsonObject->getInt("total_count", 0) setData( diff --git a/src/screens/Order/Orders.res b/src/screens/Order/Orders.res index c7c68b40d..309088941 100644 --- a/src/screens/Order/Orders.res +++ b/src/screens/Order/Orders.res @@ -4,6 +4,7 @@ let make = (~previewOnly=false) => { open HSwitchRemoteFilter open OrderUIUtils open LogicUtils + let getURL = useGetURL() let updateDetails = useUpdateMethod() let {updateTransactionEntity} = OMPSwitchHooks.useUserInfo() @@ -27,8 +28,7 @@ let make = (~previewOnly=false) => { let pageDetailDict = Recoil.useRecoilValueFromAtom(LoadedTable.table_pageDetails) let pageDetail = pageDetailDict->Dict.get("Orders")->Option.getOr(defaultValue) let (offset, setOffset) = React.useState(_ => pageDetail.offset) - let {generateReport, userManagementRevamp} = - HyperswitchAtom.featureFlagAtom->Recoil.useRecoilValueFromAtom + let {generateReport} = HyperswitchAtom.featureFlagAtom->Recoil.useRecoilValueFromAtom let fetchOrders = () => { if !previewOnly { @@ -130,27 +130,25 @@ let make = (~previewOnly=false) => {
- - + +
- + Array.length > 0}> + + +
+
+
+
{filtersUI}
-
- Array.length > 0}> - - - -
{ + let make = (~disableConnector, ~isConnectorDisabled) => { let showPopUp = PopUpState.useShowPopUp() let openConfirmationPopUp = _ => { showPopUp({ @@ -22,20 +22,13 @@ module MenuOption = { {_popoverProps => <> - {_buttonProps => } + {_ => } {panelProps => {
+ className="relative flex flex-col bg-white py-1 overflow-hidden rounded ring-1 ring-black ring-opacity-5 w-40"> {<> - { - panelProps["close"]() - setCurrentStep(_ => updateStepValue) - }} - /> { @@ -254,9 +247,7 @@ let make = () => { className={`px-4 py-2 rounded-full w-fit font-medium text-sm !text-black ${isConnectorDisabled->connectorStatusStyle}`}> {(isConnectorDisabled ? "DISABLED" : "ENABLED")->React.string}
- +
| _ =>
-
- } -} - -@react.component -let make = () => { - open APIUtils - open CommonAuthHooks - let getURL = useGetURL() - let showToast = ToastState.useShowToast() - let handleLogout = APIUtils.useHandleLogout() - let {name: userName} = useCommonAuthInfo()->Option.getOr(defaultAuthInfo) - let (currentStep, setCurrentStep) = React.useState(_ => 0) - let (carouselDirection, setCarouselDirection) = React.useState(_ => RIGHT) - let {setDashboardPageState} = React.useContext(GlobalProvider.defaultContext) - let updateDetails = useUpdateMethod(~showErrorToast=false) - let isPostLoginQuestionnairePending = - HSLocalStorage.getFromUserDetails("is_metadata_filled")->LogicUtils.getBoolFromString(true) - - React.useEffect(() => { - if !isPostLoginQuestionnairePending { - RescriptReactRouter.push(GlobalVars.appendDashboardPath(~url="/post-login-questionare")) - } - None - }, [isPostLoginQuestionnairePending]) - - let onSubmit = async (values, _) => { - try { - let postLoginSurveyUrl = getURL(~entityName=USERS, ~userType=#SET_METADATA, ~methodType=Post) - - let _ = await updateDetails( - postLoginSurveyUrl, - values->generateSurveyJson->JSON.Encode.object, - Post, - ) - HSwitchUtils.setUserDetails("is_metadata_filled", "true"->JSON.Encode.string) - setDashboardPageState(_ => #AUTO_CONNECTOR_INTEGRATION) - } catch { - | Exn.Error(e) => - let err = Exn.message(e)->Option.getOr("Failed to Fetch!") - if err->String.includes("UR_19") { - showToast(~toastType=ToastWarning, ~message="Please login again!", ~autoClose=false) - handleLogout()->ignore - } - } - Nullable.null - } - let xPositionBasedOnDirection = carouselDirection === RIGHT ? 100 : -100 - -
-
- -
-
-
-
-

- {`Hey ${userName->LogicUtils.capitalizeString}`->React.string} -

- wavinghand -
-

{`Welcome to Hyperswitch`->React.string}

-
-

- {`Help us know you better in 3 simple steps`->React.string} -

-
-
-
- - - Int.toString} - initial={{opacity: 0.0, x: xPositionBasedOnDirection}} - animate={{opacity: 1.0, x: 0}} - exit={{opacity: 0.0, x: -100}} - transition={{duration: 0.3}} - className="flex flex-col flex-wrap bg-white p-8 !rounded-md !shadow-[0_4px_9px_0_rgba(0,0,0,_0.12)] carousel-item"> - Array.get(currentStep) - ->Option.getOr(defaultValueForQuestions)} - /> - - - -
-
-
-
-} diff --git a/src/screens/PostLoginScreen/PostLoginUtils.res b/src/screens/PostLoginScreen/PostLoginUtils.res deleted file mode 100644 index 151e13ed6..000000000 --- a/src/screens/PostLoginScreen/PostLoginUtils.res +++ /dev/null @@ -1,91 +0,0 @@ -type questionsType = { - question: string, - options: array, - key: string, -} -let defaultValueForQuestions: questionsType = { - question: "", - options: [], - key: "", -} -let userRoleQuestions: questionsType = { - question: `What role fits you well?`, - options: [ - {label: "Product", value: "product"}, - {label: "Engineering", value: "engineering"}, - {label: "Finance", value: "finance"}, - {label: "Partnerships", value: "partnerships"}, - ], - key: "best_fit_role", -} -let paymentProcessorQuestions: questionsType = { - question: "How many Payment Processors do you currently use?", - options: [ - {label: "Only 1", value: "only 1"}, - {label: "2-3", value: "2-3"}, - {label: "4 or more", value: "4 or more"}, - {label: "Not accepting digital payments yet", value: "not accepting digital payments yet"}, - ], - key: "integrated_processors", -} -let requirementsQuestion: questionsType = { - question: "What brings you to Hyperswitch?", - options: [ - {label: "Improve Conversion", value: "improve conversions"}, - {label: "Reduce Costs", value: "reduce costs"}, - {label: "Market Expansion", value: "market expansion"}, - {label: "Reduce Dev Effort", value: "reduce dev efforts"}, - {label: "Mitigate Processor Risk", value: "mitigate processor risk"}, - ], - key: "dashboard_purpose", -} -let questionForSurvey = [userRoleQuestions, paymentProcessorQuestions, requirementsQuestion] - -let getBrowswerDetailsPayload = () => { - open CountryUtils - let browserDetails = HSwitchUtils.getBrowswerDetails() - let clientCountry = browserDetails.clientCountry - let clientCountryDict = Dict.fromArray([ - ("isoAlpha3", clientCountry.isoAlpha3->JSON.Encode.string), - ("countryName", clientCountry.countryName->getCountryNameFromVarient->JSON.Encode.string), - ("isoAlpha2", clientCountry.isoAlpha2->getCountryCodeStringFromVarient->JSON.Encode.string), - ("timeZones", clientCountry.timeZones->LogicUtils.getJsonFromArrayOfString), - ]) - [ - ("userAgent", browserDetails.userAgent->JSON.Encode.string), - ("browserVersion", browserDetails.browserVersion->JSON.Encode.string), - ("platform", browserDetails.platform->JSON.Encode.string), - ("browserName", browserDetails.browserName->JSON.Encode.string), - ("browserLanguage", browserDetails.browserLanguage->JSON.Encode.string), - ("screenHeight", browserDetails.screenHeight->JSON.Encode.string), - ("screenWidth", browserDetails.screenWidth->JSON.Encode.string), - ("timeZoneOffset", browserDetails.timeZoneOffset->JSON.Encode.string), - ("clientCountry", clientCountryDict->JSON.Encode.object), - ] - ->Dict.fromArray - ->JSON.Encode.object -} - -let generateSurveyJson = values => { - open LogicUtils - let valuesDict = values->getDictFromJsonObject - let survey_json = - questionForSurvey - ->Array.map(value => { - (value.key, valuesDict->getString(value.key, "")->JSON.Encode.string) - }) - ->Dict.fromArray - let browserDetailsPayload = getBrowswerDetailsPayload() - [ - ("signin_survey", survey_json->JSON.Encode.object), - ("browser_details", browserDetailsPayload), - ]->Dict.fromArray -} - -let initialValueDict = - questionForSurvey - ->Array.map(value => { - (value.key, ""->JSON.Encode.string) - }) - ->Dict.fromArray - ->JSON.Encode.object diff --git a/src/screens/Recon/ReconModule.res b/src/screens/Recon/ReconModule.res index e04ac7a20..6c963e345 100644 --- a/src/screens/Recon/ReconModule.res +++ b/src/screens/Recon/ReconModule.res @@ -57,7 +57,7 @@ let make = (~urlList) => { {if redirectToken->isNonEmptyString {