@patternfly/chatbot 6.4.0-prerelease.2 → 6.4.0-prerelease.21
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/Chatbot/Chatbot.js +1 -7
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.d.ts +2 -0
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +2 -2
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +22 -2
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +15 -9
- package/dist/cjs/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +40 -2
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.js +1 -1
- package/dist/cjs/ChatbotHeader/ChatbotHeaderMenu.test.js +1 -1
- package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.d.ts +18 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.js +25 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.test.d.ts +1 -0
- package/dist/cjs/ChatbotHeader/ChatbotHeaderNewChatButton.test.js +22 -0
- package/dist/cjs/ChatbotHeader/index.d.ts +1 -0
- package/dist/cjs/ChatbotHeader/index.js +1 -0
- package/dist/cjs/DeepThinking/DeepThinking.d.ts +18 -0
- package/dist/cjs/DeepThinking/DeepThinking.js +18 -0
- package/dist/cjs/DeepThinking/DeepThinking.test.d.ts +1 -0
- package/dist/cjs/DeepThinking/DeepThinking.test.js +48 -0
- package/dist/cjs/DeepThinking/index.d.ts +2 -0
- package/dist/cjs/DeepThinking/index.js +23 -0
- package/dist/cjs/FileDetails/FileDetails.d.ts +22 -3
- package/dist/cjs/FileDetails/FileDetails.js +27 -912
- package/dist/cjs/FileDetails/FileDetails.test.js +16 -0
- package/dist/cjs/FileDetailsLabel/FileDetailsLabel.d.ts +8 -2
- package/dist/cjs/FileDetailsLabel/FileDetailsLabel.js +14 -2
- package/dist/cjs/FileDetailsLabel/FileDetailsLabel.test.js +19 -1
- package/dist/cjs/FilePreview/FilePreview.d.ts +26 -0
- package/dist/cjs/FilePreview/FilePreview.js +26 -0
- package/dist/cjs/FilePreview/FilePreview.test.d.ts +1 -0
- package/dist/cjs/FilePreview/FilePreview.test.js +97 -0
- package/dist/cjs/FilePreview/index.d.ts +2 -0
- package/dist/cjs/FilePreview/index.js +23 -0
- package/dist/cjs/ImagePreview/ImagePreview.d.ts +53 -0
- package/dist/cjs/ImagePreview/ImagePreview.js +47 -0
- package/dist/cjs/ImagePreview/ImagePreview.test.d.ts +1 -0
- package/dist/cjs/ImagePreview/ImagePreview.test.js +225 -0
- package/dist/cjs/ImagePreview/index.d.ts +2 -0
- package/dist/cjs/ImagePreview/index.js +23 -0
- package/dist/cjs/Message/CodeBlockMessage/CodeBlockMessage.js +3 -3
- package/dist/cjs/Message/LinkMessage/LinkMessage.d.ts +2 -1
- package/dist/cjs/Message/LinkMessage/LinkMessage.js +7 -3
- package/dist/cjs/Message/ListMessage/ListItemMessage.d.ts +1 -1
- package/dist/cjs/Message/ListMessage/ListItemMessage.js +16 -1
- package/dist/cjs/Message/Message.d.ts +15 -0
- package/dist/cjs/Message/Message.js +129 -32
- package/dist/cjs/Message/Message.test.js +71 -0
- package/dist/cjs/Message/SuperscriptMessage/SuperscriptMessage.d.ts +3 -0
- package/dist/cjs/Message/SuperscriptMessage/SuperscriptMessage.js +5 -0
- package/dist/cjs/Message/UserFeedback/UserFeedback.d.ts +15 -1
- package/dist/cjs/Message/UserFeedback/UserFeedback.js +4 -4
- package/dist/cjs/Message/UserFeedback/UserFeedback.test.js +44 -0
- package/dist/cjs/MessageBar/MessageBar.js +19 -4
- package/dist/cjs/MessageBox/JumpButton.d.ts +5 -0
- package/dist/cjs/MessageBox/JumpButton.js +1 -1
- package/dist/cjs/MessageBox/JumpButton.test.js +4 -4
- package/dist/cjs/MessageBox/MessageBox.d.ts +9 -0
- package/dist/cjs/MessageBox/MessageBox.js +2 -2
- package/dist/cjs/MessageBox/MessageBox.test.js +2 -2
- package/dist/cjs/SourcesCard/SourcesCard.d.ts +13 -1
- package/dist/cjs/SourcesCard/SourcesCard.js +6 -6
- package/dist/cjs/SourcesCard/SourcesCard.test.js +49 -0
- package/dist/cjs/ToolResponse/ToolResponse.d.ts +30 -0
- package/dist/cjs/ToolResponse/ToolResponse.js +18 -0
- package/dist/cjs/ToolResponse/ToolResponse.test.d.ts +1 -0
- package/dist/cjs/ToolResponse/ToolResponse.test.js +60 -0
- package/dist/cjs/ToolResponse/index.d.ts +2 -0
- package/dist/cjs/ToolResponse/index.js +23 -0
- package/dist/cjs/index.d.ts +8 -0
- package/dist/cjs/index.js +13 -1
- package/dist/css/main.css +339 -27
- package/dist/css/main.css.map +1 -1
- package/dist/dynamic/DeepThinking/package.json +1 -0
- package/dist/dynamic/FilePreview/package.json +1 -0
- package/dist/dynamic/ImagePreview/package.json +1 -0
- package/dist/dynamic/ToolResponse/package.json +1 -0
- package/dist/esm/Chatbot/Chatbot.js +1 -7
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.d.ts +2 -0
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.js +2 -2
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.d.ts +22 -2
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.js +17 -11
- package/dist/esm/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.js +41 -3
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.js +1 -1
- package/dist/esm/ChatbotHeader/ChatbotHeaderMenu.test.js +1 -1
- package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.d.ts +18 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.js +22 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.test.d.ts +1 -0
- package/dist/esm/ChatbotHeader/ChatbotHeaderNewChatButton.test.js +20 -0
- package/dist/esm/ChatbotHeader/index.d.ts +1 -0
- package/dist/esm/ChatbotHeader/index.js +1 -0
- package/dist/esm/DeepThinking/DeepThinking.d.ts +18 -0
- package/dist/esm/DeepThinking/DeepThinking.js +14 -0
- package/dist/esm/DeepThinking/DeepThinking.test.d.ts +1 -0
- package/dist/esm/DeepThinking/DeepThinking.test.js +43 -0
- package/dist/esm/DeepThinking/index.d.ts +2 -0
- package/dist/esm/DeepThinking/index.js +2 -0
- package/dist/esm/FileDetails/FileDetails.d.ts +22 -3
- package/dist/esm/FileDetails/FileDetails.js +27 -912
- package/dist/esm/FileDetails/FileDetails.test.js +16 -0
- package/dist/esm/FileDetailsLabel/FileDetailsLabel.d.ts +8 -2
- package/dist/esm/FileDetailsLabel/FileDetailsLabel.js +14 -2
- package/dist/esm/FileDetailsLabel/FileDetailsLabel.test.js +19 -1
- package/dist/esm/FilePreview/FilePreview.d.ts +26 -0
- package/dist/esm/FilePreview/FilePreview.js +21 -0
- package/dist/esm/FilePreview/FilePreview.test.d.ts +1 -0
- package/dist/esm/FilePreview/FilePreview.test.js +92 -0
- package/dist/esm/FilePreview/index.d.ts +2 -0
- package/dist/esm/FilePreview/index.js +2 -0
- package/dist/esm/ImagePreview/ImagePreview.d.ts +53 -0
- package/dist/esm/ImagePreview/ImagePreview.js +42 -0
- package/dist/esm/ImagePreview/ImagePreview.test.d.ts +1 -0
- package/dist/esm/ImagePreview/ImagePreview.test.js +220 -0
- package/dist/esm/ImagePreview/index.d.ts +2 -0
- package/dist/esm/ImagePreview/index.js +2 -0
- package/dist/esm/Message/CodeBlockMessage/CodeBlockMessage.js +5 -5
- package/dist/esm/Message/LinkMessage/LinkMessage.d.ts +2 -1
- package/dist/esm/Message/LinkMessage/LinkMessage.js +7 -3
- package/dist/esm/Message/ListMessage/ListItemMessage.d.ts +1 -1
- package/dist/esm/Message/ListMessage/ListItemMessage.js +16 -1
- package/dist/esm/Message/Message.d.ts +15 -0
- package/dist/esm/Message/Message.js +129 -32
- package/dist/esm/Message/Message.test.js +71 -0
- package/dist/esm/Message/SuperscriptMessage/SuperscriptMessage.d.ts +3 -0
- package/dist/esm/Message/SuperscriptMessage/SuperscriptMessage.js +3 -0
- package/dist/esm/Message/UserFeedback/UserFeedback.d.ts +15 -1
- package/dist/esm/Message/UserFeedback/UserFeedback.js +4 -4
- package/dist/esm/Message/UserFeedback/UserFeedback.test.js +45 -1
- package/dist/esm/MessageBar/MessageBar.js +19 -4
- package/dist/esm/MessageBox/JumpButton.d.ts +5 -0
- package/dist/esm/MessageBox/JumpButton.js +1 -1
- package/dist/esm/MessageBox/JumpButton.test.js +4 -4
- package/dist/esm/MessageBox/MessageBox.d.ts +9 -0
- package/dist/esm/MessageBox/MessageBox.js +2 -2
- package/dist/esm/MessageBox/MessageBox.test.js +2 -2
- package/dist/esm/SourcesCard/SourcesCard.d.ts +13 -1
- package/dist/esm/SourcesCard/SourcesCard.js +6 -6
- package/dist/esm/SourcesCard/SourcesCard.test.js +50 -1
- package/dist/esm/ToolResponse/ToolResponse.d.ts +30 -0
- package/dist/esm/ToolResponse/ToolResponse.js +14 -0
- package/dist/esm/ToolResponse/ToolResponse.test.d.ts +1 -0
- package/dist/esm/ToolResponse/ToolResponse.test.js +55 -0
- package/dist/esm/ToolResponse/index.d.ts +2 -0
- package/dist/esm/ToolResponse/index.js +2 -0
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.js +8 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -6
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/AttachmentEdit.tsx +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +101 -3
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/FilePreview.tsx +33 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/ImagePreview.tsx +53 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithDeepThinking.tsx +17 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithFeedback.tsx +111 -85
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithSources.tsx +70 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithToolResponse.tsx +135 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +38 -4
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/PreviewAttachment.tsx +1 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +107 -2
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessageWithExtraContent.tsx +616 -3
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/file-preview.svg +9 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotConversationEditing.tsx +202 -0
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderBasic.tsx +17 -3
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawer.tsx +36 -5
- package/patternfly-docs/content/extensions/chatbot/examples/UI/ChatbotHeaderDrawerWithPin.tsx +12 -2
- package/patternfly-docs/content/extensions/chatbot/examples/UI/UI.md +22 -3
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +1 -1
- package/patternfly-docs/patternfly-docs.config.js +1 -1
- package/src/Chatbot/Chatbot.scss +9 -2
- package/src/Chatbot/Chatbot.tsx +18 -31
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryDropdown.tsx +5 -1
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.scss +16 -10
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.test.tsx +132 -3
- package/src/ChatbotConversationHistoryNav/ChatbotConversationHistoryNav.tsx +80 -33
- package/src/ChatbotHeader/ChatbotHeaderMenu.test.tsx +1 -1
- package/src/ChatbotHeader/ChatbotHeaderMenu.tsx +2 -2
- package/src/ChatbotHeader/ChatbotHeaderNewChatButton.test.tsx +25 -0
- package/src/ChatbotHeader/ChatbotHeaderNewChatButton.tsx +64 -0
- package/src/ChatbotHeader/index.ts +1 -0
- package/src/ChatbotModal/ChatbotModal.scss +1 -1
- package/src/DeepThinking/DeepThinking.scss +24 -0
- package/src/DeepThinking/DeepThinking.test.tsx +61 -0
- package/src/DeepThinking/DeepThinking.tsx +68 -0
- package/src/DeepThinking/index.ts +3 -0
- package/src/FileDetails/FileDetails.scss +10 -0
- package/src/FileDetails/FileDetails.test.tsx +16 -0
- package/src/FileDetails/FileDetails.tsx +89 -32
- package/src/FileDetails/__snapshots__/FileDetails.test.tsx.snap +20 -14
- package/src/FileDetailsLabel/FileDetailsLabel.test.tsx +21 -1
- package/src/FileDetailsLabel/FileDetailsLabel.tsx +16 -3
- package/src/FileDetailsLabel/__snapshots__/FileDetailsLabel.test.tsx.snap +20 -14
- package/src/FilePreview/FilePreview.scss +22 -0
- package/src/FilePreview/FilePreview.test.tsx +112 -0
- package/src/FilePreview/FilePreview.tsx +58 -0
- package/src/FilePreview/index.ts +3 -0
- package/src/ImagePreview/ImagePreview.scss +61 -0
- package/src/ImagePreview/ImagePreview.test.tsx +253 -0
- package/src/ImagePreview/ImagePreview.tsx +200 -0
- package/src/ImagePreview/index.ts +3 -0
- package/src/Message/CodeBlockMessage/CodeBlockMessage.scss +2 -1
- package/src/Message/CodeBlockMessage/CodeBlockMessage.tsx +6 -5
- package/src/Message/LinkMessage/LinkMessage.tsx +6 -2
- package/src/Message/ListMessage/ListItemMessage.tsx +5 -1
- package/src/Message/ListMessage/ListMessage.scss +17 -0
- package/src/Message/Message.scss +44 -0
- package/src/Message/Message.test.tsx +90 -0
- package/src/Message/Message.tsx +171 -46
- package/src/Message/SuperscriptMessage/SuperscriptMessage.scss +8 -0
- package/src/Message/SuperscriptMessage/SuperscriptMessage.tsx +13 -0
- package/src/Message/TextMessage/TextMessage.scss +46 -5
- package/src/Message/UserFeedback/UserFeedback.test.tsx +107 -0
- package/src/Message/UserFeedback/UserFeedback.tsx +41 -6
- package/src/MessageBar/MessageBar.tsx +23 -3
- package/src/MessageBox/JumpButton.test.tsx +4 -4
- package/src/MessageBox/JumpButton.tsx +20 -4
- package/src/MessageBox/MessageBox.scss +0 -12
- package/src/MessageBox/MessageBox.test.tsx +2 -2
- package/src/MessageBox/MessageBox.tsx +23 -2
- package/src/SourcesCard/SourcesCard.scss +17 -0
- package/src/SourcesCard/SourcesCard.test.tsx +93 -0
- package/src/SourcesCard/SourcesCard.tsx +116 -80
- package/src/ToolResponse/ToolResponse.scss +36 -0
- package/src/ToolResponse/ToolResponse.test.tsx +78 -0
- package/src/ToolResponse/ToolResponse.tsx +95 -0
- package/src/ToolResponse/index.ts +3 -0
- package/src/index.ts +12 -0
- package/src/main.scss +16 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
|
2
|
-
import { Flex,
|
|
2
|
+
import { Flex, FlexItem, Truncate } from '@patternfly/react-core';
|
|
3
3
|
import path from 'path-browserify';
|
|
4
|
-
interface FileDetailsProps {
|
|
4
|
+
export interface FileDetailsProps {
|
|
5
5
|
/** Class name applied to container */
|
|
6
6
|
className?: string;
|
|
7
7
|
/** Name of file, including extension */
|
|
@@ -10,8 +10,24 @@ interface FileDetailsProps {
|
|
|
10
10
|
languageTestId?: string;
|
|
11
11
|
/** Class name applied to file name */
|
|
12
12
|
fileNameClassName?: string;
|
|
13
|
+
/** File size */
|
|
14
|
+
fileSize?: string;
|
|
15
|
+
/** Whether to truncate file name */
|
|
16
|
+
hasTruncation?: boolean;
|
|
13
17
|
}
|
|
14
18
|
|
|
19
|
+
// manually added for image modal
|
|
20
|
+
// based on https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Formats/Image_types
|
|
21
|
+
export const IMAGE_FORMATS = {
|
|
22
|
+
png: 'PNG',
|
|
23
|
+
apng: 'APNG',
|
|
24
|
+
avif: 'AVIF',
|
|
25
|
+
gif: 'GIF',
|
|
26
|
+
jpg: 'JPEG',
|
|
27
|
+
svg: 'SVG',
|
|
28
|
+
webp: 'WebP'
|
|
29
|
+
};
|
|
30
|
+
|
|
15
31
|
// source https://gist.github.com/ppisarczyk/43962d06686722d26d176fad46879d41
|
|
16
32
|
// FIXME We could probably check against the PF Language hash to trim this down to what the code editor supports.
|
|
17
33
|
// I can also see an argument to leaving this open, or researching what the third-party we use for uploads is using
|
|
@@ -678,7 +694,6 @@ export const extensionToLanguage = {
|
|
|
678
694
|
viw: 'SQL',
|
|
679
695
|
db2: 'SQLPL',
|
|
680
696
|
ston: 'STON',
|
|
681
|
-
svg: 'SVG',
|
|
682
697
|
sage: 'Sage',
|
|
683
698
|
sagews: 'Sage',
|
|
684
699
|
sls: 'Scheme',
|
|
@@ -935,54 +950,96 @@ export const extensionToLanguage = {
|
|
|
935
950
|
ppt: 'Presentation',
|
|
936
951
|
pptx: 'Presentation',
|
|
937
952
|
odp: 'Presentation',
|
|
938
|
-
pdf: 'PDF'
|
|
953
|
+
pdf: 'PDF',
|
|
954
|
+
// manually added for image modal
|
|
955
|
+
// based on https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Formats/Image_types
|
|
956
|
+
...IMAGE_FORMATS
|
|
939
957
|
};
|
|
940
958
|
|
|
941
959
|
export const FileDetails = ({
|
|
942
960
|
className,
|
|
943
961
|
fileName,
|
|
944
962
|
fileNameClassName,
|
|
945
|
-
languageTestId
|
|
963
|
+
languageTestId,
|
|
964
|
+
fileSize,
|
|
965
|
+
hasTruncation = true
|
|
946
966
|
}: PropsWithChildren<FileDetailsProps>) => {
|
|
947
967
|
const language = extensionToLanguage[path.extname(fileName).slice(1)]?.toUpperCase();
|
|
968
|
+
const isImage = IMAGE_FORMATS[path.extname(fileName).slice(1)] ? true : false;
|
|
948
969
|
return (
|
|
949
970
|
<Flex className={`pf-chatbot__file-details ${className ? className : ''}`} gap={{ default: 'gapSm' }}>
|
|
950
971
|
<Flex
|
|
951
|
-
className=
|
|
972
|
+
className={`${isImage ? 'pf-chatbot__image-icon' : 'pf-chatbot__code-icon'}`}
|
|
952
973
|
justifyContent={{ default: 'justifyContentCenter' }}
|
|
953
974
|
alignItems={{ default: 'alignItemsCenter' }}
|
|
954
975
|
alignSelf={{ default: 'alignSelfCenter' }}
|
|
955
976
|
>
|
|
956
|
-
|
|
957
|
-
<
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
977
|
+
{isImage ? (
|
|
978
|
+
<svg
|
|
979
|
+
aria-hidden="true"
|
|
980
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
981
|
+
width="24"
|
|
982
|
+
height="25"
|
|
983
|
+
viewBox="0 0 24 25"
|
|
984
|
+
fill="none"
|
|
985
|
+
>
|
|
986
|
+
<path
|
|
987
|
+
d="M0 4.5C0 2.29086 1.79086 0.5 4 0.5H20C22.2091 0.5 24 2.29086 24 4.5V20.5C24 22.7091 22.2091 24.5 20 24.5H4C1.79086 24.5 0 22.7091 0 20.5V4.5Z"
|
|
988
|
+
fill="currentColor"
|
|
989
|
+
/>
|
|
962
990
|
<path
|
|
963
|
-
d="
|
|
991
|
+
d="M4 7.5C4 6.39688 4.89688 5.5 6 5.5H18C19.1031 5.5 20 6.39688 20 7.5V17.5C20 18.6031 19.1031 19.5 18 19.5H6C4.89688 19.5 4 18.6031 4 17.5V7.5ZM14.1187 10.8281C13.9781 10.6219 13.7469 10.5 13.5 10.5C13.2531 10.5 13.0188 10.6219 12.8813 10.8281L10.1625 14.8156L9.33437 13.7812C9.19062 13.6031 8.975 13.5 8.75 13.5C8.525 13.5 8.30625 13.6031 8.16563 13.7812L6.16563 16.2812C5.98438 16.5063 5.95 16.8156 6.075 17.075C6.2 17.3344 6.4625 17.5 6.75 17.5H9.75H10.75H17.25C17.5281 17.5 17.7844 17.3469 17.9125 17.1C18.0406 16.8531 18.025 16.5562 17.8687 16.3281L14.1187 10.8281ZM7.5 10.5C7.89782 10.5 8.27936 10.342 8.56066 10.0607C8.84196 9.77936 9 9.39782 9 9C9 8.60218 8.84196 8.22064 8.56066 7.93934C8.27936 7.65804 7.89782 7.5 7.5 7.5C7.10218 7.5 6.72064 7.65804 6.43934 7.93934C6.15804 8.22064 6 8.60218 6 9C6 9.39782 6.15804 9.77936 6.43934 10.0607C6.72064 10.342 7.10218 10.5 7.5 10.5Z"
|
|
964
992
|
fill="white"
|
|
965
993
|
/>
|
|
966
|
-
</
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
994
|
+
</svg>
|
|
995
|
+
) : (
|
|
996
|
+
<svg
|
|
997
|
+
aria-hidden="true"
|
|
998
|
+
width="24"
|
|
999
|
+
height="24"
|
|
1000
|
+
viewBox="0 0 24 24"
|
|
1001
|
+
fill="currentColor"
|
|
1002
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
1003
|
+
>
|
|
1004
|
+
<path
|
|
1005
|
+
d="M0 4C0 1.79086 1.79086 0 4 0H20C22.2091 0 24 1.79086 24 4V20C24 22.2091 22.2091 24 20 24H4C1.79086 24 0 22.2091 0 20V4Z"
|
|
1006
|
+
fill="currentColor"
|
|
1007
|
+
/>
|
|
1008
|
+
<g clipPath="url(#clip0_3280_27505)">
|
|
1009
|
+
<path
|
|
1010
|
+
d="M13.8204 5.63002C13.3954 5.50752 12.9529 5.75502 12.8304 6.18002L9.63035 17.38C9.50785 17.805 9.75535 18.2475 10.1804 18.37C10.6054 18.4925 11.0479 18.245 11.1704 17.82L14.3704 6.62002C14.4929 6.19502 14.2454 5.75252 13.8204 5.63002ZM15.8354 8.63252C15.5229 8.94502 15.5229 9.45252 15.8354 9.76502L18.0679 12L15.8329 14.235C15.5204 14.5475 15.5204 15.055 15.8329 15.3675C16.1454 15.68 16.6529 15.68 16.9654 15.3675L19.7654 12.5675C20.0779 12.255 20.0779 11.7475 19.7654 11.435L16.9654 8.63502C16.6529 8.32252 16.1454 8.32252 15.8329 8.63502L15.8354 8.63252ZM8.16785 8.63252C7.85535 8.32002 7.34785 8.32002 7.03535 8.63252L4.23535 11.4325C3.92285 11.745 3.92285 12.2525 4.23535 12.565L7.03535 15.365C7.34785 15.6775 7.85535 15.6775 8.16785 15.365C8.48035 15.0525 8.48035 14.545 8.16785 14.2325L5.93285 12L8.16785 9.76502C8.48035 9.45252 8.48035 8.94502 8.16785 8.63252Z"
|
|
1011
|
+
fill="white"
|
|
1012
|
+
/>
|
|
1013
|
+
</g>
|
|
1014
|
+
<defs>
|
|
1015
|
+
<clipPath>
|
|
1016
|
+
<rect width="16" height="12.8" fill="white" transform="translate(4 5.60001)" />
|
|
1017
|
+
</clipPath>
|
|
1018
|
+
</defs>
|
|
1019
|
+
</svg>
|
|
984
1020
|
)}
|
|
985
|
-
</
|
|
1021
|
+
</Flex>
|
|
1022
|
+
<Flex gap={{ default: 'gapXs' }}>
|
|
1023
|
+
<FlexItem>
|
|
1024
|
+
<Flex direction={{ default: 'column' }} gap={{ default: 'gapNone' }}>
|
|
1025
|
+
<FlexItem>
|
|
1026
|
+
<span className="pf-chatbot__code-fileName">
|
|
1027
|
+
{hasTruncation ? (
|
|
1028
|
+
<Truncate className={fileNameClassName} content={path.parse(fileName).name} />
|
|
1029
|
+
) : (
|
|
1030
|
+
fileName
|
|
1031
|
+
)}
|
|
1032
|
+
</span>
|
|
1033
|
+
</FlexItem>
|
|
1034
|
+
{!isImage && language && (
|
|
1035
|
+
<FlexItem data-testid={languageTestId} className="pf-chatbot__code-language">
|
|
1036
|
+
{language}
|
|
1037
|
+
</FlexItem>
|
|
1038
|
+
)}
|
|
1039
|
+
</Flex>
|
|
1040
|
+
</FlexItem>
|
|
1041
|
+
{fileSize && <FlexItem className="pf-chatbot__code-file-size">{fileSize}</FlexItem>}
|
|
1042
|
+
</Flex>
|
|
986
1043
|
</Flex>
|
|
987
1044
|
);
|
|
988
1045
|
};
|
|
@@ -9,6 +9,7 @@ exports[`FileDetails should render file details 1`] = `
|
|
|
9
9
|
class="pf-v6-l-flex pf-m-align-items-center pf-m-align-self-center pf-m-justify-content-center pf-chatbot__code-icon"
|
|
10
10
|
>
|
|
11
11
|
<svg
|
|
12
|
+
aria-hidden="true"
|
|
12
13
|
fill="currentColor"
|
|
13
14
|
height="24"
|
|
14
15
|
viewBox="0 0 24 24"
|
|
@@ -40,33 +41,38 @@ exports[`FileDetails should render file details 1`] = `
|
|
|
40
41
|
</svg>
|
|
41
42
|
</div>
|
|
42
43
|
<div
|
|
43
|
-
class="pf-v6-l-
|
|
44
|
+
class="pf-v6-l-flex pf-m-gap-xs"
|
|
44
45
|
>
|
|
45
46
|
<div
|
|
46
|
-
class="
|
|
47
|
+
class=""
|
|
47
48
|
>
|
|
48
|
-
<
|
|
49
|
-
class="pf-
|
|
49
|
+
<div
|
|
50
|
+
class="pf-v6-l-flex pf-m-column pf-m-gap-none"
|
|
50
51
|
>
|
|
51
52
|
<div
|
|
52
|
-
|
|
53
|
+
class=""
|
|
53
54
|
>
|
|
54
55
|
<span
|
|
55
|
-
class="pf-
|
|
56
|
+
class="pf-chatbot__code-fileName"
|
|
56
57
|
>
|
|
57
58
|
<span
|
|
58
|
-
class="pf-v6-c-
|
|
59
|
+
class="pf-v6-c-truncate"
|
|
60
|
+
tabindex="0"
|
|
59
61
|
>
|
|
60
|
-
|
|
62
|
+
<span
|
|
63
|
+
class="pf-v6-c-truncate__start"
|
|
64
|
+
>
|
|
65
|
+
test
|
|
66
|
+
</span>
|
|
61
67
|
</span>
|
|
62
68
|
</span>
|
|
63
69
|
</div>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
<div
|
|
71
|
+
class="pf-chatbot__code-language"
|
|
72
|
+
>
|
|
73
|
+
TEXT
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
70
76
|
</div>
|
|
71
77
|
</div>
|
|
72
78
|
</div>
|
|
@@ -2,6 +2,7 @@ import { render, screen } from '@testing-library/react';
|
|
|
2
2
|
import '@testing-library/jest-dom';
|
|
3
3
|
import FileDetailsLabel from './FileDetailsLabel';
|
|
4
4
|
import userEvent from '@testing-library/user-event';
|
|
5
|
+
import { BellIcon } from '@patternfly/react-icons';
|
|
5
6
|
|
|
6
7
|
describe('FileDetailsLabel', () => {
|
|
7
8
|
it('should render file details label', () => {
|
|
@@ -18,6 +19,19 @@ describe('FileDetailsLabel', () => {
|
|
|
18
19
|
expect(screen.getByText('test')).toBeTruthy();
|
|
19
20
|
expect(screen.queryByTestId('language')).toBeFalsy();
|
|
20
21
|
});
|
|
22
|
+
it('should pass file size down', () => {
|
|
23
|
+
render(<FileDetailsLabel fileName="test.svg" fileSize="100MB" />);
|
|
24
|
+
expect(screen.getByText('100MB')).toBeTruthy();
|
|
25
|
+
});
|
|
26
|
+
it('should pass truncation prop down as true by default', () => {
|
|
27
|
+
render(<FileDetailsLabel fileName="test.svg" />);
|
|
28
|
+
expect(screen.getByText('test')).toBeTruthy();
|
|
29
|
+
expect(screen.queryByText('test.svg')).toBeFalsy();
|
|
30
|
+
});
|
|
31
|
+
it('should pass truncation prop down when false', () => {
|
|
32
|
+
render(<FileDetailsLabel fileName="test.svg" hasTruncation={false} />);
|
|
33
|
+
expect(screen.getByText('test.svg')).toBeTruthy();
|
|
34
|
+
});
|
|
21
35
|
it('should not show spinner by default', () => {
|
|
22
36
|
render(<FileDetailsLabel fileName="test.txt" spinnerTestId="spinner" />);
|
|
23
37
|
expect(screen.queryByTestId('spinner')).toBeFalsy();
|
|
@@ -42,6 +56,12 @@ describe('FileDetailsLabel', () => {
|
|
|
42
56
|
});
|
|
43
57
|
it('should use closeButtonAriaLabel prop appropriately', () => {
|
|
44
58
|
render(<FileDetailsLabel fileName="test.txt" onClose={jest.fn()} closeButtonAriaLabel="Delete file" />);
|
|
45
|
-
screen.getByRole('button', { name: /Delete file/i });
|
|
59
|
+
expect(screen.getByRole('button', { name: /Delete file/i })).toBeTruthy();
|
|
60
|
+
});
|
|
61
|
+
it('should support custom close icon', () => {
|
|
62
|
+
render(
|
|
63
|
+
<FileDetailsLabel fileName="test.txt" onClose={jest.fn()} closeButtonIcon={<BellIcon data-testid="bell" />} />
|
|
64
|
+
);
|
|
65
|
+
expect(screen.getByTestId('bell')).toBeTruthy();
|
|
46
66
|
});
|
|
47
67
|
});
|
|
@@ -4,7 +4,7 @@ import FileDetails from '../FileDetails';
|
|
|
4
4
|
import { Spinner } from '@patternfly/react-core';
|
|
5
5
|
import { TimesIcon } from '@patternfly/react-icons';
|
|
6
6
|
|
|
7
|
-
interface FileDetailsLabelProps {
|
|
7
|
+
export interface FileDetailsLabelProps {
|
|
8
8
|
/** Name of file, including extension */
|
|
9
9
|
fileName: string;
|
|
10
10
|
/** Unique id of file */
|
|
@@ -21,6 +21,12 @@ interface FileDetailsLabelProps {
|
|
|
21
21
|
languageTestId?: string;
|
|
22
22
|
/** Custom test id for the loading spinner in the component */
|
|
23
23
|
spinnerTestId?: string;
|
|
24
|
+
/** File size */
|
|
25
|
+
fileSize?: string;
|
|
26
|
+
/** Whether to truncate file name */
|
|
27
|
+
hasTruncation?: boolean;
|
|
28
|
+
/** Icon used for close button */
|
|
29
|
+
closeButtonIcon?: React.ReactNode;
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
export const FileDetailsLabel = ({
|
|
@@ -31,7 +37,11 @@ export const FileDetailsLabel = ({
|
|
|
31
37
|
onClose,
|
|
32
38
|
closeButtonAriaLabel,
|
|
33
39
|
languageTestId,
|
|
34
|
-
spinnerTestId
|
|
40
|
+
spinnerTestId,
|
|
41
|
+
fileSize,
|
|
42
|
+
hasTruncation = true,
|
|
43
|
+
closeButtonIcon = <TimesIcon />,
|
|
44
|
+
...props
|
|
35
45
|
}: PropsWithChildren<FileDetailsLabelProps>) => {
|
|
36
46
|
const handleClose = (event) => {
|
|
37
47
|
onClose && onClose(event, fileName, fileId);
|
|
@@ -45,17 +55,20 @@ export const FileDetailsLabel = ({
|
|
|
45
55
|
type="button"
|
|
46
56
|
variant="plain"
|
|
47
57
|
aria-label={closeButtonAriaLabel ?? `Close ${fileName}`}
|
|
48
|
-
icon={
|
|
58
|
+
icon={closeButtonIcon}
|
|
49
59
|
onClick={handleClose}
|
|
50
60
|
/>
|
|
51
61
|
}
|
|
52
62
|
{...(onClick && { onClick: (event) => onClick(event, fileName, fileId) })}
|
|
63
|
+
{...props}
|
|
53
64
|
>
|
|
54
65
|
<div className="pf-chatbot__file-label-contents">
|
|
55
66
|
<FileDetails
|
|
56
67
|
className={isLoading ? 'pf-chatbot__file-label-loading' : undefined}
|
|
57
68
|
fileName={fileName}
|
|
58
69
|
languageTestId={languageTestId}
|
|
70
|
+
fileSize={fileSize}
|
|
71
|
+
hasTruncation={hasTruncation}
|
|
59
72
|
/>
|
|
60
73
|
{isLoading && <Spinner data-testid={spinnerTestId} size="sm" />}
|
|
61
74
|
</div>
|
|
@@ -21,6 +21,7 @@ exports[`FileDetailsLabel should render file details label 1`] = `
|
|
|
21
21
|
class="pf-v6-l-flex pf-m-align-items-center pf-m-align-self-center pf-m-justify-content-center pf-chatbot__code-icon"
|
|
22
22
|
>
|
|
23
23
|
<svg
|
|
24
|
+
aria-hidden="true"
|
|
24
25
|
fill="currentColor"
|
|
25
26
|
height="24"
|
|
26
27
|
viewBox="0 0 24 24"
|
|
@@ -52,33 +53,38 @@ exports[`FileDetailsLabel should render file details label 1`] = `
|
|
|
52
53
|
</svg>
|
|
53
54
|
</div>
|
|
54
55
|
<div
|
|
55
|
-
class="pf-v6-l-
|
|
56
|
+
class="pf-v6-l-flex pf-m-gap-xs"
|
|
56
57
|
>
|
|
57
58
|
<div
|
|
58
|
-
class="
|
|
59
|
+
class=""
|
|
59
60
|
>
|
|
60
|
-
<
|
|
61
|
-
class="pf-
|
|
61
|
+
<div
|
|
62
|
+
class="pf-v6-l-flex pf-m-column pf-m-gap-none"
|
|
62
63
|
>
|
|
63
64
|
<div
|
|
64
|
-
|
|
65
|
+
class=""
|
|
65
66
|
>
|
|
66
67
|
<span
|
|
67
|
-
class="pf-
|
|
68
|
+
class="pf-chatbot__code-fileName"
|
|
68
69
|
>
|
|
69
70
|
<span
|
|
70
|
-
class="pf-v6-c-
|
|
71
|
+
class="pf-v6-c-truncate"
|
|
72
|
+
tabindex="0"
|
|
71
73
|
>
|
|
72
|
-
|
|
74
|
+
<span
|
|
75
|
+
class="pf-v6-c-truncate__start"
|
|
76
|
+
>
|
|
77
|
+
test
|
|
78
|
+
</span>
|
|
73
79
|
</span>
|
|
74
80
|
</span>
|
|
75
81
|
</div>
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
<div
|
|
83
|
+
class="pf-chatbot__code-language"
|
|
84
|
+
>
|
|
85
|
+
TEXT
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
82
88
|
</div>
|
|
83
89
|
</div>
|
|
84
90
|
</div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.pf-chatbot__file-preview-body {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: var(--pf-t--global--spacer--md);
|
|
5
|
+
align-items: center;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.pf-chatbot__file-preview-icon {
|
|
10
|
+
color: var(--pf-t--global--icon--color--subtle);
|
|
11
|
+
width: var(--pf-t--global--icon--size--2xl);
|
|
12
|
+
height: var(--pf-t--global--icon--size--2xl);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.pf-chatbot__file-preview-name {
|
|
16
|
+
font-size: var(--pf-t--global--font--size--xl);
|
|
17
|
+
font-weight: var(--pf-t--global--font--weight--heading--default);
|
|
18
|
+
}
|
|
19
|
+
.pf-chatbot__file-preview-body {
|
|
20
|
+
color: var(--pf-t--global--text--color--subtle);
|
|
21
|
+
font-size: var(--pf-t--global--font--size--body--lg);
|
|
22
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import '@testing-library/jest-dom';
|
|
3
|
+
import FilePreview from './FilePreview';
|
|
4
|
+
import { ChatbotDisplayMode } from '../Chatbot';
|
|
5
|
+
import { Button, ModalBodyProps, ModalHeaderProps } from '@patternfly/react-core';
|
|
6
|
+
|
|
7
|
+
describe('FilePreview', () => {
|
|
8
|
+
const defaultProps = {
|
|
9
|
+
isModalOpen: true,
|
|
10
|
+
handleModalToggle: jest.fn(),
|
|
11
|
+
fileName: 'test-file.txt',
|
|
12
|
+
children: 'File content preview'
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
jest.clearAllMocks();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should render with basic props', () => {
|
|
20
|
+
render(<FilePreview {...defaultProps} />);
|
|
21
|
+
expect(screen.getByText('File preview')).toBeInTheDocument();
|
|
22
|
+
expect(screen.getByText('test-file.txt')).toBeInTheDocument();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should render with custom title', () => {
|
|
26
|
+
const customTitle = 'Custom file preview title';
|
|
27
|
+
render(<FilePreview {...defaultProps} title={customTitle} />);
|
|
28
|
+
expect(screen.getByRole('heading', { name: customTitle })).toBeTruthy();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should handle modal toggle when closed', () => {
|
|
32
|
+
const mockToggle = jest.fn();
|
|
33
|
+
render(<FilePreview {...defaultProps} isModalOpen={false} handleModalToggle={mockToggle} />);
|
|
34
|
+
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should apply default display mode class', () => {
|
|
38
|
+
render(<FilePreview {...defaultProps} />);
|
|
39
|
+
const modal = screen.getByRole('dialog');
|
|
40
|
+
expect(modal).toHaveClass('pf-chatbot__file-preview-modal--default');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should apply custom display mode class', () => {
|
|
44
|
+
render(<FilePreview {...defaultProps} displayMode={ChatbotDisplayMode.fullscreen} />);
|
|
45
|
+
const modal = screen.getByRole('dialog');
|
|
46
|
+
expect(modal).toHaveClass('pf-chatbot__file-preview-modal--fullscreen');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should apply compact styling when isCompact is true', () => {
|
|
50
|
+
render(<FilePreview {...defaultProps} isCompact />);
|
|
51
|
+
const modal = screen.getByRole('dialog');
|
|
52
|
+
expect(modal).toHaveClass('pf-m-compact');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('should not apply compact styling when isCompact is false', () => {
|
|
56
|
+
render(<FilePreview {...defaultProps} isCompact={false} />);
|
|
57
|
+
const modal = screen.getByRole('dialog');
|
|
58
|
+
expect(modal).not.toHaveClass('pf-m-compact');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should apply custom className', () => {
|
|
62
|
+
const customClass = 'custom-file-preview';
|
|
63
|
+
render(<FilePreview {...defaultProps} className={customClass} />);
|
|
64
|
+
const modal = screen.getByRole('dialog');
|
|
65
|
+
expect(modal).toHaveClass(customClass);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should pass through additional props to ChatbotModal', () => {
|
|
69
|
+
render(<FilePreview {...defaultProps} data-testid="file-preview-modal" />);
|
|
70
|
+
const modal = screen.getByTestId('file-preview-modal');
|
|
71
|
+
expect(modal).toBeInTheDocument();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should pass modalHeaderProps to ModalHeader', () => {
|
|
75
|
+
const modalHeaderProps = {
|
|
76
|
+
'data-testid': 'custom-header'
|
|
77
|
+
} as ModalHeaderProps;
|
|
78
|
+
render(<FilePreview {...defaultProps} modalHeaderProps={modalHeaderProps} />);
|
|
79
|
+
const header = screen.getByTestId('custom-header');
|
|
80
|
+
expect(header).toBeInTheDocument();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should pass modalBodyProps to ModalBody', () => {
|
|
84
|
+
const modalBodyProps = {
|
|
85
|
+
'data-testid': 'custom-body'
|
|
86
|
+
} as ModalBodyProps;
|
|
87
|
+
render(<FilePreview {...defaultProps} modalBodyProps={modalBodyProps} />);
|
|
88
|
+
const body = screen.getByTestId('custom-body');
|
|
89
|
+
expect(body).toBeInTheDocument();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should pass ouiaId to ChatbotModal', () => {
|
|
93
|
+
const ouiaId = 'file-preview-ouia-id';
|
|
94
|
+
render(<FilePreview {...defaultProps} ouiaId={ouiaId} />);
|
|
95
|
+
const modal = screen.getByRole('dialog');
|
|
96
|
+
expect(modal).toHaveAttribute('data-ouia-component-id', ouiaId);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should handle complex children', () => {
|
|
100
|
+
const complexChildren = (
|
|
101
|
+
<div>
|
|
102
|
+
<h3>File details</h3>
|
|
103
|
+
<p>Size: 1.2 MB</p>
|
|
104
|
+
<Button>Download</Button>
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
107
|
+
render(<FilePreview {...defaultProps}>{complexChildren}</FilePreview>);
|
|
108
|
+
expect(screen.getByRole('heading', { name: /File details/i })).toBeTruthy();
|
|
109
|
+
expect(screen.getByText('Size: 1.2 MB')).toBeTruthy();
|
|
110
|
+
expect(screen.getByRole('button', { name: /Download/i })).toBeTruthy();
|
|
111
|
+
});
|
|
112
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ModalBody, ModalBodyProps, ModalHeader, ModalHeaderProps } from '@patternfly/react-core';
|
|
2
|
+
import type { FunctionComponent } from 'react';
|
|
3
|
+
import { ChatbotDisplayMode } from '../Chatbot';
|
|
4
|
+
import ChatbotModal, { ChatbotModalProps } from '../ChatbotModal';
|
|
5
|
+
import { FileIcon } from '@patternfly/react-icons';
|
|
6
|
+
|
|
7
|
+
export interface FilePreviewProps extends ChatbotModalProps {
|
|
8
|
+
/** Class applied to modal */
|
|
9
|
+
className?: string;
|
|
10
|
+
/** Function that handles modal toggle */
|
|
11
|
+
handleModalToggle: (event: React.MouseEvent | MouseEvent | KeyboardEvent) => void;
|
|
12
|
+
/** Whether modal is open */
|
|
13
|
+
isModalOpen: boolean;
|
|
14
|
+
/** Title of modal */
|
|
15
|
+
title?: string;
|
|
16
|
+
/** Display mode for the Chatbot parent; this influences the styles applied */
|
|
17
|
+
displayMode?: ChatbotDisplayMode;
|
|
18
|
+
/** File name */
|
|
19
|
+
fileName: string;
|
|
20
|
+
/** Sets modal to compact styling. */
|
|
21
|
+
isCompact?: boolean;
|
|
22
|
+
/** Additional props passed to modal header */
|
|
23
|
+
modalHeaderProps?: ModalHeaderProps;
|
|
24
|
+
/** Additional props passed to modal body */
|
|
25
|
+
modalBodyProps?: ModalBodyProps;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const FilePreview: FunctionComponent<FilePreviewProps> = ({
|
|
29
|
+
isModalOpen,
|
|
30
|
+
displayMode = ChatbotDisplayMode.default,
|
|
31
|
+
children,
|
|
32
|
+
fileName,
|
|
33
|
+
isCompact,
|
|
34
|
+
className,
|
|
35
|
+
handleModalToggle,
|
|
36
|
+
title = 'File preview',
|
|
37
|
+
modalHeaderProps,
|
|
38
|
+
modalBodyProps,
|
|
39
|
+
...props
|
|
40
|
+
}: FilePreviewProps) => (
|
|
41
|
+
<ChatbotModal
|
|
42
|
+
isOpen={isModalOpen}
|
|
43
|
+
className={`pf-chatbot__file-preview-modal pf-chatbot__file-preview-modal--${displayMode} ${isCompact ? 'pf-m-compact' : ''} ${className ? className : ''}`}
|
|
44
|
+
displayMode={displayMode}
|
|
45
|
+
onClose={handleModalToggle}
|
|
46
|
+
isCompact={isCompact}
|
|
47
|
+
{...props}
|
|
48
|
+
>
|
|
49
|
+
<ModalHeader title={title} {...modalHeaderProps} />
|
|
50
|
+
<ModalBody className="pf-chatbot__file-preview-body" {...modalBodyProps}>
|
|
51
|
+
<FileIcon className="pf-chatbot__file-preview-icon" />
|
|
52
|
+
<h2 className="pf-chatbot__file-preview-name">{fileName}</h2>
|
|
53
|
+
{children && <div className="pf-chatbot__file-preview-body">{children}</div>}
|
|
54
|
+
</ModalBody>
|
|
55
|
+
</ChatbotModal>
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
export default FilePreview;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
.pf-chatbot__image-preview-body {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: var(--pf-t--global--spacer--lg);
|
|
5
|
+
--pf-v6-c-label--MaxWidth: initial;
|
|
6
|
+
--pf-v6-c-modal-box--ZIndex: var(--pf-t--global--z-index--2xl);
|
|
7
|
+
|
|
8
|
+
img {
|
|
9
|
+
flex: 1 0 0;
|
|
10
|
+
align-self: stretch;
|
|
11
|
+
}
|
|
12
|
+
.pf-chatbot__file-label {
|
|
13
|
+
min-width: fit-content;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.pf-chatbot__image-preview-stack {
|
|
18
|
+
height: unset;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.pf-v6-c-modal-box__footer.pf-chatbot__image-preview-footer {
|
|
22
|
+
padding-block-start: var(--pf-t--global--spacer--sm);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.pf-chatbot__image-preview-footer-buttons {
|
|
26
|
+
display: flex;
|
|
27
|
+
gap: var(--pf-t--global--spacer--xs);
|
|
28
|
+
align-items: center;
|
|
29
|
+
justify-content: space-between;
|
|
30
|
+
flex: 1;
|
|
31
|
+
|
|
32
|
+
.pf-v6-c-button {
|
|
33
|
+
border-radius: var(--pf-t--global--border--radius--pill);
|
|
34
|
+
padding: var(--pf-t--global--spacer--sm);
|
|
35
|
+
width: 2.31rem;
|
|
36
|
+
height: 2.31rem;
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
justify-content: center;
|
|
40
|
+
}
|
|
41
|
+
button:disabled,
|
|
42
|
+
button[disabled] {
|
|
43
|
+
.pf-v6-c-icon__content {
|
|
44
|
+
color: var(--pf-t--global--icon--color--disabled);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
.pf-v6-c-button__text {
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
}
|
|
51
|
+
// Interactive states
|
|
52
|
+
.pf-v6-c-button:hover,
|
|
53
|
+
.pf-v6-c-button:focus {
|
|
54
|
+
.pf-v6-c-button__icon {
|
|
55
|
+
color: var(--pf-t--global--icon--color--regular);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
.pf-v6-c-button__icon {
|
|
59
|
+
color: var(--pf-t--global--icon--color--subtle);
|
|
60
|
+
}
|
|
61
|
+
}
|