Skip to content

Commit

Permalink
[8.10] [Security Solution] Fixes Assistant Connector and Actions RBAC…
Browse files Browse the repository at this point in the history
… Flow (#164382) (#164645)

# Backport

This will backport the following commits from `main` to `8.10`:
- [[Security Solution] Fixes Assistant Connector and Actions RBAC Flow
(#164382)](#164382)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Garrett
Spong","email":"[email protected]"},"sourceCommit":{"committedDate":"2023-08-23T21:22:39Z","message":"[Security
Solution] Fixes Assistant Connector and Actions RBAC Flow
(#164382)\n\n## Summary\r\n\r\nResolves
#159374 by ensuring\r\nthat if a
user doesn't have the appropriate `Connectors & Actions`\r\nprivileges,
they will be shown the appropriate messaging and any UI\r\ncontrols for
adding Connectors will be disabled or unavailable.\r\n\r\n####
Connectors and Actions `NONE` or Connectors and Actions `READ`
if\r\n*NO* existing connectors exist:\r\n\r\n<p
align=\"center\">\r\n<img
width=\"500\"\r\nsrc=\"https://github.com/elastic/kibana/assets/2946766/d9535ae9-a31e-499b-9b18-6004e3db64de\"\r\n/>\r\n</p>
\r\n\r\n#### Connectors and Actions `READ` if existing connector count >
0:\r\n\r\n`Add Connector...` option isn't available:\r\n\r\n<p
align=\"center\">\r\n<img
width=\"500\"\r\nsrc=\"https://github.com/elastic/kibana/assets/2946766/bd6a06a7-ffa2-4cfc-a2b7-844da99cb171\"\r\n/>\r\n</p>
\r\n\r\n<p align=\"center\">\r\n<img
width=\"500\"\r\nsrc=\"https://github.com/elastic/kibana/assets/2946766/4681086e-1015-45b9-9afb-ff604c52cd38\"\r\n/>\r\n</p>
\r\n\r\n\r\n\r\nAlso addresses:\r\n\r\n* Fixes disabled state of header
connector selector for setup flows.\r\n* Adds `AssistantAvailability`
interface to `AssistantContext` for\r\nexposing ui feature controls like
`Connectors & Actions` privileges.\r\n* Hides `Add new connector...`
option if user doesn't have `ALL`\r\n`Connectors & Actions`
privileges.\r\n* Hoists dependencies from `assistant/index.tsx` to
`connector_setup` as\r\nit was already fetching dependencies from
`useAssistantContext`.\r\n\r\nNote: `ConnectorButton` and
`ConnectorMissingCallout` should probably be\r\ncombined into a single
component and show appropriate messaging given\r\nthe user's `Connectors
& Actions` privileges. I kept them separate for\r\nnow as to not modify
the control flow around the two components (till we\r\ncan further
refactor `assistant/index.tsx`), which means the missing\r\nconnector
callout is sort of doing double duty at the moment.\r\n\r\n\r\n###
Checklist\r\n\r\nDelete any items that are not applicable to this
PR.\r\n\r\n- [X] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[X] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"db7ac1bb417a4c84d29e1d7e9e831bdaf650358c","branchLabelMapping":{"^v8.11.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:
SecuritySolution","Feature:Elastic AI
Assistant","v8.10.0","v8.11.0"],"number":164382,"url":"https://github.com/elastic/kibana/pull/164382","mergeCommit":{"message":"[Security
Solution] Fixes Assistant Connector and Actions RBAC Flow
(#164382)\n\n## Summary\r\n\r\nResolves
#159374 by ensuring\r\nthat if a
user doesn't have the appropriate `Connectors & Actions`\r\nprivileges,
they will be shown the appropriate messaging and any UI\r\ncontrols for
adding Connectors will be disabled or unavailable.\r\n\r\n####
Connectors and Actions `NONE` or Connectors and Actions `READ`
if\r\n*NO* existing connectors exist:\r\n\r\n<p
align=\"center\">\r\n<img
width=\"500\"\r\nsrc=\"https://github.com/elastic/kibana/assets/2946766/d9535ae9-a31e-499b-9b18-6004e3db64de\"\r\n/>\r\n</p>
\r\n\r\n#### Connectors and Actions `READ` if existing connector count >
0:\r\n\r\n`Add Connector...` option isn't available:\r\n\r\n<p
align=\"center\">\r\n<img
width=\"500\"\r\nsrc=\"https://github.com/elastic/kibana/assets/2946766/bd6a06a7-ffa2-4cfc-a2b7-844da99cb171\"\r\n/>\r\n</p>
\r\n\r\n<p align=\"center\">\r\n<img
width=\"500\"\r\nsrc=\"https://github.com/elastic/kibana/assets/2946766/4681086e-1015-45b9-9afb-ff604c52cd38\"\r\n/>\r\n</p>
\r\n\r\n\r\n\r\nAlso addresses:\r\n\r\n* Fixes disabled state of header
connector selector for setup flows.\r\n* Adds `AssistantAvailability`
interface to `AssistantContext` for\r\nexposing ui feature controls like
`Connectors & Actions` privileges.\r\n* Hides `Add new connector...`
option if user doesn't have `ALL`\r\n`Connectors & Actions`
privileges.\r\n* Hoists dependencies from `assistant/index.tsx` to
`connector_setup` as\r\nit was already fetching dependencies from
`useAssistantContext`.\r\n\r\nNote: `ConnectorButton` and
`ConnectorMissingCallout` should probably be\r\ncombined into a single
component and show appropriate messaging given\r\nthe user's `Connectors
& Actions` privileges. I kept them separate for\r\nnow as to not modify
the control flow around the two components (till we\r\ncan further
refactor `assistant/index.tsx`), which means the missing\r\nconnector
callout is sort of doing double duty at the moment.\r\n\r\n\r\n###
Checklist\r\n\r\nDelete any items that are not applicable to this
PR.\r\n\r\n- [X] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[X] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"db7ac1bb417a4c84d29e1d7e9e831bdaf650358c"}},"sourceBranch":"main","suggestedTargetBranches":["8.10"],"targetPullRequestStates":[{"branch":"8.10","label":"v8.10.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.11.0","labelRegex":"^v8.11.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/164382","number":164382,"mergeCommit":{"message":"[Security
Solution] Fixes Assistant Connector and Actions RBAC Flow
(#164382)\n\n## Summary\r\n\r\nResolves
#159374 by ensuring\r\nthat if a
user doesn't have the appropriate `Connectors & Actions`\r\nprivileges,
they will be shown the appropriate messaging and any UI\r\ncontrols for
adding Connectors will be disabled or unavailable.\r\n\r\n####
Connectors and Actions `NONE` or Connectors and Actions `READ`
if\r\n*NO* existing connectors exist:\r\n\r\n<p
align=\"center\">\r\n<img
width=\"500\"\r\nsrc=\"https://github.com/elastic/kibana/assets/2946766/d9535ae9-a31e-499b-9b18-6004e3db64de\"\r\n/>\r\n</p>
\r\n\r\n#### Connectors and Actions `READ` if existing connector count >
0:\r\n\r\n`Add Connector...` option isn't available:\r\n\r\n<p
align=\"center\">\r\n<img
width=\"500\"\r\nsrc=\"https://github.com/elastic/kibana/assets/2946766/bd6a06a7-ffa2-4cfc-a2b7-844da99cb171\"\r\n/>\r\n</p>
\r\n\r\n<p align=\"center\">\r\n<img
width=\"500\"\r\nsrc=\"https://github.com/elastic/kibana/assets/2946766/4681086e-1015-45b9-9afb-ff604c52cd38\"\r\n/>\r\n</p>
\r\n\r\n\r\n\r\nAlso addresses:\r\n\r\n* Fixes disabled state of header
connector selector for setup flows.\r\n* Adds `AssistantAvailability`
interface to `AssistantContext` for\r\nexposing ui feature controls like
`Connectors & Actions` privileges.\r\n* Hides `Add new connector...`
option if user doesn't have `ALL`\r\n`Connectors & Actions`
privileges.\r\n* Hoists dependencies from `assistant/index.tsx` to
`connector_setup` as\r\nit was already fetching dependencies from
`useAssistantContext`.\r\n\r\nNote: `ConnectorButton` and
`ConnectorMissingCallout` should probably be\r\ncombined into a single
component and show appropriate messaging given\r\nthe user's `Connectors
& Actions` privileges. I kept them separate for\r\nnow as to not modify
the control flow around the two components (till we\r\ncan further
refactor `assistant/index.tsx`), which means the missing\r\nconnector
callout is sort of doing double duty at the moment.\r\n\r\n\r\n###
Checklist\r\n\r\nDelete any items that are not applicable to this
PR.\r\n\r\n- [X] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[X] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"db7ac1bb417a4c84d29e1d7e9e831bdaf650358c"}}]}]
BACKPORT-->

Co-authored-by: Garrett Spong <[email protected]>
  • Loading branch information
kibanamachine and spong authored Aug 23, 2023
1 parent ea9ec1f commit c94b0f8
Show file tree
Hide file tree
Showing 24 changed files with 290 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export const AssistantHeader: React.FC<Props> = ({
<EuiFlexItem grow={false}>
<AssistantTitle
{...currentTitle}
isDisabled={isDisabled}
docLinks={docLinks}
selectedConversation={currentConversation}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ import { ConnectorSelectorInline } from '../../connectorland/connector_selector_
* information about the assistant feature and access to documentation.
*/
export const AssistantTitle: React.FC<{
isDisabled?: boolean;
title: string | JSX.Element;
titleIcon: string;
docLinks: Omit<DocLinksStart, 'links'>;
selectedConversation: Conversation | undefined;
}> = ({ title, titleIcon, docLinks, selectedConversation }) => {
}> = ({ isDisabled = false, title, titleIcon, docLinks, selectedConversation }) => {
const selectedConnectorId = selectedConversation?.apiConfig?.connectorId;

const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = docLinks;
Expand Down Expand Up @@ -116,7 +117,7 @@ export const AssistantTitle: React.FC<{
</EuiFlexItem>
<EuiFlexItem grow={false}>
<ConnectorSelectorInline
isDisabled={selectedConversation === undefined}
isDisabled={isDisabled || selectedConversation === undefined}
onConnectorModalVisibilityChange={() => {}}
onConnectorSelectionChange={() => {}}
selectedConnectorId={selectedConnectorId}
Expand Down
14 changes: 3 additions & 11 deletions x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ const AssistantComponent: React.FC<Props> = ({
setConversationId,
}) => {
const {
actionTypeRegistry,
assistantTelemetry,
augmentMessageCodeBlocks,
conversations,
Expand All @@ -98,11 +97,7 @@ const AssistantComponent: React.FC<Props> = ({
const { createConversation } = useConversation();

// Connector details
const {
data: connectors,
isSuccess: areConnectorsFetched,
refetch: refetchConnectors,
} = useLoadConnectors({ http });
const { data: connectors, isSuccess: areConnectorsFetched } = useLoadConnectors({ http });
const defaultConnectorId = useMemo(() => getDefaultConnector(connectors)?.id, [connectors]);
const defaultProvider = useMemo(
() =>
Expand Down Expand Up @@ -171,14 +166,10 @@ const AssistantComponent: React.FC<Props> = ({
}, [areConnectorsFetched, connectors?.length, currentConversation, setLastConversationId]);

const { comments: connectorComments, prompt: connectorPrompt } = useConnectorSetup({
actionTypeRegistry,
http,
refetchConnectors,
conversation: blockBotConversation,
onSetupComplete: () => {
bottomRef.current?.scrollIntoView({ behavior: 'auto' });
},
conversation: blockBotConversation,
isConnectorConfigured: !!connectors?.length,
});

const currentTitle: { title: string | JSX.Element; titleIcon: string } =
Expand Down Expand Up @@ -475,6 +466,7 @@ const AssistantComponent: React.FC<Props> = ({
<EuiFlexGroup justifyContent="spaceAround">
<EuiFlexItem grow={false}>
<ConnectorMissingCallout
isConnectorConfigured={connectors?.length > 0}
isSettingsModalVisible={isSettingsModalVisible}
setIsSettingsModalVisible={setIsSettingsModalVisible}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,23 @@ import React from 'react';
import { AssistantProvider, useAssistantContext } from '.';
import { httpServiceMock } from '@kbn/core-http-browser-mocks';
import { actionTypeRegistryMock } from '@kbn/triggers-actions-ui-plugin/public/application/action_type_registry.mock';
import { AssistantAvailability } from '../..';

const actionTypeRegistry = actionTypeRegistryMock.create();
const mockGetInitialConversations = jest.fn(() => ({}));
const mockGetComments = jest.fn(() => []);
const mockHttp = httpServiceMock.createStartContract({ basePath: '/test' });
const mockAssistantAvailability: AssistantAvailability = {
hasAssistantPrivilege: false,
hasConnectorsAllPrivilege: true,
hasConnectorsReadPrivilege: true,
isAssistantEnabled: true,
};

const ContextWrapper: React.FC = ({ children }) => (
<AssistantProvider
actionTypeRegistry={actionTypeRegistry}
assistantAvailability={mockAssistantAvailability}
augmentMessageCodeBlocks={jest.fn()}
baseAllow={[]}
baseAllowReplacement={[]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import {
SYSTEM_PROMPT_LOCAL_STORAGE_KEY,
} from './constants';
import { CONVERSATIONS_TAB, SettingsTabs } from '../assistant/settings/assistant_settings';
import { AssistantTelemetry } from './types';
import { AssistantAvailability, AssistantTelemetry } from './types';

export interface ShowAssistantOverlayProps {
showOverlay: boolean;
Expand All @@ -48,6 +48,7 @@ type ShowAssistantOverlay = ({
}: ShowAssistantOverlayProps) => void;
export interface AssistantProviderProps {
actionTypeRegistry: ActionTypeRegistryContract;
assistantAvailability: AssistantAvailability;
assistantTelemetry?: AssistantTelemetry;
augmentMessageCodeBlocks: (currentConversation: Conversation) => CodeBlockDetails[][];
baseAllow: string[];
Expand Down Expand Up @@ -79,6 +80,7 @@ export interface AssistantProviderProps {

export interface UseAssistantContext {
actionTypeRegistry: ActionTypeRegistryContract;
assistantAvailability: AssistantAvailability;
assistantTelemetry?: AssistantTelemetry;
augmentMessageCodeBlocks: (currentConversation: Conversation) => CodeBlockDetails[][];
allQuickPrompts: QuickPrompt[];
Expand Down Expand Up @@ -126,6 +128,7 @@ const AssistantContext = React.createContext<UseAssistantContext | undefined>(un

export const AssistantProvider: React.FC<AssistantProviderProps> = ({
actionTypeRegistry,
assistantAvailability,
assistantTelemetry,
augmentMessageCodeBlocks,
baseAllow,
Expand Down Expand Up @@ -244,6 +247,7 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({
const value = useMemo(
() => ({
actionTypeRegistry,
assistantAvailability,
assistantTelemetry,
augmentMessageCodeBlocks,
allQuickPrompts: localStorageQuickPrompts ?? [],
Expand Down Expand Up @@ -279,6 +283,7 @@ export const AssistantProvider: React.FC<AssistantProviderProps> = ({
}),
[
actionTypeRegistry,
assistantAvailability,
assistantTelemetry,
augmentMessageCodeBlocks,
baseAllow,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,14 @@ export interface AssistantTelemetry {
reportAssistantMessageSent: (params: { conversationId: string; role: string }) => void;
reportAssistantQuickPrompt: (params: { conversationId: string; promptTitle: string }) => void;
}

export interface AssistantAvailability {
// True when user is Enterprise, or Security Complete PLI for serverless. When false, the Assistant is disabled and unavailable
isAssistantEnabled: boolean;
// When true, the Assistant is hidden and unavailable
hasAssistantPrivilege: boolean;
// When true, user has `All` privilege for `Connectors and Actions` (show/execute/delete/save ui capabilities)
hasConnectorsAllPrivilege: boolean;
// When true, user has `Read` privilege for `Connectors and Actions` (show/execute ui capabilities)
hasConnectorsReadPrivilege: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,46 @@
* 2.0.
*/

import React from 'react';
import React, { useCallback } from 'react';
import { EuiCard, EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui';

import { GenAiLogo } from '@kbn/stack-connectors-plugin/public/common';
import * as i18n from '../translations';
import { useAssistantContext } from '../../assistant_context';

export interface ConnectorButtonProps {
setIsConnectorModalVisible: React.Dispatch<React.SetStateAction<boolean>>;
setIsConnectorModalVisible?: React.Dispatch<React.SetStateAction<boolean>>;
}

/**
* Simple button component for adding a connector. Note: component is basic and does not handle connector
* add logic. Must pass in `setIsConnectorModalVisible`, see ConnectorSetup component if wanting to manage
* connector add logic.
* add logic. See ConnectorSetup component if wanting to manage connector add logic.
*/
export const ConnectorButton: React.FC<ConnectorButtonProps> = React.memo<ConnectorButtonProps>(
({ setIsConnectorModalVisible }) => {
const { assistantAvailability } = useAssistantContext();

const title = assistantAvailability.hasConnectorsAllPrivilege
? i18n.ADD_CONNECTOR_TITLE
: i18n.ADD_CONNECTOR_MISSING_PRIVILEGES_TITLE;
const description = assistantAvailability.hasConnectorsAllPrivilege
? i18n.ADD_CONNECTOR_DESCRIPTION
: i18n.ADD_CONNECTOR_MISSING_PRIVILEGES_DESCRIPTION;

const onClick = useCallback(() => {
setIsConnectorModalVisible?.(true);
}, [setIsConnectorModalVisible]);

return (
<EuiFlexGroup gutterSize="l" justifyContent="spaceAround">
<EuiFlexItem grow={false}>
<EuiCard
data-test-subj="connectorButton"
layout="horizontal"
icon={<EuiIcon size="xl" type={GenAiLogo} />}
title={i18n.ADD_CONNECTOR_TITLE}
description={i18n.ADD_CONNECTOR_DESCRIPTION}
onClick={() => setIsConnectorModalVisible(true)}
title={title}
description={description}
onClick={assistantAvailability.hasConnectorsAllPrivilege ? onClick : undefined}
/>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';

import { render } from '@testing-library/react';
import { ConnectorMissingCallout } from '.';
import { AssistantAvailability } from '../../..';
import { TestProviders } from '../../mock/test_providers/test_providers';

describe('connectorMissingCallout', () => {
describe('when connectors and actions privileges', () => {
describe('are `READ`', () => {
const assistantAvailability: AssistantAvailability = {
hasAssistantPrivilege: true,
hasConnectorsAllPrivilege: false,
hasConnectorsReadPrivilege: true,
isAssistantEnabled: true,
};

it('should show connector privileges required button if no connectors exist', async () => {
const { queryByTestId } = render(
<TestProviders assistantAvailability={assistantAvailability}>
<ConnectorMissingCallout
isConnectorConfigured={false}
isSettingsModalVisible={false}
setIsSettingsModalVisible={jest.fn()}
/>
</TestProviders>
);

expect(queryByTestId('connectorButton')).toBeInTheDocument();
});

it('should NOT show connector privileges required button if at least one connector exists', async () => {
const { queryByTestId } = render(
<TestProviders assistantAvailability={assistantAvailability}>
<ConnectorMissingCallout
isConnectorConfigured={true}
isSettingsModalVisible={false}
setIsSettingsModalVisible={jest.fn()}
/>
</TestProviders>
);

expect(queryByTestId('connectorButton')).not.toBeInTheDocument();
});
});

describe('are `NONE`', () => {
const assistantAvailability: AssistantAvailability = {
hasAssistantPrivilege: true,
hasConnectorsAllPrivilege: false,
hasConnectorsReadPrivilege: false,
isAssistantEnabled: true,
};

it('should show connector privileges required button', async () => {
const { queryByTestId } = render(
<TestProviders assistantAvailability={assistantAvailability}>
<ConnectorMissingCallout
isConnectorConfigured={true}
isSettingsModalVisible={false}
setIsSettingsModalVisible={jest.fn()}
/>
</TestProviders>
);

expect(queryByTestId('connectorButton')).toBeInTheDocument();
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,24 @@ import { FormattedMessage } from '@kbn/i18n-react';
import * as i18n from '../translations';
import { useAssistantContext } from '../../assistant_context';
import { CONVERSATIONS_TAB } from '../../assistant/settings/assistant_settings';
import { ConnectorButton } from '../connector_button';

interface Props {
isConnectorConfigured: boolean;
isSettingsModalVisible: boolean;
setIsSettingsModalVisible: React.Dispatch<React.SetStateAction<boolean>>;
}

/**
* Error callout to be displayed when there is no connector configured for a conversation. Includes deep-link
* to conversation settings to quickly resolve.
* to conversation settings to quickly resolve. Falls back to <ConnectorButton /> connector if privileges aren't met.
*
* TODO: Add 'quick fix' button to just pick a connector
* TODO: Add setting for 'default connector' so we can auto-resolve and not even show this
*/
export const ConnectorMissingCallout: React.FC<Props> = React.memo(
({ isSettingsModalVisible, setIsSettingsModalVisible }) => {
const { setSelectedSettingsTab } = useAssistantContext();
({ isConnectorConfigured, isSettingsModalVisible, setIsSettingsModalVisible }) => {
const { assistantAvailability, setSelectedSettingsTab } = useAssistantContext();

const onConversationSettingsClicked = useCallback(() => {
if (!isSettingsModalVisible) {
Expand All @@ -36,28 +38,40 @@ export const ConnectorMissingCallout: React.FC<Props> = React.memo(
}
}, [isSettingsModalVisible, setIsSettingsModalVisible, setSelectedSettingsTab]);

// Show missing callout if user has all privileges or read privileges and at least 1 connector configured
const showMissingCallout =
assistantAvailability.hasConnectorsAllPrivilege ||
(assistantAvailability.hasConnectorsReadPrivilege && isConnectorConfigured);

return (
<EuiCallOut
color="danger"
iconType="controlsVertical"
size="m"
title={i18n.MISSING_CONNECTOR_CALLOUT_TITLE}
>
<p>
{' '}
<FormattedMessage
defaultMessage="Select a connector above or from the {link} to continue"
id="xpack.elasticAssistant.assistant.connectors.connectorMissingCallout.calloutDescription"
values={{
link: (
<EuiLink onClick={onConversationSettingsClicked}>
{i18n.MISSING_CONNECTOR_CONVERSATION_SETTINGS_LINK}
</EuiLink>
),
}}
/>
</p>
</EuiCallOut>
<>
{showMissingCallout ? (
<EuiCallOut
data-test-subj="connectorMissingCallout"
color="danger"
iconType="controlsVertical"
size="m"
title={i18n.MISSING_CONNECTOR_CALLOUT_TITLE}
>
<p>
{' '}
<FormattedMessage
defaultMessage="Select a connector above or from the {link} to continue"
id="xpack.elasticAssistant.assistant.connectors.connectorMissingCallout.calloutDescription"
values={{
link: (
<EuiLink onClick={onConversationSettingsClicked}>
{i18n.MISSING_CONNECTOR_CONVERSATION_SETTINGS_LINK}
</EuiLink>
),
}}
/>
</p>
</EuiCallOut>
) : (
<ConnectorButton />
)}
</>
);
}
);
Expand Down
Loading

0 comments on commit c94b0f8

Please sign in to comment.