From bea80585446557ac003b82d769319f9ab81b36c2 Mon Sep 17 00:00:00 2001 From: abijithS-aot Date: Wed, 22 May 2024 05:38:15 -0700 Subject: [PATCH 1/6] multitenant landing page --- .../src/apiManager/endpoints/index.js | 1 + .../src/apiManager/services/tenantServices.js | 12 ++ .../src/components/MultiTenant/LandingPage.js | 56 +++++++++ .../src/components/MultiTenant/index.js | 6 + .../components/MultiTenant/landingPage.css | 115 ++++++++++++++++++ .../src/components/PrivateRoute.jsx | 4 + 6 files changed, 194 insertions(+) create mode 100644 forms-flow-web/src/components/MultiTenant/LandingPage.js create mode 100644 forms-flow-web/src/components/MultiTenant/index.js create mode 100644 forms-flow-web/src/components/MultiTenant/landingPage.css diff --git a/forms-flow-web/src/apiManager/endpoints/index.js b/forms-flow-web/src/apiManager/endpoints/index.js index db909cb84b..86eb95d5f2 100644 --- a/forms-flow-web/src/apiManager/endpoints/index.js +++ b/forms-flow-web/src/apiManager/endpoints/index.js @@ -77,6 +77,7 @@ const API = { HANDLE_AUTHORIZATION_FOR_DESIGNER: `${WEB_BASE_URL}/authorizations/resource/`, GET_FILTERS : `${WEB_BASE_URL}/filter`, GET_BPM_TASK_FILTERS : `${BPM_BASE_URL_EXT}/v1/task-filters`, + VALIDATE_TENANT: `${MT_ADMIN_BASE_URL}/${MT_ADMIN_BASE_URL_VERSION}/tenants/tenant_id/validate`, }; export default API; diff --git a/forms-flow-web/src/apiManager/services/tenantServices.js b/forms-flow-web/src/apiManager/services/tenantServices.js index adbacd8dd4..55d5bb651b 100644 --- a/forms-flow-web/src/apiManager/services/tenantServices.js +++ b/forms-flow-web/src/apiManager/services/tenantServices.js @@ -1,9 +1,12 @@ import { tenantDetail } from "../../constants/tenantConstant"; +import { RequestService } from "@formsflow/service"; import { setTenantDetails, setTenantID, } from "../../actions/tenantActions"; import { Keycloak_Tenant_Client } from "../../constants/constants"; +import { replaceUrl } from "../../helper/helper"; +import API from "../endpoints"; @@ -25,3 +28,12 @@ export const setTenantFromId = (tenantKey, ...rest) => { done(null, tenantDetail); }; }; + +export const validateTenant = (tenantId) => { + const validateTenantUrl = replaceUrl( + API.VALIDATE_TENANT, + "", + tenantId + ); + return RequestService.httpGETRequest(validateTenantUrl); +}; \ No newline at end of file diff --git a/forms-flow-web/src/components/MultiTenant/LandingPage.js b/forms-flow-web/src/components/MultiTenant/LandingPage.js new file mode 100644 index 0000000000..5428d3ebf4 --- /dev/null +++ b/forms-flow-web/src/components/MultiTenant/LandingPage.js @@ -0,0 +1,56 @@ +import React, { useState } from "react"; +import "./landingPage.css"; +import { validateTenant } from "../../apiManager/services/tenantServices"; + +const LandingPage = () => { + const [username, setUsername] = useState(""); + + const handleSubmit = () => { + console.log("clicking"); + validateTenant(username); + }; + + return ( +
+
+ Login Image +
+
+
+ formsflow Logo +

Enter your Tenant Name

+
+ + setUsername(e.target.value)} + className="input" + placeholder="Eg: johndoe" + /> +
+
+ + +
+
+
+ Contact formsflow.ai support +
+ +
+
+
+ ); +}; + +export default LandingPage; \ No newline at end of file diff --git a/forms-flow-web/src/components/MultiTenant/index.js b/forms-flow-web/src/components/MultiTenant/index.js new file mode 100644 index 0000000000..986610f4c7 --- /dev/null +++ b/forms-flow-web/src/components/MultiTenant/index.js @@ -0,0 +1,6 @@ +import React from "react"; +import LandingPage from "./LandingPage"; + +export default React.memo(() => { + return ; +}); diff --git a/forms-flow-web/src/components/MultiTenant/landingPage.css b/forms-flow-web/src/components/MultiTenant/landingPage.css new file mode 100644 index 0000000000..6d64a706e5 --- /dev/null +++ b/forms-flow-web/src/components/MultiTenant/landingPage.css @@ -0,0 +1,115 @@ +.landing { + display: flex; + justify-content: center; + align-items: center; + /* height: 100vh; */ + } + + .imageContainer { + flex: 1; + text-align: center; + } + + .image { + background-repeat: no-repeat; + background-position: top ; + background-color:transparent; + overflow: visible; + white-space: nowrap; + height: 100%; + vertical-align: middle; + margin: 0; + padding: 0 50px; + width: 572px; + } + + .formContainer { + flex: 1; + margin-left: 20px; + display: flex; + justify-content: center; + align-items: center; + } + + .innerContainer { + width: 100%; + max-width: 400px; + display: flex; + flex-direction: column; + align-items: flex-start; + } + + .logo { + max-width: 150px; + margin-bottom: 20px; + } + + .heading { + margin-bottom: 20px; + font-size: 24px; + } + + .formControls { + width: 100%; + margin-bottom: 20px; + } + + .label { + display: block; + margin-bottom: 20px; + } + + .input { + width: 100%; + padding: 10px; + margin-bottom: 20px; + border-radius: 5px; + border: 1px solid rgb(147, 157, 162); + color: #000; + background-color: #E8F0FE; + } + + .input::placeholder { + color: #ccc; + } + + .button { + width: 150px; + padding: 8px; + font-size: 14px; + border-radius: 5px; + border: none; + background-color: #007bff; + color: #fff; + cursor: pointer; + margin-bottom: 60px; + } + + .buttonDisabled { + width: 150px; + padding: 8px; + font-size: 14px; + border-radius: 5px; + border: none; + color: #fff; + margin-bottom: 60px; + background-color: #cccccc; + cursor: not-allowed; + } + + + .line { + width: 100%; + height: 1px; + background-color: #ccc; + margin-bottom: 20px; + } + + .supportText { + color: black; + } + + .supportLink { + margin-bottom: 20px; + } + \ No newline at end of file diff --git a/forms-flow-web/src/components/PrivateRoute.jsx b/forms-flow-web/src/components/PrivateRoute.jsx index 4628ccd53a..a7db33b3a4 100644 --- a/forms-flow-web/src/components/PrivateRoute.jsx +++ b/forms-flow-web/src/components/PrivateRoute.jsx @@ -42,6 +42,7 @@ import InsightsPage from "./Insights"; import Application from "./Application"; import Modeler from "./Modeler"; import Drafts from "./Draft"; +import LandingPage from "./MultiTenant"; import { BPM_API_URL_WITH_VERSION, WEB_BASE_URL, @@ -223,6 +224,9 @@ const PrivateRoute = React.memo((props) => { {ENABLE_FORMS_MODULE && ( )} + {ENABLE_FORMS_MODULE && ( + + )} {ENABLE_FORMS_MODULE && ( )} From c72b0944dd6299c9c6682e812df1dc39b055dc0f Mon Sep 17 00:00:00 2001 From: abilpraju-aot Date: Wed, 5 Jun 2024 00:33:07 +0530 Subject: [PATCH 2/6] route page for tenant login --- .../src/apiManager/endpoints/index.js | 2 +- forms-flow-web/src/components/BaseRouting.jsx | 15 +- .../src/components/MultiTenant/LandingPage.js | 81 ++++--- .../components/MultiTenant/landingPage.css | 217 +++++++++--------- .../src/components/PrivateRoute.jsx | 2 +- 5 files changed, 174 insertions(+), 143 deletions(-) diff --git a/forms-flow-web/src/apiManager/endpoints/index.js b/forms-flow-web/src/apiManager/endpoints/index.js index 86eb95d5f2..dde4c7a40d 100644 --- a/forms-flow-web/src/apiManager/endpoints/index.js +++ b/forms-flow-web/src/apiManager/endpoints/index.js @@ -77,7 +77,7 @@ const API = { HANDLE_AUTHORIZATION_FOR_DESIGNER: `${WEB_BASE_URL}/authorizations/resource/`, GET_FILTERS : `${WEB_BASE_URL}/filter`, GET_BPM_TASK_FILTERS : `${BPM_BASE_URL_EXT}/v1/task-filters`, - VALIDATE_TENANT: `${MT_ADMIN_BASE_URL}/${MT_ADMIN_BASE_URL_VERSION}/tenants/tenant_id/validate`, + VALIDATE_TENANT: `${MT_ADMIN_BASE_URL}/${MT_ADMIN_BASE_URL_VERSION}/tenants//validate`, }; export default API; diff --git a/forms-flow-web/src/components/BaseRouting.jsx b/forms-flow-web/src/components/BaseRouting.jsx index c5de082e5b..12be48a183 100644 --- a/forms-flow-web/src/components/BaseRouting.jsx +++ b/forms-flow-web/src/components/BaseRouting.jsx @@ -1,10 +1,10 @@ import React from "react"; -import { Route, Switch, Redirect, useLocation } from "react-router-dom"; +import { Route, Switch, useLocation } from "react-router-dom"; import { useSelector } from "react-redux"; import PublicRoute from "./PublicRoute"; import PrivateRoute from "./PrivateRoute"; -import { BASE_ROUTE } from "../constants/constants"; +import { BASE_ROUTE, MULTITENANCY_ENABLED } from "../constants/constants"; import Footer from "../components/Footer"; import { ToastContainer } from "react-toastify"; @@ -15,6 +15,7 @@ import i18n from "../resourceBundles/i18n"; import { setLanguage } from "../actions/languageSetAction"; import { initPubSub } from "../actions/pubSubActions"; import { push } from "connected-react-router"; +import LandingPage from "./MultiTenant"; const BaseRouting = React.memo( ({ store, publish, subscribe, getKcInstance }) => { @@ -49,10 +50,11 @@ const BaseRouting = React.memo( React.useEffect(() => { publish("ES_ROUTE", location); }, [location]); - - return ( - + if (MULTITENANCY_ENABLED && !location.pathname.startsWith("/tenant/")) { + return ; + } + return (
@@ -74,8 +76,7 @@ const BaseRouting = React.memo( /> - - +
{isAuth ?
: null}
diff --git a/forms-flow-web/src/components/MultiTenant/LandingPage.js b/forms-flow-web/src/components/MultiTenant/LandingPage.js index 5428d3ebf4..dd4a71e090 100644 --- a/forms-flow-web/src/components/MultiTenant/LandingPage.js +++ b/forms-flow-web/src/components/MultiTenant/LandingPage.js @@ -1,49 +1,74 @@ import React, { useState } from "react"; +import { useHistory } from "react-router-dom"; import "./landingPage.css"; import { validateTenant } from "../../apiManager/services/tenantServices"; +import { useTranslation } from "react-i18next"; const LandingPage = () => { const [username, setUsername] = useState(""); + const [error, setError] = useState(null); + const history = useHistory(); + const { t } = useTranslation(); - const handleSubmit = () => { - console.log("clicking"); - validateTenant(username); + const handleSubmit = (event) => { + event.preventDefault(); + validateTenant(username) + .then((res) => { + if (res.data.status === "INVALID") { + setError(t("Tenant not found")); + } else { + setError(null); // Clear the error if validation is successful + history.push(`/tenant/${username}`); + } + }) + .catch((err) => { + console.error("error", err); + }); }; return (
- Login Image + Login Image
- formsflow Logo -

Enter your Tenant Name

-
- - setUsername(e.target.value)} - className="input" - placeholder="Eg: johndoe" - /> -
-
+ formsflow Logo +

{t("Enter your Tenant Name")}

+
+
+ + setUsername(e.target.value)} + className={`form-control ${error ? "is-invalid" : ""}`} + placeholder="Eg: johndoe" + required + /> + {error &&
{error}
} +
- -
-
-
- Contact formsflow.ai support -
+ +
+
{t("Contact formsflow.ai support")}
@@ -53,4 +78,4 @@ const LandingPage = () => { ); }; -export default LandingPage; \ No newline at end of file +export default LandingPage; diff --git a/forms-flow-web/src/components/MultiTenant/landingPage.css b/forms-flow-web/src/components/MultiTenant/landingPage.css index 6d64a706e5..162ac5dc14 100644 --- a/forms-flow-web/src/components/MultiTenant/landingPage.css +++ b/forms-flow-web/src/components/MultiTenant/landingPage.css @@ -1,115 +1,120 @@ .landing { - display: flex; - justify-content: center; + display: flex; + justify-content: center; + align-items: center; + padding: 20px; + height: 100vh; +} + +.imageContainer { + width: 100%; + max-width: 50%; /* Adjust as needed */ + margin-right: 20px; /* Add margin for spacing */ +} + +.image { + width: 100%; + height: auto; +} + +.formContainer { + width: 100%; + max-width: 500px; /* Adjust as needed */ + padding: 20px; + background-color: #f9f9f9; + border-radius: 10px; + box-shadow: + 0 2.8px 2.2px rgba(0, 0, 0, 0.034), + 0 6.7px 5.3px rgba(0, 0, 0, 0.048), + 0 12.5px 10px rgba(0, 0, 0, 0.06), + 0 22.3px 17.9px rgba(0, 0, 0, 0.072), + 0 41.8px 33.4px rgba(0, 0, 0, 0.086), + 0 100px 80px rgba(0, 0, 0, 0.12), + 0 0 10px rgba(0, 0, 0, 0.1); /* Add top border shadow */ +} + +.innerContainer { + display: flex; + flex-direction: column; + align-items: center; +} + +.logo { + max-width: 150px; + margin-top: 20px; +} + +.heading { + margin-bottom: 20px; + font-size: 24px; +} + +.form-tenant { + width: 100%; +} + +.form-group-tenant { + width: 100%; + margin-bottom: 20px; + text-align: left; +} + +.form-label-tenant { + display: block; + margin-bottom: 10px; + font-size: 16px; + font-weight: 200; +} + +.form-control-tenant { + width: 100%; +} + +.btn-tenant { + display: block; + width: 100%; + margin-bottom: 20px; +} + +.line-tenant { + width: 100%; + height: 1px; + background-color: #ccc; + margin-bottom: 20px; +} + +.supportText { + color: black; +} + +.supportLink { + margin-bottom: 20px; +} + +.supportLink a { + color: #007bff; + text-decoration: none; +} + +.supportLink a:hover { + text-decoration: underline; +} + +/* Media Queries for Responsive Design */ +@media (max-width: 768px) { + .landing { + flex-direction: column; align-items: center; - /* height: 100vh; */ } .imageContainer { - flex: 1; - text-align: center; - } - - .image { - background-repeat: no-repeat; - background-position: top ; - background-color:transparent; - overflow: visible; - white-space: nowrap; - height: 100%; - vertical-align: middle; - margin: 0; - padding: 0 50px; - width: 572px; - } - - .formContainer { - flex: 1; - margin-left: 20px; - display: flex; - justify-content: center; - align-items: center; - } - - .innerContainer { - width: 100%; - max-width: 400px; - display: flex; - flex-direction: column; - align-items: flex-start; - } - - .logo { - max-width: 150px; - margin-bottom: 20px; - } - - .heading { - margin-bottom: 20px; - font-size: 24px; - } - - .formControls { - width: 100%; - margin-bottom: 20px; - } - - .label { - display: block; - margin-bottom: 20px; - } - - .input { - width: 100%; - padding: 10px; + max-width: 100%; + margin-right: 0; margin-bottom: 20px; - border-radius: 5px; - border: 1px solid rgb(147, 157, 162); - color: #000; - background-color: #E8F0FE; } - .input::placeholder { - color: #ccc; - } - - .button { - width: 150px; - padding: 8px; - font-size: 14px; - border-radius: 5px; - border: none; - background-color: #007bff; - color: #fff; - cursor: pointer; - margin-bottom: 60px; - } - - .buttonDisabled { - width: 150px; - padding: 8px; - font-size: 14px; - border-radius: 5px; - border: none; - color: #fff; - margin-bottom: 60px; - background-color: #cccccc; - cursor: not-allowed; - } - - - .line { - width: 100%; - height: 1px; - background-color: #ccc; - margin-bottom: 20px; - } - - .supportText { - color: black; - } - - .supportLink { - margin-bottom: 20px; + .formContainer { + max-width: 100%; + margin-right: 0; } - \ No newline at end of file +} diff --git a/forms-flow-web/src/components/PrivateRoute.jsx b/forms-flow-web/src/components/PrivateRoute.jsx index 621d2a53bb..c8ee73eae5 100644 --- a/forms-flow-web/src/components/PrivateRoute.jsx +++ b/forms-flow-web/src/components/PrivateRoute.jsx @@ -81,7 +81,7 @@ const PrivateRoute = React.memo((props) => { const tenant = useSelector((state) => state.tenants); const [authError, setAuthError] = React.useState(false); const [kcInstance, setKcInstance] = React.useState(getKcInstance()); - + const authenticate = (instance, store) => { setKcInstance(instance); store.dispatch( From 4042eb704603f8858e8a2457bcfc3ef50d832ef9 Mon Sep 17 00:00:00 2001 From: abilpraju-aot Date: Wed, 5 Jun 2024 19:44:36 +0530 Subject: [PATCH 3/6] changed style --- .../src/components/MultiTenant/LandingPage.js | 4 +- .../components/MultiTenant/landingPage.css | 51 +++++++++---------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/forms-flow-web/src/components/MultiTenant/LandingPage.js b/forms-flow-web/src/components/MultiTenant/LandingPage.js index dd4a71e090..b0cc660106 100644 --- a/forms-flow-web/src/components/MultiTenant/LandingPage.js +++ b/forms-flow-web/src/components/MultiTenant/LandingPage.js @@ -67,11 +67,11 @@ const LandingPage = () => { {t("Proceed to Sign In")} -
+ {/*
{t("Contact formsflow.ai support")}
+
*/}
diff --git a/forms-flow-web/src/components/MultiTenant/landingPage.css b/forms-flow-web/src/components/MultiTenant/landingPage.css index 162ac5dc14..1da43a9b6f 100644 --- a/forms-flow-web/src/components/MultiTenant/landingPage.css +++ b/forms-flow-web/src/components/MultiTenant/landingPage.css @@ -1,36 +1,31 @@ .landing { display: flex; - justify-content: center; - align-items: center; - padding: 20px; height: 100vh; } .imageContainer { - width: 100%; - max-width: 50%; /* Adjust as needed */ - margin-right: 20px; /* Add margin for spacing */ + flex: 1; + display: flex; + background-position: left top; } .image { - width: 100%; - height: auto; + width: auto; + max-width: 100%; + max-height: 100%; + object-fit: contain; /* Ensure the image does not stretch */ + align-self: flex-start; } .formContainer { - width: 100%; - max-width: 500px; /* Adjust as needed */ - padding: 20px; + flex: 1; + max-width: 500px; + max-height: 400px; + padding: 5rem; background-color: #f9f9f9; - border-radius: 10px; - box-shadow: - 0 2.8px 2.2px rgba(0, 0, 0, 0.034), - 0 6.7px 5.3px rgba(0, 0, 0, 0.048), - 0 12.5px 10px rgba(0, 0, 0, 0.06), - 0 22.3px 17.9px rgba(0, 0, 0, 0.072), - 0 41.8px 33.4px rgba(0, 0, 0, 0.086), - 0 100px 80px rgba(0, 0, 0, 0.12), - 0 0 10px rgba(0, 0, 0, 0.1); /* Add top border shadow */ + border-top: 2px solid transparent; + margin: 10rem 10rem auto auto; /* Default margin for larger screens */ + box-shadow: 0 0.5rem 1rem 0 rgba(3,3,3,0.16), 0 0 0.375rem 0 rgba(3,3,3,0.08); /* Add top border shadow */ } .innerContainer { @@ -41,7 +36,6 @@ .logo { max-width: 150px; - margin-top: 20px; } .heading { @@ -63,7 +57,7 @@ display: block; margin-bottom: 10px; font-size: 16px; - font-weight: 200; + line-height: 1.66666667; } .form-control-tenant { @@ -74,6 +68,10 @@ display: block; width: 100%; margin-bottom: 20px; + padding: 6px 10px; + font-size: 14px; + line-height: 1.3333333; + border-radius: 1px; } .line-tenant { @@ -100,7 +98,7 @@ text-decoration: underline; } -/* Media Queries for Responsive Design */ + @media (max-width: 768px) { .landing { flex-direction: column; @@ -112,9 +110,10 @@ margin-right: 0; margin-bottom: 20px; } - +} + +@media (max-width: 576px) { .formContainer { - max-width: 100%; - margin-right: 0; + margin: 0px;; } } From f2a0a1aeb6aa5aca2223581f677d62af44c91dda Mon Sep 17 00:00:00 2001 From: abilpraju-aot Date: Thu, 6 Jun 2024 13:56:54 +0530 Subject: [PATCH 4/6] updated style --- .../src/components/MultiTenant/LandingPage.js | 14 ++-- .../components/MultiTenant/landingPage.css | 70 +++++++++---------- 2 files changed, 41 insertions(+), 43 deletions(-) diff --git a/forms-flow-web/src/components/MultiTenant/LandingPage.js b/forms-flow-web/src/components/MultiTenant/LandingPage.js index b0cc660106..7ecf45e2a9 100644 --- a/forms-flow-web/src/components/MultiTenant/LandingPage.js +++ b/forms-flow-web/src/components/MultiTenant/LandingPage.js @@ -43,10 +43,10 @@ const LandingPage = () => { className="logo" />

{t("Enter your Tenant Name")}

-
-
-