fix: icon ds missing when plugin not present (#40327)

This commit is contained in:
Aman Agarwal 2025-04-23 15:23:10 +05:30 committed by GitHub
parent ea214c254f
commit 68354422eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 42 additions and 47 deletions

View File

@ -12,7 +12,7 @@ import { Flex } from "@appsmith/ads";
import styled from "styled-components";
import { noop } from "lodash";
import { EditableName, useIsRenaming } from "IDE";
import ImageAlt from "assets/images/placeholder-image.svg";
export interface SaveActionNameParams {
id: string;
name: string;
@ -64,7 +64,7 @@ const PluginActionNameEditor = ({
isFeatureEnabled,
action?.userPermissions,
);
const iconUrl = getAssetUrl(plugin?.iconLocation) || "";
const iconUrl = getAssetUrl(plugin?.iconLocation ?? ImageAlt);
const icon = ActionUrlIcon(iconUrl);
const handleDoubleClick = isChangePermitted ? enterEditMode : noop;

View File

@ -598,15 +598,25 @@ export const getDatasourcePlugins = createSelector(getPlugins, (plugins) => {
return plugins.filter((plugin) => plugin?.allowUserDatasources ?? true);
});
export const getPluginImages = createSelector(getPlugins, (plugins) => {
const pluginImages: Record<string, string> = {};
export const getPluginImages = createSelector(
getPlugins,
getDatasources,
(plugins, datasources) => {
const pluginImages: Record<string, string> = {};
plugins.forEach((plugin) => {
pluginImages[plugin.id] = plugin?.iconLocation ?? ImageAlt;
});
plugins.forEach((plugin) => {
pluginImages[plugin.id] = plugin?.iconLocation ?? ImageAlt;
});
return pluginImages;
});
datasources.forEach((datasource) => {
if (!pluginImages[datasource.pluginId]) {
pluginImages[datasource.pluginId] = ImageAlt;
}
});
return pluginImages;
},
);
export const getPluginNames = createSelector(getPlugins, (plugins) => {
const pluginNames: Record<string, string> = {};
@ -1676,7 +1686,7 @@ export const getQuerySegmentItems = createSelector(
const items: EntityItem[] = actions.map((action) => {
let group;
const iconUrl = getAssetUrl(
pluginGroups[action.config.pluginId]?.iconLocation,
pluginGroups[action.config.pluginId]?.iconLocation ?? ImageAlt,
);
if (action.config.pluginType === PluginType.API) {

View File

@ -32,6 +32,7 @@ import {
getCurrentJSCollections,
getQueryModuleInstances,
getJSModuleInstancesData,
getPluginImages,
} from "ee/selectors/entitiesSelector";
import {
getModalDropdownList,
@ -64,7 +65,7 @@ import { selectEvaluationVersion } from "ee/selectors/applicationSelectors";
import { isJSAction } from "ee/workers/Evaluation/evaluationUtils";
import type { DataTreeEntity } from "entities/DataTree/dataTreeTypes";
import type { ModuleInstanceDataState } from "ee/constants/ModuleInstanceConstants";
import { getModuleIcon, getPluginImagesFromPlugins } from "pages/Editor/utils";
import { getModuleIcon } from "pages/Editor/utils";
import { getAllModules } from "ee/selectors/modulesSelector";
import type { Module } from "ee/constants/ModuleConstants";
import {
@ -420,6 +421,7 @@ export function getApiQueriesAndJSActionOptionsWithChildren(
queryModuleInstances: ModuleInstanceDataState,
jsModuleInstances: ReturnType<typeof getJSModuleInstancesData>,
modules: Record<string, Module>,
pluginImages: Record<string, string>,
) {
// this function gets a list of all the queries/apis and attaches it to actionList
getApiAndQueryOptions(
@ -429,6 +431,7 @@ export function getApiQueriesAndJSActionOptionsWithChildren(
handleClose,
queryModuleInstances,
modules,
pluginImages,
);
// this function gets a list of all the JS Objects and attaches it to actionList
@ -446,8 +449,8 @@ function getApiAndQueryOptions(
handleClose: () => void,
queryModuleInstances: ModuleInstanceDataState,
modules: Record<string, Module>,
pluginImages: Record<string, string>,
) {
const pluginImages = getPluginImagesFromPlugins(plugins);
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const pluginGroups: any = keyBy(plugins, "id");
@ -686,6 +689,7 @@ export function useApisQueriesAndJsActionOptions(handleClose: () => void) {
) as unknown as ModuleInstanceDataState;
const jsModuleInstancesData = useSelector(getJSModuleInstancesData);
const modules = useSelector(getAllModules);
const pluginImages = useSelector(getPluginImages);
// this function gets all the Queries/API's/JS Objects and attaches it to actionList
return getApiQueriesAndJSActionOptionsWithChildren(
@ -698,5 +702,6 @@ export function useApisQueriesAndJsActionOptions(handleClose: () => void) {
queryModuleInstances,
jsModuleInstancesData,
modules,
pluginImages,
);
}

View File

@ -4,11 +4,10 @@ import { useSelector } from "react-redux";
import { keyBy } from "lodash";
import type { LogItemProps } from "../ErrorLogItem";
import { Colors } from "constants/Colors";
import { getPlugins } from "ee/selectors/entitiesSelector";
import { getPluginImages, getPlugins } from "ee/selectors/entitiesSelector";
import EntityLink from "../../EntityLink";
import { DebuggerLinkUI } from "components/editorComponents/Debugger/DebuggerEntityLink";
import { getIconForEntity } from "ee/components/editorComponents/Debugger/ErrorLogs/getLogIconForEntity";
import { getPluginImagesFromPlugins } from "pages/Editor/utils";
const EntityLinkWrapper = styled.div`
display: flex;
@ -50,7 +49,7 @@ const getIcon = (props: LogItemProps, pluginImages: Record<string, string>) => {
export default function LogEntityLink(props: LogItemProps) {
const plugins = useSelector(getPlugins);
const pluginGroups = useMemo(() => keyBy(plugins, "id"), [plugins]);
const pluginImages = getPluginImagesFromPlugins(plugins);
const pluginImages = useSelector(getPluginImages);
const plugin = props.iconId ? pluginGroups[props.iconId] : undefined;

View File

@ -19,6 +19,7 @@ import {
getAllJSCollections,
getJSModuleInstancesData,
getModuleInstances,
getPluginImages,
getPlugins,
} from "ee/selectors/entitiesSelector";
import store from "store";
@ -115,6 +116,7 @@ class ActionSelectorControl extends BaseControl<ControlProps> {
const queryModuleInstances = [] as ModuleInstanceDataState;
const jsModuleInstances = getJSModuleInstancesData(state);
const modules = getAllModules(state);
const pluginImages = getPluginImages(state);
if (!!moduleInstances) {
for (const moduleInstance of Object.values(moduleInstances)) {
@ -174,6 +176,7 @@ class ActionSelectorControl extends BaseControl<ControlProps> {
queryModuleInstances,
jsModuleInstances,
modules,
pluginImages,
);
try {

View File

@ -5,12 +5,12 @@ import { useSelector } from "react-redux";
import {
getDatasources,
getDatasourcesGroupedByPluginCategory,
getPlugins,
getPluginImages,
} from "ee/selectors/entitiesSelector";
import history from "utils/history";
import { datasourcesEditorIdURL, integrationEditorURL } from "ee/RouteBuilder";
import { getSelectedDatasourceId } from "ee/navigation/FocusSelectors";
import { get, keyBy } from "lodash";
import { get } from "lodash";
import CreateDatasourceButton from "./CreateDatasourceButton";
import { useLocation } from "react-router";
import {
@ -53,8 +53,7 @@ export const DataSidePane = (props: DataSidePaneProps) => {
>("");
const datasources = useSelector(getDatasources);
const groupedDatasources = useSelector(getDatasourcesGroupedByPluginCategory);
const plugins = useSelector(getPlugins);
const groupedPlugins = keyBy(plugins, "id");
const pluginImages = useSelector(getPluginImages);
const location = useLocation();
const goToDatasource = useCallback((id: string) => {
history.push(datasourcesEditorIdURL({ datasourceId: id }));
@ -123,9 +122,7 @@ export const DataSidePane = (props: DataSidePaneProps) => {
title: data.name,
startIcon: (
<DatasourceIcon
src={getAssetUrl(
groupedPlugins[data.pluginId]?.iconLocation || "",
)}
src={getAssetUrl(pluginImages[data.pluginId])}
/>
),
description: get(dsUsageMap, data.id, ""),

View File

@ -6,6 +6,7 @@ import styled from "styled-components";
import { getAssetUrl } from "ee/utils/airgapHelpers";
import { PluginImage } from "pages/Editor/DataSourceEditor/DSFormHeader";
import { isEnvironmentConfigured } from "ee/utils/Environments";
import ImageAlt from "assets/images/placeholder-image.svg";
import type { Plugin } from "entities/Plugin";
import {
isDatasourceAuthorizedForQueryCreation,
@ -76,7 +77,10 @@ function ListItemWrapper(props: {
className={`t--ds-list ${selected ? "active" : ""}`}
onClick={() => onClick(ds)}
>
<PluginImage alt="Datasource" src={getAssetUrl(plugin?.iconLocation)} />
<PluginImage
alt="Datasource"
src={getAssetUrl(plugin?.iconLocation || ImageAlt)}
/>
<ListLabels>
<Tooltip content={ds.name} placement="left">
<DsTitle>

View File

@ -28,8 +28,7 @@ import {
JsFileIconV2,
} from "pages/Editor/Explorer/ExplorerIcons";
import { getAssetUrl } from "ee/utils/airgapHelpers";
import { type Plugin, PluginType } from "entities/Plugin";
import ImageAlt from "assets/images/placeholder-image.svg";
import { PluginType } from "entities/Plugin";
import { Icon } from "@appsmith/ads";
import { objectKeys } from "@appsmith/utils";
@ -438,13 +437,3 @@ export function getModuleIcon(
</EntityIcon>
);
}
export function getPluginImagesFromPlugins(plugins: Plugin[]) {
const pluginImages: Record<string, string> = {};
plugins.forEach((plugin) => {
pluginImages[plugin.id] = plugin?.iconLocation ?? ImageAlt;
});
return pluginImages;
}

View File

@ -169,18 +169,6 @@ export const getExistingActionNames = createSelector(
},
);
export const getPluginIdToImageLocation = createSelector(
getPlugins,
(plugins) =>
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
plugins.reduce((acc: any, p: Plugin) => {
acc[p.id] = p.iconLocation;
return acc;
}, {}),
);
/**
* returns a objects of existing page name in data tree
*