Skip to content

Commit

Permalink
feat: added an ads entity context menu template component (#39358)
Browse files Browse the repository at this point in the history
## Description
Extracted EntityContextMenu, used in EntityItems, into ADS templates.


Fixes #39355


## Automation

/ok-to-test tags="@tag.Sanity"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/13408405832>
> Commit: 7296773
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13408405832&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Sanity`
> Spec:
> <hr>Wed, 19 Feb 2025 09:11:12 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced an interactive context menu component featuring options
such as Rename, Copy, and Delete with a tooltip display.
- Added a demonstration story to preview the new component in an
interactive development environment.
- Enhanced styling to provide a refined and consistent user interface
for the context menu.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
alex-golovanov authored Feb 20, 2025
1 parent 8d4f616 commit 0fdac20
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* eslint-disable no-console */
import React from "react";
import type { Meta, StoryObj } from "@storybook/react";

import { MenuItem } from "../../Menu";
import { EntityContextMenu } from "./EntityContextMenu";

const meta: Meta<typeof EntityContextMenu> = {
title: "ADS/Templates/Entity Context Menu",
component: EntityContextMenu,
};

export default meta;

type Story = StoryObj<typeof EntityContextMenu>;

export const Basic: Story = {
args: {
tooltipContent: "More actions",
children: (
<>
<MenuItem onClick={console.log} startIcon="edit-line">
Rename
</MenuItem>
<MenuItem onClick={console.log} startIcon="copy-control">
Copy
</MenuItem>
<MenuItem onClick={console.log} startIcon="delete">
Delete
</MenuItem>
</>
),
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import styled from "styled-components";

import { MenuContent as ADSMenuContent } from "../../Menu";

export const MenuContent = styled(ADSMenuContent)`
width: 220px;
max-height: unset;
`;

export const ButtonContainer = styled.div`
position: relative;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from "react";
import { useToggle } from "usehooks-ts";

import { Button } from "../../Button";
import { Menu, MenuTrigger } from "../../Menu";
import { Tooltip } from "../../Tooltip";

import {
EntityClassNames,
DEFAULT_DATA_TEST_ID,
DEFAULT_TOOLTIP_CONTENT,
} from "./constants";

import * as Styled from "./EntityContextMenu.styles";

interface Props {
dataTestid?: string;
children?: React.ReactNode[] | React.ReactNode;
tooltipContent?: React.ReactNode;
}

export const EntityContextMenu = (props: Props) => {
const {
children,
dataTestid = DEFAULT_DATA_TEST_ID,
tooltipContent = DEFAULT_TOOLTIP_CONTENT,
} = props;

const [isMenuOpen, toggleMenuOpen] = useToggle();

return (
<Menu onOpenChange={toggleMenuOpen} open={isMenuOpen}>
<MenuTrigger className="t--context-menu">
<Styled.ButtonContainer>
<Tooltip
content={tooltipContent}
isDisabled={isMenuOpen}
mouseLeaveDelay={0}
placement="right"
>
<Button
className={EntityClassNames.CONTEXT_MENU}
data-testid={dataTestid}
isIconButton
kind="tertiary"
startIcon="more-2-fill"
/>
</Tooltip>
</Styled.ButtonContainer>
</MenuTrigger>
<Styled.MenuContent
align="start"
className={`t--entity-context-menu ${EntityClassNames.CONTEXT_MENU_CONTENT}`}
side="right"
>
{children}
</Styled.MenuContent>
</Menu>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export enum EntityClassNames {
CONTEXT_MENU = "entity-context-menu",
CONTEXT_MENU_CONTENT = "entity-context-menu-content",
}

export const DEFAULT_DATA_TEST_ID = "t--more-action-trigger";
export const DEFAULT_TOOLTIP_CONTENT = "More actions";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { EntityContextMenu } from "./EntityContextMenu";
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from "./Sidebar";
export * from "./EditableEntityName";
export * from "./EditableDismissibleTab";
export * from "./EntityTabsHeader";
export * from "./EntityContextMenu";
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useCallback, useMemo } from "react";
import { EntityItem } from "@appsmith/ads";
import { EntityItem, EntityContextMenu } from "@appsmith/ads";
import type { AppState } from "ee/reducers";
import { getJsCollectionByBaseId } from "ee/selectors/entitiesSelector";
import { useDispatch, useSelector } from "react-redux";
Expand All @@ -20,7 +20,6 @@ import { jsCollectionIdURL } from "ee/RouteBuilder";
import { JsFileIconV2 } from "pages/Editor/Explorer/ExplorerIcons";
import { AppJSContextMenuItems } from "./AppJSContextMenuItems";
import type { EntityItem as EntityItemProps } from "ee/IDE/Interfaces/EntityItem";
import EntityContextMenu from "IDE/Components/EntityContextMenu";

export const JSEntityItem = ({ item }: { item: EntityItemProps }) => {
const jsAction = useSelector((state: AppState) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useCallback, useMemo } from "react";
import { EntityItem } from "@appsmith/ads";
import { EntityItem, EntityContextMenu } from "@appsmith/ads";
import type { AppState } from "ee/reducers";
import {
getActionByBaseId,
Expand All @@ -25,7 +25,6 @@ import { useActiveActionBaseId } from "ee/pages/Editor/Explorer/hooks";
import { PluginType } from "entities/Plugin";
import { useParentEntityInfo } from "ee/IDE/hooks/useParentEntityInfo";
import { AppQueryContextMenuItems } from "./AppQueryContextMenuItems";
import EntityContextMenu from "IDE/Components/EntityContextMenu";
import type { EntityItem as EntityItemProps } from "ee/IDE/Interfaces/EntityItem";

export const QueryEntityItem = ({ item }: { item: EntityItemProps }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import type { JSCollection } from "entities/JSCollection";
import { Copy, Delete, Move, Prettify } from "./ContextMenuItems";
import { RenameMenuItem } from "IDE";
import { MenuSeparator } from "@appsmith/ads";
import EntityContextMenu from "IDE/Components/EntityContextMenu";
import { MenuSeparator, EntityContextMenu } from "@appsmith/ads";
import { InspectStateMenuItem } from "components/editorComponents/Debugger/StateInspector/CTAs";

interface AppJSEditorContextMenuProps {
Expand Down

0 comments on commit 0fdac20

Please sign in to comment.