From 824b2fe1231de1d073a1b19054507643b325400f Mon Sep 17 00:00:00 2001 From: Alex Golovanov Date: Tue, 18 Jun 2024 18:05:31 +0300 Subject: [PATCH] refactor: move apps link out of menu & refactor nav menu data --- app/client/src/pages/Editor/EditorHeader.tsx | 2 - .../src/pages/Editor/EditorName/index.tsx | 17 +- ...onMenuData.ts => useNavigationMenuData.ts} | 168 ++++++++++-------- .../src/pages/Editor/IDE/Header/index.tsx | 46 ++--- 4 files changed, 112 insertions(+), 121 deletions(-) rename app/client/src/pages/Editor/EditorName/{NavigationMenuData.ts => useNavigationMenuData.ts} (53%) diff --git a/app/client/src/pages/Editor/EditorHeader.tsx b/app/client/src/pages/Editor/EditorHeader.tsx index 90ed66444295..370faadfcd8b 100644 --- a/app/client/src/pages/Editor/EditorHeader.tsx +++ b/app/client/src/pages/Editor/EditorHeader.tsx @@ -75,7 +75,6 @@ import { Omnibar } from "./commons/Omnibar"; import { EditorShareButton } from "./EditorShareButton"; import { HelperBarInHeader } from "./HelpBarInHeader"; import { AppsmithLink } from "./AppsmithLink"; -import { GetNavigationMenuData } from "./EditorName/NavigationMenuData"; const { cloudHosting } = getAppsmithConfigs(); @@ -208,7 +207,6 @@ export function EditorHeader() { editInteractionKind={EditInteractionKind.SINGLE} editorName="Application" fill - getNavigationMenu={GetNavigationMenuData} isError={isErroredSavingName} isNewEditor={ applicationList.filter((el) => el.id === applicationId) diff --git a/app/client/src/pages/Editor/EditorName/index.tsx b/app/client/src/pages/Editor/EditorName/index.tsx index c2267f818abd..21ef14192e94 100644 --- a/app/client/src/pages/Editor/EditorName/index.tsx +++ b/app/client/src/pages/Editor/EditorName/index.tsx @@ -1,6 +1,5 @@ import React, { useState, useCallback } from "react"; -import { useTheme } from "styled-components"; import type { noop } from "lodash"; import type { CommonComponentProps, @@ -9,14 +8,12 @@ import type { import { SavingState } from "design-system-old"; import EditableName from "./EditableName"; import { NavigationMenu } from "./NavigationMenu"; -import type { Theme } from "constants/DefaultTheme"; import { Menu, toast, MenuTrigger } from "design-system"; import ForkApplicationModal from "pages/Applications/ForkApplicationModal"; import { Container, StyledIcon } from "./components"; import { useSelector } from "react-redux"; import { getCurrentApplicationId } from "selectors/editorSelectors"; -import type { MenuItemData } from "./NavigationMenuItem"; -import type { NavigationMenuDataProps } from "./NavigationMenuData"; +import { useNavigationMenuData } from "./useNavigationMenuData"; type EditorNameProps = CommonComponentProps & { applicationId?: string | undefined; @@ -34,10 +31,6 @@ type EditorNameProps = CommonComponentProps & { isPopoverOpen: boolean; setIsPopoverOpen: typeof noop; editorName: string; - getNavigationMenu: ({ - editMode, - setForkApplicationModalOpen, - }: NavigationMenuDataProps) => MenuItemData[]; }; export function EditorName(props: EditorNameProps) { @@ -45,14 +38,11 @@ export function EditorName(props: EditorNameProps) { defaultSavingState, defaultValue, editorName, - getNavigationMenu, isNewEditor, isPopoverOpen, setIsPopoverOpen, } = props; - const theme = useTheme() as Theme; - const [isEditingDefault, setIsEditingDefault] = useState(isNewEditor); const [isEditing, setIsEditing] = useState(!!isEditingDefault); const [isInvalid, setIsInvalid] = useState(false); @@ -102,9 +92,8 @@ export function EditorName(props: EditorNameProps) { } }, []); - const NavigationMenuData = getNavigationMenu({ + const navigationMenuData = useNavigationMenuData({ editMode, - theme, setForkApplicationModalOpen, }); @@ -145,7 +134,7 @@ export function EditorName(props: EditorNameProps) { diff --git a/app/client/src/pages/Editor/EditorName/NavigationMenuData.ts b/app/client/src/pages/Editor/EditorName/useNavigationMenuData.ts similarity index 53% rename from app/client/src/pages/Editor/EditorName/NavigationMenuData.ts rename to app/client/src/pages/Editor/EditorName/useNavigationMenuData.ts index 194b101df6ad..0a8fb8f222c1 100644 --- a/app/client/src/pages/Editor/EditorName/NavigationMenuData.ts +++ b/app/client/src/pages/Editor/EditorName/useNavigationMenuData.ts @@ -1,3 +1,5 @@ +import type React from "react"; +import { useCallback, useMemo } from "react"; import { useDispatch, useSelector } from "react-redux"; import { useHistory } from "react-router-dom"; import type { noop } from "lodash"; @@ -18,19 +20,18 @@ import { getCurrentApplication } from "@appsmith/selectors/applicationSelectors" import { Colors } from "constants/Colors"; import { getCurrentApplicationId } from "selectors/editorSelectors"; import { toast } from "design-system"; -import type { ThemeProp } from "WidgetProvider/constants"; import { DOCS_BASE_URL } from "constants/ThirdPartyConstants"; import { getAppsmithConfigs } from "@appsmith/configs"; import { getCurrentUser } from "selectors/usersSelectors"; const { cloudHosting, intercomAppID } = getAppsmithConfigs(); -export interface NavigationMenuDataProps extends ThemeProp { +export interface NavigationMenuDataProps { editMode: typeof noop; setForkApplicationModalOpen: React.Dispatch>; } -export const GetNavigationMenuData = ({ +export const useNavigationMenuData = ({ editMode, setForkApplicationModalOpen, }: NavigationMenuDataProps): MenuItemData[] => { @@ -38,12 +39,16 @@ export const GetNavigationMenuData = ({ const history = useHistory(); const applicationId = useSelector(getCurrentApplicationId); - const isApplicationIdPresent = !!(applicationId && applicationId.length > 0); - const user = useSelector(getCurrentUser); + const { isIntercomConsentGiven } = user || {}; const currentApplication = useSelector(getCurrentApplication); + + const hasDeletePermission = hasDeleteApplicationPermission( + currentApplication?.userPermissions, + ); + const hasExportPermission = isPermitted( currentApplication?.userPermissions ?? [], PERMISSION_TYPE.EXPORT_APPLICATION, @@ -58,7 +63,7 @@ export const GetNavigationMenuData = ({ } }; - const exportAppAsJSON = () => { + const exportAppAsJSON = useCallback(() => { const id = `t--export-app-link`; const existingLink = document.getElementById(id); existingLink && existingLink.remove(); @@ -75,9 +80,13 @@ export const GetNavigationMenuData = ({ toast.show(`Successfully exported ${currentApplication?.name}`, { kind: "success", }); - }; + }, [ + applicationId, + currentApplication?.gitApplicationMetadata?.branchName, + currentApplication?.name, + ]); - const deleteApplication = () => { + const deleteApplication = useCallback(() => { if (applicationId && applicationId.length > 0) { dispatch({ type: ReduxActionTypes.DELETE_APPLICATION_INIT, @@ -91,85 +100,88 @@ export const GetNavigationMenuData = ({ kind: "error", }); } - }; + }, [applicationId, dispatch, history]); - return [ - { - text: "Back to all apps", - onClick: () => history.replace(APPLICATIONS_URL), - type: MenuTypes.MENU, - isVisible: true, - }, - { - text: "divider_1", - type: MenuTypes.MENU_DIVIDER, - isVisible: true, - }, - { - text: "Rename", - onClick: editMode, - type: MenuTypes.MENU, - isVisible: true, - }, - { - text: "Fork application", - onClick: () => setForkApplicationModalOpen(true), - type: MenuTypes.MENU, - isVisible: isApplicationIdPresent && hasEditPermission, - }, - { - text: "Export application", - onClick: exportAppAsJSON, - type: MenuTypes.MENU, - isVisible: isApplicationIdPresent && hasExportPermission, - }, - hasDeleteApplicationPermission(currentApplication?.userPermissions) && { - text: "Delete application", - confirmText: "Are you sure?", - onClick: deleteApplication, - type: MenuTypes.RECONFIRM, - isVisible: isApplicationIdPresent, - style: { color: Colors.ERROR_RED }, - }, - { - text: "divider_2", - type: MenuTypes.MENU_DIVIDER, - isVisible: true, - }, - { - text: "Help", - type: MenuTypes.PARENT, - isVisible: true, - children: [ + return useMemo( + () => + [ { - text: "Documentation", - onClick: () => openExternalLink(DOCS_BASE_URL), + text: "Rename", + onClick: editMode, type: MenuTypes.MENU, isVisible: true, - startIcon: "book-line", }, { - text: "Report a bug", - onClick: () => - openExternalLink( - "https://github.com/appsmithorg/appsmith/issues/new/choose", - ), + text: "Fork application", + onClick: () => setForkApplicationModalOpen(true), type: MenuTypes.MENU, - isVisible: true, - startIcon: "bug-line", + isVisible: isApplicationIdPresent && hasEditPermission, }, { - startIcon: "chat-help", - text: "Chat with us", - onClick: () => { - if (cloudHosting || user?.isIntercomConsentGiven) { - window.Intercom("show"); - } - }, + text: "Export application", + onClick: exportAppAsJSON, type: MenuTypes.MENU, - isVisible: intercomAppID && window.Intercom, + isVisible: isApplicationIdPresent && hasExportPermission, }, - ], - }, - ].filter(Boolean) as MenuItemData[]; + hasDeletePermission && { + text: "Delete application", + confirmText: "Are you sure?", + onClick: deleteApplication, + type: MenuTypes.RECONFIRM, + isVisible: isApplicationIdPresent, + style: { color: Colors.ERROR_RED }, + }, + { + text: "divider_2", + type: MenuTypes.MENU_DIVIDER, + isVisible: true, + }, + { + text: "Help", + type: MenuTypes.PARENT, + isVisible: true, + children: [ + { + text: "Documentation", + onClick: () => openExternalLink(DOCS_BASE_URL), + type: MenuTypes.MENU, + isVisible: true, + startIcon: "book-line", + }, + { + text: "Report a bug", + onClick: () => + openExternalLink( + "https://github.com/appsmithorg/appsmith/issues/new/choose", + ), + type: MenuTypes.MENU, + isVisible: true, + startIcon: "bug-line", + }, + { + startIcon: "chat-help", + text: "Chat with us", + onClick: () => { + if (cloudHosting || isIntercomConsentGiven) { + window.Intercom("show"); + } + }, + type: MenuTypes.MENU, + isVisible: intercomAppID && window.Intercom, + }, + ], + }, + ].filter(Boolean) as MenuItemData[], + [ + editMode, + isApplicationIdPresent, + hasEditPermission, + exportAppAsJSON, + hasExportPermission, + hasDeletePermission, + deleteApplication, + setForkApplicationModalOpen, + isIntercomConsentGiven, + ], + ); }; diff --git a/app/client/src/pages/Editor/IDE/Header/index.tsx b/app/client/src/pages/Editor/IDE/Header/index.tsx index 5005bea3d860..3fde69faf453 100644 --- a/app/client/src/pages/Editor/IDE/Header/index.tsx +++ b/app/client/src/pages/Editor/IDE/Header/index.tsx @@ -2,7 +2,6 @@ import React, { useCallback, useState } from "react"; import { Flex, Tooltip, - Text, Divider, Modal, ModalContent, @@ -13,6 +12,7 @@ import { Tab, TabPanel, Button, + Link, } from "design-system"; import { useDispatch, useSelector } from "react-redux"; import { EditInteractionKind, SavingState } from "design-system-old"; @@ -29,7 +29,6 @@ import { HEADER_TITLES, } from "@appsmith/constants/messages"; import EditorName from "pages/Editor/EditorName"; -import { GetNavigationMenuData } from "pages/Editor/EditorName/NavigationMenuData"; import { getCurrentApplicationId, getCurrentPageId, @@ -76,6 +75,7 @@ import { EditorState } from "@appsmith/entities/IDE/constants"; import { EditorSaveIndicator } from "pages/Editor/EditorSaveIndicator"; import type { Page } from "@appsmith/constants/ReduxActionConstants"; import { IDEHeader, IDEHeaderTitle } from "IDE"; +import { APPLICATIONS_URL } from "constants/routes"; const StyledDivider = styled(Divider)` height: 50%; @@ -166,7 +166,7 @@ const Header = () => { dispatch(updateApplication(id, data)); }; - const handlePublish = () => { + const handlePublish = useCallback(() => { if (applicationId) { dispatch(publishApplication(applicationId)); @@ -201,23 +201,18 @@ const Header = () => { templateTitle: currentApplication?.forkedFromTemplateTitle, }); } - }; + }, [applicationId, currentApplication, dispatch]); - const handleClickDeploy = useCallback( - (fromDeploy?: boolean) => { - if (isGitConnected) { - dispatch(showConnectGitModal()); - AnalyticsUtil.logEvent("GS_DEPLOY_GIT_CLICK", { - source: fromDeploy - ? "Deploy button" - : "Application name menu (top left)", - }); - } else { - handlePublish(); - } - }, - [dispatch, handlePublish], - ); + const handleClickDeploy = useCallback(() => { + if (isGitConnected) { + dispatch(showConnectGitModal()); + AnalyticsUtil.logEvent("GS_DEPLOY_GIT_CLICK", { + source: "Deploy button", + }); + } else { + handlePublish(); + } + }, [dispatch, handlePublish, isGitConnected]); return ( <> @@ -230,12 +225,10 @@ const Header = () => { {currentWorkspace.name && ( <> - - {currentWorkspace.name + " / "} - + + {currentWorkspace.name} + + {"/"} { editInteractionKind={EditInteractionKind.SINGLE} editorName="Application" fill - getNavigationMenu={GetNavigationMenuData} isError={isErroredSavingName} isNewEditor={ applicationList.filter((el) => el.id === applicationId) @@ -343,7 +335,7 @@ const Header = () => { isDisabled={isProtectedMode} isLoading={isPublishing} kind="tertiary" - onClick={() => handleClickDeploy(true)} + onClick={handleClickDeploy} size="md" startIcon={"rocket"} >