From 35deceda8f03eaaf453bc43254b68ed5cb1a29f3 Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Tue, 9 Jan 2024 16:34:11 +0530 Subject: [PATCH 1/8] feat: Added pages section in header --- .../src/pages/Editor/IDE/Header/index.tsx | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/app/client/src/pages/Editor/IDE/Header/index.tsx b/app/client/src/pages/Editor/IDE/Header/index.tsx index 51102efbce6..27e72be1d34 100644 --- a/app/client/src/pages/Editor/IDE/Header/index.tsx +++ b/app/client/src/pages/Editor/IDE/Header/index.tsx @@ -13,6 +13,7 @@ import { Tab, TabPanel, Button, + Icon, } from "design-system"; import { useDispatch, useSelector } from "react-redux"; import { EditInteractionKind, SavingState } from "design-system-old"; @@ -35,6 +36,7 @@ import { getCurrentApplicationId, getCurrentPageId, getIsPublishingApplication, + getPageById, } from "selectors/editorSelectors"; import { getApplicationList, @@ -91,6 +93,7 @@ const Header = () => { const isPublishing = useSelector(getIsPublishingApplication); const isGitConnected = useSelector(getIsGitConnected); const pageId = useSelector(getCurrentPageId) as string; + const currentPage = useSelector(getPageById(pageId)); // states const [isPopoverOpen, setIsPopoverOpen] = useState(false); @@ -186,10 +189,34 @@ const Header = () => { alignItems={"center"} className={"header-left-section"} flex={"1"} + gap={"spaces-4"} height={"100%"} justifyContent={"left"} > + + + {"Pages /"} + + + + {currentPage?.pageName} + + + + Date: Wed, 10 Jan 2024 11:19:23 +0530 Subject: [PATCH 2/8] feat: pages section toggle added --- app/client/src/actions/ideActions.ts | 9 ++++ .../src/ce/constants/ReduxActionConstants.tsx | 1 + app/client/src/ce/constants/messages.ts | 7 +++ .../src/pages/Editor/IDE/EditorPane/index.tsx | 7 ++- .../pages/Editor/IDE/Header/DeaultTitle.tsx | 14 ++++++ .../pages/Editor/IDE/Header/EditorTitle.tsx | 43 +++++++++++++++++ .../src/pages/Editor/IDE/Header/index.tsx | 46 +++++++++---------- .../src/reducers/uiReducers/ideReducer.ts | 6 +++ app/client/src/selectors/ideSelectors.tsx | 3 ++ 9 files changed, 111 insertions(+), 25 deletions(-) create mode 100644 app/client/src/pages/Editor/IDE/Header/DeaultTitle.tsx create mode 100644 app/client/src/pages/Editor/IDE/Header/EditorTitle.tsx diff --git a/app/client/src/actions/ideActions.ts b/app/client/src/actions/ideActions.ts index 1077b41a848..bcc701dc74e 100644 --- a/app/client/src/actions/ideActions.ts +++ b/app/client/src/actions/ideActions.ts @@ -9,3 +9,12 @@ export const setIdeEditorViewMode = (mode: EditorViewMode) => { }, }; }; + +export const setIdeEditorPagesActiveStatus = (active: boolean) => { + return { + type: ReduxActionTypes.SET_IDE_EDITOR_PAGES_ACTIVE_STATUS, + payload: { + pagesActive: active, + }, + }; +}; diff --git a/app/client/src/ce/constants/ReduxActionConstants.tsx b/app/client/src/ce/constants/ReduxActionConstants.tsx index cdc5fcc4da3..80693215db2 100644 --- a/app/client/src/ce/constants/ReduxActionConstants.tsx +++ b/app/client/src/ce/constants/ReduxActionConstants.tsx @@ -922,6 +922,7 @@ const ActionTypes = { "RESET_CURRENT_PLUGIN_ID_FOR_CREATE_NEW_APP", UPDATE_THEME_SETTING: "UPDATE_THEME_SETTING", SET_IDE_EDITOR_VIEW_MODE: "SET_IDE_EDITOR_VIEW_MODE", + SET_IDE_EDITOR_PAGES_ACTIVE_STATUS: "SET_IDE_EDITOR_PAGES_ACTIVE_STATUS", }; export const ReduxActionTypes = { diff --git a/app/client/src/ce/constants/messages.ts b/app/client/src/ce/constants/messages.ts index 0187a095ed4..ca4d3828b37 100644 --- a/app/client/src/ce/constants/messages.ts +++ b/app/client/src/ce/constants/messages.ts @@ -2427,3 +2427,10 @@ export const ADD_PAGE_FROM_TEMPLATE_MODAL = { title: () => "Add page(s) from a template", buildingBlocksTitle: () => "Building Blocks", }; + +export const HEADER_TITLES = { + DATA: () => "Data", + EDITOR: () => "Pages", + SETTINGS: () => "Settings", + LIBRARIES: () => "Libraries", +}; diff --git a/app/client/src/pages/Editor/IDE/EditorPane/index.tsx b/app/client/src/pages/Editor/IDE/EditorPane/index.tsx index 3df6f1a50ec..09748d4421b 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/index.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/index.tsx @@ -2,13 +2,18 @@ import React from "react"; import { Flex } from "design-system"; import type { RouteComponentProps } from "react-router"; import { Switch } from "react-router"; +import { useSelector } from "react-redux"; + import Pages from "pages/Editor/Explorer/Pages"; import { SentryRoute } from "@appsmith/AppRouter"; import { ADD_PATH } from "constants/routes"; import EditorPaneSegments from "./EditorPaneSegments"; import GlobalAdd from "./GlobalAdd"; +import { getPagesActiveStatus } from "selectors/ideSelectors"; const EditorPane = ({ match: { path } }: RouteComponentProps) => { + const active = useSelector(getPagesActiveStatus); + return ( { overflow="hidden" width="260px" > - + {active && } {/* divider is inside the Pages component */} diff --git a/app/client/src/pages/Editor/IDE/Header/DeaultTitle.tsx b/app/client/src/pages/Editor/IDE/Header/DeaultTitle.tsx new file mode 100644 index 00000000000..4d004215231 --- /dev/null +++ b/app/client/src/pages/Editor/IDE/Header/DeaultTitle.tsx @@ -0,0 +1,14 @@ +import React from "react"; +import { Flex, Text } from "design-system"; + +const DefaultTitle = ({ title }: { title: string }) => { + return ( + + + {title} + + + ); +}; + +export { DefaultTitle }; diff --git a/app/client/src/pages/Editor/IDE/Header/EditorTitle.tsx b/app/client/src/pages/Editor/IDE/Header/EditorTitle.tsx new file mode 100644 index 00000000000..5ca5ff0570d --- /dev/null +++ b/app/client/src/pages/Editor/IDE/Header/EditorTitle.tsx @@ -0,0 +1,43 @@ +import React from "react"; +import { Flex, Text, Icon } from "design-system"; +import { useDispatch, useSelector } from "react-redux"; + +import { createMessage, HEADER_TITLES } from "@appsmith/constants/messages"; +import { setIdeEditorPagesActiveStatus } from "actions/ideActions"; +import { getPagesActiveStatus } from "selectors/ideSelectors"; + +const EditorTitle = ({ title }: { title: string }) => { + const dispatch = useDispatch(); + const active = useSelector(getPagesActiveStatus); + + const onClickHandler = () => { + dispatch(setIdeEditorPagesActiveStatus(!active)); + }; + + return ( + + + {createMessage(HEADER_TITLES.EDITOR) + " /"} + + + + {title} + + + + + ); +}; + +export { EditorTitle }; diff --git a/app/client/src/pages/Editor/IDE/Header/index.tsx b/app/client/src/pages/Editor/IDE/Header/index.tsx index 27e72be1d34..0220c7e3d78 100644 --- a/app/client/src/pages/Editor/IDE/Header/index.tsx +++ b/app/client/src/pages/Editor/IDE/Header/index.tsx @@ -13,7 +13,6 @@ import { Tab, TabPanel, Button, - Icon, } from "design-system"; import { useDispatch, useSelector } from "react-redux"; import { EditInteractionKind, SavingState } from "design-system-old"; @@ -29,6 +28,7 @@ import { IN_APP_EMBED_SETTING, INVITE_TAB, RENAME_APPLICATION_TOOLTIP, + HEADER_TITLES, } from "@appsmith/constants/messages"; import EditorName from "pages/Editor/EditorName"; import { GetNavigationMenuData } from "pages/Editor/EditorName/NavigationMenuData"; @@ -70,6 +70,10 @@ import type { NavigationSetting } from "constants/AppConstants"; import { useHref } from "pages/Editor/utils"; import { viewerURL } from "@appsmith/RouteBuilder"; import HelpBar from "components/editorComponents/GlobalSearch/HelpBar"; +import { EditorTitle } from "./EditorTitle"; +import { useCurrentAppState } from "pages/Editor/IDE/hooks"; +import { DefaultTitle } from "./DeaultTitle"; +import { EditorState } from "entities/IDE/constants"; const StyledDivider = styled(Divider)` height: 50%; @@ -94,6 +98,7 @@ const Header = () => { const isGitConnected = useSelector(getIsGitConnected); const pageId = useSelector(getCurrentPageId) as string; const currentPage = useSelector(getPageById(pageId)); + const appState = useCurrentAppState(); // states const [isPopoverOpen, setIsPopoverOpen] = useState(false); @@ -175,6 +180,21 @@ const Header = () => { [dispatch, handlePublish], ); + const TitleComponent = () => { + switch (appState) { + case EditorState.DATA: + return ; + case EditorState.EDITOR: + return ; + case EditorState.SETTINGS: + return ; + case EditorState.LIBRARIES: + return ; + default: + return ; + } + }; + return ( { justifyContent={"left"} > - - - {"Pages /"} - - - - {currentPage?.pageName} - - - - + , ) => ({ ...state, view: action.payload.view }), + [ReduxActionTypes.SET_IDE_EDITOR_PAGES_ACTIVE_STATUS]: ( + state: IDEState, + action: ReduxAction<{ pagesActive: boolean }>, + ) => ({ ...state, pagesActive: action.payload.pagesActive }), }); export interface IDEState { view: EditorViewMode; + pagesActive: boolean; } export default ideReducer; diff --git a/app/client/src/selectors/ideSelectors.tsx b/app/client/src/selectors/ideSelectors.tsx index d116d8b3091..142ffb973d4 100644 --- a/app/client/src/selectors/ideSelectors.tsx +++ b/app/client/src/selectors/ideSelectors.tsx @@ -19,3 +19,6 @@ export const getIsSideBySideEnabled = createSelector( ); export const getIDEViewMode = (state: AppState) => state.ui.ide.view; + +export const getPagesActiveStatus = (state: AppState) => + state.ui.ide.pagesActive; From b81bf2a770e3878e0824574401ee178a2db2205d Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:27:45 +0530 Subject: [PATCH 3/8] fix: import of EditorState --- app/client/src/pages/Editor/IDE/Header/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/client/src/pages/Editor/IDE/Header/index.tsx b/app/client/src/pages/Editor/IDE/Header/index.tsx index 0220c7e3d78..3a1d0dd3215 100644 --- a/app/client/src/pages/Editor/IDE/Header/index.tsx +++ b/app/client/src/pages/Editor/IDE/Header/index.tsx @@ -73,7 +73,7 @@ import HelpBar from "components/editorComponents/GlobalSearch/HelpBar"; import { EditorTitle } from "./EditorTitle"; import { useCurrentAppState } from "pages/Editor/IDE/hooks"; import { DefaultTitle } from "./DeaultTitle"; -import { EditorState } from "entities/IDE/constants"; +import { EditorState } from "@appsmith/entities/IDE/constants"; const StyledDivider = styled(Divider)` height: 50%; From 6650025a86ce6b1d8e4d627bef714f29c79b540d Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:51:37 +0530 Subject: [PATCH 4/8] fix: Added back entity properties --- .../src/pages/Editor/IDE/EditorPane/index.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/client/src/pages/Editor/IDE/EditorPane/index.tsx b/app/client/src/pages/Editor/IDE/EditorPane/index.tsx index 637101065f0..74dfc4e4fa9 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/index.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/index.tsx @@ -10,11 +10,17 @@ import { ADD_PATH } from "constants/routes"; import EditorPaneSegments from "./EditorPaneSegments"; import GlobalAdd from "./GlobalAdd"; import { useEditorPaneWidth } from "../hooks"; -import { getPagesActiveStatus } from "selectors/ideSelectors"; +import { + getIsSideBySideEnabled, + getPagesActiveStatus, +} from "selectors/ideSelectors"; +import EntityProperties from "pages/Editor/Explorer/Entity/EntityProperties"; const EditorPane = ({ match: { path } }: RouteComponentProps) => { const width = useEditorPaneWidth(); const active = useSelector(getPagesActiveStatus); + const isSideBySideEnabled = useSelector(getIsSideBySideEnabled); + return ( { overflow="hidden" width={width + "px"} > - {active && } + {/** Entity Properties component is needed to render + the Bindings popover in the context menu. Will be removed eventually **/} + + {!isSideBySideEnabled && } + {/* This below pages component will get changed */} + {isSideBySideEnabled && active && } {/* divider is inside the Pages component */} From 07c229aeebc12ae7a3401c900159eca7bdf52261 Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:54:33 +0530 Subject: [PATCH 5/8] fix: renamed variable active to pagesActive --- app/client/src/pages/Editor/IDE/EditorPane/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/client/src/pages/Editor/IDE/EditorPane/index.tsx b/app/client/src/pages/Editor/IDE/EditorPane/index.tsx index 74dfc4e4fa9..9f7752c51b2 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/index.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/index.tsx @@ -18,7 +18,7 @@ import EntityProperties from "pages/Editor/Explorer/Entity/EntityProperties"; const EditorPane = ({ match: { path } }: RouteComponentProps) => { const width = useEditorPaneWidth(); - const active = useSelector(getPagesActiveStatus); + const pagesActive = useSelector(getPagesActiveStatus); const isSideBySideEnabled = useSelector(getIsSideBySideEnabled); return ( @@ -35,7 +35,7 @@ const EditorPane = ({ match: { path } }: RouteComponentProps) => { {!isSideBySideEnabled && } {/* This below pages component will get changed */} - {isSideBySideEnabled && active && } + {isSideBySideEnabled && pagesActive && } {/* divider is inside the Pages component */} From 1ef426dcac7c599153fa728ed4a60fef02bf4deb Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Wed, 10 Jan 2024 12:47:12 +0530 Subject: [PATCH 6/8] feat: Added minimal segment --- .../Editor/IDE/EditorPane/MinimalSegment.tsx | 25 +++++++++++++++++++ .../Editor/IDE/EditorPane/PagesSection.tsx | 19 ++++++++++++++ .../src/pages/Editor/IDE/EditorPane/index.tsx | 25 ++++++++++++++----- 3 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 app/client/src/pages/Editor/IDE/EditorPane/MinimalSegment.tsx create mode 100644 app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx diff --git a/app/client/src/pages/Editor/IDE/EditorPane/MinimalSegment.tsx b/app/client/src/pages/Editor/IDE/EditorPane/MinimalSegment.tsx new file mode 100644 index 00000000000..a0cc3a4e398 --- /dev/null +++ b/app/client/src/pages/Editor/IDE/EditorPane/MinimalSegment.tsx @@ -0,0 +1,25 @@ +import React from "react"; +import { Flex, Text } from "design-system"; +import { createMessage, EDITOR_PANE_TEXTS } from "@appsmith/constants/messages"; + +const MinimalSegment = () => { + return ( + + + {createMessage(EDITOR_PANE_TEXTS.queries_tab)} + + {createMessage(EDITOR_PANE_TEXTS.js_tab)} + {createMessage(EDITOR_PANE_TEXTS.ui_tab)} + + ); +}; + +export { MinimalSegment }; diff --git a/app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx b/app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx new file mode 100644 index 00000000000..2572d5a9c72 --- /dev/null +++ b/app/client/src/pages/Editor/IDE/EditorPane/PagesSection.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import { Flex, Text } from "design-system"; + +const PagesSection = () => { + return ( + + + Pages + + + ); +}; + +export { PagesSection }; diff --git a/app/client/src/pages/Editor/IDE/EditorPane/index.tsx b/app/client/src/pages/Editor/IDE/EditorPane/index.tsx index 9f7752c51b2..2e11978f5a9 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/index.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/index.tsx @@ -15,6 +15,8 @@ import { getPagesActiveStatus, } from "selectors/ideSelectors"; import EntityProperties from "pages/Editor/Explorer/Entity/EntityProperties"; +import { PagesSection } from "./PagesSection"; +import { MinimalSegment } from "./MinimalSegment"; const EditorPane = ({ match: { path } }: RouteComponentProps) => { const width = useEditorPaneWidth(); @@ -34,13 +36,24 @@ const EditorPane = ({ match: { path } }: RouteComponentProps) => { the Bindings popover in the context menu. Will be removed eventually **/} {!isSideBySideEnabled && } - {/* This below pages component will get changed */} - {isSideBySideEnabled && pagesActive && } {/* divider is inside the Pages component */} - - - - + + {/* This below pages component will get changed */} + {isSideBySideEnabled && pagesActive && } + + {!pagesActive && ( + + + + + )} + + {/* show minimal segments if pages is active */} + {pagesActive && } ); }; From d1ea4a59c4534ff65d398986419358556a5a7afe Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:41:56 +0530 Subject: [PATCH 7/8] feat: completed minimal segment in left pane --- .../Editor/IDE/EditorPane/MinimalSegment.tsx | 60 +++++++++++++++++-- app/client/src/selectors/ideSelectors.tsx | 11 ++++ 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/app/client/src/pages/Editor/IDE/EditorPane/MinimalSegment.tsx b/app/client/src/pages/Editor/IDE/EditorPane/MinimalSegment.tsx index a0cc3a4e398..e53553a5940 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/MinimalSegment.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/MinimalSegment.tsx @@ -1,23 +1,71 @@ import React from "react"; -import { Flex, Text } from "design-system"; +import { Flex, Text, Tag } from "design-system"; +import { useSelector } from "react-redux"; + import { createMessage, EDITOR_PANE_TEXTS } from "@appsmith/constants/messages"; +import { + getActionsCount, + getJsActionsCount, + getWidgetsCount, +} from "selectors/ideSelectors"; const MinimalSegment = () => { + const actionsCount = useSelector(getActionsCount); + const jsActionsCount = useSelector(getJsActionsCount); + const widgetsCount = useSelector(getWidgetsCount); + return ( - - {createMessage(EDITOR_PANE_TEXTS.queries_tab)} - - {createMessage(EDITOR_PANE_TEXTS.js_tab)} - {createMessage(EDITOR_PANE_TEXTS.ui_tab)} + + + {createMessage(EDITOR_PANE_TEXTS.queries_tab)} + + + {actionsCount} + + + + {createMessage(EDITOR_PANE_TEXTS.js_tab)} + + {jsActionsCount} + + + + {createMessage(EDITOR_PANE_TEXTS.ui_tab)} + + {widgetsCount} + + ); }; diff --git a/app/client/src/selectors/ideSelectors.tsx b/app/client/src/selectors/ideSelectors.tsx index 142ffb973d4..dfefca9122e 100644 --- a/app/client/src/selectors/ideSelectors.tsx +++ b/app/client/src/selectors/ideSelectors.tsx @@ -22,3 +22,14 @@ export const getIDEViewMode = (state: AppState) => state.ui.ide.view; export const getPagesActiveStatus = (state: AppState) => state.ui.ide.pagesActive; + +export const getActionsCount = (state: AppState) => + state.entities.actions.length || 0; + +export const getJsActionsCount = (state: AppState) => + state.entities.jsActions.length || 0; + +export const getWidgetsCount = (state: AppState) => + Object.values(state.entities.canvasWidgets).filter( + (w) => w.type !== "CANVAS_WIDGET", + ).length || 0; From 595f95edba6c801ba283b6fbaca551ee2cb5ce14 Mon Sep 17 00:00:00 2001 From: albinAppsmith <87797149+albinAppsmith@users.noreply.github.com> Date: Wed, 10 Jan 2024 18:57:31 +0530 Subject: [PATCH 8/8] feat: completed pages redesign --- .../Editor/Explorer/Common/components.tsx | 3 + .../Editor/IDE/EditorPane/MinimalSegment.tsx | 10 +- .../Editor/IDE/EditorPane/PagesSection.tsx | 211 +++++++++++++++++- .../src/pages/Editor/IDE/EditorPane/index.tsx | 24 +- 4 files changed, 229 insertions(+), 19 deletions(-) diff --git a/app/client/src/pages/Editor/Explorer/Common/components.tsx b/app/client/src/pages/Editor/Explorer/Common/components.tsx index 07eb8d01d94..d72fac82c31 100644 --- a/app/client/src/pages/Editor/Explorer/Common/components.tsx +++ b/app/client/src/pages/Editor/Explorer/Common/components.tsx @@ -9,6 +9,9 @@ export const RelativeContainer = styled.div` `; export const StyledEntity = styled(Entity)<{ entitySize?: number }>` + &.page.fullWidth { + width: 100%; + } &.pages > div:not(.t--entity-item) > div > div { max-height: 40vh; min-height: ${({ entitySize }) => diff --git a/app/client/src/pages/Editor/IDE/EditorPane/MinimalSegment.tsx b/app/client/src/pages/Editor/IDE/EditorPane/MinimalSegment.tsx index e53553a5940..dc48c896706 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/MinimalSegment.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/MinimalSegment.tsx @@ -1,6 +1,6 @@ import React from "react"; import { Flex, Text, Tag } from "design-system"; -import { useSelector } from "react-redux"; +import { useDispatch, useSelector } from "react-redux"; import { createMessage, EDITOR_PANE_TEXTS } from "@appsmith/constants/messages"; import { @@ -8,19 +8,27 @@ import { getJsActionsCount, getWidgetsCount, } from "selectors/ideSelectors"; +import { setIdeEditorPagesActiveStatus } from "actions/ideActions"; const MinimalSegment = () => { + const dispatch = useDispatch(); const actionsCount = useSelector(getActionsCount); const jsActionsCount = useSelector(getJsActionsCount); const widgetsCount = useSelector(getWidgetsCount); + const onClickHandler = () => { + dispatch(setIdeEditorPagesActiveStatus(false)); + }; + return ( { + const dispatch = useDispatch(); + const location = useLocation(); + const pages: Page[] = useSelector(selectAllPages); + const currentPageId = useSelector(getCurrentPageId); + const applicationId = useSelector(getCurrentApplicationId); + const userAppPermissions = useSelector( + (state: AppState) => getCurrentApplication(state)?.userPermissions ?? [], + ); + const workspaceId = useSelector(getCurrentWorkspaceId); + const instanceId = useSelector(getInstanceId); + + const [isMenuOpen, setIsMenuOpen] = useState(false); + + const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); + + const [springs, api] = useSpring(() => ({ + from: { opacity: 0, height: "0%" }, + to: { opacity: 1, height: "100%" }, + })); + + const hasExportPermission = isPermitted( + userAppPermissions ?? [], + PERMISSION_TYPE.EXPORT_APPLICATION, + ); + + const canCreatePages = getHasCreatePagePermission( + isFeatureEnabled, + userAppPermissions, + ); + + useEffect(() => { + api.start(); + }, []); + + const switchPage = useCallback( + (page: Page) => { + const navigateToUrl = + currentPageId === page.pageId + ? widgetListURL({}) + : builderURL({ + pageId: page.pageId, + }); + AnalyticsUtil.logEvent("PAGE_NAME_CLICK", { + name: page.pageName, + fromUrl: location.pathname, + type: "PAGES", + toUrl: navigateToUrl, + }); + dispatch(toggleInOnboardingWidgetSelection(true)); + dispatch(setIdeEditorPagesActiveStatus(false)); + history.push(navigateToUrl, { + invokedBy: NavigationMethod.EntityExplorer, + }); + }, + [location.pathname, currentPageId], + ); + + const createPageCallback = useCallback(() => { + const name = getNextEntityName( + "Page", + pages.map((page: Page) => page.pageName), + ); + dispatch(setIdeEditorPagesActiveStatus(false)); + dispatch( + createNewPageFromEntities( + applicationId, + name, + workspaceId, + false, + instanceId, + ), + ); + }, [dispatch, pages, applicationId]); + + const onMenuClose = useCallback(() => setIsMenuOpen(false), [setIsMenuOpen]); + + const pageElements = useMemo( + () => + pages.map((page) => { + const icon = page.isDefault ? defaultPageIcon : pageIcon; + const isCurrentPage = currentPageId === page.pageId; + const pagePermissions = page.userPermissions; + const canManagePages = getHasManagePagePermission( + isFeatureEnabled, + pagePermissions, + ); + + const contextMenu = ( + + ); + + return ( + switchPage(page)} + active={isCurrentPage} + canEditEntityName={canManagePages} + className={`page fullWidth ${isCurrentPage && "activePage"}`} + contextMenu={contextMenu} + disabled={page.isHidden} + entityId={page.pageId} + icon={icon} + isDefaultExpanded={isCurrentPage} + key={page.pageId} + name={page.pageName} + onNameEdit={resolveAsSpaceChar} + searchKeyword={""} + step={1} + updateEntityName={(id, name) => + updatePage({ id, name, isHidden: !!page.isHidden }) + } + /> + ); + }), + [pages, currentPageId, applicationId, location.pathname], + ); + return ( - - - Pages - - + + + All Pages ({pages.length}) + + {canCreatePages ? ( + + ) : null} + + + {pageElements} + + ); }; diff --git a/app/client/src/pages/Editor/IDE/EditorPane/index.tsx b/app/client/src/pages/Editor/IDE/EditorPane/index.tsx index 2e11978f5a9..559c61fe7bc 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/index.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/index.tsx @@ -23,6 +23,17 @@ const EditorPane = ({ match: { path } }: RouteComponentProps) => { const pagesActive = useSelector(getPagesActiveStatus); const isSideBySideEnabled = useSelector(getIsSideBySideEnabled); + const PagesRender = () => { + if (!isSideBySideEnabled) { + return ; + /* divider is inside the Pages component */ + } else if (isSideBySideEnabled && pagesActive) { + return ; + } else { + return null; + } + }; + return ( { {/** Entity Properties component is needed to render the Bindings popover in the context menu. Will be removed eventually **/} - {!isSideBySideEnabled && } - {/* divider is inside the Pages component */} - - {/* This below pages component will get changed */} - {isSideBySideEnabled && pagesActive && } + - {!pagesActive && ( + {pagesActive ? ( + + ) : ( { )} - - {/* show minimal segments if pages is active */} - {pagesActive && } ); };