From 421ff9d3057169f8da72e3da13dde011ae24b0d6 Mon Sep 17 00:00:00 2001 From: Alan Raju <94040192+alanraju-aot@users.noreply.github.com> Date: Fri, 22 Apr 2022 09:57:26 +0530 Subject: [PATCH 001/637] Delete installationAutomation.bat --- installationAutomation.bat | 496 ------------------------------------- 1 file changed, 496 deletions(-) delete mode 100644 installationAutomation.bat diff --git a/installationAutomation.bat b/installationAutomation.bat deleted file mode 100644 index 424bf0111b..0000000000 --- a/installationAutomation.bat +++ /dev/null @@ -1,496 +0,0 @@ -@echo off - -::=================== INIT =====================> -:Installation -set analytics=0; -set /p choice=Do you want to include analytics in the installation? [y/n] -if %choice%==y ( -set analytics=1; -goto :INSTALL_WITH_ANALYTICS -) -if %choice% ==n ( -goto :INSTALL_WITHOUT_ANALYTICS -) - -:INSTALL_WITH_ANALYTICS -echo installation will be completed in the following order: -echo 1. form.io -echo 2. web -echo 3. analytics -echo 4. webapi -echo 5. camunda - - -echo press enter to continue -pause>null -goto :KEYCLOAK - -:INSTALL_WITHOUT_ANALYTICS - -echo The installation will be completed in the following order -echo 1. form.io -echo 2. web -echo 3. webapi -echo 4. camunda - -echo press enter to continue -pause>null -goto :KEYCLOAK - - - -::================KEYCLOAK=========================> -:KEYCLOAK -cd .\forms-flow-idm\keycloak -:keycloak repeat -:choice -set /P c=Do you have an existing keycloak?[y/n]? -if /I "%c%" EQU "y" goto :INSTALL WITH EXISTING KEYCLOAK -if /I "%c%" EQU "n" goto :USE DEFAULT KEYCLOAK SETUP -goto :choice - - -:USE DEFAULT KEYCLOAK SETUP -echo WE ARE SETING UP OUR DEFAULT KEYCLOCK FOR YOU -echo press enter to continue -pause> null -findstr /v /i /c:"FORMIO_DEFAULT_PROJECT_URL" sample.env > .env - - -for /f "tokens=*" %%s in (.env) do ( - echo %%s -) - -echo %cd% -::docker-compose up -d - -:choice -set /P c=process FAILD with some error? please repeat. [y/n]? -if /I "%c%" EQU "y" goto :keycloak repeat -if /I "%c%" EQU "n" goto :FORMSFLOW FORMS -goto :choice - - -::------------------------------------------ -:INSTALL WITH EXISTING KEYCLOAK - -echo existing keycloak setup here -pause -:choice -set /P c=process FAILD with some error? please repeat. [y/n]? -if /I "%c%" EQU "y" goto :keycloak repeat -if /I "%c%" EQU "n" goto :FORMSFLOW FORMS -goto :choice -::------------------------------------------ -::================KEYCLOAK-ENDS=========================> - -::=================FORMS-STARTS=========================> -:FORMSFLOW FORMS -cls -echo FORMSFLOW FORMS - -cd ..\..\forms-flow-forms -echo %cd% - -::fetching ip address -for /f "tokens=14" %%a in ('ipconfig ^| findstr IPv4') do set _IPaddr=%%a - -:choice -set /P choice=Are you sure you want run default settings[y/n]? -if /I "%choice%" EQU "y" goto :FORMS DEFAULT SETUP -if /I "%choice%" EQU "n" goto :FORMS CUSTOM SETUP -goto :choice - -:FORMS DEFAULT SETUP - -findstr /v /i /c:"FORMIO_DEFAULT_PROJECT_URL" sample.env > .env -setlocal ENABLEDELAYEDEXPANSION -set word=%_IPaddr% -set str=FORMIO_DEFAULT_PROJECT_URL=http://{your-ip-address}:3001 -set strng=%str:{your-ip-address}=!word!% - -echo %strng%>>".env" - -for /f "tokens=*" %%s in (.env) do ( - echo %%s -) - -::docker-compose -f docker-compose-windows.yml up -d forms-flow-forms - -pause> null - -:ROLS - -::------------------------------------------ -:FORMS CUSTOM SETUP -echo formsflow custom setup here -echo please wait until the process complete -echo BEFORE MOVING TO THE NEXT STEP PLEASE MAKE SURE THAT FORMSFLOW FORMS IS UP IN http://localhost:3001 -pause> null - -::------------------------------------------ - -::================FORMS-ENDS=========================> - -::==========FETCHING ROLS=========> -:ROLS - -cd .\script -echo %cd% - - -set hour=6 -set res=F -SET email=admin@example.com -SET password=changeme -SET host=http://localhost:3001 - -set token=nul - -setlocal ENABLEDELAYEDEXPANSION - -:: Getting x-jwt-token -for /F "skip=1delims=" %%I in ('curl -d "{ \"data\": { \"email\": \"!email!\", \"password\": \"!password!\"} }" -H "Content-Type: application/json" -sSL -D - !host!/user/login -o null') do ( - set header=%%I - if "!header:~0,11!"=="x-jwt-token" ( - set token=!header:~13! - ) -) - -:: Getting role id's and mapping it into an array -for /f "delims=" %%R in ('curl -H "x-jwt-token:!token!" -sSL -D - !host!/role') do ( -set "JSON=%%R" -) - -SET id[]=0 -SET title[]="" -SET i=0 -for %%a in (!JSON!) do ( - set line=%%a - set line=!line:{=! - set line=!line:[=! - set line=!line:"=! - if "!line:~0,3!"=="_id" ( - set id=!line:~4! - set id[!i!]=!id! - ) - if "!line:~0,5!"=="title" ( - set title=!line:~6! - set title[!i!]=!title! - set /a i=i+1 - ) -) - -:: Getting user id's and mapping it into an array -for /f "delims=" %%R in ('curl -H "x-jwt-token:!token!" -sSL -D - !host!/user') do ( -set "JSON=%%R" -) - -for %%a in (!JSON!) do ( - set line=%%a - set line=!line:{=! - set line=!line:[=! - set line=!line:"=! - if "!line:~0,3!"=="_id" ( - set id=!line:~4! - set id[!i!]=!id! - ) - if "!line:~0,5!"=="title" ( - set title=!line:~6! - set title[!i!]=!title! - set /a i=i+1 - ) -) -echo ------------------------------------------- -echo Role Name - ID -echo ------------------------------------------- -for /L %%a in (0,1,!i!) do ( -echo !title[%%a]! - !id[%%a]! -set !title[%%a]!=!id[%%a]! -) - -set Administrator=%id[0]% -set Anonymous=%id[1]% -set Authenticated=%id[2]% -set formsflowClient=%id[3]% -set formsflowReviewer=%id[4]% -set User=%id[5]% - -:WEB -::==========PASSING ROLIDS========> - - - - -::================WEB STARTS=========================> -:WEB -echo FORMS FLOW WEB -cd ..\..\forms-flow-web -echo %cd% -:choice -set /P c=Are you sure you want run default settings[Y/N]? -if /I "%c%" EQU "Y" goto :WEB DEFAULT INSTALLATION -if /I "%c%" EQU "N" goto :WEB CUSTOM INSTALLATION -goto :choice - - -:WEB DEFAULT INSTALLATION - -findstr /v /i /c:"FORMIO_DEFAULT_PROJECT_URL=" /c:"KEYCLOAK_URL=" /c:"FORMSFLOW_API_URL=" /c:"CAMUNDA_API_URL=" /c:"WEBSOCKET_SECURITY_ORIGIN=" /c:"CLIENT_ROLE_ID=" /c:"DESIGNER_ROLE_ID=" /c:"REVIEWER_ROLE_ID" /c:"ANONYMOUS_ID" /c:"USER_RESOURCE_ID" sample.env > .env - -for /f "tokens=14" %%a in ('ipconfig ^| findstr IPv4') do set _IPaddr=%%a - -setlocal ENABLEDELAYEDEXPANSION -set word=%_IPaddr% -set str=FORMIO_DEFAULT_PROJECT_URL=http://{your-ip-address}:3001 -set strng=%str:{your-ip-address}=!word!% - -set key=%_IPaddr% -set ste=KEYCLOAK_URL=http://{your-ip-address}:8080 -set stng=%ste:{your-ip-address}=!key!% - -set api=%_IPaddr% -set stp=FORMSFLOW_API_URL=http://{your-ip-address}:5000 -set strong=%stp:{your-ip-address}=!api!% - -set websock=%_IPaddr% -set lpu=CAMUNDA_API_URL=http://{your-ip-address}:8000/camunda -set streng=%lpu:{your-ip-address}=!websock!% - -echo %strng% >>".env" -echo %stng% >>".env" -echo %strong% >>".env" -echo %streng% >>".env" -echo CLIENT_ROLE_ID=%formsflowClient% >> .env -echo DESIGNER_ROLE_ID=%Administrator% >> .env -echo REVIEWER_ROLE_ID=%formsflowReviewer% >> .env -echo ANONYMOUS_ID=%Anonymous% >> .env -echo USER_RESOURCE_ID=%User% >> .env -for /f "tokens=*" %%s in (.env) do ( -echo %%s -) - -::docker-compose up -d - -if %analytics% ==1 ( -echo you have chosen the option to install analytics. -echo press ENTER to continue -pause> null -goto :ANALYTICS -) - -if %analytics% ==0 ( -echo let's move to the installation of api -echo press ENTER to continue -pause> null -goto :API -) -::------------------------------------------ -:WEB CUSTOM INSTALLATION - -echo web custom installation here - -if %analytics% ==1 ( -echo you have chosen the option to install analytics. -echo press ENTER to continue -pause> null -goto :ANALYTICS -) - -if %analytics% ==0 ( -echo let's move to the installation of api -echo press ENTER to continue -pause> null - -goto :API - -::------------------------------------------ -::==================WEB-ENDS=========================> - - - - - - - -::============ANALYTICS STARTS=======================> -:ANALYTICS -echo ANALYTICS -cd ..\forms-flow-analytics -echo %cd% - -:choice -set /P c=Are you sure you want run default settings[y/n]? -if /I "%c%" EQU "y" goto :ANALYTICS DEFAULT INSTALLATION -if /I "%c%" EQU "n" goto :ANALYTICS CUSTOM INSTALLATION -goto :choice - - -:ANALYTICS DEFAULT INSTALLATION - -findstr /v /i /c:"REDASH_HOST=" sample.env > .env - -setlocal ENABLEDELAYEDEXPANSION -set key=%_IPaddr% -set ste=REDASH_HOST=http://{your-ip-address}:7000 -set strng=%ste:{your-ip-address}=!key!% -echo %strng%>>".env" - -for /f "tokens=*" %%s in (.env) do ( - echo %%s -) -::docker-compose up -d -echo press ENTER to move to API installation -pause>null -goto :API - -::------------------------------------------ -:ANALYTICS CUSTOM INSTALLATION -echo ANALYTICS custom setup -echo press ENTER to move to API installation -pause -goto :API -::------------------------------------------ - -::============ANALYTICS ENDS=========================> - - -::================API STARTS=========================> -:API -echo FORMSFLOW API -cd ..\forms-flow-api -echo %cd% -:choice -set /P c=Are you sure you want run default settings?: [y/n] -if /I "%c%" EQU "y" goto :API DEFAULT INSTALLATION -if /I "%c%" EQU "n" goto :API CUSTOM INSALATION -goto :choice - -:API DEFAULT INSTALLATION - -findstr /v /i /c:"INSIGHT_API_URL=" /c:"KEYCLOAK_URL=" /c:"FORMSFLOW_API_URL=" /c:"CAMUNDA_API_URL=" /c:"INSIGHT_API_KEY=" /c:"KEYCLOAK_BPM_CLIENT_SECRET=" sample.env > .env - -set /p keycloakSecret="what is your Keycloak client secret key?" -echo KEYCLOAK_BPM_CLIENT_SECRET=%keycloakSecret% >> .env - -set /p redashApiKey="what is your Redash API key?" -echo INSIGHT_API_KEY=%redashApiKey% >> .env - -setlocal ENABLEDELAYEDEXPANSION -set word=%_IPaddr% -set str=KEYCLOAK_URL=http://{your-ip-address}:8080 -set strng=%str:{your-ip-address}=!word!% - -set key=%_IPaddr% -set ste=CAMUNDA_API_URL=http://{your-ip-address}:8000/camunda -set stng=%ste:{your-ip-address}=!key!% - -set api=%_IPaddr% -set stp=FORMSFLOW_API_URL=http://{your-ip-address}:5000 -set strong=%stp:{your-ip-address}=!api!% - -set websock=%_IPaddr% -set lpu=INSIGHT_API_URL=http://{your-ip-address}:7000 -set streng=%lpu:{your-ip-address}=!websock!% - -echo %strng% >>".env" -echo %stng% >>".env" -echo %strong% >>".env" -echo %streng% >>".env" -KEYCLOAK_ADMIN_USERNAME=admin >> .env -KEYCLOAK_ADMIN_PASSWORD=changeme >> .env - - -for /f "tokens=*" %%s in (.env) do ( -echo %%s -) - -::docker-compose -f docker-compose-windows.yml up -d - -echo press ENTER to install BPM -pause> null -goto :BPM - - -::------------------------------------------ -:API CUSTOM INSALATION -echo API custom installation here -echo press ENTER to install BPM -pause> null -goto :BPM - -::------------------------------------------ - - -::=================API NDS===========================> - - - -::=================BPM STARTS===========================> -:BPM -cls -echo FORMSFLOW BPM -cd ..\forms-flow-bpm -echo %cd% - -:choice -set /P c=Are you sure you want run default settings[y/n]? -if /I "%c%" EQU "y" goto :BPM DEFAULT INSTALLATION -if /I "%c%" EQU "n" goto :BPM CUSTOM INSTALLATION -goto :choice - - -:BPM DEFAULT INSTALLATION - -findstr /v /i /c:"FORMIO_DEFAULT_PROJECT_URL" /c:"KEYCLOAK_URL=" /c:"KEYCLOAK_BPM_CLIENT_SECRET=" /c:"FORMSFLOW_API_URL=" /c:"WEBSOCKET_SECURITY_ORIGIN=" sample.env > .env - - -setlocal ENABLEDELAYEDEXPANSION -set word=%_IPaddr% -set str=FORMIO_DEFAULT_PROJECT_URL=http://{your-ip-address}:3001 -set strng=%str:{your-ip-address}=!word!% - -set key=%_IPaddr% -set ste=KEYCLOAK_URL=http://{your-ip-address}:8080 -set stng=%ste:{your-ip-address}=!key!% - -set api=%_IPaddr% -set stp=FORMSFLOW_API_URL=http://{your-ip-address}:5000 -set strong=%stp:{your-ip-address}=!api!% - -set websock=%_IPaddr% -set lpu=WEBSOCKET_SECURITY_ORIGIN=http://{your-ip-address}:3000 -set streng=%lpu:{your-ip-address}=!websock!% - -echo %strng% >>".env" -echo %stng% >>".env" -echo %strong% >>".env" -echo %streng% >>".env" - -set /p clientsecret="what is your client secret?" -echo KEYCLOAK_BPM_CLIENT_SECRET=%clientsecret% >> .env - -for /f "tokens=*" %%s in (.env) do ( -echo %%s -) - -::docker-compose -f docker-compose-windows.yml up -d forms-flow-bpm - -pause -goto :END - -::------------------------------------------ -:BPM CUSTOM INSTALLATION -echo bpm custom installation here -pause -goto :END -::------------------------------------------ - -::=================BPM ENDS===========================> - - - -:END -echo INSTALLATION FLOW IS COMPLETED -Pause - From 274fd5ae0b697571f1d1cd9da8c73740604e32b8 Mon Sep 17 00:00:00 2001 From: sreehari ps Date: Wed, 11 May 2022 12:46:19 +0530 Subject: [PATCH 002/637] adding eslint to web-ci --- .github/workflows/forms-flow-web-ci.yml | 6 +++--- forms-flow-web/package.json | 3 ++- .../src/_tests_/test-components/test-error/index.test.js | 2 +- .../src/_tests_/test-components/test-form/stepper.test.js | 2 +- .../_tests_/test-components/test-serviceflow/constants.js | 3 --- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/workflows/forms-flow-web-ci.yml b/.github/workflows/forms-flow-web-ci.yml index 2598d7b874..6fbc04bbf1 100644 --- a/.github/workflows/forms-flow-web-ci.yml +++ b/.github/workflows/forms-flow-web-ci.yml @@ -43,9 +43,9 @@ jobs: - name: Install dependencies run: | npm ci - # - name: Linting - # run: | - # npm run lint + - name: Linting + run: | + npm run lint unit-tests: needs: setup-job runs-on: ubuntu-20.04 diff --git a/forms-flow-web/package.json b/forms-flow-web/package.json index bd31a0e394..a0f52f9834 100644 --- a/forms-flow-web/package.json +++ b/forms-flow-web/package.json @@ -10,7 +10,8 @@ "eject": "react-scripts eject", "test": "react-scripts test --detectOpenHandles --silent", "preinstall": "npx npm-force-resolutions", - "coverage": "react-scripts test --coverage --watchAll=false" + "coverage": "react-scripts test --coverage --watchAll=false", + "lint": "eslint src --no-fix --max-warnings 0" }, "author": { "name": "Abhilash" diff --git a/forms-flow-web/src/_tests_/test-components/test-error/index.test.js b/forms-flow-web/src/_tests_/test-components/test-error/index.test.js index fb84bc7efb..2534848645 100644 --- a/forms-flow-web/src/_tests_/test-components/test-error/index.test.js +++ b/forms-flow-web/src/_tests_/test-components/test-error/index.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { render } from '@testing-library/react'; import LoadError from '../../../components/Error/index'; test('render LoadError', () => { diff --git a/forms-flow-web/src/_tests_/test-components/test-form/stepper.test.js b/forms-flow-web/src/_tests_/test-components/test-form/stepper.test.js index e5f164e4ef..f3bb36f1bc 100644 --- a/forms-flow-web/src/_tests_/test-components/test-form/stepper.test.js +++ b/forms-flow-web/src/_tests_/test-components/test-form/stepper.test.js @@ -51,7 +51,7 @@ it("should render the stepper component without break",()=>{ expect(screen.getByText("Preview and Confirm")).toBeInTheDocument() expect(screen.getByText("Drag and Drop a form component")).toBeInTheDocument() expect(screen.getByText("Create Form")).toBeInTheDocument() - const savebtn = screen.getByText("Save & Preview"); + // const savebtn = screen.getByText("Save & Preview"); const titleInput = screen.getByLabelText("Title"); fireEvent.change(titleInput,{ target:{value:"created by jest"} diff --git a/forms-flow-web/src/_tests_/test-components/test-serviceflow/constants.js b/forms-flow-web/src/_tests_/test-components/test-serviceflow/constants.js index 1d46d174c0..7152fbe449 100644 --- a/forms-flow-web/src/_tests_/test-components/test-serviceflow/constants.js +++ b/forms-flow-web/src/_tests_/test-components/test-serviceflow/constants.js @@ -103,9 +103,6 @@ export const initialstate = { "tenantId": null } ], - listReqParams:{ - sorting:[{sortBy: 'created', sortOrder: 'desc', label: 'Created'}] - }, filterListSearchParams:{}, filterListSortParams:{ sorting:[{sortBy: 'created', sortOrder: 'desc', label: 'Created'}] From f970de688598370e38d2d0da27baee62e2706adf Mon Sep 17 00:00:00 2001 From: AbijithS-aot Date: Wed, 11 May 2022 15:02:21 +0530 Subject: [PATCH 003/637] lint issue solved --- forms-flow-web/src/components/Form/List.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/forms-flow-web/src/components/Form/List.js b/forms-flow-web/src/components/Form/List.js index 3755b28c43..72a3a93e0c 100644 --- a/forms-flow-web/src/components/Form/List.js +++ b/forms-flow-web/src/components/Form/List.js @@ -203,13 +203,8 @@ const List = React.memo((props) => { 1 ? t( " Applications are submitted against") :t( " Application is submitted against")} ` + `"${props.formName}"` +t(". Are you sure want to delete ?"): - t("Are you sure you wish to delete the form ") + - props.formName + - "?" + (formProcessData.id && applicationCount) ? applicationCountResponse ? `${applicationCount} ${applicationCount > 1 ? `${t( " Applications are submitted against")}`:`${t( " Application is submitted against")}`} "${props.formName}". ${t("Are you sure you wish to delete the form?")}` : (` ${t("Are you sure you wish to delete the form")} "${props.formName}"?`): + `${t("Are you sure you wish to delete the form ")} "${props.formName}"?` } onNo={() => onNo()} onYes={() => {onYes(formId, forms,formProcessData,path,formCheckList)}} From 4158f00417fca48278aa8ef22deb5da34b4b53bf Mon Sep 17 00:00:00 2001 From: shuhaib-aot Date: Wed, 11 May 2022 15:54:43 +0530 Subject: [PATCH 004/637] fixed if no dash board data is there then it will show the message --- forms-flow-web/src/components/Admin/Insightdashboard.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/forms-flow-web/src/components/Admin/Insightdashboard.js b/forms-flow-web/src/components/Admin/Insightdashboard.js index 073bf560be..1fd57088fc 100644 --- a/forms-flow-web/src/components/Admin/Insightdashboard.js +++ b/forms-flow-web/src/components/Admin/Insightdashboard.js @@ -202,7 +202,8 @@ const handleSizeChange = (sizePerPage,page)=>{ {updateError &&
}
- {isloading ?isError ? : :} + {isloading ?isError ? : : + (dashboards.length?:

No Dashboards Found

)}
); From b11ae2613144298d6543e53f81fb650eb4e3f87d Mon Sep 17 00:00:00 2001 From: Alan Raju <94040192+alanraju-aot@users.noreply.github.com> Date: Wed, 11 May 2022 16:30:18 +0530 Subject: [PATCH 005/637] Update docker-compose.yml --- deployment/docker/bundle/configuration/docker-compose.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deployment/docker/bundle/configuration/docker-compose.yml b/deployment/docker/bundle/configuration/docker-compose.yml index 409eda9ce0..34903e7564 100644 --- a/deployment/docker/bundle/configuration/docker-compose.yml +++ b/deployment/docker/bundle/configuration/docker-compose.yml @@ -20,7 +20,7 @@ services: forms-flow-bpm: container_name: forms-flow-bpm - image: formsflow/forms-flow-bpm:v4.0.5 + image: formsflow/forms-flow-bpm:latest restart: always links: - forms-flow-bpm-db @@ -85,7 +85,7 @@ services: forms-flow-forms: container_name: forms-flow-forms - image: formsflow/forms-flow-forms:v4.0.5 + image: formsflow/forms-flow-forms:latest # The app will restart until Mongo is listening restart: always links: @@ -110,7 +110,7 @@ services: forms-flow-web: container_name: forms-flow-web - image: formsflow/forms-flow-web:v4.0.5 + image: formsflow/forms-flow-web:latest volumes: - ./config.js:/usr/share/nginx/html/config/config.js ports: @@ -137,7 +137,7 @@ services: forms-flow-webapi: container_name: forms-flow-webapi - image: formsflow/forms-flow-webapi:v4.0.5 + image: formsflow/forms-flow-webapi:latest restart: always links: - forms-flow-webapi-db From 5ee58f13f269612f6d13b34609b094b31dbd68f2 Mon Sep 17 00:00:00 2001 From: sreehari-aot <93634377+sreehari-aot@users.noreply.github.com> Date: Wed, 11 May 2022 16:48:57 +0530 Subject: [PATCH 006/637] Fwf 1307/web tenant authentication (#4) * web tenant auth initial commit * path updates * multitenant path updates for forms * navbar routing, redirect bugfix * missing routes forms * updated routes * url update for create * missing routes, stepper component * multitenancy update for task detail * test case fix * readme, config and env update * environmental bug fixes * config json update * redirect fix, code cleanup, boolean fix * protecting routes for roles Co-authored-by: Abil P Raju <83952803+abilpraju-aot@users.noreply.github.com> --- deployment/docker/docker-compose-linux.yml | 1 + deployment/docker/docker-compose-windows.yml | 1 + forms-flow-web/Dockerfile | 2 + forms-flow-web/README.md | 1 + forms-flow-web/docker-compose.yml | 1 + forms-flow-web/public/config/config.sample.js | 3 +- forms-flow-web/sample.env | 1 + forms-flow-web/src/actions/actionConstants.js | 7 +- forms-flow-web/src/actions/tenantActions.js | 43 +++++++++++ .../apiManager/services/formatterService.js | 4 +- .../src/apiManager/services/tenantServices.js | 26 +++++++ forms-flow-web/src/components/Admin/index.js | 3 +- .../Application/ApplicationHistory.js | 5 +- .../src/components/Application/List.js | 7 +- .../components/Application/ViewApplication.js | 7 +- .../components/Application/historyTable.js | 12 ++-- .../src/components/Application/index.js | 7 +- .../src/components/Application/table.js | 14 ++-- forms-flow-web/src/components/BaseRouting.jsx | 10 ++- .../src/components/Dashboard/Dashboard.js | 3 +- forms-flow-web/src/components/Form/Create.js | 6 +- .../src/components/Form/Item/Edit.js | 5 +- .../src/components/Form/Item/Preview.js | 7 +- .../Form/Item/Submission/Item/Edit.js | 12 ++-- .../Form/Item/Submission/Item/index.js | 17 +++-- .../components/Form/Item/Submission/List.js | 16 +++-- .../components/Form/Item/Submission/index.js | 11 +-- .../src/components/Form/Item/View.js | 21 +++--- .../src/components/Form/Item/index.js | 16 +++-- forms-flow-web/src/components/Form/List.js | 20 +++--- forms-flow-web/src/components/Form/Stepper.js | 61 +++++++++------- forms-flow-web/src/components/Form/index.js | 8 +-- .../src/components/Insights/Insights.js | 3 +- .../src/components/PrivateRoute.jsx | 71 +++++++++++++------ .../ServiceFlow/details/ServiceTaskDetails.js | 6 +- .../filter/ServiceTaskFilterListDropDown.js | 5 +- .../src/components/ServiceFlow/index.js | 11 +-- .../ServiceFlow/list/ServiceTaskList.js | 6 +- forms-flow-web/src/constants/constants.js | 10 +++ forms-flow-web/src/containers/NavBar.jsx | 20 +++--- forms-flow-web/src/modules/index.js | 4 +- forms-flow-web/src/modules/tenantReducer.js | 29 ++++++++ forms-flow-web/src/services/UserService.js | 34 ++++++--- 43 files changed, 396 insertions(+), 161 deletions(-) create mode 100644 forms-flow-web/src/actions/tenantActions.js create mode 100644 forms-flow-web/src/apiManager/services/tenantServices.js create mode 100644 forms-flow-web/src/modules/tenantReducer.js diff --git a/deployment/docker/docker-compose-linux.yml b/deployment/docker/docker-compose-linux.yml index 2573bb8d14..94001789b6 100644 --- a/deployment/docker/docker-compose-linux.yml +++ b/deployment/docker/docker-compose-linux.yml @@ -141,6 +141,7 @@ services: - REACT_APP_USER_ACCESS_PERMISSIONS=${USER_ACCESS_PERMISSIONS} - REACT_APP_WEB_BASE_CUSTOM_URL=${WEB_BASE_CUSTOM_URL:-} - REACT_APP_FORMIO_JWT_SECRET=${FORMIO_JWT_SECRET:---- change me now ---} + - REACT_APP_MULTI_TENANCY_ENABLED=${MULTI_TENANCY_ENABLED:false} ports: - '3000:8080' tty: true diff --git a/deployment/docker/docker-compose-windows.yml b/deployment/docker/docker-compose-windows.yml index ed455aaa2e..9bf8b131c1 100644 --- a/deployment/docker/docker-compose-windows.yml +++ b/deployment/docker/docker-compose-windows.yml @@ -142,6 +142,7 @@ services: - REACT_APP_USER_ACCESS_PERMISSIONS=${USER_ACCESS_PERMISSIONS} - REACT_APP_WEB_BASE_CUSTOM_URL=${WEB_BASE_CUSTOM_URL:-} - REACT_APP_FORMIO_JWT_SECRET=${FORMIO_JWT_SECRET:---- change me now ---} + - REACT_APP_MULTI_TENANCY_ENABLED=${MULTI_TENANCY_ENABLED:false} ports: - '3000:8080' tty: true diff --git a/forms-flow-web/Dockerfile b/forms-flow-web/Dockerfile index 28c6bbd9d2..eefd2d22b8 100644 --- a/forms-flow-web/Dockerfile +++ b/forms-flow-web/Dockerfile @@ -25,6 +25,7 @@ ARG REACT_APP_APPLICATION_NAME ARG REACT_APP_USER_ACCESS_PERMISSIONS ARG REACT_APP_WEB_BASE_CUSTOM_URL ARG REACT_APP_FORMIO_JWT_SECRET +ARG REACT_APP_MULTI_TENANCY_ENABLED ENV NODE_ENV ${NODE_ENV} ENV REACT_APP_CLIENT_ROLE ${REACT_APP_CLIENT_ROLE} @@ -47,6 +48,7 @@ ENV REACT_APP_APPLICATION_NAME ${REACT_APP_APPLICATION_NAME} ENV REACT_APP_USER_ACCESS_PERMISSIONS ${REACT_APP_USER_ACCESS_PERMISSIONS} ENV REACT_APP_WEB_BASE_CUSTOM_URL ${REACT_APP_WEB_BASE_CUSTOM_URL} ENV REACT_APP_FORMIO_JWT_SECRET ${REACT_APP_FORMIO_JWT_SECRET} +ENV REACT_APP_MULTI_TENANCY_ENABLED ${REACT_APP_MULTI_TENANCY_ENABLED} # add `/app/node_modules/.bin` to $PATH ENV PATH /forms-flow-web/app/node_modules/.bin:$PATH diff --git a/forms-flow-web/README.md b/forms-flow-web/README.md index 4cb576573e..d5a16c8e36 100644 --- a/forms-flow-web/README.md +++ b/forms-flow-web/README.md @@ -62,6 +62,7 @@ is mentioned on the [link](../forms-flow-idm/keycloak/README.md#create-forms-flo `WEB_BASE_CUSTOM_URL`|Clients can use WEB_BASE_CUSTOM_URL env variable to provide their custom URL | `USER_ACCESS_PERMISSIONS`| JSON formatted permissions to enable / disable few access on user login.|| `{"accessAllowApplications":false,"accessAllowSubmissions":false}` |`FORMIO_JWT_SECRET`|forms-flow-forms jwt secret| |`--- change me now ---` +`MULTI_TENANCY_ENABLED`|Multi tenancy enabled flag for the environment|true/false | false * NOTE - While configuring USER_ACCESS_PERMISSIONS the accessAllowApplications will hide / show application tab, the same way accessAllowSubmissions does for viewSubmission button. To enable this feature you need to add access-allow-applications, access-allow-submissions with the respective user group in keycloak. diff --git a/forms-flow-web/docker-compose.yml b/forms-flow-web/docker-compose.yml index ed492f7a8f..3ad103120a 100644 --- a/forms-flow-web/docker-compose.yml +++ b/forms-flow-web/docker-compose.yml @@ -29,6 +29,7 @@ services: - REACT_APP_USER_ACCESS_PERMISSIONS=${USER_ACCESS_PERMISSIONS} - REACT_APP_WEB_BASE_CUSTOM_URL=${WEB_BASE_CUSTOM_URL} - REACT_APP_FORMIO_JWT_SECRET=${FORMIO_JWT_SECRET:---- change me now ---} + - REACT_APP_MULTI_TENANCY_ENABLED=${MULTI_TENANCY_ENABLED:false} ports: - "3000:8080" tty: true diff --git a/forms-flow-web/public/config/config.sample.js b/forms-flow-web/public/config/config.sample.js index 655c6053fb..3b8f053305 100644 --- a/forms-flow-web/public/config/config.sample.js +++ b/forms-flow-web/public/config/config.sample.js @@ -46,6 +46,7 @@ window["_env_"] = { //custom url REACT_APP_WEB_BASE_CUSTOM_URL:"Custom URL", REACT_APP_FORMIO_JWT_SECRET:"Jwt secret key", - REACT_APP_USER_ACCESS_PERMISSIONS:{accessAllowApplications:false, accessAllowSubmissions:false} + REACT_APP_USER_ACCESS_PERMISSIONS:{accessAllowApplications:false, accessAllowSubmissions:false}, + REACT_APP_MULTI_TENANCY_ENABLED:'false' }; diff --git a/forms-flow-web/sample.env b/forms-flow-web/sample.env index 128bab0fcb..f49f9ef337 100644 --- a/forms-flow-web/sample.env +++ b/forms-flow-web/sample.env @@ -52,3 +52,4 @@ USER_ACCESS_PERMISSIONS={"accessAllowApplications":false,"accessAllowSubmissions #JWT SECRETE KEY #FORMIO_JWT_SECRET=--- change me now --- +#MULTI_TENANCY_ENABLED=false \ No newline at end of file diff --git a/forms-flow-web/src/actions/actionConstants.js b/forms-flow-web/src/actions/actionConstants.js index ca770a8496..7f042aa7f8 100644 --- a/forms-flow-web/src/actions/actionConstants.js +++ b/forms-flow-web/src/actions/actionConstants.js @@ -127,7 +127,12 @@ const ACTION_CONSTANTS = { DASHBOARDS_UPDATE_ERROR:"DASHBOARDS_UPDATE_ERROR", DASHBOARDS_HIDE_UPDATE_ERROR:"DASHBOARDS_HIDE_UPDATE_ERROR", // Process - RESET_PROCESS:'RESET_PROCESS' + RESET_PROCESS:'RESET_PROCESS', + // Tenant + RESET_TENANT:"RESET_TENANT", + SET_TENANT_DETAILS:"SET_TENANT_DETAILS", + SET_TENANT_ID:"SET_TENANT_ID", + IS_TENANT_DETAIL_LOADING:"IS_TENANT_DETAIL_LOADING" }; export default ACTION_CONSTANTS; diff --git a/forms-flow-web/src/actions/tenantActions.js b/forms-flow-web/src/actions/tenantActions.js new file mode 100644 index 0000000000..756b440ac2 --- /dev/null +++ b/forms-flow-web/src/actions/tenantActions.js @@ -0,0 +1,43 @@ +import ACTION_CONSTANTS from "./actionConstants"; + +export const resetTenant = (tenantId) => dispatch => { + dispatch({ + type: ACTION_CONSTANTS.RESET_TENANT, + payload: tenantId + }) +} + +export const setTenantID = (tenantID) => dispatch => { + dispatch({ + type: ACTION_CONSTANTS.SET_TENANT_ID, + payload: tenantID + }) +} + +export const setTenantDetails = (tenantDetails) => dispatch => { + dispatch({ + type: ACTION_CONSTANTS.SET_TENANT_DETAILS, + payload: tenantDetails + }) +} + +export const setTenantListLoading = (isLoading) => dispatch => { + dispatch({ + type: ACTION_CONSTANTS.IS_TENANT_LIST_LOADING, + payload: isLoading + }) +} + +export const setTenantDetailLoading = (isLoading) => dispatch => { + dispatch({ + type: ACTION_CONSTANTS.IS_TENANT_DETAIL_LOADING, + payload: isLoading + }) +} + +export const serviceActionError = (data) => dispatch => { + dispatch({ + type: ACTION_CONSTANTS.ERROR, + payload: 'Error Handling Message' + }) +} \ No newline at end of file diff --git a/forms-flow-web/src/apiManager/services/formatterService.js b/forms-flow-web/src/apiManager/services/formatterService.js index e76f092d9f..8eedbd2d31 100644 --- a/forms-flow-web/src/apiManager/services/formatterService.js +++ b/forms-flow-web/src/apiManager/services/formatterService.js @@ -76,8 +76,8 @@ export const getFormIdSubmissionIdFromURL = (formUrl) => { return {formId,submissionId}; } -export const getFormUrl = (formId, submissionId) => { - return `${window.location.origin}/form/${formId}/submission/${submissionId}`; +export const getFormUrl = (formId, submissionId, redirectUrl) => { + return `${window.location.origin}${redirectUrl}form/${formId}/submission/${submissionId}`; } export const getISODateTime=(date)=>{ diff --git a/forms-flow-web/src/apiManager/services/tenantServices.js b/forms-flow-web/src/apiManager/services/tenantServices.js new file mode 100644 index 0000000000..90993edcb1 --- /dev/null +++ b/forms-flow-web/src/apiManager/services/tenantServices.js @@ -0,0 +1,26 @@ +import {tenantDetail} from "../../constants/tenantConstant"; +import { + setTenantDetails, + setTenantID, +} from "../../actions/tenantActions"; +import { Keycloak_Tenant_Client } from "../../constants/constants"; + +export const getTenantKeycloakJson = (tenantKey) => { + + let tenantData = {...tenantDetail} + if(tenantKey){ + tenantData.clientId = tenantKey + "-" + Keycloak_Tenant_Client + } + return tenantData; +} + +export const setTenantFromId = (tenantKey, ...rest)=>{ + let tenantData = {...tenantDetail} + const done = rest.length ? rest[0] : ()=>{}; + tenantData.clientId = tenantKey + "-" + Keycloak_Tenant_Client + return dispatch => { + dispatch(setTenantID(tenantKey)); + dispatch(setTenantDetails(tenantData)); + done(null,tenantDetail); + } +} \ No newline at end of file diff --git a/forms-flow-web/src/components/Admin/index.js b/forms-flow-web/src/components/Admin/index.js index eeeed3e491..3cb7342eea 100644 --- a/forms-flow-web/src/components/Admin/index.js +++ b/forms-flow-web/src/components/Admin/index.js @@ -5,6 +5,7 @@ import {useDispatch} from "react-redux"; import { fetchdashboards, fetchGroups } from "../../apiManager/services/dashboardsService"; import ACTION_CONSTANTS from "../../actions/actionConstants"; import './insightDashboard.scss' +import { BASE_ROUTE } from "../../constants/constants"; const AdminDashboard = () => { @@ -24,7 +25,7 @@ const AdminDashboard = () => { return (
- +
diff --git a/forms-flow-web/src/components/Application/ApplicationHistory.js b/forms-flow-web/src/components/Application/ApplicationHistory.js index 393a9f426e..615d03c382 100644 --- a/forms-flow-web/src/components/Application/ApplicationHistory.js +++ b/forms-flow-web/src/components/Application/ApplicationHistory.js @@ -19,6 +19,7 @@ import { import Loading from "../../containers/Loading"; import Nodata from '../../components/Nodata'; import {setUpdateHistoryLoader} from "../../actions/taskApplicationHistoryActions"; +import { MULTITENANCY_ENABLED } from "../../constants/constants"; const HistoryList = React.memo((props) => { @@ -26,6 +27,8 @@ const HistoryList = React.memo((props) => { const isHistoryListLoading = useSelector(state => state.taskAppHistory.isHistoryListLoading); const appHistory = useSelector(state => state.taskAppHistory.appHistory); const applicationId = props.applicationId; + const tenantKey = useSelector(state => state.tenants?.tenantId); + const redirectUrl = MULTITENANCY_ENABLED ? `/tenant/${tenantKey}/` : '/'; const {t}=useTranslation(); useEffect(()=>{ @@ -61,7 +64,7 @@ const HistoryList = React.memo((props) => { {(props) => ( diff --git a/forms-flow-web/src/components/Application/List.js b/forms-flow-web/src/components/Application/List.js index 2afbc64254..26781c2802 100644 --- a/forms-flow-web/src/components/Application/List.js +++ b/forms-flow-web/src/components/Application/List.js @@ -16,7 +16,7 @@ import { defaultSortedBy, } from "./table"; import {getUserRolePermission} from "../../helper/user"; -import {CLIENT, STAFF_REVIEWER} from "../../constants/constants"; +import {CLIENT, MULTITENANCY_ENABLED, STAFF_REVIEWER} from "../../constants/constants"; import {CLIENT_EDIT_STATUS} from "../../constants/applicationConstants"; import Alert from 'react-bootstrap/Alert' import { Translation } from "react-i18next"; @@ -37,7 +37,8 @@ export const ApplicationList = React.memo(() => { const iserror = useSelector(state=>state.applications.iserror); const error = useSelector(state=>state.applications.error); const [filtermode,setfiltermode] = React.useState(false); - + const tenantKey = useSelector(state => state.tenants?.tenantId); + const redirectUrl = MULTITENANCY_ENABLED ? `/tenant/${tenantKey}/` : '/'; const [lastModified,setLastModified] = React.useState(null); const [isLoading,setIsLoading] = React.useState(false); useEffect(()=>{ @@ -117,7 +118,7 @@ export const ApplicationList = React.memo(() => { bootstrap4 keyField="id" data={listApplications(applications)} - columns={columns(applicationStatus,lastModified,setLastModified,t)} + columns={columns(applicationStatus,lastModified,setLastModified,t,redirectUrl)} search > {(props) => ( diff --git a/forms-flow-web/src/components/Application/ViewApplication.js b/forms-flow-web/src/components/Application/ViewApplication.js index 587cfc6027..fecf4c8c27 100644 --- a/forms-flow-web/src/components/Application/ViewApplication.js +++ b/forms-flow-web/src/components/Application/ViewApplication.js @@ -14,6 +14,7 @@ import View from "../Form/Item/Submission/Item/View"; import {getForm, getSubmission} from "react-formio"; import NotFound from "../NotFound"; import { Translation } from "react-i18next"; +import { MULTITENANCY_ENABLED } from '../../constants/constants'; const ViewApplication = React.memo(() => { const {applicationId} = useParams(); @@ -21,8 +22,10 @@ const ViewApplication = React.memo(() => { const applicationDetailStatusCode = useSelector(state=>state.applications.applicationDetailStatusCode) const isApplicationDetailLoading = useSelector(state=>state.applications.isApplicationDetailLoading); const applicationProcess = useSelector(state => state.applications.applicationProcess); + const tenantKey = useSelector(state => state.tenants?.tenantId); const dispatch= useDispatch(); - + const redirectUrl = MULTITENANCY_ENABLED ? `/tenant/${tenantKey}/` : '/'; + useEffect(()=>{ dispatch(setApplicationDetailLoader(true)); dispatch(getApplicationById(applicationId,(err,res)=>{ @@ -52,7 +55,7 @@ const ViewApplication = React.memo(() => { return (
- +

diff --git a/forms-flow-web/src/components/Application/historyTable.js b/forms-flow-web/src/components/Application/historyTable.js index 17cbdc0d18..bdf2e7242d 100644 --- a/forms-flow-web/src/components/Application/historyTable.js +++ b/forms-flow-web/src/components/Application/historyTable.js @@ -9,9 +9,9 @@ export const defaultSortedBy = [ }, ]; -const linkSubmision = (cell) => { +const linkSubmision = (cell, row, redirectUrl) => { const {formId,submissionId} = getFormIdSubmissionIdFromURL(cell); - const url = getFormUrl(formId,submissionId) + const url = getFormUrl(formId,submissionId, redirectUrl) return (
window.open(url, "_blank")}>  {(t)=>t("View Submission")} @@ -26,7 +26,8 @@ function timeFormatter(cell) { // History table columns -export const columns_history = [ +export const columns_history = (redirectUrl)=>( + [ { dataField: "applicationStatus", text: {(t)=>t("Status")}, @@ -46,9 +47,10 @@ export const columns_history = [ { dataField: "formUrl", text: {(t)=>t("Submissions")}, - formatter: linkSubmision, + formatter: (cell, row)=>linkSubmision(cell, row, redirectUrl), }, -]; +] +) const customTotal = (from, to, size) => ( {(t)=>t("Showing")} {from} {(t)=>t("to")} {to} {(t)=>t("of")} {size} Results diff --git a/forms-flow-web/src/components/Application/index.js b/forms-flow-web/src/components/Application/index.js index 67dbf71791..7f76a71355 100644 --- a/forms-flow-web/src/components/Application/index.js +++ b/forms-flow-web/src/components/Application/index.js @@ -5,6 +5,7 @@ import ApplicationList from './List'; import ViewApplication from './ViewApplication'; import './Application.scss'; import { setCurrentPage } from '../../actions/bpmActions'; +import { BASE_ROUTE } from '../../constants/constants'; export default React.memo(() => { const showApplications= useSelector((state) => state.user.showApplications); @@ -18,9 +19,9 @@ export default React.memo(() => {
{showApplications?<> - - - + + + :null }
diff --git a/forms-flow-web/src/components/Application/table.js b/forms-flow-web/src/components/Application/table.js index 26ff228d9a..a437790ee0 100644 --- a/forms-flow-web/src/components/Application/table.js +++ b/forms-flow-web/src/components/Application/table.js @@ -28,17 +28,17 @@ const getApplicationStatusOptions = (rows) => { return selectOptions; } -const linkApplication = (cell, row) => { +const linkApplication = (cell, row, redirectUrl) => { return ( - + {cell} ); } -const linkSubmission = (cell,row) => { - const url = row.isClientEdit ? `/form/${row.formId}/submission/${row.submissionId}/edit`:`/form/${row.formId}/submission/${row.submissionId}`; +const linkSubmission = (cell,row,redirectUrl) => { + const url = row.isClientEdit ? `${redirectUrl}form/${row.formId}/submission/${row.submissionId}/edit`:`${redirectUrl}form/${row.formId}/submission/${row.submissionId}`; const buttonText = row.isClientEdit ? (row.applicationStatus===AWAITING_ACKNOWLEDGEMENT?'Acknowledge':{(t)=>t("Edit")}) : {(t)=>t("View")} const icon=row.isClientEdit? 'fa fa-edit' : 'fa fa-eye'; return ( @@ -73,12 +73,12 @@ export const columns_history = [ }, ]; -export const columns = (applicationStatus,lastModified,callback,t) => { +export const columns = (applicationStatus,lastModified,callback,t,redirectUrl) => { return [ { dataField: "id", text: {(t)=>t("Application Id")}, - formatter: linkApplication, + formatter: (cell, row)=>linkApplication(cell, row, redirectUrl), headerClasses: 'classApplicationId', sort: true, filter: textFilter({ @@ -127,7 +127,7 @@ export const columns = (applicationStatus,lastModified,callback,t) => { { dataField: "formUrl", text: {(t)=>t("Link To Form Submission")}, - formatter: linkSubmission, + formatter:(cell,row)=>linkSubmission(cell,row,redirectUrl), }, { diff --git a/forms-flow-web/src/components/BaseRouting.jsx b/forms-flow-web/src/components/BaseRouting.jsx index d54ef04642..604064fa47 100644 --- a/forms-flow-web/src/components/BaseRouting.jsx +++ b/forms-flow-web/src/components/BaseRouting.jsx @@ -1,18 +1,20 @@ import React from "react"; -import { Route, Switch } from "react-router-dom"; +import { Route, Switch, Redirect } from "react-router-dom"; import {useSelector} from "react-redux"; import PublicRoute from "./PublicRoute"; import PrivateRoute from "./PrivateRoute"; +import { BASE_ROUTE } from "../constants/constants"; /*import SideBar from "../containers/SideBar";*/ import NavBar from "../containers/NavBar"; import Footer from "../components/Footer"; import { ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css' +import NotFound from "./NotFound"; const BaseRouting = React.memo(({store}) => { - const isAuth = useSelector((state) => state.user.isAuthenticated); +const isAuth = useSelector((state) => state.user.isAuthenticated); return ( <> @@ -23,9 +25,11 @@ const BaseRouting = React.memo(({store}) => { - + + + {isAuth?
:null}
diff --git a/forms-flow-web/src/components/Dashboard/Dashboard.js b/forms-flow-web/src/components/Dashboard/Dashboard.js index 6cd5ad1e8b..e38abc7d63 100644 --- a/forms-flow-web/src/components/Dashboard/Dashboard.js +++ b/forms-flow-web/src/components/Dashboard/Dashboard.js @@ -14,6 +14,7 @@ import LoadError from "../Error"; import DateRangePicker from "@wojtekmaj/react-daterange-picker"; import moment from "moment"; import { Translation,useTranslation } from "react-i18next"; +import { BASE_ROUTE } from "../../constants/constants"; import { setMetricsSubmissionLimitChange, setMetricsSubmissionPageChange, setMetricsSubmissionSearch, setMetricsSubmissionSort } from "../../actions/metricsActions"; const firsDay = moment().format("YYYY-MM-01"); @@ -267,7 +268,7 @@ const Dashboard = React.memo(() => {

- + ); }); diff --git a/forms-flow-web/src/components/Form/Create.js b/forms-flow-web/src/components/Form/Create.js index 14ab6f2da3..47f5a9ebc1 100644 --- a/forms-flow-web/src/components/Form/Create.js +++ b/forms-flow-web/src/components/Form/Create.js @@ -8,6 +8,7 @@ import { SUBMISSION_ACCESS, ANONYMOUS_ID, FORM_ACCESS, + MULTITENANCY_ENABLED, } from "../../constants/constants"; import { addHiddenApplicationComponent } from "../../constants/applicationComponent"; import { saveFormProcessMapper } from "../../apiManager/services/processServices"; @@ -51,6 +52,9 @@ const [form, dispatchFormAction] = useReducer(reducer, _cloneDeep(formData)); const saveText = {(t)=>t("Save & Preview")}; const errors = useSelector((state)=>state.form.error) const lang = useSelector((state) => state.user.lang); +const tenantKey = useSelector(state => state.tenants?.tenantId); +const redirectUrl = MULTITENANCY_ENABLED ? `/tenant/${tenantKey}/` : '/' + const {t}=useTranslation(); useEffect(() => { @@ -114,7 +118,7 @@ const {t}=useTranslation(); saveFormProcessMapper(data, update, (err, res) => { if (!err) { toast.success(t("Form Saved")); - dispatch(push(`/formflow/${form._id}/view-edit/`)); + dispatch(push(`${redirectUrl}formflow/${form._id}/view-edit/`)); } else { toast.error("Error in creating form process mapper"); } diff --git a/forms-flow-web/src/components/Form/Item/Edit.js b/forms-flow-web/src/components/Form/Item/Edit.js index e65395368b..7db87b3ac2 100644 --- a/forms-flow-web/src/components/Form/Item/Edit.js +++ b/forms-flow-web/src/components/Form/Item/Edit.js @@ -9,6 +9,7 @@ import { SUBMISSION_ACCESS, ANONYMOUS_ID, FORM_ACCESS, + MULTITENANCY_ENABLED, } from "../../../constants/constants"; import { addHiddenApplicationComponent } from "../../../constants/applicationComponent"; import { toast } from "react-toastify"; @@ -58,6 +59,8 @@ const Edit = React.memo(() => { const applicationCount = useSelector((state) =>state.process.applicationCount) const formProcessList = useSelector((state)=>state.process.formProcessList) const formPreviousData = useSelector((state)=>state.process.formPreviousData) + const tenantKey = useSelector(state => state.tenants?.tenantId); + const redirectUrl = MULTITENANCY_ENABLED ? `/tenant/${tenantKey}/` : '/' const saveText = ({(t)=>t("Save Form")}); const lang = useSelector((state) => state.user.lang); const history = useHistory(); @@ -205,7 +208,7 @@ const Edit = React.memo(() => { dispatch(setFormPreviosData({...newData,isTitleChanged})); } toast.success(t("Form Saved")); - dispatch(push(`/formflow/${submittedData._id}/preview`)); + dispatch(push(`${redirectUrl}formflow/${submittedData._id}/preview`)); // ownProps.setPreviewMode(true); } else { toast.error(t("Error while saving Form")); diff --git a/forms-flow-web/src/components/Form/Item/Preview.js b/forms-flow-web/src/components/Form/Item/Preview.js index 75b6c15ed4..df1da67804 100644 --- a/forms-flow-web/src/components/Form/Item/Preview.js +++ b/forms-flow-web/src/components/Form/Item/Preview.js @@ -6,6 +6,7 @@ import { Button } from "react-bootstrap"; import Loading from "../../../containers/Loading"; import { Translation } from "react-i18next"; import { formio_resourceBundles } from "../../../resourceBundles/formio_resourceBundles"; +import { MULTITENANCY_ENABLED } from "../../../constants/constants"; const Preview = class extends PureComponent { constructor(props) { @@ -28,7 +29,9 @@ const Preview = class extends PureComponent { form: { form, isActive: isFormActive }, dispatch, handleNext, + tenants } = this.props; + const tenantKey = tenants?.tenantId if (isFormActive ) { return ; } @@ -39,7 +42,8 @@ const Preview = class extends PureComponent {