From 368d4c660919e742ad8563a2c98db092ad3d9165 Mon Sep 17 00:00:00 2001 From: Ankita Kinger Date: Thu, 23 Jan 2025 21:21:34 +0530 Subject: [PATCH 1/5] removing unused files & components --- .../Editor/Explorer/EntityExplorer.test.tsx | 407 ------------------ .../pages/Editor/Explorer/EntityExplorer.tsx | 132 ------ .../src/pages/Editor/Explorer/Pages/index.tsx | 157 ------- .../src/pages/Editor/Explorer/index.tsx | 103 ----- .../Statusbar.test.tsx | 238 ---------- .../FirstTimeUserOnboarding/Statusbar.tsx | 115 ----- .../EditorPane}/Pages/AddPageContextMenu.tsx | 0 .../EditorPane}/Pages/PageContextMenu.tsx | 0 .../{components => Pages}/PageElement.tsx | 2 +- .../EditorPane/{ => Pages}/PagesSection.tsx | 4 +- .../pages/Editor/IDE/Header/EditorTitle.tsx | 2 +- .../Editor/WidgetsEditorEntityExplorer.tsx | 29 -- 12 files changed, 4 insertions(+), 1185 deletions(-) delete mode 100644 app/client/src/pages/Editor/Explorer/EntityExplorer.test.tsx delete mode 100644 app/client/src/pages/Editor/Explorer/EntityExplorer.tsx delete mode 100644 app/client/src/pages/Editor/Explorer/Pages/index.tsx delete mode 100644 app/client/src/pages/Editor/Explorer/index.tsx delete mode 100644 app/client/src/pages/Editor/FirstTimeUserOnboarding/Statusbar.test.tsx delete mode 100644 app/client/src/pages/Editor/FirstTimeUserOnboarding/Statusbar.tsx rename app/client/src/pages/Editor/{Explorer => IDE/EditorPane}/Pages/AddPageContextMenu.tsx (100%) rename app/client/src/pages/Editor/{Explorer => IDE/EditorPane}/Pages/PageContextMenu.tsx (100%) rename app/client/src/pages/Editor/IDE/EditorPane/{components => Pages}/PageElement.tsx (98%) rename app/client/src/pages/Editor/IDE/EditorPane/{ => Pages}/PagesSection.tsx (95%) delete mode 100644 app/client/src/pages/Editor/WidgetsEditorEntityExplorer.tsx diff --git a/app/client/src/pages/Editor/Explorer/EntityExplorer.test.tsx b/app/client/src/pages/Editor/Explorer/EntityExplorer.test.tsx deleted file mode 100644 index 04091582d3cd..000000000000 --- a/app/client/src/pages/Editor/Explorer/EntityExplorer.test.tsx +++ /dev/null @@ -1,407 +0,0 @@ -import { act, fireEvent, render } from "test/testUtils"; -import { - buildChildren, - widgetCanvasFactory, -} from "test/factories/WidgetFactoryUtils"; -import React from "react"; -import { MockPageDSL } from "test/testCommon"; -import { DEFAULT_ENTITY_EXPLORER_WIDTH } from "constants/AppConstants"; -import { runSagaMiddleware } from "store"; -import urlBuilder from "ee/entities/URLRedirect/URLAssembly"; -import * as explorerSelector from "selectors/explorerSelector"; -import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants"; -import * as widgetSelectionsActions from "actions/widgetSelectionActions"; -import { SelectionRequestType } from "sagas/WidgetSelectUtils"; -import { NavigationMethod } from "utils/history"; -import WidgetsEditorEntityExplorer from "../WidgetsEditorEntityExplorer"; - -jest.useFakeTimers(); -const pushState = jest.spyOn(window.history, "pushState"); - -// TODO: Fix this the next time the file is edited -// eslint-disable-next-line @typescript-eslint/no-explicit-any -pushState.mockImplementation((state: any, title: any, url: any) => { - window.document.title = title; - window.location.pathname = url; -}); - -jest.mock("ee/utils/permissionHelpers", () => { - return { - __esModule: true, - ...jest.requireActual("ee/utils/permissionHelpers"), - }; -}); - -jest.mock("ee/pages/Editor/Explorer/helpers", () => ({ - __esModule: true, - ...jest.requireActual("ee/pages/Editor/Explorer/helpers"), -})); - -jest.mock("ee/utils/BusinessFeatures/permissionPageHelpers", () => ({ - __esModule: true, - ...jest.requireActual("ee/utils/BusinessFeatures/permissionPageHelpers"), -})); - -jest.mock("selectors/explorerSelector", () => ({ - __esModule: true, - ...jest.requireActual("selectors/explorerSelector"), -})); - -jest - .spyOn(explorerSelector, "getExplorerWidth") - .mockImplementation(() => DEFAULT_ENTITY_EXPLORER_WIDTH); - -describe("Entity Explorer tests", () => { - beforeAll(() => { - runSagaMiddleware(); - }); - - beforeEach(() => { - urlBuilder.updateURLParams( - { - baseApplicationId: "appId", - applicationSlug: "appSlug", - applicationVersion: 2, - }, - [ - { - basePageId: "pageId", - pageSlug: "pageSlug", - }, - ], - ); - }); - - it("Should render Widgets tree in entity explorer", async () => { - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const children: any = buildChildren([{ type: "TABS_WIDGET" }]); - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const dsl: any = widgetCanvasFactory.build({ - children, - }); - const component = render( - - - , - ); - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const widgetsTree: Element = await component.findByText( - "Widgets", - { - selector: "div.t--entity-name", - }, - { timeout: 3000 }, - ); - - act(() => { - fireEvent.click(widgetsTree); - jest.runAllTimers(); - }); - const tabsWidget = component.queryByText(children[0].widgetName); - - expect(tabsWidget).toBeTruthy(); - }); - - describe("Widget Selection in entity explorer", () => { - const spyWidgetSelection = jest.spyOn( - widgetSelectionsActions, - "selectWidgetInitAction", - ); - - beforeEach(() => { - spyWidgetSelection.mockClear(); - }); - - it("Select widget on entity explorer", async () => { - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const children: any = buildChildren([ - { type: "TABS_WIDGET", widgetId: "tabsWidgetId" }, - ]); - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const dsl: any = widgetCanvasFactory.build({ - children, - }); - const component = render( - - - , - ); - // TODO: Fix this the next time the file is edited - const tabsWidget: Element = await component.findByText( - children[0].widgetName, - undefined, - { timeout: 3000 }, - ); - - act(() => { - fireEvent.click(tabsWidget); - jest.runAllTimers(); - }); - - expect(spyWidgetSelection).toHaveBeenCalledWith( - SelectionRequestType.One, - ["tabsWidgetId"], - NavigationMethod.EntityExplorer, - undefined, - ); - }); - - it("CMD + click Multi Select widget on entity explorer", async () => { - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const children: any = buildChildren([ - { - type: "CHECKBOX_WIDGET", - parentId: "0", - widgetId: "checkboxWidgetId", - }, - { type: "SWITCH_WIDGET", parentId: "0", widgetId: "switchWidgetId" }, - ]); - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const dsl: any = widgetCanvasFactory.build({ - children, - }); - const component = render( - - - , - ); - // TODO: Fix this the next time the file is edited - const checkBox: Element = await component.findByText( - children[0].widgetName, - undefined, - { timeout: 3000 }, - ); - - act(() => { - fireEvent.click(checkBox); - jest.runAllTimers(); - }); - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const switchWidget: any = component.queryByText(children[1].widgetName); - - expect(spyWidgetSelection).toHaveBeenCalledWith( - SelectionRequestType.One, - ["checkboxWidgetId"], - NavigationMethod.EntityExplorer, - undefined, - ); - - act(() => { - fireEvent.click(switchWidget, { - ctrlKey: true, - }); - jest.runAllTimers(); - }); - expect(spyWidgetSelection).toHaveBeenCalledWith( - SelectionRequestType.PushPop, - ["switchWidgetId"], - undefined, - undefined, - ); - }); - - it("Shift + Click Multi Select widget on entity explorer", async () => { - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const children: any = buildChildren([ - { - type: "CHECKBOX_WIDGET", - parentId: "0", - widgetId: "checkboxWidgetId", - }, - { type: "SWITCH_WIDGET", parentId: "0", widgetId: "switchWidgetId" }, - { type: "BUTTON_WIDGET", parentId: "0", widgetId: "buttonWidgetId" }, - ]); - // TODO: Fix this the next time the file is edited - const dsl = widgetCanvasFactory.build({ - children, - }); - const component = render( - - - , - ); - - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const checkboxWidget: any = await component.findByText( - children[0].widgetName, - undefined, - { timeout: 3000 }, - ); - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const buttonWidget: any = component.queryByText(children[2].widgetName); - - act(() => { - fireEvent.click(checkboxWidget); - jest.runAllTimers(); - }); - - expect(spyWidgetSelection).toHaveBeenCalledWith( - SelectionRequestType.One, - ["checkboxWidgetId"], - NavigationMethod.EntityExplorer, - undefined, - ); - - act(() => { - fireEvent.click(buttonWidget, { - shiftKey: true, - }); - jest.runAllTimers(); - }); - - expect(spyWidgetSelection).toHaveBeenCalledWith( - SelectionRequestType.ShiftSelect, - ["buttonWidgetId"], - undefined, - undefined, - ); - }); - - it("Shift + Click Deselect Non Siblings", async () => { - const containerId = "containerWidgetId"; - const canvasId = "canvasWidgetId"; - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const children: any = buildChildren([ - { - type: "CHECKBOX_WIDGET", - parentId: canvasId, - widgetId: "checkboxWidgetId", - }, - { - type: "SWITCH_WIDGET", - parentId: canvasId, - widgetId: "switchWidgetId", - }, - { - type: "BUTTON_WIDGET", - parentId: canvasId, - widgetId: "buttonWidgetId", - }, - ]); - const canvasWidget = buildChildren([ - { - type: "CANVAS_WIDGET", - parentId: containerId, - children, - widgetId: canvasId, - }, - ]); - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const containerChildren: any = buildChildren([ - { - type: "CONTAINER_WIDGET", - children: canvasWidget, - widgetId: containerId, - parentId: MAIN_CONTAINER_WIDGET_ID, - }, - { - type: "CHART_WIDGET", - parentId: MAIN_CONTAINER_WIDGET_ID, - widgetId: "chartWidgetId", - }, - ]); - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const dsl: any = widgetCanvasFactory.build({ - children: containerChildren, - }); - const component = render( - - - , - ); - // TODO: Fix this the next time the file is edited - const containerWidget: Element = await component.findByText( - containerChildren[0].widgetName, - undefined, - { timeout: 3000 }, - ); - - act(() => { - fireEvent.click(containerWidget); - jest.runAllTimers(); - }); - - expect(spyWidgetSelection).toHaveBeenCalledWith( - SelectionRequestType.One, - [containerId], - NavigationMethod.EntityExplorer, - undefined, - ); - - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const collapsible: any = component.container.querySelector( - `.t--entity-collapse-toggle[id="arrow-right-s-line"]`, - ); - - fireEvent.click(collapsible); - - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const buttonWidget: any = component.queryByText(children[2].widgetName); - - act(() => { - fireEvent.click(buttonWidget, { - shiftKey: true, - }); - jest.runAllTimers(); - }); - - expect(spyWidgetSelection).toHaveBeenCalledWith( - SelectionRequestType.ShiftSelect, - ["buttonWidgetId"], - undefined, - undefined, - ); - - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const checkBoxWidget: any = component.queryByText(children[0].widgetName); - - act(() => { - fireEvent.click(checkBoxWidget, { - shiftKey: true, - }); - jest.runAllTimers(); - }); - expect(spyWidgetSelection).toHaveBeenCalledWith( - SelectionRequestType.ShiftSelect, - ["checkboxWidgetId"], - undefined, - undefined, - ); - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const chartWidget: any = component.queryByText( - containerChildren[1].widgetName, - ); - - act(() => { - fireEvent.click(chartWidget, { - shiftKey: true, - }); - jest.runAllTimers(); - }); - expect(spyWidgetSelection).toHaveBeenCalledWith( - SelectionRequestType.ShiftSelect, - ["chartWidgetId"], - undefined, - undefined, - ); - }); - }); -}); diff --git a/app/client/src/pages/Editor/Explorer/EntityExplorer.tsx b/app/client/src/pages/Editor/Explorer/EntityExplorer.tsx deleted file mode 100644 index c86c3c293053..000000000000 --- a/app/client/src/pages/Editor/Explorer/EntityExplorer.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import React, { useRef, useCallback, useEffect } from "react"; -import styled from "styled-components"; -import { NonIdealState, Classes } from "@blueprintjs/core"; -import { useDispatch, useSelector } from "react-redux"; - -import { Colors } from "constants/Colors"; - -import { getIsFirstTimeUserOnboardingEnabled } from "selectors/onboardingSelectors"; -import { toggleInOnboardingWidgetSelection } from "actions/onboardingActions"; - -import { forceOpenWidgetPanel } from "actions/widgetSidebarActions"; -import Files from "./Files"; -import ExplorerWidgetGroup from "./Widgets/WidgetGroup"; -import { builderURL } from "ee/RouteBuilder"; -import history from "utils/history"; -import { - getCurrentBasePageId, - getCurrentPageId, - getPagePermissions, -} from "selectors/editorSelectors"; -import { fetchWorkspace } from "ee/actions/workspaceActions"; -import { getCurrentWorkspaceId } from "ee/selectors/selectedWorkspaceSelectors"; -import { importSvg } from "@appsmith/ads-old"; -import AnalyticsUtil from "ee/utils/AnalyticsUtil"; -import { EntityExplorerWrapper } from "./Common/EntityExplorerWrapper"; -import { getCurrentApplicationId } from "selectors/editorSelectors"; -import { FilesContextProvider } from "./Files/FilesContextProvider"; -import { getHasCreateActionPermission } from "ee/utils/BusinessFeatures/permissionPageHelpers"; -import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; -import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; -import { ActionParentEntityType } from "ee/entities/Engine/actionHelpers"; -import { getShowWorkflowFeature } from "ee/selectors/workflowSelectors"; - -const NoEntityFoundSvg = importSvg( - async () => import("assets/svg/no_entities_found.svg"), -); - -const NoResult = styled(NonIdealState)` - &.${Classes.NON_IDEAL_STATE} { - height: auto; - margin: 20px 0; - - .${Classes.NON_IDEAL_STATE_VISUAL} { - margin-bottom: 16px; - height: 52px; - - svg { - height: 52px; - width: 144px; - } - } - - div { - color: ${Colors.DOVE_GRAY2}; - } - - .${Classes.HEADING} { - margin-bottom: 4px; - color: ${(props) => props.theme.colors.textOnWhiteBG}; - } - } -`; - -function EntityExplorer({ isActive }: { isActive: boolean }) { - const dispatch = useDispatch(); - const explorerRef = useRef(null); - const isFirstTimeUserOnboardingEnabled = useSelector( - getIsFirstTimeUserOnboardingEnabled, - ); - const noResults = false; - const basePageId = useSelector(getCurrentBasePageId); - const pageId = useSelector(getCurrentPageId); - const showWidgetsSidebar = useCallback(() => { - AnalyticsUtil.logEvent("EXPLORER_WIDGET_CLICK"); - history.push(builderURL({ basePageId })); - dispatch(forceOpenWidgetPanel(true)); - - if (isFirstTimeUserOnboardingEnabled) { - dispatch(toggleInOnboardingWidgetSelection(true)); - } - }, [isFirstTimeUserOnboardingEnabled, basePageId]); - - const currentWorkspaceId = useSelector(getCurrentWorkspaceId); - - useEffect(() => { - dispatch(fetchWorkspace(currentWorkspaceId)); - }, [currentWorkspaceId]); - - const applicationId = useSelector(getCurrentApplicationId); - - const pagePermissions = useSelector(getPagePermissions); - - const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); - - const canCreateActions = getHasCreateActionPermission( - isFeatureEnabled, - pagePermissions, - ); - - const showWorkflows = useSelector(getShowWorkflowFeature); - - return ( - - - - - - {noResults && ( - } - title="No entities found" - /> - )} - - ); -} - -EntityExplorer.displayName = "EntityExplorer"; - -export default EntityExplorer; diff --git a/app/client/src/pages/Editor/Explorer/Pages/index.tsx b/app/client/src/pages/Editor/Explorer/Pages/index.tsx deleted file mode 100644 index db37964f5f8d..000000000000 --- a/app/client/src/pages/Editor/Explorer/Pages/index.tsx +++ /dev/null @@ -1,157 +0,0 @@ -import React, { - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from "react"; -import { useDispatch, useSelector } from "react-redux"; -import { - getCurrentApplicationId, - getCurrentPageId, -} from "selectors/editorSelectors"; -import { EntityClassNames } from "../Entity"; -import { createNewPageFromEntities } from "actions/pageActions"; -import { ADD_PAGE_TOOLTIP, createMessage } from "ee/constants/messages"; -import type { Page } from "entities/Page"; -import { getNextEntityName } from "utils/AppsmithUtils"; -import { getExplorerPinned } from "selectors/explorerSelector"; -import { setExplorerPinnedAction } from "actions/explorerActions"; -import { selectAllPages } from "ee/selectors/entitiesSelector"; -import { - getExplorerStatus, - saveExplorerStatus, -} from "ee/pages/Editor/Explorer/helpers"; -import AddPageContextMenu from "./AddPageContextMenu"; -import { useLocation } from "react-router"; -import type { AppState } from "ee/reducers"; -import { getCurrentWorkspaceId } from "ee/selectors/selectedWorkspaceSelectors"; -import { getInstanceId } from "ee//selectors/tenantSelectors"; -import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; -import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; -import { getHasCreatePagePermission } from "ee/utils/BusinessFeatures/permissionPageHelpers"; -import { - ENTITY_HEIGHT, - RelativeContainer, - StyledEntity, -} from "../Common/components"; -import { EntityExplorerResizeHandler } from "../Common/EntityExplorerResizeHandler"; -import { PageElement } from "pages/Editor/IDE/EditorPane/components/PageElement"; -import { getCurrentApplication } from "ee/selectors/applicationSelectors"; - -function Pages() { - const applicationId = useSelector(getCurrentApplicationId); - const pages: Page[] = useSelector(selectAllPages); - const currentPageId = useSelector(getCurrentPageId); - const pinned = useSelector(getExplorerPinned); - const dispatch = useDispatch(); - const isPagesOpen = getExplorerStatus(applicationId, "pages"); - const pageResizeRef = useRef(null); - const storedHeightKey = "pagesContainerHeight_" + applicationId; - const storedHeight = localStorage.getItem(storedHeightKey); - const location = useLocation(); - - useEffect(() => { - if ((isPagesOpen === null ? true : isPagesOpen) && pageResizeRef.current) { - pageResizeRef.current.style.height = storedHeight + "px"; - } - }, [pageResizeRef]); - - useEffect(() => { - // scroll to the current page - const currentPage = document.getElementById("entity-" + currentPageId); - - if (currentPage) { - setTimeout(() => currentPage.scrollIntoView(), 0); - } - }, [currentPageId]); - - const [isMenuOpen, openMenu] = useState(false); - - const workspaceId = useSelector(getCurrentWorkspaceId); - const instanceId = useSelector(getInstanceId); - - const createPageCallback = useCallback(() => { - const name = getNextEntityName( - "Page", - pages.map((page: Page) => page.pageName), - ); - - dispatch( - createNewPageFromEntities(applicationId, name, workspaceId, instanceId), - ); - }, [dispatch, pages, applicationId]); - - const onMenuClose = useCallback(() => openMenu(false), [openMenu]); - - /** - * toggles the pinned state of sidebar - */ - const onPin = useCallback(() => { - dispatch(setExplorerPinnedAction(!pinned)); - }, [pinned, dispatch, setExplorerPinnedAction]); - - const onPageToggle = useCallback( - (isOpen: boolean) => { - saveExplorerStatus(applicationId, "pages", isOpen); - }, - [applicationId], - ); - - const userAppPermissions = useSelector( - (state: AppState) => getCurrentApplication(state)?.userPermissions ?? [], - ); - - const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); - - const canCreatePages = getHasCreatePagePermission( - isFeatureEnabled, - userAppPermissions, - ); - - const pageElements = useMemo( - () => pages.map((page) => ), - [pages, location.pathname], - ); - - return ( - - - } - entityId="Pages" - entitySize={ENTITY_HEIGHT * pages.length} - icon={""} - isDefaultExpanded={ - isPagesOpen === null || isPagesOpen === undefined ? true : isPagesOpen - } - name="Pages" - onClickPreRightIcon={onPin} - onToggle={onPageToggle} - searchKeyword={""} - showAddButton={canCreatePages} - step={0} - > - {pageElements} - - - - ); -} - -Pages.displayName = "Pages"; - -export default React.memo(Pages); diff --git a/app/client/src/pages/Editor/Explorer/index.tsx b/app/client/src/pages/Editor/Explorer/index.tsx deleted file mode 100644 index 61bc6b77ac4b..000000000000 --- a/app/client/src/pages/Editor/Explorer/index.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import React, { useEffect } from "react"; -import { toggleInOnboardingWidgetSelection } from "actions/onboardingActions"; -import { forceOpenWidgetPanel } from "actions/widgetSidebarActions"; -import { SegmentedControl } from "@appsmith/ads"; -import { useDispatch, useSelector } from "react-redux"; -import { useLocation } from "react-router"; -import type { AppState } from "ee/reducers"; -import { builderURL } from "ee/RouteBuilder"; -import { getCurrentBasePageId } from "selectors/editorSelectors"; -import { getIsFirstTimeUserOnboardingEnabled } from "selectors/onboardingSelectors"; -import AnalyticsUtil from "ee/utils/AnalyticsUtil"; -import { trimQueryString } from "utils/helpers"; -import history from "utils/history"; -import EntityExplorer from "./EntityExplorer"; -import { getExplorerSwitchIndex } from "selectors/editorContextSelectors"; -import { setExplorerSwitchIndex } from "actions/editorContextActions"; -import UIEntitySidebar from "../widgetSidebar/UIEntitySidebar"; -import { ExplorerWrapper } from "./Common/ExplorerWrapper"; - -const selectForceOpenWidgetPanel = (state: AppState) => - state.ui.onBoarding.forceOpenWidgetPanel; - -const options = [ - { - value: "explorer", - label: "Explorer", - }, - { - value: "widgets", - label: "Widgets", - }, -]; - -function ExplorerContent() { - const dispatch = useDispatch(); - const isFirstTimeUserOnboardingEnabled = useSelector( - getIsFirstTimeUserOnboardingEnabled, - ); - const basePageId = useSelector(getCurrentBasePageId); - const location = useLocation(); - const activeSwitchIndex = useSelector(getExplorerSwitchIndex); - - const setActiveSwitchIndex = (index: number) => { - dispatch(setExplorerSwitchIndex(index)); - }; - const openWidgetPanel = useSelector(selectForceOpenWidgetPanel); - - useEffect(() => { - const currentIndex = openWidgetPanel ? 1 : 0; - - if (currentIndex !== activeSwitchIndex) { - setActiveSwitchIndex(currentIndex); - } - }, [openWidgetPanel]); - - const onChange = (value: string) => { - if (value === options[0].value) { - dispatch(forceOpenWidgetPanel(false)); - } else if (value === options[1].value) { - if ( - !(trimQueryString(builderURL({ basePageId })) === location.pathname) - ) { - history.push(builderURL({ basePageId })); - AnalyticsUtil.logEvent("WIDGET_TAB_CLICK", { - type: "WIDGET_TAB", - fromUrl: location.pathname, - toUrl: builderURL({ basePageId }), - }); - } - - AnalyticsUtil.logEvent("EXPLORER_WIDGET_CLICK"); - dispatch(forceOpenWidgetPanel(true)); - dispatch(setExplorerSwitchIndex(1)); - - if (isFirstTimeUserOnboardingEnabled) { - dispatch(toggleInOnboardingWidgetSelection(true)); - } - } - }; - const { value: activeOption } = options[activeSwitchIndex]; - - return ( - -
- -
- - - - -
- ); -} - -export default ExplorerContent; diff --git a/app/client/src/pages/Editor/FirstTimeUserOnboarding/Statusbar.test.tsx b/app/client/src/pages/Editor/FirstTimeUserOnboarding/Statusbar.test.tsx deleted file mode 100644 index 2e0d8384dc9c..000000000000 --- a/app/client/src/pages/Editor/FirstTimeUserOnboarding/Statusbar.test.tsx +++ /dev/null @@ -1,238 +0,0 @@ -const dispatch = jest.fn(); - -import React from "react"; -import { Provider } from "react-redux"; -import { render } from "test/testUtils"; -import OnboardingStatusbar from "./Statusbar"; -import { getStore } from "./testUtils"; -import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; -import { SIGNPOSTING_STEP } from "./Utils"; -import { signpostingStepUpdateInit } from "actions/onboardingActions"; -import * as onboardingSelectors from "selectors/onboardingSelectors"; - -// TODO: Fix this the next time the file is edited -// eslint-disable-next-line @typescript-eslint/no-explicit-any -let container: any = null; - -jest.mock("react-redux", () => { - const originalModule = jest.requireActual("react-redux"); - - return { - ...originalModule, - useDispatch: () => dispatch, - }; -}); - -jest.mock("../../../selectors/onboardingSelectors", () => { - const originalModule = jest.requireActual( - "../../../selectors/onboardingSelectors", - ); - - return { - ...originalModule, - isWidgetActionConnectionPresent: jest.fn(), - }; -}); - -const originalOnboardingSelectors = jest.requireActual( - "../../../selectors/onboardingSelectors", -); - -// TODO: Fix this the next time the file is edited -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function renderComponent(store: any) { - render( - - - , - container, - ); -} - -describe("Statusbar", () => { - beforeEach(() => { - container = document.createElement("div"); - document.body.appendChild(container); - }); - - afterEach(() => { - jest.clearAllMocks(); - }); - - it("is rendered", async () => { - renderComponent(getStore(0)); - expect(dispatch).toHaveBeenCalledTimes(5); - expect(dispatch).toHaveBeenCalledWith( - expect.objectContaining({ - payload: { - completed: false, - step: expect.any(String), - }, - type: ReduxActionTypes.SIGNPOSTING_STEP_UPDATE_INIT, - }), - ); - }); - - it("on completing first step", async () => { - renderComponent(getStore(1)); - expect(dispatch).toHaveBeenNthCalledWith( - 1, - signpostingStepUpdateInit({ - step: SIGNPOSTING_STEP.CONNECT_A_DATASOURCE, - completed: true, - }), - ); - }); - - it("on completing second step", async () => { - renderComponent(getStore(2)); - expect(dispatch).toHaveBeenNthCalledWith( - 2, - signpostingStepUpdateInit({ - step: SIGNPOSTING_STEP.CREATE_A_QUERY, - completed: true, - }), - ); - }); - - it("on completing third step", async () => { - renderComponent(getStore(3)); - expect(dispatch).toHaveBeenNthCalledWith( - 3, - signpostingStepUpdateInit({ - step: SIGNPOSTING_STEP.ADD_WIDGETS, - completed: true, - }), - ); - }); - - it("on completing fourth step", async () => { - const isWidgetActionConnectionPresentSelector = jest.spyOn( - onboardingSelectors, - "isWidgetActionConnectionPresent", - ); - - isWidgetActionConnectionPresentSelector.mockImplementation(() => { - return true; - }); - renderComponent(getStore(4)); - expect(dispatch).toHaveBeenNthCalledWith( - 4, - signpostingStepUpdateInit({ - step: SIGNPOSTING_STEP.CONNECT_DATA_TO_WIDGET, - completed: true, - }), - ); - }); - - it("on completing fifth step", async () => { - renderComponent(getStore(5)); - expect(dispatch).toHaveBeenNthCalledWith( - 5, - signpostingStepUpdateInit({ - step: SIGNPOSTING_STEP.DEPLOY_APPLICATIONS, - completed: true, - }), - ); - }); - - it("should test useIsWidgetActionConnectionPresent function", () => { - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const store = getStore(4).getState() as any; - const isWidgetActionConnectionPresentHelper = () => { - return originalOnboardingSelectors.isWidgetActionConnectionPresent.resultFunc( - store.entities.canvasWidgets, - store.entities.actions, - store.evaluations.dependencies.inverseDependencyMap, - ); - }; - - //Both property and trigger dependency present - expect(isWidgetActionConnectionPresentHelper()).toBe(true); - //only trigger dependency present - store.evaluations.dependencies.inverseDependencyMap = {}; - expect(isWidgetActionConnectionPresentHelper()).toBe(true); - //no dependency present - store.entities.canvasWidgets = {}; - store.entities.actions = []; - expect(isWidgetActionConnectionPresentHelper()).toBe(false); - //only trigger dependency present - store.entities.canvasWidgets = { - [Math.random()]: { - widgetName: "widget", - onClick: "{{Query.run()}}", - dynamicTriggerPathList: [ - { - key: "onClick", - }, - ], - text: "{{Query.data}}", - }, - }; - store.entities.actions = [ - { - config: { - id: Math.random(), - pageId: 1, - name: "Query", - }, - }, - ]; - expect(isWidgetActionConnectionPresentHelper()).toBe(true); - //no dependency present - store.entities.canvasWidgets = {}; - store.entities.actions = []; - expect(isWidgetActionConnectionPresentHelper()).toBe(false); - //only nested trigger dependency present - store.entities.canvasWidgets = { - [Math.random()]: { - widgetName: "widget", - column: { - onClick: "{{Query.run()}}", - }, - dynamicTriggerPathList: [ - { - key: "column.onClick", - }, - ], - text: "label", - }, - }; - store.entities.actions = [ - { - config: { - id: Math.random(), - pageId: 1, - name: "Query", - }, - }, - ]; - expect(isWidgetActionConnectionPresentHelper()).toBe(true); - //no dependency present - store.entities.canvasWidgets = {}; - store.entities.actions = []; - expect(isWidgetActionConnectionPresentHelper()).toBe(false); - //only property dependency present - store.entities.canvasWidgets = { - [Math.random()]: { - widgetName: "widget", - dynamicTriggerPathList: [], - text: "{{Query.data}}", - }, - }; - store.entities.actions = [ - { - config: { - id: Math.random(), - pageId: 1, - name: "Query", - }, - }, - ]; - store.evaluations.dependencies.inverseDependencyMap = { - "Query.data": ["Query", "widget.text"], - }; - expect(isWidgetActionConnectionPresentHelper()).toBe(true); - }); -}); diff --git a/app/client/src/pages/Editor/FirstTimeUserOnboarding/Statusbar.tsx b/app/client/src/pages/Editor/FirstTimeUserOnboarding/Statusbar.tsx deleted file mode 100644 index c073e8973b27..000000000000 --- a/app/client/src/pages/Editor/FirstTimeUserOnboarding/Statusbar.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import { useEffect } from "react"; -import { useDispatch, useSelector } from "react-redux"; -import { - getApplicationLastDeployedAt, - getCurrentPageId, -} from "selectors/editorSelectors"; -import { - getCanvasWidgets, - getPageActions, - getSavedDatasources, -} from "ee/selectors/entitiesSelector"; -import { SIGNPOSTING_STEP } from "./Utils"; -import { - getFirstTimeUserOnboardingComplete, - isWidgetActionConnectionPresent, -} from "selectors/onboardingSelectors"; -import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; -import { signpostingStepUpdateInit } from "actions/onboardingActions"; - -const useStatusListener = () => { - const datasources = useSelector(getSavedDatasources); - const pageId = useSelector(getCurrentPageId); - const actions = useSelector(getPageActions(pageId)); - const widgets = useSelector(getCanvasWidgets); - const isConnectionPresent = useSelector(isWidgetActionConnectionPresent); - const isDeployed = !!useSelector(getApplicationLastDeployedAt); - const isFirstTimeUserOnboardingComplete = useSelector( - getFirstTimeUserOnboardingComplete, - ); - const dispatch = useDispatch(); - - let percentage = 0; - - if (datasources.length || actions.length) { - percentage += 20; - } - - if (actions.length) { - percentage += 20; - } - - if (Object.keys(widgets).length > 1) { - percentage += 20; - } - - if (isConnectionPresent) { - percentage += 20; - } - - if (isDeployed) { - percentage += 20; - } - - useEffect(() => { - dispatch( - signpostingStepUpdateInit({ - step: SIGNPOSTING_STEP.CONNECT_A_DATASOURCE, - completed: !!(datasources.length || actions.length), - }), - ); - }, [datasources.length, actions.length]); - - useEffect(() => { - dispatch( - signpostingStepUpdateInit({ - step: SIGNPOSTING_STEP.CREATE_A_QUERY, - completed: !!actions.length, - }), - ); - }, [actions.length]); - - useEffect(() => { - dispatch( - signpostingStepUpdateInit({ - step: SIGNPOSTING_STEP.ADD_WIDGETS, - completed: Object.keys(widgets).length > 1, - }), - ); - }, [Object.keys(widgets).length]); - - useEffect(() => { - dispatch( - signpostingStepUpdateInit({ - step: SIGNPOSTING_STEP.CONNECT_DATA_TO_WIDGET, - completed: isConnectionPresent, - }), - ); - }, [isConnectionPresent]); - - useEffect(() => { - dispatch( - signpostingStepUpdateInit({ - step: SIGNPOSTING_STEP.DEPLOY_APPLICATIONS, - completed: isDeployed, - }), - ); - }, [isDeployed]); - - useEffect(() => { - if (percentage === 100 && !isFirstTimeUserOnboardingComplete) { - dispatch({ - type: ReduxActionTypes.SET_FIRST_TIME_USER_ONBOARDING_COMPLETE, - payload: true, - }); - } - }, [percentage, isFirstTimeUserOnboardingComplete]); -}; - -export function OnboardingStatusbar() { - useStatusListener(); - - return null; -} - -export default OnboardingStatusbar; diff --git a/app/client/src/pages/Editor/Explorer/Pages/AddPageContextMenu.tsx b/app/client/src/pages/Editor/IDE/EditorPane/Pages/AddPageContextMenu.tsx similarity index 100% rename from app/client/src/pages/Editor/Explorer/Pages/AddPageContextMenu.tsx rename to app/client/src/pages/Editor/IDE/EditorPane/Pages/AddPageContextMenu.tsx diff --git a/app/client/src/pages/Editor/Explorer/Pages/PageContextMenu.tsx b/app/client/src/pages/Editor/IDE/EditorPane/Pages/PageContextMenu.tsx similarity index 100% rename from app/client/src/pages/Editor/Explorer/Pages/PageContextMenu.tsx rename to app/client/src/pages/Editor/IDE/EditorPane/Pages/PageContextMenu.tsx diff --git a/app/client/src/pages/Editor/IDE/EditorPane/components/PageElement.tsx b/app/client/src/pages/Editor/IDE/EditorPane/Pages/PageElement.tsx similarity index 98% rename from app/client/src/pages/Editor/IDE/EditorPane/components/PageElement.tsx rename to app/client/src/pages/Editor/IDE/EditorPane/Pages/PageElement.tsx index cb880183451b..dcac18c33895 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/components/PageElement.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/Pages/PageElement.tsx @@ -7,7 +7,7 @@ import { defaultPageIcon, pageIcon } from "pages/Editor/Explorer/ExplorerIcons"; import { getHasManagePagePermission } from "ee/utils/BusinessFeatures/permissionPageHelpers"; import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; -import PageContextMenu from "pages/Editor/Explorer/Pages/PageContextMenu"; +import PageContextMenu from "./PageContextMenu"; import { getCurrentApplicationId, getCurrentPageId, diff --git a/app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx b/app/client/src/pages/Editor/IDE/EditorPane/Pages/PagesSection.tsx similarity index 95% rename from app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx rename to app/client/src/pages/Editor/IDE/EditorPane/Pages/PagesSection.tsx index b1ecd0dd7ede..56c9bf93b7d5 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/Pages/PagesSection.tsx @@ -13,11 +13,11 @@ import { EntityClassNames } from "pages/Editor/Explorer/Entity"; import { getCurrentApplication } from "ee/selectors/applicationSelectors"; import type { AppState } from "ee/reducers"; import { createNewPageFromEntities } from "actions/pageActions"; -import AddPageContextMenu from "pages/Editor/Explorer/Pages/AddPageContextMenu"; +import AddPageContextMenu from "./AddPageContextMenu"; import { getNextEntityName } from "utils/AppsmithUtils"; import { getCurrentWorkspaceId } from "ee/selectors/selectedWorkspaceSelectors"; import { getInstanceId } from "ee/selectors/tenantSelectors"; -import { PageElement } from "pages/Editor/IDE/EditorPane/components/PageElement"; +import { PageElement } from "./PageElement"; import { PAGE_ENTITY_NAME } from "ee/constants/messages"; const PagesSection = ({ onItemSelected }: { onItemSelected: () => void }) => { diff --git a/app/client/src/pages/Editor/IDE/Header/EditorTitle.tsx b/app/client/src/pages/Editor/IDE/Header/EditorTitle.tsx index 327b6f72ed35..8817dced4805 100644 --- a/app/client/src/pages/Editor/IDE/Header/EditorTitle.tsx +++ b/app/client/src/pages/Editor/IDE/Header/EditorTitle.tsx @@ -2,7 +2,7 @@ import React from "react"; import { IDEHeaderSwitcher } from "@appsmith/ads"; import { createMessage, HEADER_TITLES } from "ee/constants/messages"; -import { PagesSection } from "../EditorPane/PagesSection"; +import { PagesSection } from "../EditorPane/Pages/PagesSection"; import { useBoolean } from "usehooks-ts"; import { useSelector } from "react-redux"; import { getCurrentPageId, getPageById } from "selectors/editorSelectors"; diff --git a/app/client/src/pages/Editor/WidgetsEditorEntityExplorer.tsx b/app/client/src/pages/Editor/WidgetsEditorEntityExplorer.tsx deleted file mode 100644 index 7826c0a6fac0..000000000000 --- a/app/client/src/pages/Editor/WidgetsEditorEntityExplorer.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from "react"; -import { useSelector } from "react-redux"; - -import EntityProperties from "./Explorer/Entity/EntityProperties"; -import Explorer from "./Explorer"; -import OnboardingStatusbar from "./FirstTimeUserOnboarding/Statusbar"; -import Pages from "./Explorer/Pages"; -import EntityExplorerSidebar from "components/editorComponents/EntityExplorerSidebar"; -import { getIsFirstTimeUserOnboardingEnabled } from "selectors/onboardingSelectors"; - -function WidgetsEditorEntityExplorer() { - const enableFirstTimeUserOnboarding = useSelector( - getIsFirstTimeUserOnboardingEnabled, - ); - - return ( - - {enableFirstTimeUserOnboarding && } - {/* PagesContainer */} - - {/* Popover that contains the bindings info */} - - {/* Contains entity explorer & widgets library along with a switcher*/} - - - ); -} - -export default WidgetsEditorEntityExplorer; From e85d5e900efcd9a947dc589e4f7824b62da6a13e Mon Sep 17 00:00:00 2001 From: Ankita Kinger Date: Fri, 24 Jan 2025 13:43:03 +0530 Subject: [PATCH 2/5] removing unused functions and constants --- app/client/src/actions/onboardingActions.ts | 22 --- .../src/ce/constants/ReduxActionConstants.tsx | 4 - .../ce/reducers/uiReducers/explorerReducer.ts | 23 ---- .../Common/EntityExplorerResizeHandler.tsx | 42 ------ .../Explorer/Common/EntityExplorerWrapper.tsx | 25 ---- .../Explorer/Common/ExplorerWrapper.tsx | 10 -- .../Editor/Explorer/Common/components.tsx | 5 - .../Editor/Explorer/Widgets/WidgetGroup.tsx | 125 ------------------ .../FirstTimeUserOnboarding/constants.ts | 10 -- .../uiReducers/appSettingsPaneReducer.ts | 19 --- .../reducers/uiReducers/onBoardingReducer.ts | 20 --- app/client/src/sagas/OnboardingSagas.ts | 47 ------- 12 files changed, 352 deletions(-) delete mode 100644 app/client/src/pages/Editor/Explorer/Common/EntityExplorerResizeHandler.tsx delete mode 100644 app/client/src/pages/Editor/Explorer/Common/EntityExplorerWrapper.tsx delete mode 100644 app/client/src/pages/Editor/Explorer/Common/ExplorerWrapper.tsx delete mode 100644 app/client/src/pages/Editor/Explorer/Widgets/WidgetGroup.tsx diff --git a/app/client/src/actions/onboardingActions.ts b/app/client/src/actions/onboardingActions.ts index 2f3412a871ad..59c907edbde5 100644 --- a/app/client/src/actions/onboardingActions.ts +++ b/app/client/src/actions/onboardingActions.ts @@ -1,5 +1,4 @@ import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; -import type { SIGNPOSTING_STEP } from "pages/Editor/FirstTimeUserOnboarding/Utils"; export const toggleInOnboardingWidgetSelection = (payload: boolean) => { return { @@ -58,27 +57,6 @@ export const signpostingMarkAllRead = () => { }; }; -export const signpostingStepUpdateInit = (payload: { - step: SIGNPOSTING_STEP; - completed: boolean; -}) => { - return { - type: ReduxActionTypes.SIGNPOSTING_STEP_UPDATE_INIT, - payload, - }; -}; - -export const signpostingStepUpdate = (payload: { - step: SIGNPOSTING_STEP; - completed: boolean; - read?: boolean; -}) => { - return { - type: ReduxActionTypes.SIGNPOSTING_STEP_UPDATE, - payload, - }; -}; - export const showSignpostingTooltip = (payload: boolean) => { return { type: ReduxActionTypes.SIGNPOSTING_SHOW_TOOLTIP, diff --git a/app/client/src/ce/constants/ReduxActionConstants.tsx b/app/client/src/ce/constants/ReduxActionConstants.tsx index bcb0b248ce1e..a25e2fc70c60 100644 --- a/app/client/src/ce/constants/ReduxActionConstants.tsx +++ b/app/client/src/ce/constants/ReduxActionConstants.tsx @@ -389,8 +389,6 @@ const OnboardingActionTypes = { UNDO_END_FIRST_TIME_USER_ONBOARDING: "UNDO_END_FIRST_TIME_USER_ONBOARDING", SET_SIGNPOSTING_OVERLAY: "SET_SIGNPOSTING_OVERLAY", SIGNPOSTING_MARK_ALL_READ: "SIGNPOSTING_MARK_ALL_READ", - SIGNPOSTING_STEP_UPDATE_INIT: "SIGNPOSTING_STEP_UPDATE_INIT", - SIGNPOSTING_STEP_UPDATE: "SIGNPOSTING_STEP_UPDATE", SIGNPOSTING_SHOW_TOOLTIP: "SIGNPOSTING_SHOW_TOOLTIP", SHOW_ANONYMOUS_DATA_POPUP: "SHOW_ANONYMOUS_DATA_POPUP", FIRST_TIME_USER_ONBOARDING_INIT: "FIRST_TIME_USER_ONBOARDING_INIT", @@ -1190,8 +1188,6 @@ const AppThemeActionErrorTypes = { }; const AppSettingsActionTypes = { - OPEN_APP_SETTINGS_PANE: "OPEN_APP_SETTINGS_PANE", - CLOSE_APP_SETTINGS_PANE: "CLOSE_APP_SETTINGS_PANE", UPDATE_APP_SETTINGS_PANE_SELECTED_TAB: "UPDATE_APP_SETTINGS_PANE_SELECTED_TAB", }; diff --git a/app/client/src/ce/reducers/uiReducers/explorerReducer.ts b/app/client/src/ce/reducers/uiReducers/explorerReducer.ts index 79875226f326..7b7867c70ab0 100644 --- a/app/client/src/ce/reducers/uiReducers/explorerReducer.ts +++ b/app/client/src/ce/reducers/uiReducers/explorerReducer.ts @@ -196,29 +196,6 @@ export const handlers = { active: action.payload, }; }, - [ReduxActionTypes.OPEN_APP_SETTINGS_PANE]: ( - state: ExplorerReduxState, - ): ExplorerReduxState => { - return { - ...state, - pinnedState: - state.pinnedState === ExplorerPinnedState.PINNED - ? ExplorerPinnedState.HIDDEN - : state.pinnedState, - active: false, - }; - }, - [ReduxActionTypes.CLOSE_APP_SETTINGS_PANE]: ( - state: ExplorerReduxState, - ): ExplorerReduxState => { - return { - ...state, - pinnedState: - state.pinnedState === ExplorerPinnedState.HIDDEN - ? ExplorerPinnedState.PINNED - : state.pinnedState, - }; - }, }; const explorerReducer = createReducer(initialState, handlers); diff --git a/app/client/src/pages/Editor/Explorer/Common/EntityExplorerResizeHandler.tsx b/app/client/src/pages/Editor/Explorer/Common/EntityExplorerResizeHandler.tsx deleted file mode 100644 index 9e4fb680ca57..000000000000 --- a/app/client/src/pages/Editor/Explorer/Common/EntityExplorerResizeHandler.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { tailwindLayers } from "constants/Layers"; -import React from "react"; -import styled from "styled-components"; -import type { CallbackResponseType } from "utils/hooks/useResize"; -import useResize, { DIRECTION } from "utils/hooks/useResize"; - -const ResizeHandler = styled.div` - &:hover { - background-color: var(--ads-v2-color-border); - } -`; - -export const EntityExplorerResizeHandler = ({ - resizeRef, - storedHeightKey, -}: { - resizeRef: React.RefObject; - storedHeightKey: string; -}) => { - const resizeAfterCallback = (data: CallbackResponseType) => { - localStorage.setItem(storedHeightKey, data.height.toString()); - }; - - const { mouseDown, setMouseDown } = useResize( - resizeRef, - DIRECTION.vertical, - resizeAfterCallback, - ); - - return ( -
setMouseDown(true)} - > - -
- ); -}; diff --git a/app/client/src/pages/Editor/Explorer/Common/EntityExplorerWrapper.tsx b/app/client/src/pages/Editor/Explorer/Common/EntityExplorerWrapper.tsx deleted file mode 100644 index 2866dc162bf9..000000000000 --- a/app/client/src/pages/Editor/Explorer/Common/EntityExplorerWrapper.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from "react"; -import styled from "styled-components"; - -const Wrapper = styled.div` - height: 100%; - overflow-y: auto; - -ms-overflow-style: none; -`; - -export const EntityExplorerWrapper = (props: { - children: React.ReactNode; - explorerRef: React.RefObject; - isActive: boolean; -}) => { - return ( - - {props.children} - - ); -}; diff --git a/app/client/src/pages/Editor/Explorer/Common/ExplorerWrapper.tsx b/app/client/src/pages/Editor/Explorer/Common/ExplorerWrapper.tsx deleted file mode 100644 index 01c292f6cc96..000000000000 --- a/app/client/src/pages/Editor/Explorer/Common/ExplorerWrapper.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from "react"; -import { tailwindLayers } from "constants/Layers"; - -export const ExplorerWrapper = (props: { children: React.ReactNode }) => ( -
- {props.children} -
-); diff --git a/app/client/src/pages/Editor/Explorer/Common/components.tsx b/app/client/src/pages/Editor/Explorer/Common/components.tsx index d72fac82c317..ec45dcde4738 100644 --- a/app/client/src/pages/Editor/Explorer/Common/components.tsx +++ b/app/client/src/pages/Editor/Explorer/Common/components.tsx @@ -1,13 +1,8 @@ import styled from "styled-components"; import Entity, { EntityClassNames } from "../Entity"; -export const ENTITY_HEIGHT = 36; export const MIN_PAGES_HEIGHT = 60; -export const RelativeContainer = styled.div` - position: relative; -`; - export const StyledEntity = styled(Entity)<{ entitySize?: number }>` &.page.fullWidth { width: 100%; diff --git a/app/client/src/pages/Editor/Explorer/Widgets/WidgetGroup.tsx b/app/client/src/pages/Editor/Explorer/Widgets/WidgetGroup.tsx deleted file mode 100644 index 46239a22ca15..000000000000 --- a/app/client/src/pages/Editor/Explorer/Widgets/WidgetGroup.tsx +++ /dev/null @@ -1,125 +0,0 @@ -import React, { memo, useCallback, useMemo } from "react"; -import { useSelector } from "react-redux"; -import Entity from "../Entity"; -import WidgetEntity from "./WidgetEntity"; -import { - getCurrentApplicationId, - getCurrentBasePageId, - getPagePermissions, -} from "selectors/editorSelectors"; -import { - ADD_WIDGET_BUTTON, - ADD_WIDGET_TOOLTIP, - createMessage, - EMPTY_WIDGET_BUTTON_TEXT, - EMPTY_WIDGET_MAIN_TEXT, -} from "ee/constants/messages"; -import { selectWidgetsForCurrentPage } from "ee/selectors/entitiesSelector"; -import { - getExplorerStatus, - saveExplorerStatus, -} from "ee/pages/Editor/Explorer/helpers"; -import { AddEntity, EmptyComponent } from "../common"; -import { noop } from "lodash"; -import { Icon } from "@appsmith/ads"; -import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; -import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; -import { getHasManagePagePermission } from "ee/utils/BusinessFeatures/permissionPageHelpers"; - -interface ExplorerWidgetGroupProps { - step: number; - searchKeyword?: string; - addWidgetsFn?: () => void; -} - -export const ExplorerWidgetGroup = memo((props: ExplorerWidgetGroupProps) => { - const applicationId = useSelector(getCurrentApplicationId); - const basePageId = useSelector(getCurrentBasePageId) || ""; - const widgets = useSelector(selectWidgetsForCurrentPage); - let isWidgetsOpen = getExplorerStatus(applicationId, "widgets"); - - if (isWidgetsOpen === null || isWidgetsOpen === undefined) { - isWidgetsOpen = widgets?.children?.length === 0; - saveExplorerStatus(applicationId, "widgets", isWidgetsOpen); - } - - const widgetsInStep = useMemo(() => { - return widgets?.children?.map((child) => child.widgetId) || []; - }, [widgets?.children]); - - const onWidgetToggle = useCallback( - (isOpen: boolean) => { - saveExplorerStatus(applicationId, "widgets", isOpen); - }, - [applicationId], - ); - - const pagePermissions = useSelector(getPagePermissions); - - const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); - - const canManagePages = getHasManagePagePermission( - isFeatureEnabled, - pagePermissions, - ); - - return ( - - {widgets?.children?.map((child) => ( - - ))} - {(!widgets?.children || widgets?.children.length === 0) && - !props.searchKeyword && ( - - )} - {widgets?.children && widgets?.children?.length > 0 && canManagePages && ( - } - name={createMessage(ADD_WIDGET_BUTTON)} - step={props.step + 1} - /> - )} - - ); -}); - -ExplorerWidgetGroup.displayName = "ExplorerWidgetGroup"; -// TODO: Fix this the next time the file is edited -// eslint-disable-next-line @typescript-eslint/no-explicit-any -(ExplorerWidgetGroup as any).whyDidYouRender = { - logOnDifferentValues: false, -}; - -export default ExplorerWidgetGroup; diff --git a/app/client/src/pages/Editor/FirstTimeUserOnboarding/constants.ts b/app/client/src/pages/Editor/FirstTimeUserOnboarding/constants.ts index 6b207add1157..22c1f646a704 100644 --- a/app/client/src/pages/Editor/FirstTimeUserOnboarding/constants.ts +++ b/app/client/src/pages/Editor/FirstTimeUserOnboarding/constants.ts @@ -1,16 +1,6 @@ -import { SIGNPOSTING_STEP } from "./Utils"; - //Hide Anonymous Data Popup after 15 seconds export const ANONYMOUS_DATA_POPOP_TIMEOUT = 15000; //Telemetry Docs Page export const TELEMETRY_DOCS_PAGE_URL = "https://docs.appsmith.com/product/telemetry"; - -export const SIGNPOSTING_ANALYTICS_STEP_NAME = { - [SIGNPOSTING_STEP.CONNECT_A_DATASOURCE]: "Connect to datasource", - [SIGNPOSTING_STEP.CREATE_A_QUERY]: "Created query", - [SIGNPOSTING_STEP.ADD_WIDGETS]: "Created Widget", - [SIGNPOSTING_STEP.CONNECT_DATA_TO_WIDGET]: "Binding success", - [SIGNPOSTING_STEP.DEPLOY_APPLICATIONS]: "Deployed app", -}; diff --git a/app/client/src/reducers/uiReducers/appSettingsPaneReducer.ts b/app/client/src/reducers/uiReducers/appSettingsPaneReducer.ts index c49045b8bfcd..17689a2b4cf3 100644 --- a/app/client/src/reducers/uiReducers/appSettingsPaneReducer.ts +++ b/app/client/src/reducers/uiReducers/appSettingsPaneReducer.ts @@ -11,25 +11,6 @@ const initialState: AppSettingsPaneReduxState = { }; const appSettingsPaneReducer = createReducer(initialState, { - [ReduxActionTypes.OPEN_APP_SETTINGS_PANE]: ( - state: AppSettingsPaneReduxState, - action: ReduxAction, - ): AppSettingsPaneReduxState => { - return { - ...state, - isOpen: true, - context: action.payload, - }; - }, - [ReduxActionTypes.CLOSE_APP_SETTINGS_PANE]: ( - state: AppSettingsPaneReduxState, - ): AppSettingsPaneReduxState => { - return { - ...state, - isOpen: false, - context: undefined, - }; - }, [ReduxActionTypes.UPDATE_APP_SETTINGS_PANE_SELECTED_TAB]: ( state: AppSettingsPaneReduxState, action: ReduxAction, diff --git a/app/client/src/reducers/uiReducers/onBoardingReducer.ts b/app/client/src/reducers/uiReducers/onBoardingReducer.ts index 7f3c295713ac..41be43fdbac1 100644 --- a/app/client/src/reducers/uiReducers/onBoardingReducer.ts +++ b/app/client/src/reducers/uiReducers/onBoardingReducer.ts @@ -77,26 +77,6 @@ const onboardingReducer = createReducer(initialState, { ) => { return { ...state, forceOpenWidgetPanel: action.payload }; }, - [ReduxActionTypes.SIGNPOSTING_STEP_UPDATE]: ( - state: OnboardingState, - action: ReduxAction, - ) => { - const index = state.stepState.findIndex( - (stepState) => stepState.step === action.payload.step, - ); - const newArray = [...state.stepState]; - - if (index >= 0) { - newArray[index] = action.payload; - } else { - newArray.push(action.payload); - } - - return { - ...state, - stepState: newArray, - }; - }, [ReduxActionTypes.SIGNPOSTING_MARK_ALL_READ]: (state: OnboardingState) => { return { ...state, diff --git a/app/client/src/sagas/OnboardingSagas.ts b/app/client/src/sagas/OnboardingSagas.ts index 3e8389329478..8e9c8b84e6c0 100644 --- a/app/client/src/sagas/OnboardingSagas.ts +++ b/app/client/src/sagas/OnboardingSagas.ts @@ -22,13 +22,10 @@ import { import { getCurrentUser } from "selectors/usersSelectors"; import history from "utils/history"; -import { getSignpostingStepStateByStep } from "selectors/onboardingSelectors"; import { disableStartSignpostingAction, removeFirstTimeUserOnboardingApplicationId as removeFirstTimeUserOnboardingApplicationIdAction, setSignpostingOverlay, - showSignpostingTooltip, - signpostingStepUpdate, } from "actions/onboardingActions"; import { getCurrentApplicationId, @@ -37,11 +34,7 @@ import { import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import type { User } from "constants/userConstants"; import { builderURL } from "ee/RouteBuilder"; -import type { SIGNPOSTING_STEP } from "pages/Editor/FirstTimeUserOnboarding/Utils"; -import type { StepState } from "reducers/uiReducers/onBoardingReducer"; -import { isUndefined } from "lodash"; import { isAirgapped } from "ee/utils/airgapHelpers"; -import { SIGNPOSTING_ANALYTICS_STEP_NAME } from "pages/Editor/FirstTimeUserOnboarding/constants"; // Signposting sagas function* setFirstTimeUserOnboardingApplicationId(action: ReduxAction) { @@ -150,42 +143,6 @@ function* disableStartFirstTimeUserOnboardingSaga() { yield call(setEnableStartSignposting, false); } -function* setSignpostingStepStateSaga( - action: ReduxAction<{ step: SIGNPOSTING_STEP; completed: boolean }>, -) { - const { completed, step } = action.payload; - const stepState: StepState | undefined = yield select( - getSignpostingStepStateByStep, - step, - ); - - // No changes to update so we ignore - if (stepState && stepState.completed === completed) return; - - const readProps = completed - ? { - read: false, - } - : {}; - - yield put( - signpostingStepUpdate({ - ...action.payload, - ...readProps, - }), - ); - - // Show tooltip when a step is completed - if (!isUndefined(readProps.read) && !readProps.read) { - // Show tooltip after a small delay to not be abrupt - yield delay(1000); - AnalyticsUtil.logEvent("SIGNPOSTING_STEP_COMPLETE", { - step_name: SIGNPOSTING_ANALYTICS_STEP_NAME[step], - }); - yield put(showSignpostingTooltip(true)); - } -} - export default function* onboardingActionSagas() { yield all([ takeLatest( @@ -216,9 +173,5 @@ export default function* onboardingActionSagas() { ReduxActionTypes.DISABLE_START_SIGNPOSTING, disableStartFirstTimeUserOnboardingSaga, ), - takeLatest( - ReduxActionTypes.SIGNPOSTING_STEP_UPDATE_INIT, - setSignpostingStepStateSaga, - ), ]); } From b36745dec2901c8da92f1f53bd831bb32146d8fd Mon Sep 17 00:00:00 2001 From: Ankita Kinger Date: Fri, 24 Jan 2025 13:57:00 +0530 Subject: [PATCH 3/5] removing unused hoo --- app/client/src/utils/hooks/useResize.tsx | 79 ------------------------ 1 file changed, 79 deletions(-) delete mode 100644 app/client/src/utils/hooks/useResize.tsx diff --git a/app/client/src/utils/hooks/useResize.tsx b/app/client/src/utils/hooks/useResize.tsx deleted file mode 100644 index 92ba30b4770c..000000000000 --- a/app/client/src/utils/hooks/useResize.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import type { MutableRefObject } from "react"; -import React from "react"; - -export enum DIRECTION { - vertical, - horizontal, -} - -export interface CallbackResponseType { - height: number; - width: number; -} - -function useResize( - ref: MutableRefObject, - direction: DIRECTION, - afterResizeCallback?: (data: CallbackResponseType) => void, -) { - const [mouseDown, setMouseDown] = React.useState(false); - - const pointer = - direction === DIRECTION.vertical ? "cursor-ns-resize" : "cursor-ew-resize"; - - const onMouseMove = (e: MouseEvent) => { - document.body.classList.add(pointer); - - if (ref.current) { - // below lines stop selection of texts - if (e.stopPropagation) e.stopPropagation(); - - if (e.preventDefault) e.preventDefault(); - - const { bottom, left, right, top } = ref.current.getBoundingClientRect(); - - const currentMouseYPosition = e.clientY; - const currentMouseXPosition = e.clientX; - - const distanceYDragged = currentMouseYPosition - bottom; - const distanceXDragged = currentMouseXPosition - right; - - const currentHeight = bottom - top; - const currentWidth = right - left; - - const newHeight = currentHeight + distanceYDragged; - const newWidth = currentWidth + distanceXDragged; - - if (direction === DIRECTION.vertical) { - ref.current.style.height = newHeight + "px"; - } else { - ref.current.style.width = newWidth + "px"; - } - - if (afterResizeCallback) { - afterResizeCallback({ height: newHeight, width: newWidth }); - } - } - }; - - const onMouseUp = () => { - setMouseDown(false); - document.body.classList.remove(pointer); - }; - - React.useEffect(() => { - if (mouseDown) { - document.addEventListener("mousemove", onMouseMove); - document.addEventListener("mouseup", onMouseUp); - } - - return () => { - document.removeEventListener("mousemove", onMouseMove); - document.removeEventListener("mouseup", onMouseUp); - }; - }, [mouseDown]); - - return { mouseDown, setMouseDown }; -} - -export default useResize; From a2176f33008474e66cac54e038086cac2bc0c3f2 Mon Sep 17 00:00:00 2001 From: Ankita Kinger Date: Fri, 24 Jan 2025 14:04:21 +0530 Subject: [PATCH 4/5] adding back components still being used in EE --- .../Common/EntityExplorerResizeHandler.tsx | 44 +++++++++++ .../Explorer/Common/EntityExplorerWrapper.tsx | 25 ++++++ .../Explorer/Common/ExplorerWrapper.tsx | 10 +++ .../Editor/Explorer/Common/components.tsx | 4 + .../EditorPane/Pages/AddPageContextMenu.tsx | 7 +- app/client/src/utils/hooks/useResize.tsx | 79 +++++++++++++++++++ 6 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 app/client/src/pages/Editor/Explorer/Common/EntityExplorerResizeHandler.tsx create mode 100644 app/client/src/pages/Editor/Explorer/Common/EntityExplorerWrapper.tsx create mode 100644 app/client/src/pages/Editor/Explorer/Common/ExplorerWrapper.tsx create mode 100644 app/client/src/utils/hooks/useResize.tsx diff --git a/app/client/src/pages/Editor/Explorer/Common/EntityExplorerResizeHandler.tsx b/app/client/src/pages/Editor/Explorer/Common/EntityExplorerResizeHandler.tsx new file mode 100644 index 000000000000..d8aa2cf21a31 --- /dev/null +++ b/app/client/src/pages/Editor/Explorer/Common/EntityExplorerResizeHandler.tsx @@ -0,0 +1,44 @@ +import { tailwindLayers } from "constants/Layers"; +import React from "react"; +import styled from "styled-components"; +import useResize, { + DIRECTION, + type CallbackResponseType, +} from "utils/hooks/useResize"; + +const ResizeHandler = styled.div` + &:hover { + background-color: var(--ads-v2-color-border); + } +`; + +export const EntityExplorerResizeHandler = ({ + resizeRef, + storedHeightKey, +}: { + resizeRef: React.RefObject; + storedHeightKey: string; +}) => { + const resizeAfterCallback = (data: CallbackResponseType) => { + localStorage.setItem(storedHeightKey, data.height.toString()); + }; + + const { mouseDown, setMouseDown } = useResize( + resizeRef, + DIRECTION.vertical, + resizeAfterCallback, + ); + + return ( +
setMouseDown(true)} + > + +
+ ); +}; diff --git a/app/client/src/pages/Editor/Explorer/Common/EntityExplorerWrapper.tsx b/app/client/src/pages/Editor/Explorer/Common/EntityExplorerWrapper.tsx new file mode 100644 index 000000000000..2866dc162bf9 --- /dev/null +++ b/app/client/src/pages/Editor/Explorer/Common/EntityExplorerWrapper.tsx @@ -0,0 +1,25 @@ +import React from "react"; +import styled from "styled-components"; + +const Wrapper = styled.div` + height: 100%; + overflow-y: auto; + -ms-overflow-style: none; +`; + +export const EntityExplorerWrapper = (props: { + children: React.ReactNode; + explorerRef: React.RefObject; + isActive: boolean; +}) => { + return ( + + {props.children} + + ); +}; diff --git a/app/client/src/pages/Editor/Explorer/Common/ExplorerWrapper.tsx b/app/client/src/pages/Editor/Explorer/Common/ExplorerWrapper.tsx new file mode 100644 index 000000000000..01c292f6cc96 --- /dev/null +++ b/app/client/src/pages/Editor/Explorer/Common/ExplorerWrapper.tsx @@ -0,0 +1,10 @@ +import React from "react"; +import { tailwindLayers } from "constants/Layers"; + +export const ExplorerWrapper = (props: { children: React.ReactNode }) => ( +
+ {props.children} +
+); diff --git a/app/client/src/pages/Editor/Explorer/Common/components.tsx b/app/client/src/pages/Editor/Explorer/Common/components.tsx index ec45dcde4738..270c003f3c4d 100644 --- a/app/client/src/pages/Editor/Explorer/Common/components.tsx +++ b/app/client/src/pages/Editor/Explorer/Common/components.tsx @@ -3,6 +3,10 @@ import Entity, { EntityClassNames } from "../Entity"; export const MIN_PAGES_HEIGHT = 60; +export const RelativeContainer = styled.div` + position: relative; +`; + export const StyledEntity = styled(Entity)<{ entitySize?: number }>` &.page.fullWidth { width: 100%; diff --git a/app/client/src/pages/Editor/IDE/EditorPane/Pages/AddPageContextMenu.tsx b/app/client/src/pages/Editor/IDE/EditorPane/Pages/AddPageContextMenu.tsx index e1501da44948..804b04f23a61 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/Pages/AddPageContextMenu.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/Pages/AddPageContextMenu.tsx @@ -1,6 +1,9 @@ import React, { useMemo, useState } from "react"; -import { AddButtonWrapper, EntityClassNames } from "../Entity"; -import EntityAddButton from "../Entity/AddButton"; +import { + AddButtonWrapper, + EntityClassNames, +} from "pages/Editor/Explorer/Entity"; +import EntityAddButton from "pages/Editor/Explorer/Entity/AddButton"; import styled from "styled-components"; import { useParams } from "react-router"; import { useDispatch } from "react-redux"; diff --git a/app/client/src/utils/hooks/useResize.tsx b/app/client/src/utils/hooks/useResize.tsx new file mode 100644 index 000000000000..92ba30b4770c --- /dev/null +++ b/app/client/src/utils/hooks/useResize.tsx @@ -0,0 +1,79 @@ +import type { MutableRefObject } from "react"; +import React from "react"; + +export enum DIRECTION { + vertical, + horizontal, +} + +export interface CallbackResponseType { + height: number; + width: number; +} + +function useResize( + ref: MutableRefObject, + direction: DIRECTION, + afterResizeCallback?: (data: CallbackResponseType) => void, +) { + const [mouseDown, setMouseDown] = React.useState(false); + + const pointer = + direction === DIRECTION.vertical ? "cursor-ns-resize" : "cursor-ew-resize"; + + const onMouseMove = (e: MouseEvent) => { + document.body.classList.add(pointer); + + if (ref.current) { + // below lines stop selection of texts + if (e.stopPropagation) e.stopPropagation(); + + if (e.preventDefault) e.preventDefault(); + + const { bottom, left, right, top } = ref.current.getBoundingClientRect(); + + const currentMouseYPosition = e.clientY; + const currentMouseXPosition = e.clientX; + + const distanceYDragged = currentMouseYPosition - bottom; + const distanceXDragged = currentMouseXPosition - right; + + const currentHeight = bottom - top; + const currentWidth = right - left; + + const newHeight = currentHeight + distanceYDragged; + const newWidth = currentWidth + distanceXDragged; + + if (direction === DIRECTION.vertical) { + ref.current.style.height = newHeight + "px"; + } else { + ref.current.style.width = newWidth + "px"; + } + + if (afterResizeCallback) { + afterResizeCallback({ height: newHeight, width: newWidth }); + } + } + }; + + const onMouseUp = () => { + setMouseDown(false); + document.body.classList.remove(pointer); + }; + + React.useEffect(() => { + if (mouseDown) { + document.addEventListener("mousemove", onMouseMove); + document.addEventListener("mouseup", onMouseUp); + } + + return () => { + document.removeEventListener("mousemove", onMouseMove); + document.removeEventListener("mouseup", onMouseUp); + }; + }, [mouseDown]); + + return { mouseDown, setMouseDown }; +} + +export default useResize; From 57771b00bdbe5d214f8aec744bdd9cbdbc541fb0 Mon Sep 17 00:00:00 2001 From: Ankita Kinger Date: Fri, 24 Jan 2025 16:34:29 +0530 Subject: [PATCH 5/5] renaming a test file and moving it to another folder --- .../Editor/IDE/EditorPane/UI/List.test.tsx | 409 ++++++++++++++++++ 1 file changed, 409 insertions(+) create mode 100644 app/client/src/pages/Editor/IDE/EditorPane/UI/List.test.tsx diff --git a/app/client/src/pages/Editor/IDE/EditorPane/UI/List.test.tsx b/app/client/src/pages/Editor/IDE/EditorPane/UI/List.test.tsx new file mode 100644 index 000000000000..09b7af082f59 --- /dev/null +++ b/app/client/src/pages/Editor/IDE/EditorPane/UI/List.test.tsx @@ -0,0 +1,409 @@ +import { act, fireEvent, render } from "test/testUtils"; +import { + buildChildren, + widgetCanvasFactory, +} from "test/factories/WidgetFactoryUtils"; +import React from "react"; +import { MockPageDSL } from "test/testCommon"; +import { DEFAULT_ENTITY_EXPLORER_WIDTH } from "constants/AppConstants"; +import { runSagaMiddleware } from "store"; +import urlBuilder from "ee/entities/URLRedirect/URLAssembly"; +import * as explorerSelector from "selectors/explorerSelector"; +import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants"; +import * as widgetSelectionsActions from "actions/widgetSelectionActions"; +import { SelectionRequestType } from "sagas/WidgetSelectUtils"; +import { NavigationMethod } from "utils/history"; +import ListWidgets from "./List"; + +jest.useFakeTimers(); +const pushState = jest.spyOn(window.history, "pushState"); + +// TODO: Fix this the next time the file is edited +// eslint-disable-next-line @typescript-eslint/no-explicit-any +pushState.mockImplementation((state: any, title: any, url: any) => { + window.document.title = title; + window.location.pathname = url; +}); + +jest.mock("ee/utils/permissionHelpers", () => { + return { + __esModule: true, + ...jest.requireActual("ee/utils/permissionHelpers"), + }; +}); + +jest.mock("ee/pages/Editor/Explorer/helpers", () => ({ + __esModule: true, + ...jest.requireActual("ee/pages/Editor/Explorer/helpers"), +})); + +jest.mock("ee/utils/BusinessFeatures/permissionPageHelpers", () => ({ + __esModule: true, + ...jest.requireActual("ee/utils/BusinessFeatures/permissionPageHelpers"), +})); + +jest.mock("selectors/explorerSelector", () => ({ + __esModule: true, + ...jest.requireActual("selectors/explorerSelector"), +})); + +jest + .spyOn(explorerSelector, "getExplorerWidth") + .mockImplementation(() => DEFAULT_ENTITY_EXPLORER_WIDTH); + +const setFocusSearchInput = jest.fn(); + +describe("Widget List in Explorer tests", () => { + beforeAll(() => { + runSagaMiddleware(); + }); + + beforeEach(() => { + urlBuilder.updateURLParams( + { + baseApplicationId: "appId", + applicationSlug: "appSlug", + applicationVersion: 2, + }, + [ + { + basePageId: "pageId", + pageSlug: "pageSlug", + }, + ], + ); + }); + + it("Should render Widgets tree in entity explorer", async () => { + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const children: any = buildChildren([{ type: "TABS_WIDGET" }]); + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const dsl: any = widgetCanvasFactory.build({ + children, + }); + const component = render( + + + , + ); + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const widgetsTree: Element = await component.findByText( + children[0].widgetName, + { + selector: "div.t--entity-name", + }, + { timeout: 3000 }, + ); + + act(() => { + fireEvent.click(widgetsTree); + jest.runAllTimers(); + }); + const tabsWidget = component.queryByText(children[0].widgetName); + + expect(tabsWidget).toBeTruthy(); + }); + + describe("Widget Selection in entity explorer", () => { + const spyWidgetSelection = jest.spyOn( + widgetSelectionsActions, + "selectWidgetInitAction", + ); + + beforeEach(() => { + spyWidgetSelection.mockClear(); + }); + + it("Select widget on entity explorer", async () => { + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const children: any = buildChildren([ + { type: "TABS_WIDGET", widgetId: "tabsWidgetId" }, + ]); + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const dsl: any = widgetCanvasFactory.build({ + children, + }); + const component = render( + + + , + ); + // TODO: Fix this the next time the file is edited + const tabsWidget: Element = await component.findByText( + children[0].widgetName, + undefined, + { timeout: 3000 }, + ); + + act(() => { + fireEvent.click(tabsWidget); + jest.runAllTimers(); + }); + + expect(spyWidgetSelection).toHaveBeenCalledWith( + SelectionRequestType.One, + ["tabsWidgetId"], + NavigationMethod.EntityExplorer, + undefined, + ); + }); + + it("CMD + click Multi Select widget on entity explorer", async () => { + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const children: any = buildChildren([ + { + type: "CHECKBOX_WIDGET", + parentId: "0", + widgetId: "checkboxWidgetId", + }, + { type: "SWITCH_WIDGET", parentId: "0", widgetId: "switchWidgetId" }, + ]); + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const dsl: any = widgetCanvasFactory.build({ + children, + }); + const component = render( + + + , + ); + // TODO: Fix this the next time the file is edited + const checkBox: Element = await component.findByText( + children[0].widgetName, + undefined, + { timeout: 3000 }, + ); + + act(() => { + fireEvent.click(checkBox); + jest.runAllTimers(); + }); + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const switchWidget: any = component.queryByText(children[1].widgetName); + + expect(spyWidgetSelection).toHaveBeenCalledWith( + SelectionRequestType.One, + ["checkboxWidgetId"], + NavigationMethod.EntityExplorer, + undefined, + ); + + act(() => { + fireEvent.click(switchWidget, { + ctrlKey: true, + }); + jest.runAllTimers(); + }); + expect(spyWidgetSelection).toHaveBeenCalledWith( + SelectionRequestType.PushPop, + ["switchWidgetId"], + undefined, + undefined, + ); + }); + + it("Shift + Click Multi Select widget on entity explorer", async () => { + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const children: any = buildChildren([ + { + type: "CHECKBOX_WIDGET", + parentId: "0", + widgetId: "checkboxWidgetId", + }, + { type: "SWITCH_WIDGET", parentId: "0", widgetId: "switchWidgetId" }, + { type: "BUTTON_WIDGET", parentId: "0", widgetId: "buttonWidgetId" }, + ]); + // TODO: Fix this the next time the file is edited + const dsl = widgetCanvasFactory.build({ + children, + }); + const component = render( + + + , + ); + + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const checkboxWidget: any = await component.findByText( + children[0].widgetName, + undefined, + { timeout: 3000 }, + ); + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const buttonWidget: any = component.queryByText(children[2].widgetName); + + act(() => { + fireEvent.click(checkboxWidget); + jest.runAllTimers(); + }); + + expect(spyWidgetSelection).toHaveBeenCalledWith( + SelectionRequestType.One, + ["checkboxWidgetId"], + NavigationMethod.EntityExplorer, + undefined, + ); + + act(() => { + fireEvent.click(buttonWidget, { + shiftKey: true, + }); + jest.runAllTimers(); + }); + + expect(spyWidgetSelection).toHaveBeenCalledWith( + SelectionRequestType.ShiftSelect, + ["buttonWidgetId"], + undefined, + undefined, + ); + }); + + it("Shift + Click Deselect Non Siblings", async () => { + const containerId = "containerWidgetId"; + const canvasId = "canvasWidgetId"; + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const children: any = buildChildren([ + { + type: "CHECKBOX_WIDGET", + parentId: canvasId, + widgetId: "checkboxWidgetId", + }, + { + type: "SWITCH_WIDGET", + parentId: canvasId, + widgetId: "switchWidgetId", + }, + { + type: "BUTTON_WIDGET", + parentId: canvasId, + widgetId: "buttonWidgetId", + }, + ]); + const canvasWidget = buildChildren([ + { + type: "CANVAS_WIDGET", + parentId: containerId, + children, + widgetId: canvasId, + }, + ]); + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const containerChildren: any = buildChildren([ + { + type: "CONTAINER_WIDGET", + children: canvasWidget, + widgetId: containerId, + parentId: MAIN_CONTAINER_WIDGET_ID, + }, + { + type: "CHART_WIDGET", + parentId: MAIN_CONTAINER_WIDGET_ID, + widgetId: "chartWidgetId", + }, + ]); + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const dsl: any = widgetCanvasFactory.build({ + children: containerChildren, + }); + const component = render( + + + , + ); + // TODO: Fix this the next time the file is edited + const containerWidget: Element = await component.findByText( + containerChildren[0].widgetName, + undefined, + { timeout: 3000 }, + ); + + act(() => { + fireEvent.click(containerWidget); + jest.runAllTimers(); + }); + + expect(spyWidgetSelection).toHaveBeenCalledWith( + SelectionRequestType.One, + [containerId], + NavigationMethod.EntityExplorer, + undefined, + ); + + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const collapsible: any = component.container.querySelector( + `.t--entity-collapse-toggle[id="arrow-right-s-line"]`, + ); + + fireEvent.click(collapsible); + + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const buttonWidget: any = component.queryByText(children[2].widgetName); + + act(() => { + fireEvent.click(buttonWidget, { + shiftKey: true, + }); + jest.runAllTimers(); + }); + + expect(spyWidgetSelection).toHaveBeenCalledWith( + SelectionRequestType.ShiftSelect, + ["buttonWidgetId"], + undefined, + undefined, + ); + + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const checkBoxWidget: any = component.queryByText(children[0].widgetName); + + act(() => { + fireEvent.click(checkBoxWidget, { + shiftKey: true, + }); + jest.runAllTimers(); + }); + expect(spyWidgetSelection).toHaveBeenCalledWith( + SelectionRequestType.ShiftSelect, + ["checkboxWidgetId"], + undefined, + undefined, + ); + // TODO: Fix this the next time the file is edited + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const chartWidget: any = component.queryByText( + containerChildren[1].widgetName, + ); + + act(() => { + fireEvent.click(chartWidget, { + shiftKey: true, + }); + jest.runAllTimers(); + }); + expect(spyWidgetSelection).toHaveBeenCalledWith( + SelectionRequestType.ShiftSelect, + ["chartWidgetId"], + undefined, + undefined, + ); + }); + }); +});