Skip to content

Commit

Permalink
chore: Replace entities in entity explorer with new ADS templates (#3…
Browse files Browse the repository at this point in the history
…8750)

## Description

Replace entities in entity explorer with new ADS templates

Fixes [#38286](#38286)
[#39289](#38289)

## Automation

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

### 🔍 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/12945261277>
> Commit: bf508e2
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12945261277&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Fri, 24 Jan 2025 08:55:33 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

## Summary by CodeRabbit

## Release Notes

- **New Features**
  - Added new context menu components for JavaScript and Query entities.
- Introduced enhanced entity item rendering for JavaScript and Query
collections.
  - Implemented more granular permission-based context menu actions.
- Added new components: `Rename`, `Copy`, `Move`, `Delete`,
`ShowBindings`, `Prettify`, and `EntityContextMenu`.

- **Improvements**
  - Streamlined context menu functionality across editor interfaces.
  - Enhanced user permissions handling for entity actions.
  - Improved modularity of editor components.
- Updated rendering logic for JavaScript and Query lists based on
feature flags.

- **Bug Fixes**
  - Refined component prop management.
- Updated navigation and analytics event logging for entity
interactions.

- **Refactoring**
  - Simplified component structures.
  - Removed deprecated prop usage.
  - Consolidated import and export statements.

These changes primarily focus on improving the user experience and
developer flexibility within the application's editor interfaces.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
ankitakinger authored Jan 24, 2025
1 parent eb72ece commit 8f5aad9
Show file tree
Hide file tree
Showing 42 changed files with 1,104 additions and 525 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useCallback } from "react";
import { MenuItem } from "@appsmith/ads";
import { useDispatch } from "react-redux";
import { setRenameEntity } from "actions/ideActions";
import { CONTEXT_RENAME, createMessage } from "ee/constants/messages";

interface Props {
disabled?: boolean;
Expand All @@ -24,7 +25,7 @@ export const RenameMenuItem = ({ disabled, entityId }: Props) => {
onSelect={setRename}
startIcon="input-cursor-move"
>
Rename
{createMessage(CONTEXT_RENAME)}
</MenuItem>
);
};
26 changes: 3 additions & 23 deletions app/client/src/ce/pages/Editor/IDE/EditorPane/JS/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,7 @@
import React from "react";
import ExplorerJSCollectionEntity from "pages/Editor/Explorer/JSActions/JSActionEntity";
import { Flex } from "@appsmith/ads";
import type { EntityItem } from "ee/entities/IDE/constants";
import { JSEntityItem } from "pages/Editor/IDE/EditorPane/JS/EntityItem/JSEntityItem";

export interface JSListItemProps {
item: EntityItem;
isActive: boolean;
parentEntityId: string;
}

export const JSListItem = (props: JSListItemProps) => {
const { isActive, item, parentEntityId } = props;

return (
<Flex data-testid="t--ide-list-item" flexDirection={"column"}>
<ExplorerJSCollectionEntity
baseCollectionId={item.key}
isActive={isActive}
key={item.key}
parentEntityId={parentEntityId}
searchKeyword={""}
step={1}
/>
</Flex>
);
export const JSEntity = (props: { item: EntityItem }) => {
return <JSEntityItem {...props} />;
};
27 changes: 27 additions & 0 deletions app/client/src/ce/pages/Editor/IDE/EditorPane/JS/old/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import ExplorerJSCollectionEntity from "pages/Editor/Explorer/JSActions/JSActionEntity";
import { Flex } from "@appsmith/ads";
import type { EntityItem } from "ee/entities/IDE/constants";

export interface JSListItemProps {
item: EntityItem;
isActive: boolean;
parentEntityId: string;
}

export const JSListItem = (props: JSListItemProps) => {
const { isActive, item, parentEntityId } = props;

return (
<Flex data-testid="t--ide-list-item" flexDirection={"column"}>
<ExplorerJSCollectionEntity
baseCollectionId={item.key}
isActive={isActive}
key={item.key}
parentEntityId={parentEntityId}
searchKeyword={""}
step={1}
/>
</Flex>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from "react";
import { IDE_TYPE, type IDEType } from "ee/entities/IDE/constants";
import EntityContextMenu from "pages/Editor/IDE/EditorPane/components/EntityContextMenu";
import { AppJSContextMenuItems } from "pages/Editor/IDE/EditorPane/JS/EntityItem/AppJSContextMenuItems";
import type { JSCollection } from "entities/JSCollection";

export const getJSContextMenuByIdeType = (
ideType: IDEType,
jsAction: JSCollection,
) => {
switch (ideType) {
case IDE_TYPE.App: {
return (
<EntityContextMenu>
<AppJSContextMenuItems jsAction={jsAction} />
</EntityContextMenu>
);
}
}
};
24 changes: 3 additions & 21 deletions app/client/src/ce/pages/Editor/IDE/EditorPane/Query/ListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,7 @@
import React from "react";
import ExplorerActionEntity from "pages/Editor/Explorer/Actions/ActionEntity";
import { QueryEntityItem } from "pages/Editor/IDE/EditorPane/Query/EntityItem/QueryEntityItem";
import type { EntityItem } from "ee/entities/IDE/constants";

export interface QueryListItemProps {
item: EntityItem;
isActive: boolean;
parentEntityId: string;
}

export const QueryListItem = (props: QueryListItemProps) => {
const { isActive, item, parentEntityId } = props;

return (
<ExplorerActionEntity
baseId={item.key}
isActive={isActive}
key={item.key}
parentEntityId={parentEntityId}
searchKeyword={""}
step={1}
type={item.type}
/>
);
export const ActionEntityItem = (props: { item: EntityItem }) => {
return <QueryEntityItem {...props} />;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from "react";
import ExplorerActionEntity from "pages/Editor/Explorer/Actions/ActionEntity";
import type { EntityItem } from "ee/entities/IDE/constants";

export interface QueryListItemProps {
item: EntityItem;
isActive: boolean;
parentEntityId: string;
}

export const QueryListItem = (props: QueryListItemProps) => {
const { isActive, item, parentEntityId } = props;

return (
<ExplorerActionEntity
baseId={item.key}
isActive={isActive}
key={item.key}
parentEntityId={parentEntityId}
searchKeyword={""}
step={1}
type={item.type}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from "react";
import { IDE_TYPE, type IDEType } from "ee/entities/IDE/constants";
import type { Action } from "entities/Action";
import { AppQueryContextMenuItems } from "pages/Editor/IDE/EditorPane/Query/EntityItem/AppQueryContextMenuItems";
import EntityContextMenu from "pages/Editor/IDE/EditorPane/components/EntityContextMenu";

export const getQueryContextMenuByIdeType = (
ideType: IDEType,
action: Action,
) => {
switch (ideType) {
case IDE_TYPE.App: {
return (
<EntityContextMenu>
<AppQueryContextMenuItems action={action} />
</EntityContextMenu>
);
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "ce/pages/Editor/IDE/EditorPane/JS/old/ListItem";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "ce/pages/Editor/IDE/EditorPane/JS/utils/getJSContextMenuByIdeType";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "ce/pages/Editor/IDE/EditorPane/Query/old/ListItem";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "ce/pages/Editor/IDE/EditorPane/Query/utils/getQueryContextMenuByIdeType";
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from "react";
import { usePluginActionContext } from "PluginActionEditor";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import { useSelector } from "react-redux";
Expand All @@ -11,21 +10,27 @@ import {
import { MODULE_TYPE } from "ee/constants/ModuleConstants";
import ConvertToModuleInstanceCTA from "ee/pages/Editor/EntityEditor/ConvertToModuleInstanceCTA";
import { PluginType } from "entities/Plugin";
import type { Action } from "entities/Action";

const ConvertToModuleCTA = () => {
const { action, plugin } = usePluginActionContext();
const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled);
interface Props {
action: Action;
}

export const ConvertToModule = ({ action }: Props) => {
const pagePermissions = useSelector(getPagePermissions);
const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled);

const isCreatePermitted = getHasCreateActionPermission(
isFeatureEnabled,
pagePermissions,
);

const isDeletePermitted = getHasDeleteActionPermission(
isFeatureEnabled,
action.userPermissions,
);

if (plugin.type === PluginType.INTERNAL) {
if (action.pluginType === PluginType.INTERNAL) {
// Workflow queries cannot be converted to modules
return null;
}
Expand All @@ -39,5 +44,3 @@ const ConvertToModuleCTA = () => {

return <ConvertToModuleInstanceCTA {...convertToModuleProps} />;
};

export default ConvertToModuleCTA;
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import React from "react";
import { MenuSub, MenuSubContent, MenuSubTrigger } from "@appsmith/ads";
import { useDispatch, useSelector } from "react-redux";
import { getPageList } from "ee/selectors/entitiesSelector";
import { usePluginActionContext } from "PluginActionEditor";
import React, { useCallback } from "react";
import { getPageList } from "selectors/editorSelectors";
import { PageMenuItem } from "./PageMenuItem";
import { useCallback } from "react";
import type { Action } from "entities/Action";
import { copyActionRequest } from "actions/pluginActionActions";
import { MenuSub, MenuSubContent, MenuSubTrigger } from "@appsmith/ads";
import { CONTEXT_COPY, createMessage } from "ee/constants/messages";
import { PageMenuItem } from "./PageMenuItem";

interface Props {
action: Action;
disabled?: boolean;
}

export const Copy = ({ disabled }: Props) => {
export const Copy = ({ action, disabled }: Props) => {
const menuPages = useSelector(getPageList);
const { action } = usePluginActionContext();
const dispatch = useDispatch();

const copyActionToPage = useCallback(
Expand All @@ -30,13 +31,14 @@ export const Copy = ({ disabled }: Props) => {

return (
<MenuSub>
<MenuSubTrigger disabled={disabled} startIcon="duplicate">
<MenuSubTrigger startIcon="duplicate">
{createMessage(CONTEXT_COPY)}
</MenuSubTrigger>
<MenuSubContent>
<MenuSubContent style={{ maxHeight: "350px" }} width="220px">
{menuPages.map((page) => {
return (
<PageMenuItem
disabled={disabled}
key={page.basePageId}
onSelect={copyActionToPage}
page={page}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,41 @@
import { useHandleDeleteClick } from "PluginActionEditor/hooks";
import React, { useCallback, useState } from "react";
import {
CONFIRM_CONTEXT_DELETE,
CONTEXT_DELETE,
createMessage,
} from "ee/constants/messages";
import { MenuItem } from "@appsmith/ads";
import { useDispatch } from "react-redux";
import { deleteAction } from "actions/pluginActionActions";
import type { Action } from "entities/Action";

interface Props {
action: Action;
disabled?: boolean;
}

export const Delete = ({ disabled }: Props) => {
const { handleDeleteClick } = useHandleDeleteClick();
export const Delete = ({ action, disabled }: Props) => {
const dispatch = useDispatch();
const [confirmDelete, setConfirmDelete] = useState(false);

const handleDeleteClick = useCallback(
({ onSuccess }: { onSuccess?: () => void }) => {
dispatch(
deleteAction({
id: action?.id ?? "",
name: action?.name ?? "",
onSuccess,
}),
);
},
[action.id, action.name, dispatch],
);

const handleSelect = useCallback(
(e?: Event) => {
e?.preventDefault();
confirmDelete ? handleDeleteClick({}) : setConfirmDelete(true);
e?.stopPropagation();
},
[confirmDelete, handleDeleteClick],
);
Expand All @@ -29,7 +46,7 @@ export const Delete = ({ disabled }: Props) => {

return (
<MenuItem
className="t--apiFormDeleteBtn error-menuitem"
className="t--apiFormDeleteBtn single-select error-menuitem"
disabled={disabled}
onSelect={handleSelect}
startIcon="trash"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useDispatch, useSelector } from "react-redux";
import { usePluginActionContext } from "PluginActionEditor";
import { getCurrentPageId } from "selectors/editorSelectors";
import { getPageList } from "ee/selectors/entitiesSelector";
import React, { useCallback, useMemo } from "react";
Expand All @@ -12,14 +11,15 @@ import {
} from "@appsmith/ads";
import { CONTEXT_MOVE, createMessage } from "ee/constants/messages";
import { PageMenuItem } from "./PageMenuItem";
import type { Action } from "entities/Action";

interface Props {
action: Action;
disabled?: boolean;
}

export const Move = ({ disabled }: Props) => {
export const Move = ({ action, disabled }: Props) => {
const dispatch = useDispatch();
const { action } = usePluginActionContext();

const currentPageId = useSelector(getCurrentPageId);
const allPages = useSelector(getPageList);
Expand All @@ -42,14 +42,15 @@ export const Move = ({ disabled }: Props) => {

return (
<MenuSub>
<MenuSubTrigger disabled={disabled} startIcon="swap-horizontal">
<MenuSubTrigger startIcon="swap-horizontal">
{createMessage(CONTEXT_MOVE)}
</MenuSubTrigger>
<MenuSubContent>
<MenuSubContent style={{ maxHeight: "350px" }} width="220px">
{menuPages.length ? (
menuPages.map((page) => {
return (
<PageMenuItem
disabled={disabled}
key={page.basePageId}
onSelect={moveActionToPage}
page={page}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ import { MenuItem } from "@appsmith/ads";
export const PageMenuItem = (props: {
page: Page;
onSelect: (id: string) => void;
disabled?: boolean;
}) => {
const handleOnSelect = useCallback(() => {
props.onSelect(props.page.pageId);
}, [props]);

return <MenuItem onSelect={handleOnSelect}>{props.page.pageName}</MenuItem>;
return (
<MenuItem disabled={props.disabled} onSelect={handleOnSelect}>
{props.page.pageName}
</MenuItem>
);
};
Loading

0 comments on commit 8f5aad9

Please sign in to comment.