Skip to content

Commit

Permalink
fix(content-sidebar): Fix Box AI Sidebar Title render logic (#3902)
Browse files Browse the repository at this point in the history
* fix(content-sidebar): Fix Box AI Sidebar Title render logic

* fix(content-sidebar): Fix Box AI Sidebar Title render logic
  • Loading branch information
kkuliczkowski-box authored Feb 6, 2025
1 parent fcf335a commit 9135321
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/elements/content-sidebar/BoxAISidebarContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { ORIGIN_BOXAI_SIDEBAR, SIDEBAR_VIEW_BOXAI } from '../../constants';
import { EVENT_JS_READY } from '../common/logger/constants';
import { mark } from '../../utils/performance';
import { BoxAISidebarContext } from './context/BoxAISidebarContext';
import BoxAISidebarTitle from './BoxAISidebarTitle';

import messages from '../common/messages';

Expand Down Expand Up @@ -102,6 +103,7 @@ function BoxAISidebarContent(props: ApiWrapperProps) {
const renderBoxAISidebarTitle = () => {
return (
<div className="bcs-BoxAISidebar-title-part">
<BoxAISidebarTitle isAIStudioAgentSelectorEnabled={isAIStudioAgentSelectorEnabled} />
{isAIStudioAgentSelectorEnabled && (
<div className="bcs-BoxAISidebar-agentSelector">
<BoxAiAgentSelectorWithApi
Expand Down Expand Up @@ -170,9 +172,11 @@ function BoxAISidebarContent(props: ApiWrapperProps) {
getAIStudioAgents={getAIStudioAgents}
hostAppName={hostAppName}
isAIStudioAgentSelectorEnabled={isAIStudioAgentSelectorEnabled}
isResetChatEnabled={isResetChatEnabled}
isStopResponseEnabled={isStopResponseEnabled}
items={items}
itemSize={itemSize}
onClearAction={onClearAction}
onModalClose={handleModalClose}
onOpenChange={handleModalClose}
onSelectAgent={onSelectAgent}
Expand Down
39 changes: 39 additions & 0 deletions src/elements/content-sidebar/BoxAISidebarTitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* @file Box AI sidebar title component
* @author Box
*/
import * as React from 'react';
import { useIntl } from 'react-intl';
import { useAgents, REQUEST_STATE } from '@box/box-ai-agent-selector';
import { Text } from '@box/blueprint-web';

import messages from '../common/messages';

interface BoxAISidebarTitleProps {
isAIStudioAgentSelectorEnabled?: boolean;
}

function BoxAISidebarTitle({ isAIStudioAgentSelectorEnabled = false }: BoxAISidebarTitleProps) {
const { formatMessage } = useIntl();

const { agents, requestState } = useAgents();

const hasAgentSelectorRequestEnded =
requestState !== REQUEST_STATE.NOT_STARTED && requestState !== REQUEST_STATE.IN_PROGRESS;
const hasAgentSelectorRequestFailed =
requestState === REQUEST_STATE.ERROR || requestState === REQUEST_STATE.CANCELLED;
const isAgentSelectorVisible = agents.length > 1 && requestState === REQUEST_STATE.SUCCESS;

// We want to display the title when the agent selector is disabled
// or when the request has failed
// or when the request has succeeded and the agent selector is not visible
return !isAIStudioAgentSelectorEnabled ||
hasAgentSelectorRequestFailed ||
(!isAgentSelectorVisible && hasAgentSelectorRequestEnded) ? (
<Text as="h3" className="bcs-title">
{formatMessage(messages.sidebarBoxAITitle)}
</Text>
) : null;
}

export default BoxAISidebarTitle;
8 changes: 8 additions & 0 deletions src/elements/content-sidebar/__tests__/BoxAISidebar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ jest.mock('@box/box-ai-content-answers', () => ({
),
}));

jest.mock('../BoxAISidebarTitle', () => () => <div data-testid="boxai-sidebar-title" />);

describe('elements/content-sidebar/BoxAISidebar', () => {
const mockProps = {
contentName: 'testName.txt',
Expand Down Expand Up @@ -108,6 +110,12 @@ describe('elements/content-sidebar/BoxAISidebar', () => {
jest.clearAllMocks();
});

test('should render BoxAISidebarTitle', async () => {
await renderComponent();

expect(screen.queryByTestId('boxai-sidebar-title')).toBeInTheDocument();
});

test('should have accessible Agent selector if isAIStudioAgentSelectorEnabled is true', async () => {
await renderComponent();

Expand Down
54 changes: 54 additions & 0 deletions src/elements/content-sidebar/__tests__/BoxAISidebarTitle.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import { REQUEST_STATE, useAgents as originalUseAgents } from '@box/box-ai-agent-selector';
import { render, screen } from '../../../test-utils/testing-library';
import BoxAISidebarTitle from '../BoxAISidebarTitle';

jest.mock('@box/box-ai-agent-selector', () => {
const actualModule = jest.requireActual('@box/box-ai-agent-selector');
return {
...actualModule,
useAgents: jest.fn(),
};
});

const useAgents = originalUseAgents as jest.MockedFunction<typeof originalUseAgents>;

const renderComponent = props => {
return render(<BoxAISidebarTitle {...props} />);
};

describe('elements/content-sidebar/BoxAISidebarTitle', () => {
afterEach(() => {
jest.clearAllMocks();
});

test('given isAIStudioAgentSelectorEnabled is false, should render title', () => {
useAgents.mockReturnValue({ agents: [], requestState: REQUEST_STATE.NOT_STARTED, selectedAgent: null });
renderComponent({ isAIStudioAgentSelectorEnabled: false });
expect(screen.getByText('Box AI')).toBeInTheDocument();
});

describe('given isAIStudioAgentSelectorEnabled is true', () => {
test.each`
agentsData | condition
${{ agents: [], requestState: REQUEST_STATE.ERROR, selectedAgent: null }} | ${'agent selector request has failed'}
${{ agents: [], requestState: REQUEST_STATE.CANCELLED, selectedAgent: null }} | ${'agent selector request has been cancelled'}
${{ agents: [{ id: '123', name: 'Agent 1' }], requestState: REQUEST_STATE.SUCCESS, selectedAgent: { id: '123', name: 'Agent 1' } }} | ${'agent selector request is successful and there is 1 agent available'}
`('and $condition, should render title', ({ agentsData }) => {
useAgents.mockReturnValue(agentsData);
renderComponent({ isAIStudioAgentSelectorEnabled: true });
expect(screen.getByText('Box AI')).toBeInTheDocument();
});

test.each`
agentsData | condition
${{ agents: [], requestState: REQUEST_STATE.NOT_STARTED, selectedAgent: null }} | ${'agent selector has not started loading'}
${{ agents: [], requestState: REQUEST_STATE.IN_PROGRESS, selectedAgent: null }} | ${'agent selector request is in progress'}
${{ agents: [{ id: '123', name: 'Agent 1' }, { id: '124', name: 'Agent 2' }], requestState: REQUEST_STATE.SUCCESS, selectedAgent: { id: '123', name: 'Agent 1' } }} | ${'agent selector request is successful and 2 agents are available'}
`('and $condition, should not render title', ({ agentsData }) => {
useAgents.mockReturnValue(agentsData);
renderComponent({ isAIStudioAgentSelectorEnabled: true });
expect(screen.queryByText('Box AI')).not.toBeInTheDocument();
});
});
});

0 comments on commit 9135321

Please sign in to comment.