diff --git a/app/client/src/ce/components/editorComponents/Debugger/ErrorLogs/getLogIconForEntity.tsx b/app/client/src/ce/components/editorComponents/Debugger/ErrorLogs/getLogIconForEntity.tsx index 0e02f7ae03..fafb6abbb0 100644 --- a/app/client/src/ce/components/editorComponents/Debugger/ErrorLogs/getLogIconForEntity.tsx +++ b/app/client/src/ce/components/editorComponents/Debugger/ErrorLogs/getLogIconForEntity.tsx @@ -1,5 +1,4 @@ import React from "react"; -import type { Plugin } from "api/PluginApi"; import type { LogItemProps } from "components/editorComponents/Debugger/ErrorLogs/ErrorLogItem"; import { PluginType } from "entities/Action"; import WidgetIcon from "pages/Editor/Explorer/Widgets/WidgetIcon"; @@ -13,7 +12,7 @@ import { ENTITY_TYPE } from "entities/DataTree/dataTreeFactory"; export const getIconForEntity: Record< string, - (props: LogItemProps, pluginGroups: Record) => any + (props: LogItemProps, pluginImages: Record) => any > = { [ENTITY_TYPE.WIDGET]: (props) => { if (props.source?.pluginType) { @@ -25,19 +24,16 @@ export const getIconForEntity: Record< [ENTITY_TYPE.JSACTION]: () => { return JsFileIconV2(16, 16, true, true); }, - [ENTITY_TYPE.ACTION]: (props, pluginGroups) => { + [ENTITY_TYPE.ACTION]: (props, pluginImages) => { const { iconId, source } = props; if (source?.pluginType === PluginType.API && source.httpMethod) { // If the source is an API action. return ApiMethodIcon(source.httpMethod, "16px", "32px", 50); - } else if (iconId && pluginGroups[iconId]) { + } else if (iconId && pluginImages[iconId]) { // If the source is a Datasource action. return ( - entityIcon + entityIcon ); } diff --git a/app/client/src/components/editorComponents/ActionCreator/helpers.tsx b/app/client/src/components/editorComponents/ActionCreator/helpers.tsx index 6b96ebc666..38b9cb3a2b 100644 --- a/app/client/src/components/editorComponents/ActionCreator/helpers.tsx +++ b/app/client/src/components/editorComponents/ActionCreator/helpers.tsx @@ -20,7 +20,6 @@ import type { JSAction, Variable } from "entities/JSCollection"; import keyBy from "lodash/keyBy"; import { getActionConfig } from "pages/Editor/Explorer/Actions/helpers"; import { JsFileIconV2 } from "pages/Editor/Explorer/ExplorerIcons"; -import { useMemo } from "react"; import { useDispatch, useSelector } from "react-redux"; import type { ActionData, @@ -69,9 +68,10 @@ import { setShowCreateNewModal } from "actions/propertyPaneActions"; import { setIdeEditorViewMode } from "actions/ideActions"; import { EditorViewMode } from "@appsmith/entities/IDE/constants"; import { getIsSideBySideEnabled } from "selectors/ideSelectors"; -import { resolveIcon } from "pages/Editor/utils"; +import { getModuleIcon, getPluginImagesFromPlugins } from "pages/Editor/utils"; import { getAllModules } from "@appsmith/selectors/modulesSelector"; import type { Module } from "@appsmith/constants/ModuleConstants"; +import type { Plugin } from "api/PluginApi"; const actionList: { label: string; @@ -396,7 +396,7 @@ export function useModalDropdownList(handleClose: () => void) { export function getApiQueriesAndJSActionOptionsWithChildren( pageId: string, - plugins: any, + plugins: Plugin[], actions: ActionDataState, jsActions: Array, dispatch: any, @@ -422,7 +422,7 @@ export function getApiQueriesAndJSActionOptionsWithChildren( } function getApiAndQueryOptions( - plugins: any, + plugins: Plugin[], actions: ActionDataState, dispatch: any, handleClose: () => void, @@ -431,6 +431,8 @@ function getApiAndQueryOptions( ) { const state = store.getState(); const isSideBySideEnabled = getIsSideBySideEnabled(state); + const pluginImages = getPluginImagesFromPlugins(plugins); + const pluginGroups: any = keyBy(plugins, "id"); const createQueryObject: TreeDropdownOption = { label: "New query", @@ -474,7 +476,7 @@ function getApiAndQueryOptions( type: queryOptions.value, icon: getActionConfig(api.config.pluginType)?.getIcon( api.config, - plugins[(api as any).config.datasource.pluginId], + pluginGroups[(api as any).config.datasource.pluginId], api.config.pluginType === PluginType.API, ), } as TreeDropdownOption); @@ -488,7 +490,7 @@ function getApiAndQueryOptions( type: queryOptions.value, icon: getActionConfig(query.config.pluginType)?.getIcon( query.config, - plugins[(query as any).config.datasource.pluginId], + pluginGroups[(query as any).config.datasource.pluginId], ), } as TreeDropdownOption); }); @@ -499,11 +501,7 @@ function getApiAndQueryOptions( id: instance.config.id, value: instance.config.name, type: queryOptions.value, - icon: resolveIcon({ - iconLocation: plugins[module.pluginId]?.iconLocation || "", - pluginType: module.pluginType, - moduleType: module.type, - }), + icon: getModuleIcon(module, pluginImages), } as TreeDropdownOption); }); } @@ -629,7 +627,6 @@ export function useApisQueriesAndJsActionOptions(handleClose: () => void) { const plugins = useSelector((state: AppState) => { return state.entities.plugins.list; }); - const pluginGroups: any = useMemo(() => keyBy(plugins, "id"), [plugins]); const actions = useSelector(getCurrentActions); const jsActions = useSelector(getCurrentJSCollections); const queryModuleInstances = useSelector( @@ -641,7 +638,7 @@ export function useApisQueriesAndJsActionOptions(handleClose: () => void) { // this function gets all the Queries/API's/JS Objects and attaches it to actionList return getApiQueriesAndJSActionOptionsWithChildren( pageId, - pluginGroups, + plugins, actions, jsActions, dispatch, diff --git a/app/client/src/components/editorComponents/Debugger/ErrorLogs/components/LogEntityLink.tsx b/app/client/src/components/editorComponents/Debugger/ErrorLogs/components/LogEntityLink.tsx index 2415a8f297..9e074a36e7 100644 --- a/app/client/src/components/editorComponents/Debugger/ErrorLogs/components/LogEntityLink.tsx +++ b/app/client/src/components/editorComponents/Debugger/ErrorLogs/components/LogEntityLink.tsx @@ -8,7 +8,7 @@ import { getPlugins } from "@appsmith/selectors/entitiesSelector"; import EntityLink from "../../EntityLink"; import { DebuggerLinkUI } from "components/editorComponents/Debugger/DebuggerEntityLink"; import { getIconForEntity } from "@appsmith/components/editorComponents/Debugger/ErrorLogs/getLogIconForEntity"; -import type { Plugin } from "api/PluginApi"; +import { getPluginImagesFromPlugins } from "pages/Editor/utils"; const EntityLinkWrapper = styled.div` display: flex; @@ -30,11 +30,11 @@ const IconWrapper = styled.span` `; // This function is used to fetch the icon component for the entity link. -const getIcon = (props: LogItemProps, pluginGroups: Record) => { +const getIcon = (props: LogItemProps, pluginImages: Record) => { const entityType = props.source?.type; let icon = null; if (entityType) { - icon = getIconForEntity[entityType](props, pluginGroups); + icon = getIconForEntity[entityType](props, pluginImages); } return icon || icon; }; @@ -43,6 +43,7 @@ const getIcon = (props: LogItemProps, pluginGroups: Record) => { export default function LogEntityLink(props: LogItemProps) { const plugins = useSelector(getPlugins); const pluginGroups = useMemo(() => keyBy(plugins, "id"), [plugins]); + const pluginImages = getPluginImagesFromPlugins(plugins); const plugin = props.iconId ? pluginGroups[props.iconId] : undefined; return ( @@ -55,7 +56,7 @@ export default function LogEntityLink(props: LogItemProps) { lineHeight: "14px", }} > - {getIcon(props, pluginGroups)} + {getIcon(props, pluginImages)} - - - ) - ); + return getModuleIcon(module, pluginImages); } else { const action = query as ActionData; return ( diff --git a/app/client/src/components/propertyControls/ActionSelectorControl.tsx b/app/client/src/components/propertyControls/ActionSelectorControl.tsx index ef4a73e6ac..53efb66192 100644 --- a/app/client/src/components/propertyControls/ActionSelectorControl.tsx +++ b/app/client/src/components/propertyControls/ActionSelectorControl.tsx @@ -22,7 +22,6 @@ import { getPlugins, } from "@appsmith/selectors/entitiesSelector"; import store from "store"; -import keyBy from "lodash/keyBy"; import { getCurrentPageId } from "selectors/editorSelectors"; import { getApiQueriesAndJSActionOptionsWithChildren } from "components/editorComponents/ActionCreator/helpers"; import { selectEvaluationVersion } from "@appsmith/selectors/applicationSelectors"; @@ -152,12 +151,11 @@ class ActionSelectorControl extends BaseControl { const pageId = getCurrentPageId(state); const plugins = getPlugins(state); - const pluginGroups: any = keyBy(plugins, "id"); // this function gets all the Queries/API's/JS Objects and attaches it to actionList const fieldOptions = getApiQueriesAndJSActionOptionsWithChildren( pageId, - pluginGroups, + plugins, actions, jsCollections, () => { diff --git a/app/client/src/pages/Editor/APIEditor/index.tsx b/app/client/src/pages/Editor/APIEditor/index.tsx index 90d7a519a3..7f1f5b7da2 100644 --- a/app/client/src/pages/Editor/APIEditor/index.tsx +++ b/app/client/src/pages/Editor/APIEditor/index.tsx @@ -40,6 +40,7 @@ import ConvertEntityNotification from "@appsmith/pages/common/ConvertEntityNotif import { useIsEditorPaneSegmentsEnabled } from "../IDE/hooks"; import { Icon } from "design-system"; import { resolveIcon } from "../utils"; +import { ENTITY_ICON_SIZE, EntityIcon } from "../Explorer/ExplorerIcons"; type ApiEditorWrapperProps = RouteComponentProps; @@ -72,7 +73,14 @@ function ApiEditorWrapper(props: ApiEditorWrapperProps) { iconLocation: pluginGroups[pluginId]?.iconLocation || "", pluginType: action?.pluginType || "", moduleType: action?.actionConfiguration?.body?.moduleType, - }) || ; + }) || ( + + + + ); const isChangePermitted = getHasManageActionPermission( isFeatureEnabled, diff --git a/app/client/src/pages/Editor/Explorer/ExplorerIcons.tsx b/app/client/src/pages/Editor/Explorer/ExplorerIcons.tsx index e1c760a333..7fd10420ba 100644 --- a/app/client/src/pages/Editor/Explorer/ExplorerIcons.tsx +++ b/app/client/src/pages/Editor/Explorer/ExplorerIcons.tsx @@ -337,3 +337,11 @@ export function AppsmithAIIcon() { export function ActionUrlIcon(url: string) { return ; } + +export function DefaultModuleIcon() { + return ( + + + + ); +} diff --git a/app/client/src/pages/Editor/QueryEditor/index.tsx b/app/client/src/pages/Editor/QueryEditor/index.tsx index e7c90460a7..5ca74efe6d 100644 --- a/app/client/src/pages/Editor/QueryEditor/index.tsx +++ b/app/client/src/pages/Editor/QueryEditor/index.tsx @@ -41,6 +41,7 @@ import { PluginType } from "entities/Action"; import { useIsEditorPaneSegmentsEnabled } from "../IDE/hooks"; import { Icon } from "design-system"; import { resolveIcon } from "../utils"; +import { ENTITY_ICON_SIZE, EntityIcon } from "../Explorer/ExplorerIcons"; type QueryEditorProps = RouteComponentProps; @@ -66,7 +67,14 @@ function QueryEditor(props: QueryEditorProps) { iconLocation: pluginImages[pluginId] || "", pluginType: action?.pluginType || "", moduleType: action?.actionConfiguration?.body?.moduleType, - }) || ; + }) || ( + + + + ); const isDeletePermitted = getHasDeleteActionPermission( isFeatureEnabled, diff --git a/app/client/src/pages/Editor/utils.tsx b/app/client/src/pages/Editor/utils.tsx index 03597d3b22..fab1158cc4 100644 --- a/app/client/src/pages/Editor/utils.tsx +++ b/app/client/src/pages/Editor/utils.tsx @@ -20,6 +20,7 @@ import { useSelector } from "react-redux"; import { getCurrentPageId } from "selectors/editorSelectors"; import type { WidgetCardProps } from "widgets/BaseWidget"; import type { ActionResponse } from "api/ActionAPI"; +import type { Module } from "@appsmith/constants/ModuleConstants"; import { MODULE_TYPE } from "@appsmith/constants/ModuleConstants"; import { ENTITY_ICON_SIZE, @@ -29,6 +30,9 @@ import { } from "pages/Editor/Explorer/ExplorerIcons"; import { PluginType } from "entities/Action"; import { getAssetUrl } from "@appsmith/utils/airgapHelpers"; +import type { Plugin } from "api/PluginApi"; +import ImageAlt from "assets/images/placeholder-image.svg"; +import { Icon } from "design-system"; export const draggableElement = ( id: string, @@ -381,3 +385,33 @@ export function resolveIcon({ return resolveQueryModuleIcon(iconLocation, pluginType, isLargeIcon); } } + +export function getModuleIcon( + module: Module | undefined, + pluginImages: Record, + isLargeIcon = false, +) { + return module ? ( + resolveIcon({ + iconLocation: pluginImages[module.pluginId] || "", + pluginType: module.pluginType, + moduleType: module.type, + isLargeIcon, + }) + ) : ( + + + + ); +} + +export function getPluginImagesFromPlugins(plugins: Plugin[]) { + const pluginImages: Record = {}; + plugins.forEach((plugin) => { + pluginImages[plugin.id] = plugin?.iconLocation ?? ImageAlt; + }); + return pluginImages; +}