From b4c18f41e7532ae61d91f8b27b2cc937ce8d9ff7 Mon Sep 17 00:00:00 2001 From: kanishkrawatt Date: Fri, 10 Jul 2026 20:34:57 +0530 Subject: [PATCH 1/4] [RQ-4283] chore: remove API Client from legacy onboarding & workspace creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The API Client is now a separate standalone product, but the Interceptor app still surfaced it in onboarding and workspace creation, funneling users into creating local workspaces (which only ever held API Client files). Per epic RQ-4191, remove all API Client touchpoints from these flows so onboarding offers only Interceptor: - DesktopOnboardingModal / WelcomeCard: remove the "Start using API Client" welcome card (expandable local-workspace create/open options) and the FOLDER_SELECTION local-workspace-creation step it fed into; drop the now-unused WorkspaceCreationProvider wrapper and the hooks (useCreateDefaultLocalWorkspace / useOpenLocalWorkspace / LocalWorkspaceCreateOptions / redirectToApiClient). "Skip" now simply completes onboarding instead of creating a local API Client workspace and redirecting to the API Client. Drop FOLDER_SELECTION from the OnboardingStep enum. - CreateWorkspaceModalOld: remove the entire "Local workspace" option ("only API client files are supported") and its dead local-workspace creation code — the modal now creates team workspaces only. - personaRecommendationData: remove the dead "Test API endpoints -> API Client" recommendation entry. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../CreateWorkspaceModalOld.tsx | 104 ++---------- .../personaRecommendationData.tsx | 8 - .../DesktopOnboardingModal.tsx | 65 +++----- .../components/WelcomeCard/WelcomeCard.tsx | 152 ++---------------- .../DesktopOnboardingModal/types.ts | 1 - 5 files changed, 46 insertions(+), 284 deletions(-) diff --git a/app/src/componentsV2/modals/CreateWorkspaceModalOld/CreateWorkspaceModalOld.tsx b/app/src/componentsV2/modals/CreateWorkspaceModalOld/CreateWorkspaceModalOld.tsx index c2ec8a5be2..795e2afed7 100644 --- a/app/src/componentsV2/modals/CreateWorkspaceModalOld/CreateWorkspaceModalOld.tsx +++ b/app/src/componentsV2/modals/CreateWorkspaceModalOld/CreateWorkspaceModalOld.tsx @@ -1,14 +1,11 @@ import React, { useCallback, useState } from "react"; -import { Checkbox, Input, Modal, Radio, Tag } from "antd"; +import { Checkbox, Input, Modal, Radio } from "antd"; import { useDispatch, useSelector } from "react-redux"; import * as Sentry from "@sentry/react"; import { getAppMode } from "store/selectors"; import { RQButton } from "lib/design-system-v2/components"; -import { CreateTeamParams, LocalWorkspaceConfig, SharedOrPrivateWorkspaceConfig } from "types"; -import { displayFolderSelector } from "components/mode-specific/desktop/misc/FileDialogButton"; -import { CONSTANTS as GLOBAL_CONSTANTS } from "@requestly/requestly-core"; -import { IoMdClose } from "@react-icons/all-files/io/IoMdClose"; +import { CreateTeamParams, SharedOrPrivateWorkspaceConfig } from "types"; import { getFunctions, httpsCallable } from "firebase/functions"; import { trackAddTeamMemberSuccess, @@ -24,10 +21,8 @@ import { switchWorkspace } from "actions/TeamWorkspaceActions"; import { redirectToTeam } from "utils/RedirectionUtils"; import { useNavigate } from "react-router-dom"; import { getAvailableBillingTeams } from "store/features/billing/selectors"; -import { createWorkspaceFolder } from "services/fsManagerServiceAdapter"; import { isActiveWorkspaceShared } from "store/slices/workspaces/selectors"; -import { workspaceActions } from "store/slices/workspaces/slice"; -import { Workspace, WorkspaceMemberRole, WorkspaceType } from "features/workspaces/types"; +import { WorkspaceType } from "features/workspaces/types"; import "./createOldWorkspaceModal.scss"; interface Props { @@ -45,17 +40,10 @@ export const CreateWorkspaceModalOld: React.FC = ({ isOpen, defaultWorksp const isSharedWorkspaceMode = useSelector(isActiveWorkspaceShared); const billingTeams = useSelector(getAvailableBillingTeams); const [workspaceName, setWorkspaceName] = useState(""); - const [workspaceType, setWorkspaceType] = useState( - defaultWorkspaceType || (user.loggedIn ? WorkspaceType.SHARED : WorkspaceType.LOCAL) - ); - const [folderPath, setFolderPath] = useState(""); + const [workspaceType, setWorkspaceType] = useState(defaultWorkspaceType || WorkspaceType.SHARED); const [isLoading, setIsLoading] = useState(false); const [isNotifyAllSelected, setIsNotifyAllSelected] = useState(false); - const folderSelectCallback = (path: string) => { - setFolderPath(path); - }; - const handlePostTeamCreationStep = useCallback( (teamId: string, newTeamName: string, hasMembersInSameDomain: boolean) => { switchWorkspace( @@ -138,43 +126,15 @@ export const CreateWorkspaceModalOld: React.FC = ({ isOpen, defaultWorksp const createOrgTeamInvite = httpsCallable(functions, "invites-createOrganizationTeamInvite"); const upsertTeamCommonInvite = httpsCallable(functions, "invites-upsertTeamCommonInvite"); - const config = - workspaceType === WorkspaceType.LOCAL - ? ({ type: WorkspaceType.LOCAL, rootPath: folderPath } as LocalWorkspaceConfig) - : ({ type: WorkspaceType.SHARED } as SharedOrPrivateWorkspaceConfig); + const config = { type: WorkspaceType.SHARED } as SharedOrPrivateWorkspaceConfig; try { const teamId = await (async () => { - if (config.type === WorkspaceType.LOCAL) { - const workspaceCreationResult = await createWorkspaceFolder(workspaceName, config.rootPath); - if (workspaceCreationResult.type === "error") { - throw new Error(workspaceCreationResult.error.message); - } - const partialWorkspace = workspaceCreationResult.content; - const localWorkspace: Workspace = { - id: partialWorkspace.id, - name: partialWorkspace.name, - owner: user?.details?.profile?.uid, - accessCount: 1, - adminCount: 1, - members: { - [user?.details?.profile?.uid]: { - role: WorkspaceMemberRole.admin, - }, - }, - appsumo: null, - workspaceType: WorkspaceType.LOCAL, - rootPath: partialWorkspace.path, - }; - dispatch(workspaceActions.upsertWorkspace(localWorkspace)); - return partialWorkspace.id; - } else { - const response: any = await createTeam({ - teamName: workspaceName, - config, - }); - return response.data.teamId; - } + const response: any = await createTeam({ + teamName: workspaceName, + config, + }); + return response.data.teamId; })(); trackNewTeamCreateSuccess(teamId, workspaceName, "create_workspace_modal", workspaceType); @@ -216,7 +176,6 @@ export const CreateWorkspaceModalOld: React.FC = ({ isOpen, defaultWorksp }, [ billingTeams, callback, - dispatch, isNotifyAllSelected, toggleModal, user?.details?.profile?.email, @@ -224,8 +183,6 @@ export const CreateWorkspaceModalOld: React.FC = ({ isOpen, defaultWorksp handlePostTeamCreationStep, handleDomainInvitesCreation, workspaceType, - folderPath, - user?.details?.profile?.uid, ]); return ( @@ -245,7 +202,7 @@ export const CreateWorkspaceModalOld: React.FC = ({ isOpen, defaultWorksp Cancel @@ -300,45 +257,6 @@ export const CreateWorkspaceModalOld: React.FC = ({ isOpen, defaultWorksp ), }, - { - value: WorkspaceType.LOCAL, - disabled: appMode !== GLOBAL_CONSTANTS.APP_MODES.DESKTOP, - label: ( -
-
- Local workspace BETA -
-
- In a Local Workspace, your files are stored on your device. Currently, only API client files are - supported. -
- {workspaceType === WorkspaceType.LOCAL ? ( -
- {folderPath.length ? ( -
-
- SELECTED LOCATION setFolderPath("")} /> -
-
{folderPath}
-
- ) : ( - <> - displayFolderSelector(folderSelectCallback)} - > - Select a folder - -
A location to store your workspace data.
- - )} -
- ) : null} -
- ), - }, ]} > diff --git a/app/src/features/onboarding/components/recommendations/components/recommendations/personaRecommendationData.tsx b/app/src/features/onboarding/components/recommendations/components/recommendations/personaRecommendationData.tsx index 20dd8fa6ad..eb6cd7cb14 100644 --- a/app/src/features/onboarding/components/recommendations/components/recommendations/personaRecommendationData.tsx +++ b/app/src/features/onboarding/components/recommendations/components/recommendations/personaRecommendationData.tsx @@ -5,7 +5,6 @@ import { FeatureSection, FeatureReleaseTag } from "./types"; import { CONSTANTS as GLOBAL_CONSTANTS } from "@requestly/requestly-core"; import { FiVideo } from "@react-icons/all-files/fi/FiVideo"; import { IoDocumentTextOutline } from "@react-icons/all-files/io5/IoDocumentTextOutline"; -import { ApiOutlined } from "@ant-design/icons"; const { RULE_TYPES } = GLOBAL_CONSTANTS; const { RULE_TYPES_CONFIG } = APP_CONSTANTS; @@ -76,13 +75,6 @@ export const personaRecommendationData: FeatureSection[] = [ subTitle: "Create mocks for your APIs", link: PATHS.MOCK_SERVER_V2.ABSOLUTE, }, - { - id: "test_api_endpoints", - title: "Test API endpoints", - icon: () => , - subTitle: "Test responses quickly using API Client", - link: PATHS.API_CLIENT.ABSOLUTE, - }, ], }, ]; diff --git a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/DesktopOnboardingModal.tsx b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/DesktopOnboardingModal.tsx index a1e59e013b..956554f5b6 100644 --- a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/DesktopOnboardingModal.tsx +++ b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/DesktopOnboardingModal.tsx @@ -1,19 +1,13 @@ import React, { useEffect, useState } from "react"; import { Button, Modal } from "antd"; -import { useNavigate } from "react-router-dom"; -import { WorkspaceCreationView } from "componentsV2/modals/CreateWorkspaceModal/components/WorkspaceCreationView"; import { AuthCard } from "./components/AuthCard/AuthCard"; import { WelcomeCard } from "./components/WelcomeCard/WelcomeCard"; import { useDispatch, useSelector } from "react-redux"; import { globalActions } from "store/slices/global/slice"; import { getUserAuthDetails } from "store/slices/global/user/selectors"; -// import { IoMdArrowBack } from "@react-icons/all-files/io/IoMdArrowBack"; -import { redirectToApiClient } from "utils/RedirectionUtils"; import "./desktopOnboardingModal.scss"; import { trackDesktopOnboardingStepSkipped, trackDesktopOnboardingViewed } from "./analytics"; import { OnboardingStep } from "./types"; -import { WorkspaceType } from "features/workspaces/types"; -import { WorkspaceCreationProvider } from "componentsV2/modals/CreateWorkspaceModal/context"; export const DesktopOnboardingCard = ({ children, className }: { children: React.ReactNode; className?: string }) => { return
{children}
; @@ -21,7 +15,6 @@ export const DesktopOnboardingCard = ({ children, className }: { children: React export const DesktopOnboardingModal = () => { const dispatch = useDispatch(); - const navigate = useNavigate(); const user = useSelector(getUserAuthDetails); const [onboardingStep, setOnboardingStep] = useState(OnboardingStep.FEATURE_SELECTION); @@ -42,43 +35,29 @@ export const DesktopOnboardingModal = () => { wrapClassName="rq-desktop-onboarding-modal-wrapper" className="rq-desktop-onboarding-modal" > - -
- {onboardingStep === OnboardingStep.FEATURE_SELECTION ? ( - - setOnboardingStep(step)} /> +
+ {onboardingStep === OnboardingStep.FEATURE_SELECTION ? ( + + setOnboardingStep(step)} /> + + ) : onboardingStep === OnboardingStep.AUTH ? ( + <> + + setOnboardingStep(OnboardingStep.FEATURE_SELECTION)} /> - ) : onboardingStep === OnboardingStep.FOLDER_SELECTION ? ( - - setOnboardingStep(OnboardingStep.FEATURE_SELECTION)} - callback={() => { - dispatch(globalActions.updateIsOnboardingCompleted(true)); - redirectToApiClient(navigate); - }} - analyticEventSource="desktop_onboarding_modal" - /> - - ) : onboardingStep === OnboardingStep.AUTH ? ( - <> - - setOnboardingStep(OnboardingStep.FEATURE_SELECTION)} /> - - - - ) : null} -
- + + + ) : null} +
); }; diff --git a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/WelcomeCard.tsx b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/WelcomeCard.tsx index ea8b6671ca..c2e94de95c 100644 --- a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/WelcomeCard.tsx +++ b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/WelcomeCard.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef, useState } from "react"; +import React from "react"; import { Button } from "antd"; import RQOnlyLogo from "/assets/media/common/RQ-only-logo.svg"; import { useDispatch } from "react-redux"; @@ -6,20 +6,8 @@ import { globalActions } from "store/slices/global/slice"; import { trackDesktopOnboardingFeatureSelected, trackDesktopOnboardingStepSkipped } from "../../analytics"; import { OnboardingStep } from "../../types"; import { WelcomeCardHeader } from "./components/WelcomeCardHeader/WelcomeCardHeader"; -import { AnimatePresence, m } from "framer-motion"; -import { collapseExpandTransition } from "utils/animations"; -import { MdOutlineKeyboardArrowUp } from "@react-icons/all-files/md/MdOutlineKeyboardArrowUp"; -import { MdOutlineKeyboardArrowDown } from "@react-icons/all-files/md/MdOutlineKeyboardArrowDown"; -import { LocalWorkspaceCreateOptions } from "componentsV2/modals/CreateWorkspaceModal"; -import clsx from "clsx"; -import { useCreateDefaultLocalWorkspace } from "features/workspaces/hooks/useCreateDefaultLocalWorkspace"; -import { FileSystemError } from "features/apiClient/helpers/modules/sync/local/services/types"; -import { OpenWorkspaceErrorView } from "componentsV2/modals/CreateWorkspaceModal/components/LocalWorkspaceCreationView/components/OpenWorkspaceErrorView"; -import { useOpenLocalWorkspace } from "features/workspaces/hooks/useOpenLocalWorkspace"; import { MdOutlineKeyboardArrowRight } from "@react-icons/all-files/md/MdOutlineKeyboardArrowRight"; import "./welcomeCard.scss"; -import { useNavigate } from "react-router-dom"; -import { redirectToApiClient } from "utils/RedirectionUtils"; interface Props { onFeatureClick: (step: OnboardingStep) => void; @@ -27,140 +15,19 @@ interface Props { export const WelcomeCard: React.FC = ({ onFeatureClick }) => { const dispatch = useDispatch(); - const navigate = useNavigate(); - const [isApiClientCardExpanded, setIsApiClientCardExpanded] = useState(false); - const [openWorkspaceError, setOpenWorkspaceError] = useState(null); - const apiClientCardRef = useRef(null); - - const { createWorkspace, isLoading } = useCreateDefaultLocalWorkspace({ - analyticEventSource: "desktop_onboarding_modal", - onCreateWorkspaceCallback: () => { - trackDesktopOnboardingStepSkipped(OnboardingStep.FEATURE_SELECTION); - dispatch(globalActions.updateIsOnboardingCompleted(true)); - redirectToApiClient(navigate); - }, - }); - - const { openWorkspace, isLoading: isOpeningWorkspaceLoading } = useOpenLocalWorkspace({ - analyticEventSource: "desktop_onboarding_modal", - onOpenWorkspaceCallback: () => { - dispatch(globalActions.updateIsOnboardingCompleted(true)); - redirectToApiClient(navigate); - }, - onError: (error: FileSystemError) => { - setOpenWorkspaceError(error); - }, - }); - - useEffect(() => { - if (!isApiClientCardExpanded) { - return; - } - - const handleClickOutside = (event: MouseEvent) => { - if (apiClientCardRef.current && !apiClientCardRef.current.contains(event.target as Node)) { - setIsApiClientCardExpanded(false); - } - }; - - document.addEventListener("mousedown", handleClickOutside); - - return () => { - document.removeEventListener("mousedown", handleClickOutside); - }; - }, [isApiClientCardExpanded]); - - const handleApiClientCardExpandToggle = () => { - if (!isApiClientCardExpanded) { - trackDesktopOnboardingFeatureSelected("api_client"); - } - setIsApiClientCardExpanded((prev) => !prev); - }; - - if (openWorkspaceError) { - return ( -
- onFeatureClick(OnboardingStep.FOLDER_SELECTION)} - openWorkspace={openWorkspace} - isOpeningWorkspaceLoading={isOpeningWorkspaceLoading} - analyticEventSource="desktop_onboarding_modal" - /> -
- ); - } return (
- RQ Only Logo -
+ RQ Only Logo +
Welcome to Requestly
-
+
Intercept, Mock, Build & Test APIs faster
- -
-
- - {isApiClientCardExpanded ? ( - - ) : ( - - )} -
- - {isApiClientCardExpanded && ( - -
- onFeatureClick(OnboardingStep.FOLDER_SELECTION)} - onCreationCallback={() => { - dispatch(globalActions.updateIsOnboardingCompleted(true)); - redirectToApiClient(navigate); - }} - openWorkspace={openWorkspace} - isOpeningWorkspaceLoading={isOpeningWorkspaceLoading} - /> -
-
- )} -
-
-
{ trackDesktopOnboardingFeatureSelected("rules"); onFeatureClick(OnboardingStep.AUTH); @@ -175,7 +42,14 @@ export const WelcomeCard: React.FC = ({ onFeatureClick }) => {
- {" "} this screen and quick start diff --git a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/types.ts b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/types.ts index 271a41f8d8..a0ca630dbc 100644 --- a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/types.ts +++ b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/types.ts @@ -1,5 +1,4 @@ export enum OnboardingStep { FEATURE_SELECTION = "feature_selection", - FOLDER_SELECTION = "folder_selection", AUTH = "auth", } From 92f44d89c8b3e35b9f24c227f6c916e161a8ce06 Mon Sep 17 00:00:00 2001 From: kanishkrawatt Date: Mon, 13 Jul 2026 15:21:08 +0530 Subject: [PATCH 2/4] [RQ-4283] chore: remove API Client product surfaces app-wide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to the onboarding/workspace-creation removal: strip every user-reachable API Client entry point from the Interceptor app so the product is fully inaccessible/invisible. The shared infrastructure that happens to live under features/apiClient/ (workspace system, tab system, variable/secrets slices, environment backend) is left in place — other features depend on it — but nothing routes to or surfaces the API Client product anymore. Removed: - Route: apiClientRoutes registration in routes/index.tsx. - Primary sidebar "APIs" item (+ SidebarItemKey.APIs, icon, order entries). - Home page ApiClientCard (component deleted) + its render. - "API Client" breadcrumb label; PATHS.API_CLIENT.INDEX from the root-path landing set (useRootPathRedirector). - Network inspector "Edit and Replay" context-menu item and its APIClientModal replay chain (ContextMenu -> VirtualTableV2 -> NetworkTable). - Mock editor "Test" button and its APIClientModal test-mock chain. - Session viewer "Replay Request" context-menu item and its APIClientModal chain. - cURL-import deep link (AppModeInitializer OPEN_CURL_IMPORT_MODAL listener that navigated to the API Client). Orphaned imports/vars from the above cleaned up. Verified: ESLint clean on changed files (one pre-existing exhaustive-deps warning), `tsc --noEmit` introduces zero new errors (net -9 vs the repo's 1298 baseline), and `vite build` succeeds. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../ApiClientCard/apiClientCard.scss | 25 --- .../Home/components/ApiClientCard/index.tsx | 201 ------------------ .../Home/components/ApiClientCard/types.ts | 4 - .../Home/components/ApiClientCard/utils.tsx | 22 -- app/src/components/Home/index.tsx | 2 - .../MockEditorIndex/Editor/Header/index.tsx | 15 +- .../mocksV2/MockEditorIndex/Editor/index.tsx | 61 +----- .../NetworkInspector/ContextMenu/index.tsx | 18 +- .../NetworkTable/VirtualTableV2.tsx | 5 +- .../NetworkInspector/NetworkTable/index.tsx | 32 +-- app/src/hooks/AppModeInitializer.js | 18 -- app/src/hooks/useRootPathRedirector.ts | 1 - .../Sidebar/PrimarySidebar/index.tsx | 11 - .../components/RQBreadcrumb/index.tsx | 4 - app/src/routes/index.tsx | 2 - .../NetworkLogs/NetworkLogsPanel.tsx | 40 +--- 16 files changed, 9 insertions(+), 452 deletions(-) delete mode 100644 app/src/components/Home/components/ApiClientCard/apiClientCard.scss delete mode 100644 app/src/components/Home/components/ApiClientCard/index.tsx delete mode 100644 app/src/components/Home/components/ApiClientCard/types.ts delete mode 100644 app/src/components/Home/components/ApiClientCard/utils.tsx diff --git a/app/src/components/Home/components/ApiClientCard/apiClientCard.scss b/app/src/components/Home/components/ApiClientCard/apiClientCard.scss deleted file mode 100644 index bd97411fed..0000000000 --- a/app/src/components/Home/components/ApiClientCard/apiClientCard.scss +++ /dev/null @@ -1,25 +0,0 @@ -.history-card { - .middle-section { - .list { - .list-item { - align-items: center; - } - } - } -} - -.new-request-cta { - height: 100%; - width: 100%; - line-height: 20px; - font-size: var(--requestly-font-size-md, 14px); - font-weight: 500; - display: flex; - align-items: center; - justify-content: center; - svg { - width: 20px; - height: 20px; - margin-right: 8px; - } -} diff --git a/app/src/components/Home/components/ApiClientCard/index.tsx b/app/src/components/Home/components/ApiClientCard/index.tsx deleted file mode 100644 index eb755be85e..0000000000 --- a/app/src/components/Home/components/ApiClientCard/index.tsx +++ /dev/null @@ -1,201 +0,0 @@ -import { useFeatureIsOn } from "@growthbook/growthbook-react"; -import { CgStack } from "@react-icons/all-files/cg/CgStack"; -import { MdHorizontalSplit } from "@react-icons/all-files/md/MdHorizontalSplit"; -import { MdOutlineKeyboardArrowDown } from "@react-icons/all-files/md/MdOutlineKeyboardArrowDown"; -import { MdOutlineSyncAlt } from "@react-icons/all-files/md/MdOutlineSyncAlt"; -import { SiOpenapiinitiative } from "@react-icons/all-files/si/SiOpenapiinitiative"; -import { MenuProps } from "antd"; -import DropdownButton from "antd/lib/dropdown/dropdown-button"; -import { trackHomeApisActionClicked } from "components/Home/analytics"; -import { useTabs } from "componentsV2/Tabs/slice"; -import PATHS from "config/constants/sub/paths"; -import { ApiClientImporterType, CreateType } from "features/apiClient/types"; -import { RoleBasedComponent, useRBAC } from "features/rbac"; -import { RQButton, RQTooltip } from "lib/design-system-v2/components"; -import { isEmpty } from "lodash"; -import { useCallback, useMemo } from "react"; -import { useSelector } from "react-redux"; -import { useNavigate } from "react-router-dom"; -import { getUserAuthDetails } from "store/slices/global/user/selectors"; -import Postman from "../../../../assets/img/brand/postman-icon.svg?react"; -import { Card } from "../Card"; -import { CardListItem, CardType } from "../Card/types"; -import { PRODUCT_FEATURES } from "../EmptyCard/staticData"; -import "./apiClientCard.scss"; -import { getOptions } from "./utils"; - -interface CardOptions { - bodyTitle: string; - contentList: CardListItem[]; -} - -const ApiClientCard = () => { - const navigate = useNavigate(); - const user = useSelector(getUserAuthDetails); - const isLoggedIn = user?.details?.isLoggedIn; - const tabs = useTabs(); - const cardOptions = useMemo( - () => (!isEmpty(tabs) ? getOptions(tabs) : null), - [tabs] - ); - const { validatePermission } = useRBAC(); - const { isValidPermission } = validatePermission("api_client_request", "create"); - const isOpenApiSupportEnabled = useFeatureIsOn("openapi-import-support"); - - const createNewHandler = useCallback( - (type: CreateType) => { - navigate(PATHS.API_CLIENT.ABSOLUTE as string, { state: { action: "create", type } }); - trackHomeApisActionClicked(`new_${type}_clicked`); - }, - [navigate] - ); - - const importTriggerHandler = useCallback( - (modal: ApiClientImporterType) => { - navigate(PATHS.API_CLIENT.ABSOLUTE as string, { state: { modal } }); - trackHomeApisActionClicked(`${modal.toLowerCase()}_importer_clicked`); - }, - [navigate] - ); - - const items: MenuProps["items"] = [ - { - icon: , - label: "Collection", - key: "1", - onClick: () => createNewHandler(CreateType.COLLECTION), - }, - { - icon: , - label: "Environment", - key: "2", - onClick: () => createNewHandler(CreateType.ENVIRONMENT), - }, - { - type: "divider", - }, - { - key: "3", - label: "Import cURL Request", - icon: , - onClick: () => importTriggerHandler(ApiClientImporterType.CURL), - }, - ]; - - const IMPORT_OPTIONS = [ - { - key: "1", - label: "Postman", - icon: , - onClick: () => importTriggerHandler(ApiClientImporterType.POSTMAN), - }, - { - key: "2", - label: "Bruno", - icon: Bruno, - onClick: () => importTriggerHandler(ApiClientImporterType.BRUNO), - }, - { - key: "3", - label: "cURL", - icon: , - onClick: () => importTriggerHandler(ApiClientImporterType.CURL), - }, - { - key: "4", - hidden: !isOpenApiSupportEnabled, - label: "OpenAPI", - icon: , - onClick: () => importTriggerHandler(ApiClientImporterType.OPENAPI), - }, - { - key: "5", - label: "Requestly", - icon: Requestly, - onClick: () => importTriggerHandler(ApiClientImporterType.REQUESTLY), - }, - ]; - - const actionButtons = ( - - } - overlayClassName="more-options" - onClick={() => { - createNewHandler(CreateType.API); - }} - menu={{ items }} - trigger={["click"]} - > - {"New request"} - - - ); - - return ( - { - if (item.url) { - navigate(item.url as string); - trackHomeApisActionClicked("recent_tab_clicked"); - } - }} - actionButtons={actionButtons} - viewAllCta={"View all APIs"} - viewAllCtaLink={PATHS.API_CLIENT.ABSOLUTE as string} - viewAllCtaOnClick={() => trackHomeApisActionClicked("view_all_apis")} - emptyCardOptions={{ - ...PRODUCT_FEATURES.API_CLIENT, - primaryAction: ( - { - navigate(PATHS.API_CLIENT.ABSOLUTE as string); - }} - > - View requests - - } - > - { - createNewHandler(CreateType.API); - }} - > - New request - - - ), - }} - /> - ); -}; - -export default ApiClientCard; diff --git a/app/src/components/Home/components/ApiClientCard/types.ts b/app/src/components/Home/components/ApiClientCard/types.ts deleted file mode 100644 index 3c147ae57a..0000000000 --- a/app/src/components/Home/components/ApiClientCard/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum FormatType { - TABS = "TABS", - HISTORY = "HISTORY", -} diff --git a/app/src/components/Home/components/ApiClientCard/utils.tsx b/app/src/components/Home/components/ApiClientCard/utils.tsx deleted file mode 100644 index 305b84140d..0000000000 --- a/app/src/components/Home/components/ApiClientCard/utils.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { TabState } from "componentsV2/Tabs/slice/types"; -import { AbstractTabSource } from "componentsV2/Tabs/helpers/tabSource"; -import { CardListItem } from "../Card/types"; - -const formatContentList = (list: TabState[]) => { - return list.map((tabState): CardListItem => { - const tabSource = tabState.source as AbstractTabSource; - return { - id: tabSource.metadata.id, - title: tabSource.metadata.title, - icon: tabSource.getIcon(), - url: tabSource.getUrlPath(), - type: tabSource.type, - }; - }); -}; - -export const getOptions = (list: TabState[]) => { - const bodyTitle = "Recent Tabs"; - const contentList = formatContentList(list); - return { bodyTitle, contentList }; -}; diff --git a/app/src/components/Home/index.tsx b/app/src/components/Home/index.tsx index cb5ab8a99b..9ed97f380e 100644 --- a/app/src/components/Home/index.tsx +++ b/app/src/components/Home/index.tsx @@ -6,7 +6,6 @@ import UserAvatar from "../../assets/images/illustrations/avatar.svg?react"; import { APIMockingCard } from "./components/APIMockingCard"; import { RulesCard } from "./components/RulesCard"; import { HomeScreenProvider } from "./contexts"; -import ApiClientCard from "./components/ApiClientCard"; import "./home.scss"; export const Home: React.FC = () => { @@ -25,7 +24,6 @@ export const Home: React.FC = () => { - diff --git a/app/src/components/features/mocksV2/MockEditorIndex/Editor/Header/index.tsx b/app/src/components/features/mocksV2/MockEditorIndex/Editor/Header/index.tsx index c6016e73d7..dd0a96d4a9 100644 --- a/app/src/components/features/mocksV2/MockEditorIndex/Editor/Header/index.tsx +++ b/app/src/components/features/mocksV2/MockEditorIndex/Editor/Header/index.tsx @@ -1,12 +1,10 @@ import React, { useState } from "react"; import { Row, Layout, Col, Tooltip, Dropdown, Menu, Button } from "antd"; -import { ExperimentOutlined, LockOutlined, UnlockOutlined } from "@ant-design/icons"; +import { LockOutlined, UnlockOutlined } from "@ant-design/icons"; import { RQBreadcrumb, RQButton } from "lib/design-system-v2/components"; import { MockType } from "components/features/mocksV2/types"; import "./index.css"; import { trackMockEditorClosed, trackMockPasswordGenerateClicked } from "modules/analytics/events/features/mocksV2"; -import { isFeatureCompatible } from "utils/CompatibilityUtils"; -import FEATURES from "config/constants/sub/features"; import { useLocation } from "react-router-dom"; import PasswordPopup from "./PasswordPopup/PasswordPopup"; import { Conditional } from "components/common/Conditional"; @@ -20,7 +18,6 @@ interface HeaderProps { savingInProgress: boolean; handleClose: Function; handleSave: () => void; - handleTest: () => void; setPassword: (password: string) => void; password: string; isEditorReadOnly: boolean; @@ -32,7 +29,6 @@ export const MockEditorHeader: React.FC = ({ savingInProgress, handleClose, handleSave, - handleTest, setPassword, password, isEditorReadOnly, @@ -116,15 +112,6 @@ export const MockEditorHeader: React.FC = ({
- {!isNewMock && isFeatureCompatible(FEATURES.API_CLIENT) && ( - } - onClick={handleTest} - type={isEditorReadOnly ? "primary" : "secondary"} - > - Test - - )} { diff --git a/app/src/components/features/mocksV2/MockEditorIndex/Editor/index.tsx b/app/src/components/features/mocksV2/MockEditorIndex/Editor/index.tsx index 16a3b21ed8..e74a8ebb1d 100644 --- a/app/src/components/features/mocksV2/MockEditorIndex/Editor/index.tsx +++ b/app/src/components/features/mocksV2/MockEditorIndex/Editor/index.tsx @@ -8,21 +8,16 @@ import { MockEditorHeader } from "./Header"; import { Tabs } from "antd"; import APP_CONSTANTS from "config/constants"; import React, { ReactNode, useState, useMemo, useCallback, useEffect, useRef } from "react"; -import { useDispatch, useSelector } from "react-redux"; -import { getUserAuthDetails } from "store/slices/global/user/selectors"; +import { useDispatch } from "react-redux"; import { toast } from "utils/Toast"; import { FileType, MockType, RQMockCollection } from "../../types"; import type { TabsProps } from "antd"; -import { generateFinalUrl } from "../../utils"; import { requestMethodDropdownOptions } from "../constants"; import { MockEditorDataSchema, RequestMethod, ValidationErrors } from "../types"; import { cleanupEndpoint, getEditorLanguage, validateEndpoint, validateHeaders, validateStatusCode } from "../utils"; import "./index.css"; -import { trackMockEditorOpened, trackTestMockClicked } from "modules/analytics/events/features/mocksV2"; -import { APIClientModal, APIClientRequest } from "features/apiClient/components/common/APIClient"; +import { trackMockEditorOpened } from "modules/analytics/events/features/mocksV2"; import MockEditorEndpoint from "./Endpoint"; -import { trackRQDesktopLastActivity, trackRQLastActivity } from "utils/AnalyticsUtils"; -import { MOCKSV2 } from "modules/analytics/events/features/constants"; import { EditorLanguage } from "componentsV2/CodeEditor"; import { BottomSheetLayout, BottomSheetProvider } from "componentsV2/BottomSheet"; import MockLogs from "./BottomSheet/MockLogs"; @@ -30,7 +25,6 @@ import { BottomSheetFeatureContext, SheetLayout } from "componentsV2/BottomSheet import { useFeatureValue } from "@growthbook/growthbook-react"; import { ExportMocksModalWrapper } from "features/mocks/modals"; import { globalActions } from "store/slices/global/slice"; -import { getActiveWorkspaceId } from "store/slices/workspaces/selectors"; import Editor from "componentsV2/CodeEditor"; interface Props { @@ -59,10 +53,6 @@ const MockEditor: React.FC = ({ mockType, }) => { const dispatch = useDispatch(); - const user = useSelector(getUserAuthDetails); - const username = user?.details?.username; - - const activeWorkspaceId = useSelector(getActiveWorkspaceId); const areLogsVisible = useFeatureValue("mock_logs", false); @@ -87,30 +77,8 @@ const MockEditor: React.FC = ({ headers: null, }); - const [isTestModalOpen, setIsTestModalOpen] = useState(false); - const collectionPath = mockCollectionData?.path ?? ""; - const finalUrl = useMemo( - () => - generateFinalUrl({ - endpoint, - uid: user?.details?.profile?.uid, - username, - teamId: activeWorkspaceId, - password, - collectionPath, - }), - [endpoint, activeWorkspaceId, user?.details?.profile?.uid, username, password, collectionPath] - ); - - const apiRequest = useMemo(() => { - return { - url: finalUrl, - method, - }; - }, [finalUrl, method]); - //editor fields ref const endpointRef = useRef(null); const statusCodeRef = useRef(null); @@ -236,13 +204,6 @@ const MockEditor: React.FC = ({ } }, [onSave, errors, createMockEditorData, validateMockEditorData, id, dispatch]); - const handleTest = useCallback(() => { - setIsTestModalOpen(true); - trackTestMockClicked(); - trackRQLastActivity(MOCKSV2.TEST_MOCK_CLICKED); - trackRQDesktopLastActivity(MOCKSV2.TEST_MOCK_CLICKED); - }, []); - const onNameChange = (name: string) => { setName(name); }; @@ -458,7 +419,6 @@ const MockEditor: React.FC = ({ savingInProgress={savingInProgress} handleClose={onClose} handleSave={handleOnSave} - handleTest={handleTest} setPassword={setPassword} password={password} isEditorReadOnly={isEditorReadOnly} @@ -491,14 +451,6 @@ const MockEditor: React.FC = ({
- {!isNew ? ( - setIsTestModalOpen(false)} - /> - ) : null}
) : ( @@ -509,7 +461,6 @@ const MockEditor: React.FC = ({ savingInProgress={savingInProgress} handleClose={onClose} handleSave={handleOnSave} - handleTest={handleTest} setPassword={setPassword} password={password} isEditorReadOnly={isEditorReadOnly} @@ -536,14 +487,6 @@ const MockEditor: React.FC = ({ - {!isNew ? ( - setIsTestModalOpen(false)} - /> - ) : null} )} diff --git a/app/src/components/mode-specific/desktop/InterceptTraffic/WebTraffic/TrafficTableV2/NetworkInspector/ContextMenu/index.tsx b/app/src/components/mode-specific/desktop/InterceptTraffic/WebTraffic/TrafficTableV2/NetworkInspector/ContextMenu/index.tsx index 891b26e1b8..4c1cb1ee55 100644 --- a/app/src/components/mode-specific/desktop/InterceptTraffic/WebTraffic/TrafficTableV2/NetworkInspector/ContextMenu/index.tsx +++ b/app/src/components/mode-specific/desktop/InterceptTraffic/WebTraffic/TrafficTableV2/NetworkInspector/ContextMenu/index.tsx @@ -12,7 +12,6 @@ import { } from "modules/analytics/events/desktopApp"; import { trackWalkthroughCompleted } from "modules/analytics/events/misc/productWalkthrough"; import FEATURES from "config/constants/sub/features"; -import { isFeatureCompatible } from "utils/CompatibilityUtils"; import { getLogResponseById } from "store/features/desktop-traffic-table/selectors"; import "./index.css"; import { trackRQDesktopLastActivity } from "utils/AnalyticsUtils"; @@ -26,10 +25,9 @@ import { RQNetworkLog } from "../../../TrafficExporter/harLogs/types"; interface ContextMenuProps { log: RQNetworkLog; children: ReactNode; - onReplayRequest: () => void; } -export const ContextMenu: React.FC = ({ children, log, onReplayRequest }) => { +export const ContextMenu: React.FC = ({ children, log }) => { const dispatch = useDispatch(); const isTrafficTableTourCompleted = useSelector(getIsTrafficTableTourCompleted); const selectedRequestResponse = useSelector(getLogResponseById(log?.id)) || log?.response?.body; @@ -149,24 +147,12 @@ export const ContextMenu: React.FC = ({ children, log, onRepla }, ]; - if (isFeatureCompatible(FEATURES.API_CLIENT)) { - menuItems.splice(2, 0, { - key: "replay_request", - label: "Edit and Replay", - onClick: () => { - trackTrafficTableDropdownClicked("replay_request"); - trackRQDesktopLastActivity(TRAFFIC_TABLE.TRAFFIC_TABLE_REQUEST_DROPDOWN_CLICKED); - onReplayRequest(); - }, - }); - } - if (!log.requestShellCurl) { menuItems.splice(0, 1); } return menuItems; - }, [log, onReplayRequest, handleOnClick, isLocalSyncEnabled]); + }, [log, handleOnClick, isLocalSyncEnabled]); const handleDropdownOpenChange = (open: boolean) => { if (open) { diff --git a/app/src/components/mode-specific/desktop/InterceptTraffic/WebTraffic/TrafficTableV2/NetworkInspector/NetworkTable/VirtualTableV2.tsx b/app/src/components/mode-specific/desktop/InterceptTraffic/WebTraffic/TrafficTableV2/NetworkInspector/NetworkTable/VirtualTableV2.tsx index d75ac1ab9d..8151732a6a 100644 --- a/app/src/components/mode-specific/desktop/InterceptTraffic/WebTraffic/TrafficTableV2/NetworkInspector/NetworkTable/VirtualTableV2.tsx +++ b/app/src/components/mode-specific/desktop/InterceptTraffic/WebTraffic/TrafficTableV2/NetworkInspector/NetworkTable/VirtualTableV2.tsx @@ -14,10 +14,9 @@ interface Props { header: React.ReactNode; renderLogRow: any; selectedRowData: RQNetworkLog | null; - onReplayRequest: () => void; } -const VirtualTableV2: React.FC = ({ logs = [], header, renderLogRow, selectedRowData, onReplayRequest }) => { +const VirtualTableV2: React.FC = ({ logs = [], header, renderLogRow, selectedRowData }) => { const [selected, setSelected] = useState(null); const [lastKnownBottomIndex, setLastKnownBottomIndex] = useState(null); const [isScrollToBottomEnabled, setIsScrollToBottomEnabled] = useState(true); @@ -155,7 +154,7 @@ const VirtualTableV2: React.FC = ({ logs = [], header, renderLogRow, sele onContextMenu={(e: any) => setSelected(e.target?.parentElement.id)} > {header} - + {/* Hack to fix alternate colors flickering due to virtualization*/} {items[0]?.index % 2 === 0 ? null : } diff --git a/app/src/components/mode-specific/desktop/InterceptTraffic/WebTraffic/TrafficTableV2/NetworkInspector/NetworkTable/index.tsx b/app/src/components/mode-specific/desktop/InterceptTraffic/WebTraffic/TrafficTableV2/NetworkInspector/NetworkTable/index.tsx index e9c06b0bf1..0a83a2147f 100644 --- a/app/src/components/mode-specific/desktop/InterceptTraffic/WebTraffic/TrafficTableV2/NetworkInspector/NetworkTable/index.tsx +++ b/app/src/components/mode-specific/desktop/InterceptTraffic/WebTraffic/TrafficTableV2/NetworkInspector/NetworkTable/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo, useRef, useState } from "react"; +import React, { useCallback, useMemo, useState } from "react"; import { useSelector, useDispatch } from "react-redux"; import { globalActions } from "store/slices/global/slice"; import { getIsTrafficTableTourCompleted, getIsConnectedAppsTourCompleted } from "store/selectors"; @@ -9,14 +9,12 @@ import AppliedRules from "../../Tables/columns/AppliedRules"; import { ProductWalkthrough } from "components/misc/ProductWalkthrough"; import FEATURES from "config/constants/sub/features"; import VirtualTableV2 from "./VirtualTableV2"; -import { APIClientRequest } from "features/apiClient/components/common/APIClient"; import { RQNetworkLog } from "../../../TrafficExporter/harLogs/types"; import { Checkbox, Typography } from "antd"; import { trackMockResponsesRequestsSelected } from "modules/analytics/events/features/sessionRecording/mockResponseFromSession"; import { REQUEST_METHOD_COLORS, RequestMethod } from "../../../../../../../../constants/requestMethodColors"; import "./index.scss"; import { TOUR_TYPES } from "components/misc/ProductWalkthrough/types"; -import { APIClientModal } from "features/apiClient/components/common/APIClient"; export const ITEM_SIZE = 32; @@ -38,29 +36,9 @@ const NetworkTable: React.FC = ({ selectedMockRequests, }) => { const [selectedRowData, setSelectedRowData] = useState(null); - const [isReplayRequestModalOpen, setIsReplayRequestModalOpen] = useState(false); const dispatch = useDispatch(); const isTrafficTableTourCompleted = useSelector(getIsTrafficTableTourCompleted); const isConnectedAppsTourCompleted = useSelector(getIsConnectedAppsTourCompleted); - const apiClientRequestForSelectedRowRef = useRef(null); - - const onReplayRequest = useCallback(() => { - if (!selectedRowData) { - return; - } - apiClientRequestForSelectedRowRef.current = { - url: selectedRowData.url, - headers: selectedRowData.request.headers, - method: selectedRowData.request.method, - body: selectedRowData.request.body, - }; - setIsReplayRequestModalOpen(true); - }, [selectedRowData]); - - const onReplayRequestModalClose = useCallback(() => { - apiClientRequestForSelectedRowRef.current = null; - setIsReplayRequestModalOpen(false); - }, []); const columns = useMemo( () => [ @@ -270,16 +248,8 @@ const NetworkTable: React.FC = ({ renderLogRow={renderLogRow} logs={logs} selectedRowData={selectedRowData} - onReplayRequest={onReplayRequest} /> - {isReplayRequestModalOpen ? ( - - ) : null} ); }; diff --git a/app/src/hooks/AppModeInitializer.js b/app/src/hooks/AppModeInitializer.js index aee104b311..cf7c3941e8 100644 --- a/app/src/hooks/AppModeInitializer.js +++ b/app/src/hooks/AppModeInitializer.js @@ -45,7 +45,6 @@ import FEATURES from "config/constants/sub/features"; import { trackHarFileOpened } from "modules/analytics/events/features/sessionRecording/networkSessions"; import { trackLocalSessionRecordingOpened } from "modules/analytics/events/features/sessionRecording"; import { getActiveWorkspaceId } from "store/slices/workspaces/selectors"; -import { ApiClientImporterType } from "features/apiClient/types"; import { clientStorageService } from "services/clientStorageService"; import { initAndSubscribeSecretsManager } from "features/apiClient/slices/secrets-manager"; import { secretsManagerService } from "services/secretsManagerService"; @@ -395,23 +394,6 @@ const AppModeInitializer = () => { }; }); - PSMH.addMessageListener(GLOBAL_CONSTANTS.EXTENSION_MESSAGES.OPEN_CURL_IMPORT_MODAL, (message) => { - const { payload } = message; - - // Navigate to API Client with cURL import modal state - const navigationState = { - modal: ApiClientImporterType.CURL, - curlCommand: payload.curlCommand, - pageURL: payload.pageURL, - source: payload.source, - }; - - navigate(PATHS.API_CLIENT.ABSOLUTE, { state: navigationState }); - - return { - received: true, - }; - }); } }, [appMode, activeWorkspaceId, dispatch, user?.details?.isSyncEnabled, user?.details?.profile?.uid, navigate]); diff --git a/app/src/hooks/useRootPathRedirector.ts b/app/src/hooks/useRootPathRedirector.ts index 58fd70f7c7..477fe10442 100644 --- a/app/src/hooks/useRootPathRedirector.ts +++ b/app/src/hooks/useRootPathRedirector.ts @@ -25,7 +25,6 @@ const useRootPathRedirector = () => { }, [searchParams, isAuthSkipped]); const LAST_KNOWN_PATHS = new Set([ - PATHS.API_CLIENT.INDEX, PATHS.RULES.INDEX, PATHS.MOCK_SERVER.INDEX, PATHS.NETWORK_INSPECTOR.INDEX, diff --git a/app/src/layouts/DashboardLayout/Sidebar/PrimarySidebar/index.tsx b/app/src/layouts/DashboardLayout/Sidebar/PrimarySidebar/index.tsx index 53dc6327bf..78b5d52fd2 100644 --- a/app/src/layouts/DashboardLayout/Sidebar/PrimarySidebar/index.tsx +++ b/app/src/layouts/DashboardLayout/Sidebar/PrimarySidebar/index.tsx @@ -24,7 +24,6 @@ import { RQTooltip } from "lib/design-system-v2/components"; import HomeIcon from "/assets/media/common/feature_home.svg"; import NetworkIcon from "/assets/media/common/feature_network.svg"; import RulesIcon from "/assets/media/common/feature_rules.svg"; -import ApiIcon from "/assets/media/common/feature_apis.svg"; import FilesIcon from "/assets/media/common/feature_files.svg"; import SessionsIcon from "/assets/media/common/feature_sessions.svg"; @@ -35,7 +34,6 @@ enum SidebarItemKey { NETWORK = "network", NETWORK_INSPECTOR = "network_inspector", RULES = "rules", - APIs = "apis", FILES = "files", SESSIONS = "sessions", } @@ -43,7 +41,6 @@ enum SidebarItemKey { const LocalWorkspaceSidebarOrder = [ SidebarItemKey.HOME, SidebarItemKey.NETWORK, - SidebarItemKey.APIs, SidebarItemKey.SESSIONS, SidebarItemKey.RULES, SidebarItemKey.FILES, @@ -54,7 +51,6 @@ const defaultSidebarOrder = [ SidebarItemKey.NETWORK, SidebarItemKey.NETWORK_INSPECTOR, SidebarItemKey.RULES, - SidebarItemKey.APIs, SidebarItemKey.FILES, SidebarItemKey.SESSIONS, ]; @@ -122,13 +118,6 @@ export const PrimarySidebar: React.FC = () => { ), disabled: isLocalSyncEnabled, }, - [SidebarItemKey.APIs]: { - id: 4, - title: "APIs", - path: PATHS.API_CLIENT.INDEX, - icon: apis, - display: true, - }, [SidebarItemKey.FILES]: { id: 5, title: "Files", diff --git a/app/src/lib/design-system/components/RQBreadcrumb/index.tsx b/app/src/lib/design-system/components/RQBreadcrumb/index.tsx index 1513c1af9e..0d04a708dd 100644 --- a/app/src/lib/design-system/components/RQBreadcrumb/index.tsx +++ b/app/src/lib/design-system/components/RQBreadcrumb/index.tsx @@ -13,10 +13,6 @@ export const RQBreadcrumb: React.FC = (props) => { return "Files"; } - if (path === "api-client") { - return "API Client"; - } - // TODO: rather derive from the list used in Sidebar return capitalize(path.includes("-") ? path.split("-").join(" ") : path); }, []); diff --git a/app/src/routes/index.tsx b/app/src/routes/index.tsx index 6e67327428..5f25ba737e 100644 --- a/app/src/routes/index.tsx +++ b/app/src/routes/index.tsx @@ -7,7 +7,6 @@ import { automationRoutes } from "views/misc/Automation/routes"; import AppLayout from "layouts/AppLayout"; import { ruleRoutes } from "features/rules/routes"; import { sessionRoutes } from "features/sessionBook"; -import { apiClientRoutes } from "features/apiClient"; import { accountRoutes } from "./accountRoutes"; import { authRoutes } from "./authRoutes"; import { desktopRoutes } from "./desktopRoutes"; @@ -52,7 +51,6 @@ export const routesV2: RouteObject[] = [ children: [ ...ruleRoutes, ...sessionRoutes, - ...apiClientRoutes, ...accountRoutes, ...authRoutes, ...desktopRoutes, diff --git a/app/src/views/features/sessions/SessionViewer/NetworkLogs/NetworkLogsPanel.tsx b/app/src/views/features/sessions/SessionViewer/NetworkLogs/NetworkLogsPanel.tsx index cb3615c585..e10567e13a 100644 --- a/app/src/views/features/sessions/SessionViewer/NetworkLogs/NetworkLogsPanel.tsx +++ b/app/src/views/features/sessions/SessionViewer/NetworkLogs/NetworkLogsPanel.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo, useState } from "react"; +import React, { useCallback, useMemo } from "react"; import { useDispatch, useSelector } from "react-redux"; import { Empty, Typography, Row } from "antd"; import { getIncludeNetworkLogs } from "store/features/session-recording/selectors"; @@ -6,7 +6,6 @@ import { globalActions } from "store/slices/global/slice"; import { getActiveModals } from "store/slices/global/modals/selectors"; import { RQNetworkLog } from "lib/design-system/components/RQNetworkTable/types"; import { RQNetworkTable, RQNetworkTableProps } from "lib/design-system/components/RQNetworkTable"; -import { APIClientModal, APIClientRequest } from "features/apiClient/components/common/APIClient"; import RuleEditorModal from "components/common/RuleEditorModal"; import { copyToClipBoard } from "utils/Misc"; import { snakeCase } from "lodash"; @@ -29,8 +28,6 @@ interface Props { const NetworkLogsPanel: React.FC = ({ startTime, networkLogs, playerTimeOffset, disableFilters = false }) => { const dispatch = useDispatch(); const { ruleEditorModal } = useSelector(getActiveModals); - const [isApiClientModalOpen, setIsApiClientModalOpen] = useState(false); - const [selectedRequestData, setSelectedRequestData] = useState(null); const isLocalSyncEnabled = useCheckLocalSyncSupport(); const includeNetworkLogs = useSelector(getIncludeNetworkLogs); @@ -81,27 +78,6 @@ const NetworkLogsPanel: React.FC = ({ startTime, networkLogs, playerTimeO { type: "divider", }, - { - key: "replay_request", - label: "Replay Request", - disabled: isLocalSyncEnabled, - onSelect: (key, log) => { - const { url, method, headers, postData } = log.entry.request ?? {}; - - setSelectedRequestData({ - url, - method, - body: postData.text, - headers: headers.reduce((result, header) => ({ ...result, [header.name]: header.value }), {}), - }); - - trackSessionRecordingNetworkLogContextMenuOptionClicked(key); - setIsApiClientModalOpen(true); - }, - }, - { - type: "divider", - }, { key: RuleType.REDIRECT, label: "Redirect URL (Map local/Remote)", @@ -167,11 +143,6 @@ const NetworkLogsPanel: React.FC = ({ startTime, networkLogs, playerTimeO [handleContextMenuRuleOptionSelect, isLocalSyncEnabled] ); - const handleCloseApiClientModal = useCallback(() => { - setIsApiClientModalOpen(false); - setSelectedRequestData(null); - }, []); - const emptyTableView = ( No request matches the search query! @@ -195,15 +166,6 @@ const NetworkLogsPanel: React.FC = ({ startTime, networkLogs, playerTimeO disableFilters={disableFilters} /> - {isApiClientModalOpen && ( - - )} - {ruleEditorModal.isActive && ( Date: Fri, 17 Jul 2026 14:50:43 +0530 Subject: [PATCH 3/4] [RQ-4695] chore: route legacy desktop onboarding straight to auth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The desktop first-run onboarding still opened on a feature-selection screen (WelcomeCard) that framed a choice between the API Client and Rules and funnelled users into local-workspace creation. The API Client is now a standalone product, so that screen is obsolete. - Remove the FEATURE_SELECTION step / WelcomeCard (and WelcomeCardHeader) in full; drop FEATURE_SELECTION from the OnboardingStep enum. The step machine now initializes — and stays — at AUTH, so first-run users land directly on the sign-in/sign-up card. - AuthCard: remove the back-arrow (onBackClick) — there is no prior step to return to. No path creates a local workspace or redirects to the API Client during onboarding. Extension/web onboarding (OnboardingModal) is untouched. Verified: ESLint clean on changed files; `tsc --noEmit` net 0 new errors (1289 baseline unchanged); `vite build` succeeds. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../DesktopOnboardingModal.tsx | 40 ++++++------- .../components/AuthCard/AuthCard.tsx | 12 +--- .../components/WelcomeCard/WelcomeCard.tsx | 59 ------------------- .../WelcomeCardHeader/WelcomeCardHeader.tsx | 33 ----------- .../WelcomeCardHeader/welcomeCardHeader.scss | 40 ------------- .../components/WelcomeCard/welcomeCard.scss | 56 ------------------ .../DesktopOnboardingModal/types.ts | 1 - 7 files changed, 19 insertions(+), 222 deletions(-) delete mode 100644 app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/WelcomeCard.tsx delete mode 100644 app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/components/WelcomeCardHeader/WelcomeCardHeader.tsx delete mode 100644 app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/components/WelcomeCardHeader/welcomeCardHeader.scss delete mode 100644 app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/welcomeCard.scss diff --git a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/DesktopOnboardingModal.tsx b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/DesktopOnboardingModal.tsx index 956554f5b6..8471370358 100644 --- a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/DesktopOnboardingModal.tsx +++ b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/DesktopOnboardingModal.tsx @@ -1,7 +1,6 @@ import React, { useEffect, useState } from "react"; import { Button, Modal } from "antd"; import { AuthCard } from "./components/AuthCard/AuthCard"; -import { WelcomeCard } from "./components/WelcomeCard/WelcomeCard"; import { useDispatch, useSelector } from "react-redux"; import { globalActions } from "store/slices/global/slice"; import { getUserAuthDetails } from "store/slices/global/user/selectors"; @@ -16,7 +15,10 @@ export const DesktopOnboardingCard = ({ children, className }: { children: React export const DesktopOnboardingModal = () => { const dispatch = useDispatch(); const user = useSelector(getUserAuthDetails); - const [onboardingStep, setOnboardingStep] = useState(OnboardingStep.FEATURE_SELECTION); + // First-run onboarding is now a single step: sign-in/sign-up. The feature-selection + // screen (WelcomeCard) and the local-workspace folder-selection step were removed + // with the API Client (RQ-4695), so the step machine starts — and stays — at AUTH. + const [onboardingStep] = useState(OnboardingStep.AUTH); useEffect(() => { if (user.loggedIn) { @@ -36,27 +38,19 @@ export const DesktopOnboardingModal = () => { className="rq-desktop-onboarding-modal" >
- {onboardingStep === OnboardingStep.FEATURE_SELECTION ? ( - - setOnboardingStep(step)} /> - - ) : onboardingStep === OnboardingStep.AUTH ? ( - <> - - setOnboardingStep(OnboardingStep.FEATURE_SELECTION)} /> - - - - ) : null} + + + +
); diff --git a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/AuthCard/AuthCard.tsx b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/AuthCard/AuthCard.tsx index 48bc6f4a71..e8079e9667 100644 --- a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/AuthCard/AuthCard.tsx +++ b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/AuthCard/AuthCard.tsx @@ -1,5 +1,4 @@ import React from "react"; -import { IoMdArrowBack } from "@react-icons/all-files/io/IoMdArrowBack"; import { RQButton } from "lib/design-system-v2/components"; import LINKS from "config/constants/sub/links"; import { useDispatch, useSelector } from "react-redux"; @@ -10,11 +9,7 @@ import { SOURCE } from "modules/analytics/events/common/constants"; import APP_CONSTANTS from "config/constants"; import "./authCard.scss"; -interface Props { - onBackClick: () => void; -} - -export const AuthCard: React.FC = ({ onBackClick }) => { +export const AuthCard: React.FC = () => { const dispatch = useDispatch(); const appMode = useSelector(getAppMode); @@ -33,10 +28,7 @@ export const AuthCard: React.FC = ({ onBackClick }) => { }; return ( <> -
- - Create your free account -
+
Create your free account
You will be redirected to your browser to securely complete the sign-up process in a few simple steps. diff --git a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/WelcomeCard.tsx b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/WelcomeCard.tsx deleted file mode 100644 index c2e94de95c..0000000000 --- a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/WelcomeCard.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import React from "react"; -import { Button } from "antd"; -import RQOnlyLogo from "/assets/media/common/RQ-only-logo.svg"; -import { useDispatch } from "react-redux"; -import { globalActions } from "store/slices/global/slice"; -import { trackDesktopOnboardingFeatureSelected, trackDesktopOnboardingStepSkipped } from "../../analytics"; -import { OnboardingStep } from "../../types"; -import { WelcomeCardHeader } from "./components/WelcomeCardHeader/WelcomeCardHeader"; -import { MdOutlineKeyboardArrowRight } from "@react-icons/all-files/md/MdOutlineKeyboardArrowRight"; -import "./welcomeCard.scss"; - -interface Props { - onFeatureClick: (step: OnboardingStep) => void; -} - -export const WelcomeCard: React.FC = ({ onFeatureClick }) => { - const dispatch = useDispatch(); - - return ( -
- RQ Only Logo -
- Welcome to Requestly -
-
- Intercept, Mock, Build & Test APIs faster -
-
-
{ - trackDesktopOnboardingFeatureSelected("rules"); - onFeatureClick(OnboardingStep.AUTH); - }} - > - - -
-
-
- {" "} - this screen and quick start -
-
- ); -}; diff --git a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/components/WelcomeCardHeader/WelcomeCardHeader.tsx b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/components/WelcomeCardHeader/WelcomeCardHeader.tsx deleted file mode 100644 index ee61b71cf7..0000000000 --- a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/components/WelcomeCardHeader/WelcomeCardHeader.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from "react"; -import "./welcomeCardHeader.scss"; -import { m, AnimatePresence } from "framer-motion"; -import { collapseExpandTransition } from "utils/animations"; - -interface WelcomeCardHeaderProps { - title: string; - description: string | null; - iconSrc: string; -} -export const WelcomeCardHeader: React.FC = ({ - title, - description, - iconSrc, -}: WelcomeCardHeaderProps) => { - return ( -
-
- {title} -
-
-
{title}
- - {description && ( - -
{description}
-
- )} -
-
-
- ); -}; diff --git a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/components/WelcomeCardHeader/welcomeCardHeader.scss b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/components/WelcomeCardHeader/welcomeCardHeader.scss deleted file mode 100644 index da7fe40998..0000000000 --- a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/components/WelcomeCardHeader/welcomeCardHeader.scss +++ /dev/null @@ -1,40 +0,0 @@ -.welcome-card-header { - display: flex; - align-items: center; - gap: 12px; - - &__icon { - display: flex; - width: 48px; - height: 48px; - aspect-ratio: 1/1; - justify-content: center; - align-items: center; - gap: 8px; - border-radius: 50%; - border: 1px solid var(--stroke-glass, rgba(255, 255, 255, 0.4)); - background: rgba(255, 255, 255, 0.04); - - img { - width: 29px; - height: 29px; - flex-shrink: 0; - filter: brightness(0.7); - } - } - - &__content { - &-title { - color: var(--requestly-color-text-default); - font-size: var(--requestly-font-size-md); - font-weight: var(--requestly-font-weight-medium); - } - - &-description { - color: var(--requestly-color-text-subtle); - font-size: var(--requestly-font-size-sm); - margin-top: 4px; - width: 260px; - } - } -} diff --git a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/welcomeCard.scss b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/welcomeCard.scss deleted file mode 100644 index e35625e196..0000000000 --- a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/components/WelcomeCard/welcomeCard.scss +++ /dev/null @@ -1,56 +0,0 @@ -.welcome-card-option { - background: rgba(255, 255, 255, 0.04); - border-radius: 12px; - backdrop-filter: blur(10px); - cursor: pointer; - padding: var(--requestly-space-6) var(--requestly-space-8); - transition: border 0.2s ease-in-out; - border: 1px solid transparent; - - &:hover { - border: 1px solid var(--requestly-color-primary); - background: var(--requestly-color-white-t-10); - } -} - -.fade-out { - opacity: 0.2; - transition: opacity 0.2s ease-in-out; - pointer-events: none; -} - -.api-client-onboard-card { - position: relative; - - &__options-container { - padding-top: 12px; - } - - &__arrow { - width: 20px; - height: 20px; - flex-shrink: 0; - position: absolute; - right: 16px; - top: 32px; - } -} - -.api-client-onboard-card__options-container { - .local-workspace-create-options__option-title { - font-size: var(--requestly-font-size-md) !important; - } -} - -.onboarding-interceptor-card-option { - .api-client-onboard-card__arrow { - top: 35px; - opacity: 0; - } - - &:hover { - .api-client-onboard-card__arrow { - opacity: 1; - } - } -} diff --git a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/types.ts b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/types.ts index a0ca630dbc..13de4238b1 100644 --- a/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/types.ts +++ b/app/src/features/onboarding/componentsV2/DesktopOnboardingModal/types.ts @@ -1,4 +1,3 @@ export enum OnboardingStep { - FEATURE_SELECTION = "feature_selection", AUTH = "auth", } From c5ce68a758d2368b8c0557637d7521e9166578c4 Mon Sep 17 00:00:00 2001 From: kanishkrawatt Date: Fri, 17 Jul 2026 14:51:25 +0530 Subject: [PATCH 4/4] [RQ-4696] chore: hide local (file-system) workspaces from the UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WorkspaceType.LOCAL workspaces existed only to back the API Client, which is being removed. Hide them from every user-facing surface. This is UI-hiding only — on-disk workspace folders are NOT deleted, and LOCAL_STORAGE (logged-out) behavior is unchanged. - Central lever (useWorkspaceFetcher): stop fetching/injecting local workspaces into `allWorkspaces`; only shared (team) workspaces flow in now. Everything that reads `allWorkspaces` (dropdown/overlay/settings) therefore surfaces no LOCAL entry. - WorkspacesOverlay: remove the "Local workspaces" list section entirely (list rows, "Add", the empty-state section and its "New/Create local workspace" CTA) and the local-sync gating; drop the now-dead hasLocalWorkspaces / isLocalSyncEnabled state. Only the shared section and the common empty view remain. This also closes the MULTI (multi-workspace) view — its only UI entry was the LOCAL row checkboxes. - CommonEmptyView: remove the desktop-only "New local workspace" button and the local mention from the description (team-only now). - WorkspaceDropdown: remove the active-local avatar special-casing (use the generic WorkspaceAvatar for all single-view workspaces) and the "Load latest changes from your local files" refresh button. Per the ticket's decision, a user currently active in a LOCAL workspace is not force-switched or errored — they simply have no LOCAL entries to switch back to (one-way door). Migration segment strings are unchanged. Verified: ESLint clean on changed files; `tsc --noEmit` net 0 new errors (1289 baseline unchanged); `vite build` succeeds. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../workspaces/hooks/useWorkspaceFetcher.ts | 22 +++---- .../components/WorkspaceDropdown.tsx | 64 +++---------------- .../WorkspacesOverlay/WorkspacesOverlay.tsx | 31 ++------- .../CommonEmptyView/CommonEmptyView.tsx | 9 +-- 4 files changed, 29 insertions(+), 97 deletions(-) diff --git a/app/src/features/workspaces/hooks/useWorkspaceFetcher.ts b/app/src/features/workspaces/hooks/useWorkspaceFetcher.ts index 53a1580f9a..181764c213 100644 --- a/app/src/features/workspaces/hooks/useWorkspaceFetcher.ts +++ b/app/src/features/workspaces/hooks/useWorkspaceFetcher.ts @@ -1,5 +1,4 @@ import { useEffect } from "react"; -import { useFetchLocalWorkspaces } from "./useFetchLocalWorkspaces"; import { useFetchTeamWorkspaces } from "./useFetchTeamWorkspaces"; import { useDispatch, useSelector } from "react-redux"; import { workspaceActions } from "store/slices/workspaces/slice"; @@ -17,20 +16,21 @@ export const useWorkspaceFetcher = () => { const activeWorkspace = useSelector(getActiveWorkspace); const appMode = useSelector(getAppMode); - const { fetchLocalWorkspaces } = useFetchLocalWorkspaces(); const { sharedWorkspaces } = useFetchTeamWorkspaces(); useActiveWorkspacesMembersListener(); useEffect(() => { - (async () => { - try { - const allLocalWorkspaces = await fetchLocalWorkspaces(); - dispatch(workspaceActions.setAllWorkspaces([...allLocalWorkspaces, ...sharedWorkspaces])); - } catch (e) { - captureException(e); - } - })(); - }, [dispatch, fetchLocalWorkspaces, sharedWorkspaces]); + // LOCAL (file-system) workspaces are hidden from the UI (RQ-4696): they only + // ever backed the API Client, which has been removed. We no longer fetch or + // inject them, so nothing that reads `allWorkspaces` (dropdown, overlay, + // settings) surfaces a LOCAL workspace. On-disk data is untouched, and + // LOCAL_STORAGE (logged-out) is unaffected — it flows through its own path. + try { + dispatch(workspaceActions.setAllWorkspaces([...sharedWorkspaces])); + } catch (e) { + captureException(e); + } + }, [dispatch, sharedWorkspaces]); useEffect(() => { if (!user.loggedIn) { diff --git a/app/src/layouts/DashboardLayout/MenuHeader/WorkspaceSelector/components/WorkspaceDropdown.tsx b/app/src/layouts/DashboardLayout/MenuHeader/WorkspaceSelector/components/WorkspaceDropdown.tsx index 23aef14eff..502ff36ee7 100644 --- a/app/src/layouts/DashboardLayout/MenuHeader/WorkspaceSelector/components/WorkspaceDropdown.tsx +++ b/app/src/layouts/DashboardLayout/MenuHeader/WorkspaceSelector/components/WorkspaceDropdown.tsx @@ -1,22 +1,16 @@ -import React, { useMemo, useState } from "react"; +import { useMemo, useState } from "react"; import { useSelector } from "react-redux"; import { DownOutlined } from "@ant-design/icons"; -import { MdOutlineRefresh } from "@react-icons/all-files/md/MdOutlineRefresh"; import { getAppMode } from "store/selectors"; import { Dropdown, Tooltip } from "antd"; -import FEATURES from "config/constants/sub/features"; import WorkspaceAvatar from "features/workspaces/components/WorkspaceAvatar"; -import { RQButton } from "lib/design-system-v2/components"; import { trackTopbarClicked } from "modules/analytics/events/common/onboarding/header"; import { getActiveWorkspace } from "store/slices/workspaces/selectors"; import { Invite } from "types"; -import { isFeatureCompatible } from "utils/CompatibilityUtils"; import { WorkspacesOverlay } from "./WorkspacesOverlay/WorkspacesOverlay"; import { MultiWorkspaceAvatarGroup } from "../MultiWorkspaceAvatarGroup"; -import LocalWorkspaceAvatar from "features/workspaces/components/LocalWorkspaceAvatar"; import { CONSTANTS as GLOBAL_CONSTANTS } from "@requestly/requestly-core"; import { getUserAuthDetails } from "store/slices/global/user/selectors"; -import { WorkspaceType } from "features/workspaces/types"; import { ApiClientViewMode, useViewMode } from "features/apiClient/slices"; const prettifyWorkspaceName = (workspaceName: string) => { @@ -50,23 +44,12 @@ const WorkSpaceDropDown = ({ teamInvites }: { teamInvites: Invite[] }) => { } }; - const handleLocalSyncRefresh = (e: React.MouseEvent) => { - e.stopPropagation(); - window.dispatchEvent(new Event("local-sync-refresh")); - }; - const toggleDropdown = () => { setIsDropdownOpen((prev) => !prev); }; const tooltipTitle = - activeWorkspace?.workspaceType === WorkspaceType.LOCAL - ? viewMode === ApiClientViewMode.SINGLE - ? activeWorkspace.rootPath - : null - : viewMode === ApiClientViewMode.MULTI - ? null - : prettifyWorkspaceName(activeWorkspaceName); + viewMode === ApiClientViewMode.MULTI ? null : prettifyWorkspaceName(activeWorkspaceName); return ( <> @@ -94,29 +77,14 @@ const WorkSpaceDropDown = ({ teamInvites }: { teamInvites: Invite[] }) => { {viewMode === ApiClientViewMode.MULTI ? ( ) : ( - <> - {activeWorkspace?.workspaceType === WorkspaceType.LOCAL ? ( - <> - - - ) : ( - - )} - + )} {viewMode === ApiClientViewMode.SINGLE && ( @@ -128,18 +96,6 @@ const WorkSpaceDropDown = ({ teamInvites }: { teamInvites: Invite[] }) => {
- - {activeWorkspace?.workspaceType === WorkspaceType.LOCAL && - isFeatureCompatible(FEATURES.LOCAL_WORKSPACE_REFRESH) ? ( - - } - /> - - ) : null} ); }; diff --git a/app/src/layouts/DashboardLayout/MenuHeader/WorkspaceSelector/components/WorkspacesOverlay/WorkspacesOverlay.tsx b/app/src/layouts/DashboardLayout/MenuHeader/WorkspaceSelector/components/WorkspacesOverlay/WorkspacesOverlay.tsx index 53f269d865..1da78783a4 100644 --- a/app/src/layouts/DashboardLayout/MenuHeader/WorkspaceSelector/components/WorkspacesOverlay/WorkspacesOverlay.tsx +++ b/app/src/layouts/DashboardLayout/MenuHeader/WorkspaceSelector/components/WorkspacesOverlay/WorkspacesOverlay.tsx @@ -11,7 +11,6 @@ import { MdOutlineGroups } from "@react-icons/all-files/md/MdOutlineGroups"; import { globalActions } from "store/slices/global/slice"; import { trackWorkspaceJoiningModalOpened } from "modules/analytics/events/features/teams"; import LoadingModal from "../LoadingModal"; -import { useCheckLocalSyncSupport } from "features/apiClient/helpers/modules/sync/useCheckLocalSyncSupport"; import { EmptyWorkspaceListView } from "./components/EmptyWorkspaceListView/EmptyWorkspaceListView"; import { CommonEmptyView } from "./components/CommonEmptyView/CommonEmptyView"; import { useWorkspaceSwitcher } from "features/apiClient/screens/apiClient/components/sidebar/MultiWorkspaceSidebar/WorkspaceProvider/useWorkspaceSwitcher"; @@ -72,8 +71,6 @@ export const WorkspacesOverlay: React.FC = ({ toggleDrop const user = useSelector(getUserAuthDetails); const availableWorkspaces = useSelector(getAllWorkspaces); - const isLocalSyncEnabled = useCheckLocalSyncSupport({ skipWorkspaceCheck: true }); - const { handleWorkspaceSwitch, confirmWorkspaceSwitch, @@ -109,7 +106,6 @@ export const WorkspacesOverlay: React.FC = ({ toggleDrop }, map); }, [sortedAvailableWorkspaces]); - const hasLocalWorkspaces = workspaceMap[WorkspaceType.LOCAL].length > 0; const hasSharedWorkspaces = workspaceMap[WorkspaceType.SHARED].length; const handleJoinWorkspaceMenuItemClick = () => { @@ -143,31 +139,18 @@ export const WorkspacesOverlay: React.FC = ({ toggleDrop )} - {!hasLocalWorkspaces && !hasSharedWorkspaces ? ( + {!hasSharedWorkspaces ? ( <> {user.loggedIn ? : null} ) : ( -
- {isLocalSyncEnabled ? ( - - confirmWorkspaceSwitch(() => handleWorkspaceSwitch(workspace, addWorkspaceToView)) - } - /> - ) : null} - - confirmWorkspaceSwitch(() => handleWorkspaceSwitch(workspace))} - /> -
+ confirmWorkspaceSwitch(() => handleWorkspaceSwitch(workspace))} + /> )} {user.loggedIn ? ( diff --git a/app/src/layouts/DashboardLayout/MenuHeader/WorkspaceSelector/components/WorkspacesOverlay/components/CommonEmptyView/CommonEmptyView.tsx b/app/src/layouts/DashboardLayout/MenuHeader/WorkspaceSelector/components/WorkspacesOverlay/components/CommonEmptyView/CommonEmptyView.tsx index ac505bb5f2..8da167878f 100644 --- a/app/src/layouts/DashboardLayout/MenuHeader/WorkspaceSelector/components/WorkspacesOverlay/components/CommonEmptyView/CommonEmptyView.tsx +++ b/app/src/layouts/DashboardLayout/MenuHeader/WorkspaceSelector/components/WorkspacesOverlay/components/CommonEmptyView/CommonEmptyView.tsx @@ -38,9 +38,7 @@ export const CommonEmptyView: React.FC = ({ toggleDropdown empty folder
You don't have any workspaces yet.
- {appMode === GLOBAL_CONSTANTS.APP_MODES.DESKTOP - ? "Create a local workspace to store files on your device or a team workspace to collaborate with teammates." - : "Create a team workspace to collaborate with teammates."} + Create a team workspace to collaborate with teammates.
= ({ toggleDropdown New team workspace - {appMode === GLOBAL_CONSTANTS.APP_MODES.DESKTOP ? ( - handleCreateWorkspace(WorkspaceType.LOCAL)}> - New local workspace - - ) : null}
);