mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Observability AI Assistant] Fix Storybook (#183399)
Resolves https://github.com/elastic/kibana/issues/183400
## Summary
This fixes all broken stories in the Observability AI Assistant
storybook.
9200c47e
-87bb-484d-a552-68afdf79108c
---------
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
45a73a7f29
commit
4eb175f384
18 changed files with 325 additions and 48 deletions
|
@ -6,5 +6,8 @@
|
|||
*/
|
||||
|
||||
import { EuiThemeProviderDecorator } from '@kbn/kibana-react-plugin/common';
|
||||
import * as jest from 'jest-mock';
|
||||
|
||||
export const decorators = [EuiThemeProviderDecorator];
|
||||
|
||||
window.jest = jest;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { ComponentMeta, ComponentStoryObj } from '@storybook/react';
|
||||
import React from 'react';
|
||||
import { MessageRole } from '@kbn/observability-ai-assistant-plugin/public';
|
||||
import { KibanaReactStorybookDecorator } from '../../utils/storybook_decorator';
|
||||
import { KibanaReactStorybookDecorator } from '../../utils/storybook_decorator.stories';
|
||||
import { ChatBody as Component } from './chat_body';
|
||||
import { buildSystemMessage } from '../../utils/builders';
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
import { ComponentStory } from '@storybook/react';
|
||||
import React from 'react';
|
||||
import { buildSystemMessage } from '../../utils/builders';
|
||||
import { KibanaReactStorybookDecorator } from '../../utils/storybook_decorator';
|
||||
import { ChatFlyout as Component } from './chat_flyout';
|
||||
import { KibanaReactStorybookDecorator } from '../../utils/storybook_decorator.stories';
|
||||
import { ChatFlyout as Component, FlyoutPositionMode } from './chat_flyout';
|
||||
|
||||
export default {
|
||||
component: Component,
|
||||
|
@ -31,6 +31,7 @@ const defaultProps: ChatFlyoutProps = {
|
|||
isOpen: true,
|
||||
initialTitle: 'How is this working',
|
||||
initialMessages: [buildSystemMessage()],
|
||||
initialFlyoutPositionMode: FlyoutPositionMode.OVERLAY,
|
||||
onClose: () => {},
|
||||
};
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
import { ComponentMeta, ComponentStoryObj } from '@storybook/react';
|
||||
import React from 'react';
|
||||
import { KibanaReactStorybookDecorator } from '../../utils/storybook_decorator';
|
||||
import { buildConversation } from '../../utils/builders';
|
||||
import { KibanaReactStorybookDecorator } from '../../utils/storybook_decorator.stories';
|
||||
import { ConversationList as Component } from './conversation_list';
|
||||
|
||||
type ConversationListProps = React.ComponentProps<typeof Component>;
|
||||
|
@ -28,25 +29,64 @@ const Wrapper = (props: ConversationListProps) => {
|
|||
);
|
||||
};
|
||||
|
||||
export const ChatHeaderLoading: ComponentStoryObj<typeof Component> = {
|
||||
args: {},
|
||||
render: Wrapper,
|
||||
};
|
||||
|
||||
export const ChatHeaderError: ComponentStoryObj<typeof Component> = {
|
||||
args: {},
|
||||
render: Wrapper,
|
||||
};
|
||||
|
||||
export const ChatHeaderLoaded: ComponentStoryObj<typeof Component> = {
|
||||
export const ConversationListLoading: ComponentStoryObj<typeof Component> = {
|
||||
args: {
|
||||
conversations: {
|
||||
loading: true,
|
||||
error: undefined,
|
||||
value: { conversations: [] },
|
||||
refresh: () => {},
|
||||
},
|
||||
isLoading: true,
|
||||
},
|
||||
render: Wrapper,
|
||||
};
|
||||
|
||||
export const ConversationListError: ComponentStoryObj<typeof Component> = {
|
||||
args: {
|
||||
conversations: {
|
||||
loading: false,
|
||||
error: new Error('Failed to load conversations'),
|
||||
value: { conversations: [] },
|
||||
refresh: () => {},
|
||||
},
|
||||
isLoading: false,
|
||||
},
|
||||
render: Wrapper,
|
||||
};
|
||||
|
||||
export const ConversationListLoaded: ComponentStoryObj<typeof Component> = {
|
||||
args: {
|
||||
conversations: {
|
||||
loading: false,
|
||||
error: undefined,
|
||||
value: {
|
||||
conversations: [
|
||||
buildConversation({
|
||||
conversation: {
|
||||
id: 'foo',
|
||||
title: 'Why is database service responding with errors after I did rm -rf /postgres',
|
||||
last_updated: '',
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
refresh: () => {},
|
||||
},
|
||||
selectedConversationId: '',
|
||||
},
|
||||
render: Wrapper,
|
||||
};
|
||||
|
||||
export const ChatHeaderEmpty: ComponentStoryObj<typeof Component> = {
|
||||
export const ConversationListEmpty: ComponentStoryObj<typeof Component> = {
|
||||
args: {
|
||||
conversations: {
|
||||
loading: false,
|
||||
error: undefined,
|
||||
value: { conversations: [] },
|
||||
refresh: () => {},
|
||||
},
|
||||
isLoading: false,
|
||||
selectedConversationId: '',
|
||||
},
|
||||
render: Wrapper,
|
||||
|
|
|
@ -46,17 +46,17 @@ const newChatButtonWrapperClassName = css`
|
|||
`;
|
||||
|
||||
export function ConversationList({
|
||||
conversations,
|
||||
isLoading,
|
||||
selectedConversationId,
|
||||
onConversationSelect,
|
||||
onConversationDeleteClick,
|
||||
conversations,
|
||||
isLoading,
|
||||
}: {
|
||||
conversations: UseConversationListResult['conversations'];
|
||||
isLoading: boolean;
|
||||
selectedConversationId?: string;
|
||||
onConversationSelect?: (conversationId?: string) => void;
|
||||
onConversationDeleteClick: (conversationId: string) => void;
|
||||
conversations: UseConversationListResult['conversations'];
|
||||
isLoading: boolean;
|
||||
}) {
|
||||
const router = useObservabilityAIAssistantRouter();
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { ComponentStory } from '@storybook/react';
|
||||
import React from 'react';
|
||||
import { KibanaReactStorybookDecorator } from '../../utils/storybook_decorator';
|
||||
import { KibanaReactStorybookDecorator } from '../../utils/storybook_decorator.stories';
|
||||
import { FunctionListPopover as Component } from './function_list_popover';
|
||||
|
||||
export default {
|
||||
|
@ -25,9 +25,9 @@ const Template: ComponentStory<typeof Component> = (props: FunctionListPopover)
|
|||
const defaultProps: FunctionListPopover = {
|
||||
onSelectFunction: () => {},
|
||||
disabled: false,
|
||||
mode: 'prompt',
|
||||
selectedFunctionName: 'foo',
|
||||
mode: 'function',
|
||||
selectedFunctionName: '',
|
||||
};
|
||||
|
||||
export const ConversationList = Template.bind({});
|
||||
ConversationList.args = defaultProps;
|
||||
export const FunctionListPopover = Template.bind({});
|
||||
FunctionListPopover.args = defaultProps;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { ComponentMeta, ComponentStoryObj } from '@storybook/react';
|
||||
import { merge } from 'lodash';
|
||||
import { KibanaReactStorybookDecorator } from '../../utils/storybook_decorator';
|
||||
import { KibanaReactStorybookDecorator } from '../../utils/storybook_decorator.stories';
|
||||
import { KnowledgeBaseCallout as Component } from './knowledge_base_callout';
|
||||
|
||||
const meta: ComponentMeta<typeof Component> = {
|
||||
|
|
|
@ -6,9 +6,10 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ComponentStory } from '@storybook/react';
|
||||
import { ComponentStory, ComponentStoryObj } from '@storybook/react';
|
||||
import { MessageRole } from '@kbn/observability-ai-assistant-plugin/public';
|
||||
import { PromptEditor as Component, PromptEditorProps } from './prompt_editor';
|
||||
import { KibanaReactStorybookDecorator } from '../../utils/storybook_decorator';
|
||||
import { KibanaReactStorybookDecorator } from '../../utils/storybook_decorator.stories';
|
||||
|
||||
/*
|
||||
JSON Schema validation in the PromptEditor compponent does not work
|
||||
|
@ -32,7 +33,65 @@ const Template: ComponentStory<typeof Component> = (props: PromptEditorProps) =>
|
|||
return <Component {...props} />;
|
||||
};
|
||||
|
||||
const defaultProps = {};
|
||||
export const PromptEditorDisabled: ComponentStoryObj<typeof Component> = {
|
||||
args: {
|
||||
disabled: true,
|
||||
hidden: false,
|
||||
loading: false,
|
||||
initialRole: MessageRole.User,
|
||||
initialFunctionCall: undefined,
|
||||
initialContent: '',
|
||||
onChangeHeight: () => {},
|
||||
onSendTelemetry: () => {},
|
||||
onSubmit: () => {},
|
||||
},
|
||||
render: Template,
|
||||
};
|
||||
|
||||
export const PromptEditor = Template.bind({});
|
||||
PromptEditor.args = defaultProps;
|
||||
export const PromptEditorLoading: ComponentStoryObj<typeof Component> = {
|
||||
args: {
|
||||
disabled: false,
|
||||
hidden: false,
|
||||
loading: true,
|
||||
initialRole: MessageRole.User,
|
||||
initialFunctionCall: undefined,
|
||||
initialContent: '',
|
||||
onChangeHeight: () => {},
|
||||
onSendTelemetry: () => {},
|
||||
onSubmit: () => {},
|
||||
},
|
||||
render: Template,
|
||||
};
|
||||
|
||||
export const PromptEditorWithInitialContent: ComponentStoryObj<typeof Component> = {
|
||||
args: {
|
||||
disabled: false,
|
||||
hidden: false,
|
||||
loading: true,
|
||||
initialRole: MessageRole.User,
|
||||
initialFunctionCall: undefined,
|
||||
initialContent: 'Can you help me with this?',
|
||||
onChangeHeight: () => {},
|
||||
onSendTelemetry: () => {},
|
||||
onSubmit: () => {},
|
||||
},
|
||||
render: Template,
|
||||
};
|
||||
|
||||
export const PromptEditorWithInitialFunction: ComponentStoryObj<typeof Component> = {
|
||||
args: {
|
||||
disabled: false,
|
||||
hidden: false,
|
||||
loading: false,
|
||||
initialRole: MessageRole.User,
|
||||
initialFunctionCall: {
|
||||
name: 'get stuff',
|
||||
trigger: MessageRole.User,
|
||||
},
|
||||
initialContent: '',
|
||||
onChangeHeight: () => {},
|
||||
onSendTelemetry: () => {},
|
||||
onSubmit: () => {},
|
||||
},
|
||||
render: Template,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export function useChat() {
|
||||
return { next: () => {}, messages: [], setMessages: () => {}, state: undefined, stop: () => {} };
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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 { Subject } from 'rxjs';
|
||||
|
||||
export function useConversation() {
|
||||
return {
|
||||
conversation: {},
|
||||
state: 'idle',
|
||||
next: new Subject(),
|
||||
stop: () => {},
|
||||
messages: [],
|
||||
saveTitle: () => {},
|
||||
};
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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 { buildConversation } from '../../utils/builders';
|
||||
|
||||
export function useConversationList() {
|
||||
return {
|
||||
deleteConversation: () => {},
|
||||
conversations: {
|
||||
loading: false,
|
||||
error: undefined,
|
||||
value: {
|
||||
conversations: [
|
||||
buildConversation({
|
||||
conversation: {
|
||||
id: 'foo',
|
||||
title: 'Why is database service responding with errors after I did rm -rf /postgres',
|
||||
last_updated: '',
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
refresh: () => {},
|
||||
},
|
||||
isLoading: false,
|
||||
};
|
||||
}
|
|
@ -5,16 +5,16 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Subject } from 'rxjs';
|
||||
import { useChat } from './use_chat';
|
||||
|
||||
const ObservabilityAIAssistantMultipaneFlyoutContext = React.createContext(undefined);
|
||||
|
||||
export function useKibana() {
|
||||
return {
|
||||
services: {
|
||||
uiSettings: {
|
||||
get: (setting: string) => {
|
||||
if (setting === 'dateFormat') {
|
||||
return 'MMM D, YYYY HH:mm';
|
||||
}
|
||||
},
|
||||
},
|
||||
application: { navigateToApp: () => {} },
|
||||
http: {
|
||||
basePath: {
|
||||
prepend: () => '',
|
||||
|
@ -26,6 +26,32 @@ export function useKibana() {
|
|||
addError: () => {},
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
start: {
|
||||
licensing: {
|
||||
license$: new Subject(),
|
||||
},
|
||||
observabilityAIAssistant: {
|
||||
useChat,
|
||||
ObservabilityAIAssistantMultipaneFlyoutContext,
|
||||
},
|
||||
share: {
|
||||
url: {
|
||||
locators: {
|
||||
get: () => {},
|
||||
},
|
||||
},
|
||||
},
|
||||
triggersActionsUi: { getAddRuleFlyout: {}, getAddConnectorFlyout: {} },
|
||||
},
|
||||
},
|
||||
uiSettings: {
|
||||
get: (setting: string) => {
|
||||
if (setting === 'dateFormat') {
|
||||
return 'MMM D, YYYY HH:mm';
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* 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 useObservable from 'react-use/lib/useObservable';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
export function useLicense() {
|
||||
const license = useObservable(new Subject());
|
||||
|
||||
return {
|
||||
getLicense: () => license ?? null,
|
||||
hasAtLeast: () => true,
|
||||
};
|
||||
}
|
|
@ -5,10 +5,18 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
const service = {
|
||||
start: async () => {
|
||||
return {
|
||||
chat: () => new Subject(),
|
||||
complete: () => new Subject(),
|
||||
getFunctions: [],
|
||||
getSystemMessage: () => {},
|
||||
hasFunction: () => true,
|
||||
hasRenderFunction: () => true,
|
||||
sendAnalyticsEvent: () => {},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export function useObservabilityAIAssistantAppService() {
|
||||
return {
|
||||
conversations: {
|
||||
predefinedConversation$: {
|
||||
subscribe: () => {},
|
||||
unsubscribe: () => {},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
|
@ -5,10 +5,27 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FunctionVisibility } from '@kbn/observability-ai-assistant-plugin/public';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
export function useObservabilityAIAssistantChatService() {
|
||||
return {
|
||||
chat: () => new Subject(),
|
||||
complete: () => new Subject(),
|
||||
getFunctions: () => {
|
||||
return [];
|
||||
return [
|
||||
{
|
||||
id: 'foo',
|
||||
name: 'foo',
|
||||
description: 'use this function to foo',
|
||||
descriptionForUser: 'a function that functions',
|
||||
visibility: FunctionVisibility.All,
|
||||
},
|
||||
];
|
||||
},
|
||||
getSystemMessage: () => {},
|
||||
hasFunction: () => true,
|
||||
hasRenderFunction: () => true,
|
||||
sendAnalyticsEvent: () => {},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export function useObservabilityAIAssistantRouter() {
|
||||
return {
|
||||
push: () => {},
|
||||
replace: () => {},
|
||||
link: () => {},
|
||||
};
|
||||
}
|
|
@ -11,6 +11,8 @@ import {
|
|||
createStorybookService,
|
||||
type ObservabilityAIAssistantChatService,
|
||||
} from '@kbn/observability-ai-assistant-plugin/public';
|
||||
import { Subject } from 'rxjs';
|
||||
import { coreMock } from '@kbn/core/public/mocks';
|
||||
import { ObservabilityAIAssistantAppService } from '../service/create_app_service';
|
||||
import { ObservabilityAIAssistantAppServiceProvider } from '../context/observability_ai_assistant_app_service_provider';
|
||||
|
||||
|
@ -20,21 +22,33 @@ const mockService: ObservabilityAIAssistantAppService = {
|
|||
|
||||
const mockChatService: ObservabilityAIAssistantChatService = createStorybookChatService();
|
||||
|
||||
const coreStart = coreMock.createStart();
|
||||
|
||||
export function KibanaReactStorybookDecorator(Story: ComponentType) {
|
||||
const ObservabilityAIAssistantChatServiceContext = React.createContext(mockChatService);
|
||||
const ObservabilityAIAssistantMultipaneFlyoutContext = React.createContext({
|
||||
container: <div />,
|
||||
setVisibility: () => false,
|
||||
});
|
||||
|
||||
return (
|
||||
<KibanaContextProvider
|
||||
services={{
|
||||
triggersActionsUi: { getAddRuleFlyout: {} },
|
||||
uiSettings: {
|
||||
get: (setting: string) => {
|
||||
if (setting === 'dateFormat') {
|
||||
return 'MMM D, YYYY HH:mm';
|
||||
}
|
||||
},
|
||||
...coreStart,
|
||||
licensing: {
|
||||
license$: new Subject(),
|
||||
},
|
||||
observabilityAIAssistant: {
|
||||
ObservabilityAIAssistantChatServiceContext,
|
||||
// observabilityAIAssistant: {
|
||||
// ObservabilityAIAssistantChatServiceContext,
|
||||
// ObservabilityAIAssistantMultipaneFlyoutContext,
|
||||
// },
|
||||
plugins: {
|
||||
start: {
|
||||
observabilityAIAssistant: {
|
||||
ObservabilityAIAssistantMultipaneFlyoutContext,
|
||||
},
|
||||
triggersActionsUi: { getAddRuleFlyout: {}, getAddConnectorFlyout: {} },
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
Loading…
Add table
Add a link
Reference in a new issue