@patternfly/chatbot 6.5.0-prerelease.2 → 6.5.0-prerelease.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/AttachMenu/AttachMenu.d.ts +8 -2
- package/dist/cjs/AttachMenu/AttachMenu.js +2 -2
- package/dist/cjs/ChatbotFooter/ChatbotFooter.d.ts +5 -2
- package/dist/cjs/ChatbotFooter/ChatbotFooter.js +2 -2
- package/dist/cjs/ChatbotFooter/ChatbotFooter.test.js +5 -1
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +29 -2
- package/dist/cjs/CodeModal/CodeModal.d.ts +2 -0
- package/dist/cjs/CodeModal/CodeModal.js +53 -8
- package/dist/cjs/FileDetailsLabel/FileDetailsLabel.d.ts +2 -1
- package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.d.ts +3 -1
- package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.js +2 -2
- package/dist/cjs/Message/Message.d.ts +7 -1
- package/dist/cjs/Message/Message.js +11 -8
- package/dist/cjs/Message/Message.test.js +36 -0
- package/dist/cjs/Message/MessageLoading.d.ts +2 -1
- package/dist/cjs/Message/MessageLoading.js +1 -1
- package/dist/cjs/Message/TableMessage/TableMessage.d.ts +4 -1
- package/dist/cjs/Message/TableMessage/TableMessage.js +2 -2
- package/dist/cjs/Message/TextMessage/TextMessage.d.ts +4 -1
- package/dist/cjs/Message/TextMessage/TextMessage.js +2 -2
- package/dist/cjs/MessageBar/AttachButton.d.ts +2 -0
- package/dist/cjs/MessageBar/AttachButton.js +2 -2
- package/dist/cjs/MessageBar/AttachButton.test.js +4 -0
- package/dist/cjs/MessageBar/MessageBar.d.ts +16 -6
- package/dist/cjs/MessageBar/MessageBar.js +6 -5
- package/dist/cjs/MessageBar/MessageBar.test.js +62 -0
- package/dist/cjs/Onboarding/Onboarding.d.ts +36 -0
- package/dist/cjs/Onboarding/Onboarding.js +37 -0
- package/dist/cjs/Onboarding/Onboarding.test.d.ts +1 -0
- package/dist/cjs/Onboarding/Onboarding.test.js +80 -0
- package/dist/cjs/Onboarding/index.d.ts +2 -0
- package/dist/cjs/Onboarding/index.js +23 -0
- package/dist/cjs/ResponseActions/ResponseActions.d.ts +3 -0
- package/dist/cjs/ResponseActions/ResponseActions.js +28 -7
- package/dist/cjs/ResponseActions/ResponseActions.test.js +67 -12
- package/dist/cjs/__mocks__/monaco-editor.d.ts +11 -0
- package/dist/cjs/__mocks__/monaco-editor.js +18 -0
- package/dist/cjs/__mocks__/rehype-highlight.d.ts +2 -0
- package/dist/cjs/__mocks__/rehype-highlight.js +4 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +4 -1
- package/dist/css/main.css +219 -21
- package/dist/css/main.css.map +1 -1
- package/dist/dynamic/Onboarding/package.json +1 -0
- package/dist/esm/AttachMenu/AttachMenu.d.ts +8 -2
- package/dist/esm/AttachMenu/AttachMenu.js +2 -2
- package/dist/esm/ChatbotFooter/ChatbotFooter.d.ts +5 -2
- package/dist/esm/ChatbotFooter/ChatbotFooter.js +2 -2
- package/dist/esm/ChatbotFooter/ChatbotFooter.test.js +5 -1
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +30 -3
- package/dist/esm/CodeModal/CodeModal.d.ts +2 -0
- package/dist/esm/CodeModal/CodeModal.js +54 -9
- package/dist/esm/FileDetailsLabel/FileDetailsLabel.d.ts +2 -1
- package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.d.ts +3 -1
- package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.js +2 -2
- package/dist/esm/Message/Message.d.ts +7 -1
- package/dist/esm/Message/Message.js +11 -8
- package/dist/esm/Message/Message.test.js +36 -0
- package/dist/esm/Message/MessageLoading.d.ts +2 -1
- package/dist/esm/Message/MessageLoading.js +1 -1
- package/dist/esm/Message/TableMessage/TableMessage.d.ts +4 -1
- package/dist/esm/Message/TableMessage/TableMessage.js +2 -2
- package/dist/esm/Message/TextMessage/TextMessage.d.ts +4 -1
- package/dist/esm/Message/TextMessage/TextMessage.js +2 -2
- package/dist/esm/MessageBar/AttachButton.d.ts +2 -0
- package/dist/esm/MessageBar/AttachButton.js +2 -2
- package/dist/esm/MessageBar/AttachButton.test.js +4 -0
- package/dist/esm/MessageBar/MessageBar.d.ts +16 -6
- package/dist/esm/MessageBar/MessageBar.js +6 -5
- package/dist/esm/MessageBar/MessageBar.test.js +62 -0
- package/dist/esm/Onboarding/Onboarding.d.ts +36 -0
- package/dist/esm/Onboarding/Onboarding.js +30 -0
- package/dist/esm/Onboarding/Onboarding.test.d.ts +1 -0
- package/dist/esm/Onboarding/Onboarding.test.js +75 -0
- package/dist/esm/Onboarding/index.d.ts +2 -0
- package/dist/esm/Onboarding/index.js +2 -0
- package/dist/esm/ResponseActions/ResponseActions.d.ts +3 -0
- package/dist/esm/ResponseActions/ResponseActions.js +28 -7
- package/dist/esm/ResponseActions/ResponseActions.test.js +67 -12
- package/dist/esm/__mocks__/monaco-editor.d.ts +11 -0
- package/dist/esm/__mocks__/monaco-editor.js +18 -0
- package/dist/esm/__mocks__/rehype-highlight.d.ts +2 -0
- package/dist/esm/__mocks__/rehype-highlight.js +2 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -2
- package/patternfly-docs/content/extensions/chatbot/chatbot.md +57 -0
- package/patternfly-docs/content/extensions/chatbot/design-guidelines.md +12 -12
- package/patternfly-docs/content/extensions/chatbot/examples/Analytics/Analytics.md +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Customizing Messages/Customizing Messages.md +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +1 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithPersistedActions.tsx +22 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickResponses.tsx +11 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +18 -4
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +1 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessageWithExtraContent.tsx +3 -1
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotMessageBarIndicatorThinking.tsx +15 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/CompactOnboarding.tsx +141 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/Onboarding.tsx +151 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/RH-Hat-Image.svg +9 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/Settings.tsx +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +55 -27
- package/patternfly-docs/content/extensions/chatbot/examples/demos/AttachmentDemos.md +18 -18
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +29 -21
- package/patternfly-docs/content/extensions/chatbot/examples/demos/WhiteEmbeddedChatbot.tsx +451 -0
- package/patternfly-docs/patternfly-docs.config.js +2 -1
- package/patternfly-docs/patternfly-docs.source.js +1 -1
- package/src/AttachMenu/AttachMenu.tsx +26 -11
- package/src/Chatbot/Chatbot.scss +23 -1
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +25 -0
- package/src/ChatbotFooter/ChatbotFooter.scss +21 -0
- package/src/ChatbotFooter/ChatbotFooter.test.tsx +10 -1
- package/src/ChatbotFooter/ChatbotFooter.tsx +10 -3
- package/src/ChatbotHeader/ChatbotHeader.scss +19 -0
- package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +56 -14
- package/src/ChatbotModal/ChatbotModal.scss +3 -0
- package/src/CodeModal/CodeModal.tsx +72 -23
- package/src/DeepThinking/DeepThinking.scss +1 -1
- package/src/FileDetailsLabel/FileDetailsLabel.tsx +2 -2
- package/src/Message/CodeBlockMessage/CodeBlockMessage.scss +12 -0
- package/src/Message/CodeBlockMessage/CodeBlockMessage.tsx +4 -1
- package/src/Message/Message.scss +11 -7
- package/src/Message/Message.test.tsx +41 -0
- package/src/Message/Message.tsx +28 -13
- package/src/Message/MessageLoading.scss +7 -0
- package/src/Message/MessageLoading.tsx +2 -2
- package/src/Message/TableMessage/TableMessage.scss +6 -1
- package/src/Message/TableMessage/TableMessage.tsx +6 -2
- package/src/Message/TextMessage/TextMessage.scss +10 -0
- package/src/Message/TextMessage/TextMessage.tsx +11 -2
- package/src/Message/UserFeedback/UserFeedback.scss +2 -1
- package/src/MessageBar/AttachButton.test.tsx +4 -0
- package/src/MessageBar/AttachButton.tsx +4 -1
- package/src/MessageBar/MessageBar.scss +40 -3
- package/src/MessageBar/MessageBar.test.tsx +102 -1
- package/src/MessageBar/MessageBar.tsx +44 -11
- package/src/Onboarding/Onboarding.scss +101 -0
- package/src/Onboarding/Onboarding.test.tsx +148 -0
- package/src/Onboarding/Onboarding.tsx +126 -0
- package/src/Onboarding/index.ts +3 -0
- package/src/ResponseActions/ResponseActions.scss +1 -1
- package/src/ResponseActions/ResponseActions.test.tsx +111 -12
- package/src/ResponseActions/ResponseActions.tsx +38 -10
- package/src/ToolCall/ToolCall.scss +1 -1
- package/src/ToolResponse/ToolResponse.scss +3 -3
- package/src/__mocks__/monaco-editor.ts +19 -0
- package/src/__mocks__/rehype-highlight.ts +3 -0
- package/src/index.ts +3 -0
- package/src/main.scss +1 -0
- package/tsconfig.json +1 -1
- package/patternfly-docs/content/extensions/chatbot/about-chatbot.md +0 -44
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import '@testing-library/jest-dom';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
import Onboarding from './Onboarding';
|
|
5
|
+
|
|
6
|
+
const handleModalToggle = jest.fn();
|
|
7
|
+
const onPrimaryAction = jest.fn();
|
|
8
|
+
const onSecondaryAction = jest.fn();
|
|
9
|
+
|
|
10
|
+
const body =
|
|
11
|
+
'Experience personalized assistance and seamless problem-solving, simplifying your journey with Red Hat every step of the way.';
|
|
12
|
+
|
|
13
|
+
describe('Onboarding', () => {
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
jest.clearAllMocks();
|
|
16
|
+
});
|
|
17
|
+
it('should render modal correctly', () => {
|
|
18
|
+
render(
|
|
19
|
+
<Onboarding
|
|
20
|
+
isModalOpen
|
|
21
|
+
onSecondaryAction={onSecondaryAction}
|
|
22
|
+
handleModalToggle={handleModalToggle}
|
|
23
|
+
ouiaId="Terms"
|
|
24
|
+
>
|
|
25
|
+
{body}
|
|
26
|
+
</Onboarding>
|
|
27
|
+
);
|
|
28
|
+
expect(screen.getByRole('heading', { name: /Onboarding/i })).toBeTruthy();
|
|
29
|
+
expect(screen.getByRole('button', { name: /Continue/i })).toBeTruthy();
|
|
30
|
+
expect(screen.getByRole('button', { name: /Skip/i })).toBeTruthy();
|
|
31
|
+
expect(screen.getByText(body)).toBeTruthy();
|
|
32
|
+
expect(screen.getByRole('dialog')).toHaveClass('pf-chatbot__onboarding-modal');
|
|
33
|
+
expect(screen.getByRole('dialog')).toHaveClass('pf-chatbot__onboarding-modal--default');
|
|
34
|
+
});
|
|
35
|
+
it('should handle image and altText props', () => {
|
|
36
|
+
render(
|
|
37
|
+
<Onboarding
|
|
38
|
+
isModalOpen
|
|
39
|
+
onSecondaryAction={onSecondaryAction}
|
|
40
|
+
handleModalToggle={handleModalToggle}
|
|
41
|
+
headerImage="./image.png"
|
|
42
|
+
headerImageAltText="Test image"
|
|
43
|
+
>
|
|
44
|
+
{body}
|
|
45
|
+
</Onboarding>
|
|
46
|
+
);
|
|
47
|
+
expect(screen.getByRole('img')).toBeTruthy();
|
|
48
|
+
expect(screen.getByRole('img')).toHaveAttribute('alt', 'Test image');
|
|
49
|
+
});
|
|
50
|
+
it('should handle className prop', () => {
|
|
51
|
+
render(
|
|
52
|
+
<Onboarding
|
|
53
|
+
isModalOpen
|
|
54
|
+
onSecondaryAction={onSecondaryAction}
|
|
55
|
+
handleModalToggle={handleModalToggle}
|
|
56
|
+
className="test"
|
|
57
|
+
>
|
|
58
|
+
{body}
|
|
59
|
+
</Onboarding>
|
|
60
|
+
);
|
|
61
|
+
expect(screen.getByRole('dialog')).toHaveClass('pf-chatbot__onboarding-modal');
|
|
62
|
+
expect(screen.getByRole('dialog')).toHaveClass('pf-chatbot__onboarding-modal--default');
|
|
63
|
+
expect(screen.getByRole('dialog')).toHaveClass('test');
|
|
64
|
+
});
|
|
65
|
+
it('should handle title prop', () => {
|
|
66
|
+
render(
|
|
67
|
+
<Onboarding
|
|
68
|
+
isModalOpen
|
|
69
|
+
onSecondaryAction={onSecondaryAction}
|
|
70
|
+
handleModalToggle={handleModalToggle}
|
|
71
|
+
title="Updated title"
|
|
72
|
+
>
|
|
73
|
+
{body}
|
|
74
|
+
</Onboarding>
|
|
75
|
+
);
|
|
76
|
+
expect(screen.getByRole('heading', { name: /Updated title/i })).toBeTruthy();
|
|
77
|
+
expect(screen.queryByRole('heading', { name: /Onboarding/i })).toBeFalsy();
|
|
78
|
+
});
|
|
79
|
+
it('should handle primary button prop', () => {
|
|
80
|
+
render(
|
|
81
|
+
<Onboarding
|
|
82
|
+
isModalOpen
|
|
83
|
+
onSecondaryAction={onSecondaryAction}
|
|
84
|
+
handleModalToggle={handleModalToggle}
|
|
85
|
+
primaryActionBtn="First"
|
|
86
|
+
>
|
|
87
|
+
{body}
|
|
88
|
+
</Onboarding>
|
|
89
|
+
);
|
|
90
|
+
expect(screen.getByRole('button', { name: /First/i })).toBeTruthy();
|
|
91
|
+
expect(screen.queryByRole('button', { name: /Continue/i })).toBeFalsy();
|
|
92
|
+
});
|
|
93
|
+
it('should handle secondary button prop', () => {
|
|
94
|
+
render(
|
|
95
|
+
<Onboarding
|
|
96
|
+
isModalOpen
|
|
97
|
+
onSecondaryAction={onSecondaryAction}
|
|
98
|
+
handleModalToggle={handleModalToggle}
|
|
99
|
+
secondaryActionBtn="Second"
|
|
100
|
+
>
|
|
101
|
+
{body}
|
|
102
|
+
</Onboarding>
|
|
103
|
+
);
|
|
104
|
+
expect(screen.getByRole('button', { name: /Second/i })).toBeTruthy();
|
|
105
|
+
expect(screen.queryByRole('button', { name: /Skip/i })).toBeFalsy();
|
|
106
|
+
});
|
|
107
|
+
it('should handle primary button click', async () => {
|
|
108
|
+
render(
|
|
109
|
+
<Onboarding
|
|
110
|
+
isModalOpen
|
|
111
|
+
onPrimaryAction={onPrimaryAction}
|
|
112
|
+
onSecondaryAction={onSecondaryAction}
|
|
113
|
+
handleModalToggle={handleModalToggle}
|
|
114
|
+
>
|
|
115
|
+
{body}
|
|
116
|
+
</Onboarding>
|
|
117
|
+
);
|
|
118
|
+
await userEvent.click(screen.getByRole('button', { name: /Continue/i }));
|
|
119
|
+
expect(onPrimaryAction).toHaveBeenCalledTimes(1);
|
|
120
|
+
expect(handleModalToggle).toHaveBeenCalledTimes(1);
|
|
121
|
+
});
|
|
122
|
+
it('should handle secondary button click', async () => {
|
|
123
|
+
render(
|
|
124
|
+
<Onboarding isModalOpen onSecondaryAction={onSecondaryAction} handleModalToggle={handleModalToggle}>
|
|
125
|
+
{body}
|
|
126
|
+
</Onboarding>
|
|
127
|
+
);
|
|
128
|
+
await userEvent.click(screen.getByRole('button', { name: /Skip/i }));
|
|
129
|
+
expect(onSecondaryAction).toHaveBeenCalledTimes(1);
|
|
130
|
+
expect(handleModalToggle).not.toHaveBeenCalled();
|
|
131
|
+
});
|
|
132
|
+
it('should handle isCompact prop', () => {
|
|
133
|
+
render(
|
|
134
|
+
<Onboarding
|
|
135
|
+
isModalOpen
|
|
136
|
+
onSecondaryAction={onSecondaryAction}
|
|
137
|
+
handleModalToggle={handleModalToggle}
|
|
138
|
+
isCompact={true}
|
|
139
|
+
headerImage="./image.png"
|
|
140
|
+
headerImageAltText="Test image"
|
|
141
|
+
>
|
|
142
|
+
{body}
|
|
143
|
+
</Onboarding>
|
|
144
|
+
);
|
|
145
|
+
expect(screen.getByRole('dialog')).toHaveClass('pf-m-compact');
|
|
146
|
+
expect(screen.queryByRole('img')).toBeFalsy();
|
|
147
|
+
});
|
|
148
|
+
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Terms of Use Modal - Chatbot Modal Extension
|
|
3
|
+
// ============================================================================
|
|
4
|
+
import type { FunctionComponent, MouseEvent as ReactMouseEvent, Ref } from 'react';
|
|
5
|
+
import { forwardRef } from 'react';
|
|
6
|
+
import { Button, Content, ModalBody, ModalFooter, ModalProps } from '@patternfly/react-core';
|
|
7
|
+
import { ChatbotDisplayMode } from '../Chatbot';
|
|
8
|
+
import ChatbotModal from '../ChatbotModal/ChatbotModal';
|
|
9
|
+
|
|
10
|
+
export interface OnboardingProps extends ModalProps {
|
|
11
|
+
/** Class applied to modal */
|
|
12
|
+
className?: string;
|
|
13
|
+
/** Action assigned to primary modal button */
|
|
14
|
+
onPrimaryAction?: (event: React.MouseEvent | MouseEvent | KeyboardEvent) => void;
|
|
15
|
+
/** Action assigned to secondary modal button */
|
|
16
|
+
onSecondaryAction: (event: React.MouseEvent | MouseEvent | KeyboardEvent) => void;
|
|
17
|
+
/** Name of primary modal button */
|
|
18
|
+
primaryActionBtn?: string;
|
|
19
|
+
/** Name of secondary modal button */
|
|
20
|
+
secondaryActionBtn?: string;
|
|
21
|
+
/** Function that handles modal toggle */
|
|
22
|
+
handleModalToggle: (event: React.MouseEvent | MouseEvent | KeyboardEvent) => void;
|
|
23
|
+
/** Whether modal is open */
|
|
24
|
+
isModalOpen: boolean;
|
|
25
|
+
/** Title of modal */
|
|
26
|
+
title?: string;
|
|
27
|
+
/** Display mode for the Chatbot parent; this influences the styles applied */
|
|
28
|
+
displayMode?: ChatbotDisplayMode;
|
|
29
|
+
/** Optional image displayed in header */
|
|
30
|
+
headerImage?: string;
|
|
31
|
+
/** Alt text for optional image displayed in header */
|
|
32
|
+
headerImageAltText?: string;
|
|
33
|
+
/** Ref applied to modal */
|
|
34
|
+
innerRef?: React.Ref<HTMLDivElement>;
|
|
35
|
+
/** OuiaID applied to modal */
|
|
36
|
+
ouiaId?: string;
|
|
37
|
+
/** Sets modal to compact styling. */
|
|
38
|
+
isCompact?: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const OnboardingBase: FunctionComponent<OnboardingProps> = ({
|
|
42
|
+
handleModalToggle,
|
|
43
|
+
isModalOpen,
|
|
44
|
+
onPrimaryAction,
|
|
45
|
+
onSecondaryAction,
|
|
46
|
+
primaryActionBtn = 'Continue',
|
|
47
|
+
secondaryActionBtn = 'Skip',
|
|
48
|
+
title = 'Onboarding',
|
|
49
|
+
headerImage,
|
|
50
|
+
headerImageAltText = '',
|
|
51
|
+
displayMode = ChatbotDisplayMode.default,
|
|
52
|
+
className,
|
|
53
|
+
children,
|
|
54
|
+
innerRef,
|
|
55
|
+
ouiaId = 'Onboarding',
|
|
56
|
+
isCompact,
|
|
57
|
+
...props
|
|
58
|
+
}: OnboardingProps) => {
|
|
59
|
+
const handlePrimaryAction = (_event: ReactMouseEvent | MouseEvent | KeyboardEvent) => {
|
|
60
|
+
handleModalToggle(_event);
|
|
61
|
+
onPrimaryAction && onPrimaryAction(_event);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const handleSecondaryAction = (_event: ReactMouseEvent | MouseEvent | KeyboardEvent) => {
|
|
65
|
+
onSecondaryAction(_event);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const modal = (
|
|
69
|
+
<ChatbotModal
|
|
70
|
+
isOpen={isModalOpen}
|
|
71
|
+
ouiaId={ouiaId}
|
|
72
|
+
aria-labelledby="onboarding-title"
|
|
73
|
+
aria-describedby="onboarding-modal"
|
|
74
|
+
className={`pf-chatbot__onboarding-modal pf-chatbot__onboarding-modal--${displayMode} ${isCompact ? 'pf-m-compact' : ''} ${className ? className : ''}`}
|
|
75
|
+
displayMode={displayMode}
|
|
76
|
+
onClose={handleModalToggle}
|
|
77
|
+
{...props}
|
|
78
|
+
>
|
|
79
|
+
{/* This is a workaround since the PatternFly modal doesn't have ref forwarding */}
|
|
80
|
+
<section className={`pf-chatbot__onboarding--section`} aria-label={title} tabIndex={-1} ref={innerRef}>
|
|
81
|
+
<>
|
|
82
|
+
<ModalBody className="pf-chatbot__onboarding--modal-body">
|
|
83
|
+
{!isCompact && headerImage && (
|
|
84
|
+
<div className="pf-chatbot__onboarding--header">
|
|
85
|
+
<img src={headerImage} className="pf-chatbot__onboarding--image" alt={headerImageAltText} />
|
|
86
|
+
</div>
|
|
87
|
+
)}
|
|
88
|
+
<div className="pf-chatbot__onboarding--modal-text">
|
|
89
|
+
<h1 className="pf-chatbot__onboarding--title">{title}</h1>
|
|
90
|
+
<Content>{children}</Content>
|
|
91
|
+
</div>
|
|
92
|
+
</ModalBody>
|
|
93
|
+
<ModalFooter className="pf-chatbot__onboarding--footer">
|
|
94
|
+
<Button
|
|
95
|
+
isBlock
|
|
96
|
+
key="onboarding-modal-primary"
|
|
97
|
+
variant="primary"
|
|
98
|
+
onClick={handlePrimaryAction}
|
|
99
|
+
form="onboarding-form"
|
|
100
|
+
size="lg"
|
|
101
|
+
>
|
|
102
|
+
{primaryActionBtn}
|
|
103
|
+
</Button>
|
|
104
|
+
<Button
|
|
105
|
+
isBlock
|
|
106
|
+
key="onboarding-modal-secondary"
|
|
107
|
+
variant="secondary"
|
|
108
|
+
onClick={handleSecondaryAction}
|
|
109
|
+
size="lg"
|
|
110
|
+
>
|
|
111
|
+
{secondaryActionBtn}
|
|
112
|
+
</Button>
|
|
113
|
+
</ModalFooter>
|
|
114
|
+
</>
|
|
115
|
+
</section>
|
|
116
|
+
</ChatbotModal>
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
return modal;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const Onboarding = forwardRef((props: OnboardingProps, ref: Ref<HTMLDivElement>) => (
|
|
123
|
+
<OnboardingBase innerRef={ref} {...props} />
|
|
124
|
+
));
|
|
125
|
+
|
|
126
|
+
export default Onboarding;
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
--pf-v6-c-button__icon--Color: var(--pf-t--global--icon--color--subtle);
|
|
17
17
|
}
|
|
18
18
|
&:focus {
|
|
19
|
-
--pf-v6-c-button--hover--BackgroundColor: var(--pf-t--global--background--color--action--plain--alt--clicked);
|
|
20
19
|
--pf-v6-c-button__icon--Color: var(--pf-t--global--icon--color--regular);
|
|
20
|
+
--pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--hover--BackgroundColor);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -6,8 +6,8 @@ import { DownloadIcon, InfoCircleIcon, RedoIcon } from '@patternfly/react-icons'
|
|
|
6
6
|
import Message from '../Message';
|
|
7
7
|
|
|
8
8
|
const ALL_ACTIONS = [
|
|
9
|
-
{ type: 'positive', label: 'Good response', clickedLabel: '
|
|
10
|
-
{ type: 'negative', label: 'Bad response', clickedLabel: '
|
|
9
|
+
{ type: 'positive', label: 'Good response', clickedLabel: 'Good response recorded' },
|
|
10
|
+
{ type: 'negative', label: 'Bad response', clickedLabel: 'Bad response recorded' },
|
|
11
11
|
{ type: 'copy', label: 'Copy', clickedLabel: 'Copied' },
|
|
12
12
|
{ type: 'edit', label: 'Edit', clickedLabel: 'Editing' },
|
|
13
13
|
{ type: 'share', label: 'Share', clickedLabel: 'Shared' },
|
|
@@ -81,7 +81,7 @@ describe('ResponseActions', () => {
|
|
|
81
81
|
expect(button).toBeTruthy();
|
|
82
82
|
});
|
|
83
83
|
await userEvent.click(goodBtn);
|
|
84
|
-
expect(screen.getByRole('button', { name: '
|
|
84
|
+
expect(screen.getByRole('button', { name: 'Good response recorded' })).toHaveClass(
|
|
85
85
|
'pf-chatbot__button--response-action-clicked'
|
|
86
86
|
);
|
|
87
87
|
let unclickedButtons = buttons.filter((button) => button !== goodBtn);
|
|
@@ -89,7 +89,7 @@ describe('ResponseActions', () => {
|
|
|
89
89
|
expect(button).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
90
90
|
});
|
|
91
91
|
await userEvent.click(badBtn);
|
|
92
|
-
expect(screen.getByRole('button', { name: '
|
|
92
|
+
expect(screen.getByRole('button', { name: 'Bad response recorded' })).toHaveClass(
|
|
93
93
|
'pf-chatbot__button--response-action-clicked'
|
|
94
94
|
);
|
|
95
95
|
unclickedButtons = buttons.filter((button) => button !== badBtn);
|
|
@@ -117,13 +117,13 @@ describe('ResponseActions', () => {
|
|
|
117
117
|
expect(badBtn).toBeTruthy();
|
|
118
118
|
|
|
119
119
|
await userEvent.click(goodBtn);
|
|
120
|
-
expect(screen.getByRole('button', { name: '
|
|
120
|
+
expect(screen.getByRole('button', { name: 'Good response recorded' })).toHaveClass(
|
|
121
121
|
'pf-chatbot__button--response-action-clicked'
|
|
122
122
|
);
|
|
123
123
|
expect(badBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
124
124
|
|
|
125
125
|
await userEvent.click(badBtn);
|
|
126
|
-
expect(screen.getByRole('button', { name: '
|
|
126
|
+
expect(screen.getByRole('button', { name: 'Bad response recorded' })).toHaveClass(
|
|
127
127
|
'pf-chatbot__button--response-action-clicked'
|
|
128
128
|
);
|
|
129
129
|
expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
@@ -238,30 +238,30 @@ describe('ResponseActions', () => {
|
|
|
238
238
|
});
|
|
239
239
|
|
|
240
240
|
it('should be able to call onClick correctly', async () => {
|
|
241
|
-
|
|
241
|
+
for (const { type, label } of ALL_ACTIONS) {
|
|
242
242
|
const spy = jest.fn();
|
|
243
243
|
render(<ResponseActions actions={{ [type]: { onClick: spy } }} />);
|
|
244
244
|
await userEvent.click(screen.getByRole('button', { name: label }));
|
|
245
245
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
246
|
-
}
|
|
246
|
+
}
|
|
247
247
|
});
|
|
248
248
|
|
|
249
249
|
it('should swap clicked and non-clicked aria labels on click', async () => {
|
|
250
|
-
|
|
250
|
+
for (const { type, label, clickedLabel } of ALL_ACTIONS) {
|
|
251
251
|
render(<ResponseActions actions={{ [type]: { onClick: jest.fn() } }} />);
|
|
252
252
|
expect(screen.getByRole('button', { name: label })).toBeTruthy();
|
|
253
253
|
await userEvent.click(screen.getByRole('button', { name: label }));
|
|
254
254
|
expect(screen.getByRole('button', { name: clickedLabel })).toBeTruthy();
|
|
255
|
-
}
|
|
255
|
+
}
|
|
256
256
|
});
|
|
257
257
|
|
|
258
258
|
it('should swap clicked and non-clicked tooltips on click', async () => {
|
|
259
|
-
|
|
259
|
+
for (const { type, label, clickedLabel } of ALL_ACTIONS) {
|
|
260
260
|
render(<ResponseActions actions={{ [type]: { onClick: jest.fn() } }} />);
|
|
261
261
|
expect(screen.getByRole('button', { name: label })).toBeTruthy();
|
|
262
262
|
await userEvent.click(screen.getByRole('button', { name: label }));
|
|
263
263
|
expect(screen.getByRole('tooltip', { name: clickedLabel })).toBeTruthy();
|
|
264
|
-
}
|
|
264
|
+
}
|
|
265
265
|
});
|
|
266
266
|
|
|
267
267
|
it('should be able to change aria labels', () => {
|
|
@@ -322,4 +322,103 @@ describe('ResponseActions', () => {
|
|
|
322
322
|
expect(screen.getByTestId(action[key])).toBeTruthy();
|
|
323
323
|
});
|
|
324
324
|
});
|
|
325
|
+
|
|
326
|
+
// we are testing for the reverse case already above
|
|
327
|
+
it('should not deselect when clicking outside when persistActionSelection is true', async () => {
|
|
328
|
+
render(
|
|
329
|
+
<Message
|
|
330
|
+
name="Bot"
|
|
331
|
+
role="bot"
|
|
332
|
+
avatar=""
|
|
333
|
+
content="Test content"
|
|
334
|
+
actions={{
|
|
335
|
+
positive: {},
|
|
336
|
+
negative: {}
|
|
337
|
+
}}
|
|
338
|
+
persistActionSelection
|
|
339
|
+
/>
|
|
340
|
+
);
|
|
341
|
+
const goodBtn = screen.getByRole('button', { name: 'Good response' });
|
|
342
|
+
|
|
343
|
+
await userEvent.click(goodBtn);
|
|
344
|
+
expect(screen.getByRole('button', { name: 'Good response recorded' })).toHaveClass(
|
|
345
|
+
'pf-chatbot__button--response-action-clicked'
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
await userEvent.click(screen.getByText('Test content'));
|
|
349
|
+
|
|
350
|
+
expect(screen.getByRole('button', { name: 'Good response recorded' })).toHaveClass(
|
|
351
|
+
'pf-chatbot__button--response-action-clicked'
|
|
352
|
+
);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
it('should switch selection to another button when persistActionSelection is true', async () => {
|
|
356
|
+
render(
|
|
357
|
+
<Message
|
|
358
|
+
name="Bot"
|
|
359
|
+
role="bot"
|
|
360
|
+
avatar=""
|
|
361
|
+
content="Test content"
|
|
362
|
+
actions={{
|
|
363
|
+
positive: {},
|
|
364
|
+
negative: {}
|
|
365
|
+
}}
|
|
366
|
+
persistActionSelection
|
|
367
|
+
/>
|
|
368
|
+
);
|
|
369
|
+
const goodBtn = screen.getByRole('button', { name: 'Good response' });
|
|
370
|
+
const badBtn = screen.getByRole('button', { name: 'Bad response' });
|
|
371
|
+
|
|
372
|
+
await userEvent.click(goodBtn);
|
|
373
|
+
expect(goodBtn).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
374
|
+
|
|
375
|
+
await userEvent.click(badBtn);
|
|
376
|
+
expect(badBtn).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
377
|
+
expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
it('should toggle off when clicking the same button when persistActionSelection is true', async () => {
|
|
381
|
+
render(
|
|
382
|
+
<Message
|
|
383
|
+
name="Bot"
|
|
384
|
+
role="bot"
|
|
385
|
+
avatar=""
|
|
386
|
+
content="Test content"
|
|
387
|
+
actions={{
|
|
388
|
+
positive: {},
|
|
389
|
+
negative: {}
|
|
390
|
+
}}
|
|
391
|
+
persistActionSelection
|
|
392
|
+
/>
|
|
393
|
+
);
|
|
394
|
+
const goodBtn = screen.getByRole('button', { name: 'Good response' });
|
|
395
|
+
|
|
396
|
+
await userEvent.click(goodBtn);
|
|
397
|
+
expect(goodBtn).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
398
|
+
|
|
399
|
+
await userEvent.click(goodBtn);
|
|
400
|
+
expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
it('should work with custom actions when persistActionSelection is true', async () => {
|
|
404
|
+
const actions = {
|
|
405
|
+
positive: { 'data-testid': 'positive', onClick: jest.fn() },
|
|
406
|
+
negative: { 'data-testid': 'negative', onClick: jest.fn() },
|
|
407
|
+
custom: {
|
|
408
|
+
'data-testid': 'custom',
|
|
409
|
+
onClick: jest.fn(),
|
|
410
|
+
ariaLabel: 'Custom',
|
|
411
|
+
tooltipContent: 'Custom action',
|
|
412
|
+
icon: <DownloadIcon />
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
render(<ResponseActions actions={actions} persistActionSelection />);
|
|
416
|
+
|
|
417
|
+
const customBtn = screen.getByTestId('custom');
|
|
418
|
+
await userEvent.click(customBtn);
|
|
419
|
+
expect(customBtn).toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
420
|
+
|
|
421
|
+
await userEvent.click(customBtn);
|
|
422
|
+
expect(customBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked');
|
|
423
|
+
});
|
|
325
424
|
});
|
|
@@ -53,11 +53,20 @@ export interface ResponseActionProps {
|
|
|
53
53
|
listen?: ActionProps;
|
|
54
54
|
edit?: ActionProps;
|
|
55
55
|
};
|
|
56
|
+
/** When true, the selected action will persist even when clicking outside the component.
|
|
57
|
+
* When false (default), clicking outside or clicking another action will deselect the current selection. */
|
|
58
|
+
persistActionSelection?: boolean;
|
|
56
59
|
}
|
|
57
60
|
|
|
58
|
-
export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
61
|
+
export const ResponseActions: FunctionComponent<ResponseActionProps> = ({
|
|
62
|
+
actions,
|
|
63
|
+
persistActionSelection = false
|
|
64
|
+
}) => {
|
|
59
65
|
const [activeButton, setActiveButton] = useState<string>();
|
|
60
66
|
const [clickStatePersisted, setClickStatePersisted] = useState<boolean>(false);
|
|
67
|
+
|
|
68
|
+
const { positive, negative, copy, edit, share, download, listen, ...additionalActions } = actions;
|
|
69
|
+
|
|
61
70
|
useEffect(() => {
|
|
62
71
|
// Define the order of precedence for checking initial `isClicked`
|
|
63
72
|
const actionPrecedence = ['positive', 'negative', 'copy', 'edit', 'share', 'download', 'listen'];
|
|
@@ -82,13 +91,21 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({ action
|
|
|
82
91
|
// Click state is explicitly controlled by consumer.
|
|
83
92
|
setClickStatePersisted(true);
|
|
84
93
|
}
|
|
94
|
+
// If persistActionSelection is true, all selections are persisted
|
|
95
|
+
if (persistActionSelection) {
|
|
96
|
+
setClickStatePersisted(true);
|
|
97
|
+
}
|
|
85
98
|
setActiveButton(initialActive);
|
|
86
|
-
}, [actions]);
|
|
99
|
+
}, [actions, persistActionSelection]);
|
|
87
100
|
|
|
88
|
-
const { positive, negative, copy, edit, share, download, listen, ...additionalActions } = actions;
|
|
89
101
|
const responseActions = useRef<HTMLDivElement>(null);
|
|
90
102
|
|
|
91
103
|
useEffect(() => {
|
|
104
|
+
// Only add click outside listener if not persisting selection
|
|
105
|
+
if (persistActionSelection) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
92
109
|
const handleClickOutside = (e) => {
|
|
93
110
|
if (responseActions.current && !responseActions.current.contains(e.target) && !clickStatePersisted) {
|
|
94
111
|
setActiveButton(undefined);
|
|
@@ -99,15 +116,26 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({ action
|
|
|
99
116
|
return () => {
|
|
100
117
|
window.removeEventListener('click', handleClickOutside);
|
|
101
118
|
};
|
|
102
|
-
}, [clickStatePersisted]);
|
|
119
|
+
}, [clickStatePersisted, persistActionSelection]);
|
|
103
120
|
|
|
104
121
|
const handleClick = (
|
|
105
122
|
e: MouseEvent | MouseEvent<Element, MouseEvent> | KeyboardEvent,
|
|
106
123
|
id: string,
|
|
107
124
|
onClick?: (event: MouseEvent | MouseEvent<Element, MouseEvent> | KeyboardEvent) => void
|
|
108
125
|
) => {
|
|
109
|
-
|
|
110
|
-
|
|
126
|
+
if (persistActionSelection) {
|
|
127
|
+
if (activeButton === id) {
|
|
128
|
+
// Toggle off if clicking the same button
|
|
129
|
+
setActiveButton(undefined);
|
|
130
|
+
} else {
|
|
131
|
+
// Set new active button
|
|
132
|
+
setActiveButton(id);
|
|
133
|
+
}
|
|
134
|
+
setClickStatePersisted(true);
|
|
135
|
+
} else {
|
|
136
|
+
setClickStatePersisted(false);
|
|
137
|
+
setActiveButton(id);
|
|
138
|
+
}
|
|
111
139
|
onClick && onClick(e);
|
|
112
140
|
};
|
|
113
141
|
|
|
@@ -117,12 +145,12 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({ action
|
|
|
117
145
|
<ResponseActionButton
|
|
118
146
|
{...positive}
|
|
119
147
|
ariaLabel={positive.ariaLabel ?? 'Good response'}
|
|
120
|
-
clickedAriaLabel={positive.ariaLabel ?? '
|
|
148
|
+
clickedAriaLabel={positive.ariaLabel ?? 'Good response recorded'}
|
|
121
149
|
onClick={(e) => handleClick(e, 'positive', positive.onClick)}
|
|
122
150
|
className={positive.className}
|
|
123
151
|
isDisabled={positive.isDisabled}
|
|
124
152
|
tooltipContent={positive.tooltipContent ?? 'Good response'}
|
|
125
|
-
clickedTooltipContent={positive.clickedTooltipContent ?? '
|
|
153
|
+
clickedTooltipContent={positive.clickedTooltipContent ?? 'Good response recorded'}
|
|
126
154
|
tooltipProps={positive.tooltipProps}
|
|
127
155
|
icon={<OutlinedThumbsUpIcon />}
|
|
128
156
|
isClicked={activeButton === 'positive'}
|
|
@@ -135,12 +163,12 @@ export const ResponseActions: FunctionComponent<ResponseActionProps> = ({ action
|
|
|
135
163
|
<ResponseActionButton
|
|
136
164
|
{...negative}
|
|
137
165
|
ariaLabel={negative.ariaLabel ?? 'Bad response'}
|
|
138
|
-
clickedAriaLabel={negative.ariaLabel ?? '
|
|
166
|
+
clickedAriaLabel={negative.ariaLabel ?? 'Bad response recorded'}
|
|
139
167
|
onClick={(e) => handleClick(e, 'negative', negative.onClick)}
|
|
140
168
|
className={negative.className}
|
|
141
169
|
isDisabled={negative.isDisabled}
|
|
142
170
|
tooltipContent={negative.tooltipContent ?? 'Bad response'}
|
|
143
|
-
clickedTooltipContent={negative.clickedTooltipContent ?? '
|
|
171
|
+
clickedTooltipContent={negative.clickedTooltipContent ?? 'Bad response recorded'}
|
|
144
172
|
tooltipProps={negative.tooltipProps}
|
|
145
173
|
icon={<OutlinedThumbsDownIcon />}
|
|
146
174
|
isClicked={activeButton === 'negative'}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.pf-chatbot__tool-call {
|
|
2
|
-
--pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--control--read-only);
|
|
3
2
|
--pf-v6-c-card--BorderRadius: var(--pf-t--global--border--radius--small);
|
|
3
|
+
--pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--default);
|
|
4
4
|
|
|
5
5
|
overflow: unset;
|
|
6
6
|
row-gap: var(--pf-t--global--spacer--sm);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
.pf-chatbot__tool-response {
|
|
2
|
-
--pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--
|
|
2
|
+
--pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--default);
|
|
3
3
|
overflow: unset;
|
|
4
4
|
}
|
|
5
5
|
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
.pf-chatbot__tool-response-card {
|
|
28
|
-
--pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--
|
|
28
|
+
--pf-v6-c-card--BorderColor: var(--pf-t--global--border--color--default);
|
|
29
29
|
--pf-v6-c-card--first-child--PaddingBlockStart: var(--pf-t--global--spacer--sm);
|
|
30
30
|
--pf-v6-c-card__title--not--last-child--PaddingBlockEnd: var(--pf-t--global--spacer--sm);
|
|
31
31
|
--pf-v6-c-card--c-divider--child--PaddingBlockStart: var(--pf-t--global--spacer--sm);
|
|
32
32
|
|
|
33
33
|
.pf-v6-c-divider {
|
|
34
|
-
--pf-v6-c-divider--Color: var(--pf-t--global--border--color--
|
|
34
|
+
--pf-v6-c-divider--Color: var(--pf-t--global--border--color--default);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const mockEditor = {
|
|
2
|
+
layout: jest.fn(),
|
|
3
|
+
focus: jest.fn(),
|
|
4
|
+
dispose: jest.fn(),
|
|
5
|
+
getModel: jest.fn(),
|
|
6
|
+
updateOptions: jest.fn()
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const mockModel = {
|
|
10
|
+
updateOptions: jest.fn(),
|
|
11
|
+
dispose: jest.fn()
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
editor: {
|
|
16
|
+
create: jest.fn(() => mockEditor),
|
|
17
|
+
getModels: jest.fn(() => [mockModel])
|
|
18
|
+
}
|
|
19
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -75,6 +75,9 @@ export * from './MessageBox';
|
|
|
75
75
|
export { default as MessageDivider } from './MessageDivider';
|
|
76
76
|
export * from './MessageDivider';
|
|
77
77
|
|
|
78
|
+
export { default as Onboarding } from './Onboarding';
|
|
79
|
+
export * from './Onboarding';
|
|
80
|
+
|
|
78
81
|
export { default as PreviewAttachment } from './PreviewAttachment';
|
|
79
82
|
export * from './PreviewAttachment';
|
|
80
83
|
|
package/src/main.scss
CHANGED
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
@import './MessageBox/MessageBox';
|
|
32
32
|
@import './MessageDivider/MessageDivider';
|
|
33
33
|
@import './MessageBox/JumpButton';
|
|
34
|
+
@import './Onboarding/Onboarding';
|
|
34
35
|
@import './ResponseActions/ResponseActions';
|
|
35
36
|
@import './Settings/Settings';
|
|
36
37
|
@import './SourcesCard/SourcesCard.scss';
|
package/tsconfig.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
/* Basic Options */
|
|
6
6
|
// "incremental": true, /* Enable incremental compilation */
|
|
7
7
|
"target": "es2015" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
|
|
8
|
-
"module": "
|
|
8
|
+
"module": "es2020" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
|
9
9
|
// "lib": [], /* Specify library files to be included in the compilation. */
|
|
10
10
|
// "allowJs": true, /* Allow javascript files to be compiled. */
|
|
11
11
|
// "checkJs": true, /* Report errors in .js files. */
|