Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,32 +1,30 @@
import React from "react";
import { Flex } from "@appsmith/ads";
import { Flex, Icon } from "@appsmith/ads";
import { getAssetUrl } from "ee/utils/airgapHelpers";
import { EntityIcon } from "pages/Editor/Explorer/ExplorerIcons";
import { useSelector } from "react-redux";
import {
getPluginIdFromDatasourceId,
getPluginImages,
} from "ee/selectors/entitiesSelector";
import { getPluginImages } from "ee/selectors/entitiesSelector";

interface Props {
datasourceId: string;
datasourceName: string;
pluginId: string;
}

const CurrentDataSource = ({ datasourceId, datasourceName }: Props) => {
const { pluginId, pluginImages } = useSelector((state) => ({
pluginId: getPluginIdFromDatasourceId(state, datasourceId),
pluginImages: getPluginImages(state),
}));
const CurrentDataSource = ({ datasourceName, pluginId }: Props) => {
const pluginImages = useSelector((state) => getPluginImages(state));

const datasourceIcon = pluginId ? pluginImages?.[pluginId] : undefined;

return (
<Flex alignItems="center" gap="spaces-2">
<EntityIcon height="16px" width="16px">
<img alt="entityIcon" src={getAssetUrl(datasourceIcon)} />
{datasourceIcon ? (
<img alt="entityIcon" src={getAssetUrl(datasourceIcon)} />
) : (
<Icon name="datasource-v3" />
)}
</EntityIcon>
{datasourceName}
{datasourceName || "NA"}
</Flex>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import { useGoToDatasource } from "PluginActionEditor/components/PluginActionRes
const CurrentDataSourceLink = ({
datasourceId,
datasourceName,
pluginId,
}: {
datasourceId: string;
datasourceName: string;
pluginId: string;
}) => {
const { goToDatasource } = useGoToDatasource();

Expand All @@ -19,10 +21,7 @@ const CurrentDataSourceLink = ({

return (
<Link onClick={handleClick}>
<CurrentDataSource
datasourceId={datasourceId}
datasourceName={datasourceName}
/>
<CurrentDataSource datasourceName={datasourceName} pluginId={pluginId} />
</Link>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const DatasourceInfo = ({
datasourceName={datasourceName}
plugin={plugin}
/>
{showEditButton && (
{showEditButton && datasourceName && (
<Tooltip content={createMessage(EDIT_DS_CONFIG)} placement="top">
<Button
isIconButton
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React from "react";
import { useSelector } from "react-redux";
import { Flex } from "@appsmith/ads";
import { CREATE_NEW_DATASOURCE, createMessage } from "ee/constants/messages";
import {
CREATE_NEW_DATASOURCE,
createMessage,
NOT_FOUND,
} from "ee/constants/messages";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
import {
Expand Down Expand Up @@ -66,7 +70,7 @@ export const PluginDatasourceSelector = ({
const userWorkspacePermissions = useSelector(
(state: AppState) => getCurrentAppWorkspace(state).userPermissions ?? [],
);
const isChangePermitted = getHasManageActionPermission(
const isActionChangePermitted = getHasManageActionPermission(
isFeatureEnabled,
currentActionConfig?.userPermissions,
);
Expand Down Expand Up @@ -108,15 +112,23 @@ export const PluginDatasourceSelector = ({
});
}

if (!showDatasourceSelector || !isChangePermitted) {
if (!showDatasourceSelector || !isActionChangePermitted) {
return (
<CurrentDataSourceLink
datasourceId={datasourceId}
datasourceName={datasourceName}
pluginId={plugin?.id || ""}
/>
);
}

if (DATASOURCES_OPTIONS.length < 1) {
DATASOURCES_OPTIONS.push({
label: createMessage(NOT_FOUND),
value: "not found",
});
}

return (
<Flex>
<MenuField
Expand All @@ -126,8 +138,8 @@ export const PluginDatasourceSelector = ({
options={DATASOURCES_OPTIONS}
>
<CurrentDataSource
datasourceId={datasourceId}
datasourceName={datasourceName}
pluginId={plugin?.id || ""}
/>
</MenuField>
</Flex>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@ export interface DatasourceProps {
}

const DatasourceSelector = (props: DatasourceProps) => {
return props.plugin ? (
return props.plugin &&
API_FORM_COMPONENTS.includes(props.plugin.uiComponent) ? (
<ApiDatasourceSelector {...props} formName={API_EDITOR_FORM_NAME} />
) : (
<QueryDatasourceSelector {...props} formName={QUERY_EDITOR_FORM_NAME} />
)
) : null;
<ApiDatasourceSelector {...props} formName={API_EDITOR_FORM_NAME} />
) : (
<QueryDatasourceSelector {...props} formName={QUERY_EDITOR_FORM_NAME} />
);
};

export default DatasourceSelector;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
getIsFetchingDatasourceStructure,
getPluginIdFromDatasourceId,
getPluginDatasourceComponentFromId,
getDatasource,
} from "ee/selectors/entitiesSelector";
import type { AppState } from "ee/reducers";
import { fetchDatasourceStructure } from "actions/datasourceActions";
Expand All @@ -26,24 +27,33 @@ import { useEditorType } from "ee/hooks";
import { useParentEntityInfo } from "ee/hooks/datasourceEditorHooks";
import DatasourceInfo from "./DatasourceInfo";
import { getPlugin } from "ee/selectors/entitiesSelector";
import {
getHasCreateDatasourceActionPermission,
getHasManageDatasourcePermission,
getHasReadDatasourcePermission,
} from "ee/utils/BusinessFeatures/permissionPageHelpers";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";

interface Props {
datasourceId: string;
datasourceName: string;
currentActionId: string;
}

const Datasource = (props: Props) => {
const DatasourceTab = (props: Props) => {
const dispatch = useDispatch();

const { datasourceId, datasourceName } = props;

const datasourceStructure = useSelector((state) =>
getDatasourceStructureById(state, props.datasourceId),
getDatasourceStructureById(state, datasourceId),
);

const { responseTabHeight } = useSelector(getPluginActionDebuggerState);

const pluginId = useSelector((state) =>
getPluginIdFromDatasourceId(state, props.datasourceId),
getPluginIdFromDatasourceId(state, datasourceId),
);

const plugin = useSelector((state) => getPlugin(state, pluginId || ""));
Expand All @@ -54,32 +64,51 @@ const Datasource = (props: Props) => {
const [selectedTable, setSelectedTable] = useState<string>();

const isLoading = useSelector((state: AppState) =>
getIsFetchingDatasourceStructure(state, props.datasourceId),
getIsFetchingDatasourceStructure(state, datasourceId),
);

const pluginDatasourceForm = useSelector((state) =>
getPluginDatasourceComponentFromId(state, pluginId || ""),
);

const datasource = useSelector((state) => getDatasource(state, datasourceId));

const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled);

const canCreateDatasourceActions = getHasCreateDatasourceActionPermission(
isFeatureEnabled,
datasource?.userPermissions || [],
);

const canReadDatasource = getHasReadDatasourcePermission(
isFeatureEnabled,
datasource?.userPermissions || [],
);

const canManageDatasource = getHasManageDatasourcePermission(
isFeatureEnabled,
datasource?.userPermissions || [],
);

useEffect(
function resetSelectedTable() {
setSelectedTable(undefined);
},
[props.datasourceId],
[datasourceId],
);

useEffect(
function fetchDatasourceStructureEffect() {
function fetchStructure() {
if (
props.datasourceId &&
datasourceId &&
datasourceStructure === undefined &&
pluginDatasourceForm !==
DatasourceComponentTypes.RestAPIDatasourceForm
) {
dispatch(
fetchDatasourceStructure(
props.datasourceId,
datasourceId,
true,
DatasourceStructureContext.QUERY_EDITOR,
),
Expand All @@ -89,7 +118,7 @@ const Datasource = (props: Props) => {

fetchStructure();
},
[props.datasourceId, datasourceStructure, dispatch, pluginDatasourceForm],
[datasourceId, datasourceStructure, dispatch, pluginDatasourceForm],
);

useEffect(
Expand All @@ -98,22 +127,22 @@ const Datasource = (props: Props) => {
setSelectedTable(datasourceStructure.tables[0].name);
}
},
[selectedTable, props.datasourceId, isLoading, datasourceStructure],
[selectedTable, datasourceId, isLoading, datasourceStructure],
);

// eslint-disable-next-line react-perf/jsx-no-new-function-as-prop
const editDatasource = () => {
const entryPoint = DatasourceEditEntryPoints.QUERY_EDITOR_DATASOURCE_SCHEMA;

AnalyticsUtil.logEvent("EDIT_DATASOURCE_CLICK", {
datasourceId: props.datasourceId,
datasourceId,
pluginName: "",
entryPoint: entryPoint,
});

const url = datasourcesEditorIdURL({
baseParentEntityId: parentEntityId,
datasourceId: props.datasourceId,
datasourceId,
params: { ...omit(getQueryParams(), "viewMode"), viewMode: false },
generateEditorPath: true,
});
Expand All @@ -124,7 +153,12 @@ const Datasource = (props: Props) => {
const getStatusState = () => {
if (isLoading) return SchemaDisplayStatus.SCHEMA_LOADING;

if (!datasourceStructure) return SchemaDisplayStatus.NOSCHEMA;
/* When a user doesn't have view access on a datasource */
if (!canReadDatasource) return SchemaDisplayStatus.NOACCESS;

/* When a user doesn't have create new query access but has view access on the datasource */
if (!datasourceStructure || !canCreateDatasourceActions)
return SchemaDisplayStatus.NOSCHEMA;

if (datasourceStructure && "error" in datasourceStructure)
return SchemaDisplayStatus.FAILED;
Expand All @@ -144,10 +178,10 @@ const Datasource = (props: Props) => {
return (
<Flex flexDirection="column" padding="spaces-3">
<DatasourceInfo
datasourceId={props.datasourceId}
datasourceName={props.datasourceName}
datasourceId={datasourceId}
datasourceName={datasourceName}
plugin={plugin}
showEditButton={!isLoading}
showEditButton={!isLoading && canManageDatasource}
/>
<StatusDisplay
editDatasource={editDatasource}
Expand All @@ -171,8 +205,8 @@ const Datasource = (props: Props) => {
<Flex h="100%">
<DatasourceTables
currentActionId={props.currentActionId}
datasourceId={props.datasourceId}
datasourceName={props.datasourceName}
datasourceId={datasourceId}
datasourceName={datasourceName}
datasourceStructure={datasourceStructure}
plugin={plugin}
selectedTable={selectedTable}
Expand Down Expand Up @@ -200,4 +234,4 @@ const Datasource = (props: Props) => {
);
};

export { Datasource };
export { DatasourceTab };
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from "./Datasource";
export * from "./DatasourceTab";
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
} from "PluginActionEditor/store";
import { doesPluginRequireDatasource } from "ee/entities/Engine/actionHelpers";
import useShowSchema from "PluginActionEditor/components/PluginActionResponse/hooks/useShowSchema";
import { Datasource } from "PluginActionEditor/components/PluginActionResponse/components/DatasourceTab";
import { DatasourceTab } from "PluginActionEditor/components/PluginActionResponse/components/DatasourceTab";
import {
useBlockExecution,
useHandleRunClick,
Expand Down Expand Up @@ -64,10 +64,10 @@ function usePluginActionResponseTabs() {
key: DEBUGGER_TAB_KEYS.DATASOURCE_TAB,
title: "Datasource",
panelComponent: (
<Datasource
<DatasourceTab
currentActionId={action.id}
datasourceId={datasource?.id || ""}
datasourceName={datasource?.name || ""}
datasourceId={datasource?.id || action.datasource.id || ""}
datasourceName={datasource?.name || action.datasource.name || ""}
/>
),
});
Expand Down Expand Up @@ -119,10 +119,10 @@ function usePluginActionResponseTabs() {
key: DEBUGGER_TAB_KEYS.DATASOURCE_TAB,
title: "Datasource",
panelComponent: (
<Datasource
<DatasourceTab
currentActionId={action.id}
datasourceId={datasource?.id || ""}
datasourceName={datasource?.name || ""}
datasourceId={datasource?.id || action.datasource.id || ""}
datasourceName={datasource?.name || action.datasource.name || ""}
/>
),
});
Expand Down
1 change: 1 addition & 0 deletions app/client/src/ce/constants/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ export const CREATE_NEW_DATASOURCE_MOST_POPULAR_HEADER = () => "Most popular";
export const CREATE_NEW_DATASOURCE_REST_API = () => "REST API";
export const SAMPLE_DATASOURCES = () => "Sample datasources";
export const EDIT_DS_CONFIG = () => "Edit datasource configuration";
export const NOT_FOUND = () => "Not found";

export const ERROR_EVAL_ERROR_GENERIC = () =>
`Unexpected error occurred while evaluating the application`;
Expand Down
Loading