diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Workspace/MemberRoles_Spec.ts b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Workspace/MemberRoles_Spec.ts index 2b1f97c477..cb3bdf4116 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Workspace/MemberRoles_Spec.ts +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Workspace/MemberRoles_Spec.ts @@ -48,9 +48,8 @@ describe("Create new workspace and invite user & validate all roles", () => { cy.wait(2000); cy.xpath(HomePage.selectRole).click(); cy.get(".t--dropdown-option") - .should("have.length", 2) + .should("have.length", 1) .and("contain.text", `App Viewer - ${workspaceId}`); - cy.get(".t--dropdown-option").should("contain.text", `Select a role`); cy.get(HomePage.closeBtn).click(); homePage.LaunchAppFromAppHover(); @@ -88,13 +87,12 @@ describe("Create new workspace and invite user & validate all roles", () => { cy.wait(2000); cy.xpath(HomePage.selectRole).click(); cy.get(".t--dropdown-option") - .should("have.length", 3) + .should("have.length", 2) .and( "contain.text", `App Viewer - ${workspaceId}`, `Developer - ${workspaceId}`, ); - cy.get(".t--dropdown-option").should("contain.text", `Select a role`); cy.get(HomePage.closeBtn).click(); homePage.LogOutviaAPI(); }); @@ -117,19 +115,27 @@ describe("Create new workspace and invite user & validate all roles", () => { Cypress.env("TESTPASSWORD1"), "Administrator", ); - homePage.FilterApplication(appid, workspaceId); - cy.get(homePage._applicationCard) - .first() - .trigger("mouseover"); homePage.InviteUserToWorkspace( workspaceId, Cypress.env("TESTUSERNAME2"), "App Viewer", ); + cy.get(HomePage.closeBtn).click(); + cy.wait(2000); + homePage.FilterApplication(appid, workspaceId); + cy.get(homePage._applicationCard) + .first() + .trigger("mouseover"); + cy.get(homePage._appHoverIcon("edit")) + .first() + .click({ force: true }); + // cy.xpath(homePage._editPageLanding).should("exist"); + cy.wait(4000); + cy.xpath("//span[text()='SHARE']").click(); cy.wait(2000); cy.xpath(HomePage.selectRole).click(); cy.get(".t--dropdown-option") - .should("have.length", 4) + .should("have.length", 3) .should( "contain.text", `App Viewer - ${workspaceId}`, @@ -139,7 +145,6 @@ describe("Create new workspace and invite user & validate all roles", () => { "contain.text", `Administrator - ${workspaceId}`, ); - cy.get(".t--dropdown-option").should("contain.text", `Select a role`); cy.get(HomePage.closeBtn).click(); homePage.LogOutviaAPI(); }); diff --git a/app/client/package.json b/app/client/package.json index ca0e158920..d113c851b1 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -182,7 +182,6 @@ "test:unit": "$(npm bin)/jest -b --colors --no-cache --silent --coverage --collectCoverage=true --coverageDirectory='../../' --coverageReporters='json-summary'", "test:jest": "$(npm bin)/jest --watch", "generate:widget": "plop --plopfile generators/index.js", - "postbuild": "rm build/mockServiceWorker.js", "postinstall": "patch-package && CURRENT_SCOPE=client node ../shared/install-dependencies.js", "preinstall": "CURRENT_SCOPE=client node ../shared/build-shared-dep.js", "install": "node cypress/apply-patches.js" @@ -307,8 +306,5 @@ "json-schema": "0.4.0", "node-fetch": "2.6.7", "babel-plugin-styled-components": "2.0.7" - }, - "msw": { - "workerDirectory": "public" } } diff --git a/app/client/public/mockServiceWorker.js b/app/client/public/mockServiceWorker.js deleted file mode 100644 index 853ba27719..0000000000 --- a/app/client/public/mockServiceWorker.js +++ /dev/null @@ -1,322 +0,0 @@ -/** - * Mock Service Worker. - * @see https://github.com/mswjs/msw - * - Please do NOT modify this file. - * - Please do NOT serve this file on production. - */ -/* eslint-disable */ -/* tslint:disable */ - -const INTEGRITY_CHECKSUM = '795882c72c7304f6fa1d4a65a2418900' -const bypassHeaderName = 'x-msw-bypass' -const activeClientIds = new Set() - -self.addEventListener('install', function () { - return self.skipWaiting() -}) - -self.addEventListener('activate', async function (event) { - return self.clients.claim() -}) - -self.addEventListener('message', async function (event) { - const clientId = event.source.id - - if (!clientId || !self.clients) { - return - } - - const client = await self.clients.get(clientId) - - if (!client) { - return - } - - const allClients = await self.clients.matchAll() - - switch (event.data) { - case 'KEEPALIVE_REQUEST': { - sendToClient(client, { - type: 'KEEPALIVE_RESPONSE', - }) - break - } - - case 'INTEGRITY_CHECK_REQUEST': { - sendToClient(client, { - type: 'INTEGRITY_CHECK_RESPONSE', - payload: INTEGRITY_CHECKSUM, - }) - break - } - - case 'MOCK_ACTIVATE': { - activeClientIds.add(clientId) - - sendToClient(client, { - type: 'MOCKING_ENABLED', - payload: true, - }) - break - } - - case 'MOCK_DEACTIVATE': { - activeClientIds.delete(clientId) - break - } - - case 'CLIENT_CLOSED': { - activeClientIds.delete(clientId) - - const remainingClients = allClients.filter((client) => { - return client.id !== clientId - }) - - // Unregister itself when there are no more clients - if (remainingClients.length === 0) { - self.registration.unregister() - } - - break - } - } -}) - -// Resolve the "master" client for the given event. -// Client that issues a request doesn't necessarily equal the client -// that registered the worker. It's with the latter the worker should -// communicate with during the response resolving phase. -async function resolveMasterClient(event) { - const client = await self.clients.get(event.clientId) - - if (client.frameType === 'top-level') { - return client - } - - const allClients = await self.clients.matchAll() - - return allClients - .filter((client) => { - // Get only those clients that are currently visible. - return client.visibilityState === 'visible' - }) - .find((client) => { - // Find the client ID that's recorded in the - // set of clients that have registered the worker. - return activeClientIds.has(client.id) - }) -} - -async function handleRequest(event, requestId) { - const client = await resolveMasterClient(event) - const response = await getResponse(event, client, requestId) - - // Send back the response clone for the "response:*" life-cycle events. - // Ensure MSW is active and ready to handle the message, otherwise - // this message will pend indefinitely. - if (activeClientIds.has(client.id)) { - ;(async function () { - const clonedResponse = response.clone() - sendToClient(client, { - type: 'RESPONSE', - payload: { - requestId, - type: clonedResponse.type, - ok: clonedResponse.ok, - status: clonedResponse.status, - statusText: clonedResponse.statusText, - body: - clonedResponse.body === null ? null : await clonedResponse.text(), - headers: serializeHeaders(clonedResponse.headers), - redirected: clonedResponse.redirected, - }, - }) - })() - } - - return response -} - -async function getResponse(event, client, requestId) { - const { request } = event - const requestClone = request.clone() - const getOriginalResponse = () => fetch(requestClone) - - // Bypass mocking when the request client is not active. - if (!client) { - return getOriginalResponse() - } - - // Bypass initial page load requests (i.e. static assets). - // The absence of the immediate/parent client in the map of the active clients - // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet - // and is not ready to handle requests. - if (!activeClientIds.has(client.id)) { - return await getOriginalResponse() - } - - // Bypass requests with the explicit bypass header - if (requestClone.headers.get(bypassHeaderName) === 'true') { - const cleanRequestHeaders = serializeHeaders(requestClone.headers) - - // Remove the bypass header to comply with the CORS preflight check. - delete cleanRequestHeaders[bypassHeaderName] - - const originalRequest = new Request(requestClone, { - headers: new Headers(cleanRequestHeaders), - }) - - return fetch(originalRequest) - } - - // Send the request to the client-side MSW. - const reqHeaders = serializeHeaders(request.headers) - const body = await request.text() - - const clientMessage = await sendToClient(client, { - type: 'REQUEST', - payload: { - id: requestId, - url: request.url, - method: request.method, - headers: reqHeaders, - cache: request.cache, - mode: request.mode, - credentials: request.credentials, - destination: request.destination, - integrity: request.integrity, - redirect: request.redirect, - referrer: request.referrer, - referrerPolicy: request.referrerPolicy, - body, - bodyUsed: request.bodyUsed, - keepalive: request.keepalive, - }, - }) - - switch (clientMessage.type) { - case 'MOCK_SUCCESS': { - return delayPromise( - () => respondWithMock(clientMessage), - clientMessage.payload.delay, - ) - } - - case 'MOCK_NOT_FOUND': { - return getOriginalResponse() - } - - case 'NETWORK_ERROR': { - const { name, message } = clientMessage.payload - const networkError = new Error(message) - networkError.name = name - - // Rejecting a request Promise emulates a network error. - throw networkError - } - - case 'INTERNAL_ERROR': { - const parsedBody = JSON.parse(clientMessage.payload.body) - - console.error( - `\ -[MSW] Request handler function for "%s %s" has thrown the following exception: - -${parsedBody.errorType}: ${parsedBody.message} -(see more detailed error stack trace in the mocked response body) - -This exception has been gracefully handled as a 500 response, however, it's strongly recommended to resolve this error. -If you wish to mock an error response, please refer to this guide: https://mswjs.io/docs/recipes/mocking-error-responses\ -`, - request.method, - request.url, - ) - - return respondWithMock(clientMessage) - } - } - - return getOriginalResponse() -} - -self.addEventListener('fetch', function (event) { - const { request } = event - - // Bypass navigation requests. - if (request.mode === 'navigate') { - return - } - - // Opening the DevTools triggers the "only-if-cached" request - // that cannot be handled by the worker. Bypass such requests. - if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { - return - } - - // Bypass all requests when there are no active clients. - // Prevents the self-unregistered worked from handling requests - // after it's been deleted (still remains active until the next reload). - if (activeClientIds.size === 0) { - return - } - - const requestId = uuidv4() - - return event.respondWith( - handleRequest(event, requestId).catch((error) => { - console.error( - '[MSW] Failed to mock a "%s" request to "%s": %s', - request.method, - request.url, - error, - ) - }), - ) -}) - -function serializeHeaders(headers) { - const reqHeaders = {} - headers.forEach((value, name) => { - reqHeaders[name] = reqHeaders[name] - ? [].concat(reqHeaders[name]).concat(value) - : value - }) - return reqHeaders -} - -function sendToClient(client, message) { - return new Promise((resolve, reject) => { - const channel = new MessageChannel() - - channel.port1.onmessage = (event) => { - if (event.data && event.data.error) { - return reject(event.data.error) - } - - resolve(event.data) - } - - client.postMessage(JSON.stringify(message), [channel.port2]) - }) -} - -function delayPromise(cb, duration) { - return new Promise((resolve) => { - setTimeout(() => resolve(cb()), duration) - }) -} - -function respondWithMock(clientMessage) { - return new Response(clientMessage.payload.body, { - ...clientMessage.payload, - headers: clientMessage.payload.headers, - }) -} - -function uuidv4() { - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - const r = (Math.random() * 16) | 0 - const v = c == 'x' ? r : (r & 0x3) | 0x8 - return v.toString(16) - }) -} diff --git a/app/client/src/ce/constants/forms.ts b/app/client/src/ce/constants/forms.ts index 3e97445965..5e1149ae02 100644 --- a/app/client/src/ce/constants/forms.ts +++ b/app/client/src/ce/constants/forms.ts @@ -39,5 +39,3 @@ export const WELCOME_NON_SUPER_FORM_NAME = "WelcomeNonSuperSetupForm"; export const SAVE_THEME_FORM_NAME = "SaveThemeForm"; export const REDIRECT_URL_FORM = "RedirectURLForm"; export const ENTITYID_URL_FORM = "EntityIdURLForm"; - -export const inviteModalLinks: any[] = []; diff --git a/app/client/src/ce/mocks/handlers.ts b/app/client/src/ce/mocks/handlers.ts index c97e7e8413..5317c4271e 100644 --- a/app/client/src/ce/mocks/handlers.ts +++ b/app/client/src/ce/mocks/handlers.ts @@ -1,8 +1,3 @@ -import { rest } from "msw"; -import testMockApi from "./mockJsons/testMockApi.json"; +/* import { rest } from "msw"; */ -export const handlers = [ - rest.get("/api/testMockApi", (req, res, ctx) => { - return res(ctx.status(200), ctx.json(testMockApi)); - }), -]; +export const handlers = []; diff --git a/app/client/src/ce/mocks/mockJsons/testMockApi.json b/app/client/src/ce/mocks/mockJsons/testMockApi.json deleted file mode 100644 index 36ef25a18e..0000000000 --- a/app/client/src/ce/mocks/mockJsons/testMockApi.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "data": { - "environment": "CE" - } -} diff --git a/app/client/src/ce/pages/workspace/WorkspaceInviteUsersForm.tsx b/app/client/src/ce/pages/workspace/WorkspaceInviteUsersForm.tsx index ba5d8b23f9..745bcd025e 100644 --- a/app/client/src/ce/pages/workspace/WorkspaceInviteUsersForm.tsx +++ b/app/client/src/ce/pages/workspace/WorkspaceInviteUsersForm.tsx @@ -49,11 +49,7 @@ import { Size, Text, TextType, - Icon, - IconSize, - SegmentHeader, TextProps, - TooltipComponent, DropdownOption, } from "design-system"; import { Classes, Variant } from "components/ads/common"; @@ -65,8 +61,7 @@ import { ScrollIndicator } from "design-system"; import UserApi from "@appsmith/api/UserApi"; import { Colors } from "constants/Colors"; import { fetchWorkspace } from "actions/workspaceActions"; -import { SubTextPosition } from "components/constants"; -import { Link } from "react-router-dom"; +import { useHistory } from "react-router-dom"; import { Tooltip } from "@blueprintjs/core"; import { isEllipsisActive } from "utils/helpers"; @@ -228,16 +223,6 @@ export const LabelText = styled(Text)` letter-spacing: -0.24px; `; -/*const LinksWrapper = styled.div` - &:before { - border-top: 1px solid var(--appsmith-color-black-200); - content: ""; - position: absolute; - left: 12px; - right: 12px; - } -`;*/ - export const LeftIconWrapper = styled.span` font-size: 20px; line-height: 19px; @@ -247,145 +232,12 @@ export const LeftIconWrapper = styled.span` top: 1px; `; -export const SelectedIcon = styled(Icon)<{ name: string }>` - margin-right: 6px; - & > div:first-child { - height: 18px; - width: 18px; - svg { - height: 18px; - width: 18px; - rect { - fill: ${(props) => props.theme.colors.dropdownIconBg}; - rx: 0; - } - path { - fill: ${(props) => props.theme.colors.propertyPane.label}; - } - } - } - svg { - ${(props) => - props.name === "right-arrow" ? `transform: rotate(-45deg);` : ``} - path { - fill: ${(props) => - props.fillColor - ? props.fillColor - : props.theme.colors.dropdown.selected.icon}; - } - } -`; - -export const StyledSubText = styled(Text)<{ - showDropIcon?: boolean; - subTextPosition?: SubTextPosition; -}>` - ${(props) => - props.subTextPosition === SubTextPosition.BOTTOM - ? "margin-top: 3px" - : "margin-left: auto"}; - &&& { - color: ${(props) => props.theme.colors.dropdown.menu.subText}; - } - &.sub-text { - color: ${(props) => props.theme.colors.dropdown.selected.subtext}; - text-align: end; - margin-right: ${(props) => `${props.theme.spaces[4]}px`}; - } -`; - -export const OptionWrapper = styled.div<{ - disabled?: boolean; - selected: boolean; - subTextPosition?: SubTextPosition; - selectedHighlightBg?: string; -}>` - padding: ${(props) => props.theme.spaces[3] + 1}px - ${(props) => props.theme.spaces[5]}px; - ${(props) => (!props.disabled ? "cursor: pointer" : "")}; - display: flex; - width: 100%; - min-height: 36px; - flex-direction: ${(props) => - props.subTextPosition === SubTextPosition.BOTTOM ? "column" : "row"}; - align-items: ${(props) => - props.subTextPosition === SubTextPosition.BOTTOM ? "flex-start" : "center"}; - background-color: ${(props) => - props.selected - ? props.selectedHighlightBg || `var(--appsmith-color-black-200)` - : `initial`}; - &&& svg { - rect { - fill: ${(props) => props.theme.colors.dropdownIconBg}; - } - } - .bp3-popover-wrapper { - width: 100%; - } - .${Classes.TEXT} { - color: ${(props) => - props.disabled - ? Colors.GRAY2 - : props.selected - ? props.theme.colors.dropdown.menu.hoverText - : props.theme.colors.dropdown.menu.text}; - } - .${Classes.ICON} { - margin-right: ${(props) => props.theme.spaces[5]}px; - svg { - path { - ${(props) => - props.selected - ? `fill: ${props.theme.colors.dropdown.selected.icon}` - : `fill: ${props.theme.colors.dropdown.icon}`}; - } - } - } - &:hover, - &.highlighted { - background-color: ${(props) => - props.selectedHighlightBg || `var(--appsmith-color-black-200)`}; - &&& svg { - rect { - fill: ${(props) => props.theme.colors.textOnDarkBG}; - } - } - .${Classes.TEXT} { - color: ${(props) => props.theme.colors.dropdown.menu.hoverText}; - } - ${StyledSubText} { - color: ${(props) => props.theme.colors.dropdown.menu.subText}; - } - .${Classes.ICON} { - svg { - path { - fill: ${(props) => props.theme.colors.dropdown.hovered.icon}; - } - } - } - } -`; - export const StyledText = styled(Text)` overflow: hidden; text-overflow: ellipsis; white-space: nowrap; `; -export const LabelWrapper = styled.div<{ label?: string }>` - display: flex; - flex-direction: column; - align-items: flex-start; - span:last-child { - margin-top: ${(props) => props.theme.spaces[2] - 1}px; - } - &:hover { - .${Classes.TEXT} { - color: ${(props) => props.theme.colors.dropdown.selected.text}; - } - } -`; - export function TooltipWrappedText( props: TextProps & { label: string; @@ -428,19 +280,7 @@ const validateFormValues = (values: { }); } - if ( - typeof values.roles === "undefined" && - (typeof values.role === "undefined" || values.role?.trim().length === 0) - ) { - throw new SubmissionError({ - _error: createMessage(INVITE_USERS_VALIDATION_ROLE_EMPTY), - }); - } - - if ( - typeof values.role === "undefined" && - (typeof values.roles === "undefined" || values.roles.length === 0) - ) { + if (typeof values.role === "undefined" || values.role.length === 0) { throw new SubmissionError({ _error: createMessage(INVITE_USERS_VALIDATION_ROLE_EMPTY), }); @@ -453,20 +293,10 @@ const validate = (values: any) => { errors["users"] = createMessage(INVITE_USERS_VALIDATION_EMAILS_EMPTY); } - if ( - typeof values.roles === "undefined" && - (typeof values.role === "undefined" || values.role?.trim().length === 0) - ) { + if (typeof values.role === "undefined" || values.role.length === 0) { errors["role"] = createMessage(INVITE_USERS_VALIDATION_ROLE_EMPTY); } - if ( - typeof values.role === "undefined" && - (typeof values.roles === "undefined" || values.roles.length === 0) - ) { - errors["roles"] = createMessage(INVITE_USERS_VALIDATION_ROLE_EMPTY); - } - if (values.users && values.users.length > 0) { const _users = values.users.split(",").filter(Boolean); @@ -485,13 +315,10 @@ export const InviteButtonWidth = "88px"; function WorkspaceInviteUsersForm(props: any) { const [emailError, setEmailError] = useState(""); - const [selectedOption, setSelectedOption] = useState({}); + const [selectedOption, setSelectedOption] = useState([]); const userRef = React.createRef(); + const history = useHistory(); const selectedId = props?.selected?.id; - const multiSelectDropdownOptions: Partial[] = - props.options && props.options.length > 0 && props.isMultiSelectDropdown - ? props.options - : []; const selected = useMemo( () => @@ -515,11 +342,9 @@ function WorkspaceInviteUsersForm(props: any) { fetchCurrentWorkspace, fetchUser, handleSubmit, - isAclFlow = false, isApplicationInvite, isLoading, isMultiSelectDropdown = false, - links = [], message = "", placeholder = "", submitFailed, @@ -528,8 +353,6 @@ function WorkspaceInviteUsersForm(props: any) { valid, } = props; - const [selectedItems, setSelectedItems] = useState([]); - // set state for checking number of users invited const [numberOfUsersInvited, updateNumberOfUsersInvited] = useState(0); const currentWorkspace = useSelector(getCurrentAppWorkspace); @@ -541,31 +364,30 @@ function WorkspaceInviteUsersForm(props: any) { ); useEffect(() => { - if (!isAclFlow) { - fetchUser(props.workspaceId); - fetchAllRoles(props.workspaceId); - fetchCurrentWorkspace(props.workspaceId); - } + fetchUser(props.workspaceId); + fetchAllRoles(props.workspaceId); + fetchCurrentWorkspace(props.workspaceId); }, [props.workspaceId, fetchUser, fetchAllRoles, fetchCurrentWorkspace]); useEffect(() => { if (selected) { - setSelectedItems([selected]); + setSelectedOption([selected]); props.initialize({ - roles: [selected], + role: [selected], }); } }, []); - const styledRoles = props.roles.map((role: any) => { - return { - id: role.id, - value: role.name, - label: role.description, - }; - }); - - styledRoles.push(...links); + const styledRoles = + props.options && props.options.length > 0 + ? props.options + : props.roles.map((role: any) => { + return { + id: role.id, + value: role.name, + label: role.description, + }; + }); const theme = useContext(ThemeContext); @@ -592,12 +414,15 @@ function WorkspaceInviteUsersForm(props: any) { [allUsers, theme], ); - const onSelect = (_value?: string, options?: any) => { - setSelectedItems(options); + const onSelect = (_value?: string, option?: any) => { + if (option.link) { + history.push(option.link); + } + setSelectedOption(isMultiSelectDropdown ? option : [option]); }; const onRemoveOptions = (updatedItems: any) => { - setSelectedItems(updatedItems); + setSelectedOption(updatedItems); }; const getLabel = (selectedOption: Partial[]) => { @@ -626,155 +451,6 @@ function WorkspaceInviteUsersForm(props: any) { } }; - const renderOption = ({ - index, - isHighlighted, - option, - optionClickHandler, - }: { - index?: number; - option: DropdownOption | DropdownOption[]; - optionClickHandler?: (dropdownOption: DropdownOption) => void; - isHighlighted?: boolean; - }) => { - let isSelected = false; - if (props.isMultiSelect && Array.isArray(selected) && selected.length) { - isSelected = !!selected.find((selectedOption: any) => - !Array.isArray(option) ? selectedOption.value === option.value : false, - ); - } else { - isSelected = - !Array.isArray(option) && selected - ? selected.value === option.value - : false; - } - return !Array.isArray(option) && !option.isSectionHeader ? ( - !option.link ? ( - - props.removeSelectedOptionClickHandler(option) - : () => optionClickHandler?.(option) - } - role="option" - selected={ - props.isMultiSelect ? props.highlightIndex === index : isSelected - } - selectedHighlightBg={props.selectedHighlightBg} - subTextPosition={option.subTextPosition ?? SubTextPosition.LEFT} - > - {option.leftElement && ( - {option.leftElement} - )} - {option.icon ? ( - - ) : null} - {props.showLabelOnly ? ( - props.truncateOption ? ( - <> - - {option.hasCustomBadge && props.customBadge} - - ) : ( - <> - {option.label} - {option.hasCustomBadge && props.customBadge} - - ) - ) : option.label && option.value ? ( - - {option.value} - {option.label} - - ) : props.truncateOption ? ( - - ) : ( - {option.value} - )} - {option.subText ? ( - - {option.subText} - - ) : null} - - - ) : ( - - - {option.leftElement && ( - {option.leftElement} - )} - {option.icon ? ( - - ) : null} - {option.value} - {option.subText ? ( - - {option.subText} - - ) : null} - - - ) - ) : ( - - ); - }; - return ( @@ -797,10 +473,11 @@ function WorkspaceInviteUsersForm(props: any) { .join(","); return inviteUsersToWorkspace( { - ...values, + ...(props.workspaceId ? { workspaceId: props.workspaceId } : {}), users, - permissionGroupId: selectedOption.id, - workspaceId: props.workspaceId, + permissionGroupId: isMultiSelectDropdown + ? selectedOption.map((group: any) => group.id).join(",") + : selectedOption[0].id, }, dispatch, ); @@ -821,36 +498,24 @@ function WorkspaceInviteUsersForm(props: any) { placeholder={placeholder || "Enter email address"} type="text" /> - {isMultiSelectDropdown ? ( - []) => - getLabel(selected) - } - name="roles" - onSelect={onSelect} - options={multiSelectDropdownOptions} - outline={false} - placeholder="Select a role" - removeSelectedOption={onRemoveOptions} - selected={selectedItems} - showLabelOnly - size="small" - /> - ) : ( - setSelectedOption(option)} - options={styledRoles} - outline={false} - placeholder="Select a role" - renderOption={renderOption} - size="small" - /> - )} + []) => + getLabel(selected) + } + name={"role"} + onSelect={(value, option) => onSelect(value, option)} + options={styledRoles} + outline={false} + placeholder="Select a role" + removeSelectedOption={onRemoveOptions} + selected={selectedOption} + showLabelOnly={isMultiSelectDropdown} + size="small" + />