diff --git a/CODEOWNERS b/CODEOWNERS index fabb2ca64c..0124f366ae 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -193,6 +193,7 @@ app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/Appsmith app/client/src/pages/Settings/**/* @ankitakinger app/client/src/pages/workspace/settings.tsx @ankitakinger app/client/src/pages/workspace/AppInviteUsersForm.tsx @ankitakinger +app/client/src/pages/workspace/WorkspaceInviteUsersForm.tsx @ankitakinger app/client/src/components/editorComponents/form/FormDialogComponent.tsx @ankitakinger app/client/src/ce/pages/AdminSettings/**/* @ankitakinger app/client/src/ee/pages/AdminSettings/**/* @ankitakinger @@ -202,8 +203,8 @@ app/client/src/ce/pages/Applications/PrivateEmbedSettings.tsx @ankitakinger app/client/src/ee/pages/Applications/PrivateEmbedSettings.tsx @ankitakinger app/client/src/ce/pages/workspace/Members.tsx @ankitakinger app/client/src/ee/pages/workspace/Members.tsx @ankitakinger -app/client/src/ce/pages/workspace/WorkspaceInviteUsersForm.tsx @ankitakinger -app/client/src/ee/pages/workspace/WorkspaceInviteUsersForm.tsx @ankitakinger +app/client/src/ce/pages/workspace/InviteUsersForm.tsx @ankitakinger +app/client/src/ee/pages/workspace/InviteUsersForm.tsx @ankitakinger app/client/src/ce/pages/Upgrade/**/* @ankitakinger app/client/src/ee/pages/Auditlogs/**/* @ankitakinger app/client/cypress/e2e/Regression/Enterprise/**/* @ankitakinger diff --git a/app/client/cypress/e2e/Regression/ClientSide/AdminSettings/Admin_settings_spec.js b/app/client/cypress/e2e/Regression/ClientSide/AdminSettings/Admin_settings_spec.js index dcc7cf26ec..3f790297ea 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/AdminSettings/Admin_settings_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/AdminSettings/Admin_settings_spec.js @@ -71,7 +71,7 @@ describe("Admin settings page", function () { it( "airgap", - "4. Should test that settings page tab redirects and google maps doesn't exist - airgap", + "4. Should test that settings page tab redirects and developer settings doesn't exist - airgap", () => { cy.visit("/applications", { timeout: 60000 }); if (!Cypress.env("AIRGAPPED")) { diff --git a/app/client/cypress/support/Objects/CommonLocators.ts b/app/client/cypress/support/Objects/CommonLocators.ts index 1166ddc450..a5b38616c6 100644 --- a/app/client/cypress/support/Objects/CommonLocators.ts +++ b/app/client/cypress/support/Objects/CommonLocators.ts @@ -252,11 +252,10 @@ export class CommonLocators { _selectionCanvas = (canvasId: string) => `#div-selection-${canvasId}`; _sqlKeyword = ".cm-m-sql.cm-keyword"; _appLeveltooltip = (toolTip: string) => `span:contains('${toolTip}')`; - _appEditMenu = "[data-testid='t--application-edit-menu']"; - _appEditMenuBtn = "[data-testid='t--application-edit-menu-cta']"; - _appEditMenuSettings = "[data-testid='t--application-edit-menu-settings']"; - _appEditExportSettings = - "[data-testid='t--application-edit-menu-export-application']"; + _appEditMenu = "[data-testid='t--editor-menu']"; + _appEditMenuBtn = "[data-testid='t--editor-menu-cta']"; + _appEditMenuSettings = "[data-testid='t--editor-menu-settings']"; + _appEditExportSettings = "[data-testid='t--editor-menu-export-application']"; _appThemeSettings = "#t--theme-settings-header"; _appChangeThemeBtn = ".t--change-theme-btn"; _appThemeCard = ".t--theme-card"; diff --git a/app/client/src/ce/reducers/entityReducers/index.ts b/app/client/src/ce/reducers/entityReducers/index.ts index a19eac5818..ba3bd64c88 100644 --- a/app/client/src/ce/reducers/entityReducers/index.ts +++ b/app/client/src/ce/reducers/entityReducers/index.ts @@ -11,6 +11,9 @@ import pageListReducer from "reducers/entityReducers/pageListReducer"; import pluginsReducer from "reducers/entityReducers/pluginsReducer"; import autoHeightLayoutTreeReducer from "reducers/entityReducers/autoHeightReducers/autoHeightLayoutTreeReducer"; import canvasLevelsReducer from "reducers/entityReducers/autoHeightReducers/canvasLevelsReducer"; + +/* Reducers which are integrated into the core system when registering a pluggable module + or done so by a module that is designed to be eventually pluggable */ import widgetPositionsReducer from "layoutSystems/anvil/integrations/reducers/widgetPositionsReducer"; export const entityReducerObject = { diff --git a/app/client/src/pages/Applications/ApplicationCard.tsx b/app/client/src/pages/Applications/ApplicationCard.tsx index 4061622bb8..06be17ec76 100644 --- a/app/client/src/pages/Applications/ApplicationCard.tsx +++ b/app/client/src/pages/Applications/ApplicationCard.tsx @@ -97,10 +97,10 @@ const IconScrollWrapper = styled.div` } `; -type ModifiedMenuItemProps = MenuItemProps & { +export interface ModifiedMenuItemProps extends MenuItemProps { key?: string; "data-testid"?: string; -}; +} const ContextMenuTrigger = styled(Button)<{ isHidden?: boolean }>` ${(props) => props.isHidden && "opacity: 0; visibility: hidden;"} diff --git a/app/client/src/pages/Editor/EditorHeader.tsx b/app/client/src/pages/Editor/EditorHeader.tsx index 0a2c8a2fca..c9933e3c66 100644 --- a/app/client/src/pages/Editor/EditorHeader.tsx +++ b/app/client/src/pages/Editor/EditorHeader.tsx @@ -6,7 +6,9 @@ import { getApplicationLastDeployedAt, getCurrentApplicationId, getCurrentPageId, + getIsPageSaving, getIsPublishingApplication, + getPageSavingError, previewModeSelector, } from "selectors/editorSelectors"; import { @@ -25,7 +27,7 @@ import { getIsErroredSavingAppName, getCurrentApplication, } from "@appsmith/selectors/applicationSelectors"; -import EditorAppName from "./EditorAppName"; +import EditorName from "./EditorName"; import { EditInteractionKind, SavingState } from "design-system-old"; import { Button, @@ -90,6 +92,7 @@ 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(); @@ -111,6 +114,8 @@ export function EditorHeader() { const isPublishing = useSelector(getIsPublishingApplication); const pageId = useSelector(getCurrentPageId) as string; const featureFlags = useSelector(selectFeatureFlags); + const isSaving = useSelector(getIsPageSaving); + const pageSaveError = useSelector(getPageSavingError); const deployLink = useHref(viewerURL, { pageId }); const isAppSettingsPaneWithNavigationTabOpen = useSelector( @@ -265,7 +270,7 @@ export function EditorHeader() { placement="bottom" >
- el.id === applicationId) .length > 0 } @@ -290,7 +297,7 @@ export function EditorHeader() { />
- + diff --git a/app/client/src/pages/Editor/EditorAppName/EditableAppName.tsx b/app/client/src/pages/Editor/EditorName/EditableName.tsx similarity index 100% rename from app/client/src/pages/Editor/EditorAppName/EditableAppName.tsx rename to app/client/src/pages/Editor/EditorName/EditableName.tsx diff --git a/app/client/src/pages/Editor/EditorAppName/NavigationMenu.tsx b/app/client/src/pages/Editor/EditorName/NavigationMenu.tsx similarity index 100% rename from app/client/src/pages/Editor/EditorAppName/NavigationMenu.tsx rename to app/client/src/pages/Editor/EditorName/NavigationMenu.tsx diff --git a/app/client/src/pages/Editor/EditorAppName/NavigationMenuData.ts b/app/client/src/pages/Editor/EditorName/NavigationMenuData.ts similarity index 98% rename from app/client/src/pages/Editor/EditorAppName/NavigationMenuData.ts rename to app/client/src/pages/Editor/EditorName/NavigationMenuData.ts index 3c46e4a258..38e1197b81 100644 --- a/app/client/src/pages/Editor/EditorAppName/NavigationMenuData.ts +++ b/app/client/src/pages/Editor/EditorName/NavigationMenuData.ts @@ -25,10 +25,10 @@ import { toast } from "design-system"; import type { ThemeProp } from "WidgetProvider/constants"; import { DISCORD_URL, DOCS_BASE_URL } from "constants/ThirdPartyConstants"; -type NavigationMenuDataProps = ThemeProp & { +export interface NavigationMenuDataProps extends ThemeProp { editMode: typeof noop; setForkApplicationModalOpen: React.Dispatch>; -}; +} export const GetNavigationMenuData = ({ editMode, diff --git a/app/client/src/pages/Editor/EditorAppName/NavigationMenuItem.tsx b/app/client/src/pages/Editor/EditorName/NavigationMenuItem.tsx similarity index 93% rename from app/client/src/pages/Editor/EditorAppName/NavigationMenuItem.tsx rename to app/client/src/pages/Editor/EditorName/NavigationMenuItem.tsx index b84ea2bb87..bf67000940 100644 --- a/app/client/src/pages/Editor/EditorAppName/NavigationMenuItem.tsx +++ b/app/client/src/pages/Editor/EditorName/NavigationMenuItem.tsx @@ -96,7 +96,7 @@ export function NavigationMenuItem({ case MenuTypes.MENU: return ( handleClick(e, menuItemData)} > {menuItemData.text} @@ -104,7 +104,7 @@ export function NavigationMenuItem({ ); case MenuTypes.PARENT: return ( - + {menuItemData.text} {menuItemData?.children?.map((subitem, idx) => ( @@ -126,7 +126,7 @@ export function NavigationMenuItem({ return ( handleReconfirmClick(e, menuItemData)} > {confirm.text} diff --git a/app/client/src/pages/Editor/EditorName/components.ts b/app/client/src/pages/Editor/EditorName/components.ts new file mode 100644 index 0000000000..13505aa1af --- /dev/null +++ b/app/client/src/pages/Editor/EditorName/components.ts @@ -0,0 +1,37 @@ +import styled from "styled-components"; +import { Classes } from "@blueprintjs/core"; +import { getTypographyByKey } from "design-system-old"; +import { Icon } from "design-system"; + +export const Container = styled.div` + display: flex; + cursor: pointer; + &:hover { + background-color: var(--ads-v2-color-bg-subtle); + } + & .${Classes.EDITABLE_TEXT} { + height: ${(props) => props.theme.smallHeaderHeight} !important; + display: block; + cursor: pointer; + } + &&&& .${Classes.EDITABLE_TEXT}, &&&& .${Classes.EDITABLE_TEXT_EDITING} { + padding: 0; + width: 100%; + } + &&&& .${Classes.EDITABLE_TEXT_CONTENT}, &&&& .${Classes.EDITABLE_TEXT_INPUT} { + display: block; + ${getTypographyByKey("h5")}; + line-height: ${(props) => props.theme.smallHeaderHeight} !important; + padding: 0 ${(props) => props.theme.spaces[2]}px; + height: ${(props) => props.theme.smallHeaderHeight} !important; + } + &&&& .${Classes.EDITABLE_TEXT_INPUT} { + margin-right: 20px; + } +`; + +export const StyledIcon = styled(Icon)` + height: 100%; + padding-right: ${(props) => props.theme.spaces[2]}px; + align-self: center; +`; diff --git a/app/client/src/pages/Editor/EditorAppName/index.tsx b/app/client/src/pages/Editor/EditorName/index.tsx similarity index 62% rename from app/client/src/pages/Editor/EditorAppName/index.tsx rename to app/client/src/pages/Editor/EditorName/index.tsx index 10db95f714..c2267f818a 100644 --- a/app/client/src/pages/Editor/EditorAppName/index.tsx +++ b/app/client/src/pages/Editor/EditorName/index.tsx @@ -1,22 +1,25 @@ import React, { useState, useCallback } from "react"; -import styled, { useTheme } from "styled-components"; -import { Classes } from "@blueprintjs/core"; +import { useTheme } from "styled-components"; import type { noop } from "lodash"; import type { CommonComponentProps, EditInteractionKind, } from "design-system-old"; -import { getTypographyByKey, SavingState } from "design-system-old"; -import EditableAppName from "./EditableAppName"; -import { GetNavigationMenuData } from "./NavigationMenuData"; +import { SavingState } from "design-system-old"; +import EditableName from "./EditableName"; import { NavigationMenu } from "./NavigationMenu"; import type { Theme } from "constants/DefaultTheme"; -import { Icon, Menu, toast, MenuTrigger } from "design-system"; +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"; -type EditorAppNameProps = CommonComponentProps & { - applicationId: string | undefined; +type EditorNameProps = CommonComponentProps & { + applicationId?: string | undefined; defaultValue: string; placeholder?: string; editInteractionKind: EditInteractionKind; @@ -27,56 +30,30 @@ type EditorAppNameProps = CommonComponentProps & { hideEditIcon?: boolean; fill?: boolean; isError?: boolean; - isNewApp: boolean; + isNewEditor: boolean; isPopoverOpen: boolean; setIsPopoverOpen: typeof noop; + editorName: string; + getNavigationMenu: ({ + editMode, + setForkApplicationModalOpen, + }: NavigationMenuDataProps) => MenuItemData[]; }; -const Container = styled.div` - display: flex; - cursor: pointer; - &:hover { - background-color: var(--ads-v2-color-bg-subtle); - } - & .${Classes.EDITABLE_TEXT} { - height: ${(props) => props.theme.smallHeaderHeight} !important; - display: block; - cursor: pointer; - } - &&&& .${Classes.EDITABLE_TEXT}, &&&& .${Classes.EDITABLE_TEXT_EDITING} { - padding: 0; - width: 100%; - } - &&&& .${Classes.EDITABLE_TEXT_CONTENT}, &&&& .${Classes.EDITABLE_TEXT_INPUT} { - display: block; - ${getTypographyByKey("h5")}; - line-height: ${(props) => props.theme.smallHeaderHeight} !important; - padding: 0 ${(props) => props.theme.spaces[2]}px; - height: ${(props) => props.theme.smallHeaderHeight} !important; - } - &&&& .${Classes.EDITABLE_TEXT_INPUT} { - margin-right: 20px; - } -`; - -const StyledIcon = styled(Icon)` - height: 100%; - padding-right: ${(props) => props.theme.spaces[2]}px; - align-self: center; -`; - -export function EditorAppName(props: EditorAppNameProps) { +export function EditorName(props: EditorNameProps) { const { defaultSavingState, defaultValue, - isNewApp, + editorName, + getNavigationMenu, + isNewEditor, isPopoverOpen, setIsPopoverOpen, } = props; const theme = useTheme() as Theme; - const [isEditingDefault, setIsEditingDefault] = useState(isNewApp); + const [isEditingDefault, setIsEditingDefault] = useState(isNewEditor); const [isEditing, setIsEditing] = useState(!!isEditingDefault); const [isInvalid, setIsInvalid] = useState(false); const [savingState, setSavingState] = useState( @@ -84,6 +61,7 @@ export function EditorAppName(props: EditorAppNameProps) { ); const [isForkApplicationModalopen, setForkApplicationModalOpen] = useState(false); + const currentAppId = useSelector(getCurrentApplicationId); const onBlur = (value: string) => { if (props.onBlur) props.onBlur(value); @@ -92,7 +70,7 @@ export function EditorAppName(props: EditorAppNameProps) { const inputValidation = (value: string) => { if (value.trim() === "") { - toast.show("Application name can't be empty", { + toast.show(`${editorName} name can't be empty`, { kind: "error", }); } @@ -110,7 +88,7 @@ export function EditorAppName(props: EditorAppNameProps) { [inputValidation, defaultValue], ); - const handleAppNameClick = useCallback(() => { + const handleNameClick = useCallback(() => { if (!isEditing) { setIsPopoverOpen((isOpen: boolean) => { return !isOpen; @@ -124,7 +102,7 @@ export function EditorAppName(props: EditorAppNameProps) { } }, []); - const NavigationMenuData = GetNavigationMenuData({ + const NavigationMenuData = getNavigationMenu({ editMode, theme, setForkApplicationModalOpen, @@ -133,16 +111,13 @@ export function EditorAppName(props: EditorAppNameProps) { return defaultValue !== "" ? ( <> - - + - { - setForkApplicationModalOpen(false); - }} - isInEditMode - isModalOpen={isForkApplicationModalopen} - /> + {props.applicationId || currentAppId ? ( + { + setForkApplicationModalOpen(false); + }} + isInEditMode + isModalOpen={isForkApplicationModalopen} + /> + ) : null} ) : null; } -export default EditorAppName; +export default EditorName; diff --git a/app/client/src/pages/Editor/EditorSaveIndicator.tsx b/app/client/src/pages/Editor/EditorSaveIndicator.tsx index 9e4d4775ef..52e1229ed8 100644 --- a/app/client/src/pages/Editor/EditorSaveIndicator.tsx +++ b/app/client/src/pages/Editor/EditorSaveIndicator.tsx @@ -1,9 +1,6 @@ import React from "react"; - -import { useSelector } from "react-redux"; import styled from "styled-components"; import { TextType, Text } from "design-system-old"; -import { getIsPageSaving, getPageSavingError } from "selectors/editorSelectors"; import { Colors } from "constants/Colors"; import { createMessage, EDITOR_HEADER } from "@appsmith/constants/messages"; import { Icon, Spinner } from "design-system"; @@ -13,17 +10,20 @@ const SaveStatusContainer = styled.div` display: flex; `; -export function EditorSaveIndicator() { - const isSaving = useSelector(getIsPageSaving); - const pageSaveError = useSelector(getPageSavingError); - +export function EditorSaveIndicator({ + isSaving, + saveError, +}: { + isSaving: boolean; + saveError: boolean; +}) { let saveStatusIcon: React.ReactNode; let saveStatusText = ""; if (isSaving) { saveStatusIcon = ; saveStatusText = createMessage(EDITOR_HEADER.saving); } else { - if (pageSaveError) { + if (saveError) { saveStatusIcon = ( ); @@ -31,7 +31,7 @@ export function EditorSaveIndicator() { } } - if (!pageSaveError && !isSaving) return null; + if (!saveError && !isSaving) return null; return ( diff --git a/app/client/src/reducers/entityReducers/index.ts b/app/client/src/reducers/entityReducers/index.ts deleted file mode 100644 index fd9feb4532..0000000000 --- a/app/client/src/reducers/entityReducers/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { combineReducers } from "redux"; -import appReducer from "./appReducer"; -import canvasWidgetsReducer from "./canvasWidgetsReducer"; -import canvasWidgetsStructureReducer from "./canvasWidgetsStructureReducer"; -import metaWidgetsReducer from "./metaWidgetsReducer"; -import datasourceReducer from "./datasourceReducer"; -import jsActionsReducer from "./jsActionsReducer"; -import jsExecutionsReducer from "./jsExecutionsReducer"; -import metaReducer from "./metaReducer"; -import pageListReducer from "./pageListReducer"; -import pluginsReducer from "reducers/entityReducers/pluginsReducer"; -import autoHeightLayoutTreeReducer from "./autoHeightReducers/autoHeightLayoutTreeReducer"; -import canvasLevelsReducer from "./autoHeightReducers/canvasLevelsReducer"; -import actionsReducer from "@appsmith/reducers/entityReducers/actionsReducer"; - -/* Reducers which are integrated into the core system when registering a pluggable module - or done so by a module that is designed to be eventually pluggable */ -import widgetPositionsReducer from "layoutSystems/anvil/integrations/reducers/widgetPositionsReducer"; - -const entityReducer = combineReducers({ - canvasWidgets: canvasWidgetsReducer, - canvasWidgetsStructure: canvasWidgetsStructureReducer, - metaWidgets: metaWidgetsReducer, - actions: actionsReducer, - datasources: datasourceReducer, - pageList: pageListReducer, - jsExecutions: jsExecutionsReducer, - plugins: pluginsReducer, - meta: metaReducer, - app: appReducer, - jsActions: jsActionsReducer, - autoHeightLayoutTree: autoHeightLayoutTreeReducer, - canvasLevels: canvasLevelsReducer, - widgetPositions: widgetPositionsReducer, -}); - -export default entityReducer;