@red-hat-developer-hub/backstage-plugin-lightspeed 2.5.0 → 2.5.1

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.
Files changed (39) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +5 -1
  3. package/dist/alpha.d.ts +5 -0
  4. package/dist/components/LightSpeedChat.esm.js +82 -17
  5. package/dist/components/LightSpeedChat.esm.js.map +1 -1
  6. package/dist/components/LightspeedDrawerContext.esm.js.map +1 -1
  7. package/dist/components/notebooks/AddDocumentModal.esm.js +122 -23
  8. package/dist/components/notebooks/AddDocumentModal.esm.js.map +1 -1
  9. package/dist/components/notebooks/DocumentSidebar.esm.js +19 -1
  10. package/dist/components/notebooks/DocumentSidebar.esm.js.map +1 -1
  11. package/dist/components/notebooks/FileListItem.esm.js +94 -0
  12. package/dist/components/notebooks/FileListItem.esm.js.map +1 -0
  13. package/dist/components/notebooks/NotebookView.esm.js +46 -26
  14. package/dist/components/notebooks/NotebookView.esm.js.map +1 -1
  15. package/dist/components/notebooks/OverwriteConfirmModal.esm.js +2 -1
  16. package/dist/components/notebooks/OverwriteConfirmModal.esm.js.map +1 -1
  17. package/dist/components/notebooks/SidebarCollapseIcon.esm.js +5 -2
  18. package/dist/components/notebooks/SidebarCollapseIcon.esm.js.map +1 -1
  19. package/dist/hooks/toolCallsCacheStore.esm.js +61 -0
  20. package/dist/hooks/toolCallsCacheStore.esm.js.map +1 -0
  21. package/dist/hooks/useConversationMessages.esm.js +18 -14
  22. package/dist/hooks/useConversationMessages.esm.js.map +1 -1
  23. package/dist/hooks/useDeleteConversation.esm.js +2 -0
  24. package/dist/hooks/useDeleteConversation.esm.js.map +1 -1
  25. package/dist/hooks/useLightspeedProviderState.esm.js +35 -8
  26. package/dist/hooks/useLightspeedProviderState.esm.js.map +1 -1
  27. package/dist/translations/de.esm.js +5 -0
  28. package/dist/translations/de.esm.js.map +1 -1
  29. package/dist/translations/es.esm.js +5 -0
  30. package/dist/translations/es.esm.js.map +1 -1
  31. package/dist/translations/fr.esm.js +5 -0
  32. package/dist/translations/fr.esm.js.map +1 -1
  33. package/dist/translations/it.esm.js +5 -0
  34. package/dist/translations/it.esm.js.map +1 -1
  35. package/dist/translations/ja.esm.js +5 -0
  36. package/dist/translations/ja.esm.js.map +1 -1
  37. package/dist/translations/ref.esm.js +5 -0
  38. package/dist/translations/ref.esm.js.map +1 -1
  39. package/package.json +2 -2
@@ -1,9 +1,12 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { useState } from 'react';
2
+ import { useState, useEffect } from 'react';
3
3
  import { makeStyles } from '@material-ui/core/styles';
4
4
  import CloseIcon from '@mui/icons-material/Close';
5
5
  import Alert from '@mui/material/Alert';
6
+ import Box from '@mui/material/Box';
7
+ import Button from '@mui/material/Button';
6
8
  import Dialog from '@mui/material/Dialog';
9
+ import DialogActions from '@mui/material/DialogActions';
7
10
  import DialogContent from '@mui/material/DialogContent';
8
11
  import DialogTitle from '@mui/material/DialogTitle';
9
12
  import IconButton from '@mui/material/IconButton';
@@ -14,6 +17,7 @@ import { NOTEBOOK_MAX_FILES } from '../../const.esm.js';
14
17
  import { useUploadDocument } from '../../hooks/notebooks/useUploadDocument.esm.js';
15
18
  import { useTranslation } from '../../hooks/useTranslation.esm.js';
16
19
  import { getNotebookAcceptedFileTypes, validateFiles } from '../../utils/notebook-upload-utils.esm.js';
20
+ import { FileListItem } from './FileListItem.esm.js';
17
21
 
18
22
  const useStyles = makeStyles((theme) => ({
19
23
  dialogPaper: {
@@ -50,6 +54,32 @@ const useStyles = makeStyles((theme) => ({
50
54
  "& .pf-v6-c-multiple-file-upload__main:hover": {
51
55
  backgroundColor: "color-mix(in srgb, var(--pf-t--global--color--brand--default) 10%, transparent)"
52
56
  }
57
+ },
58
+ fileListContainer: {
59
+ marginTop: theme.spacing(2),
60
+ maxHeight: 200,
61
+ overflowY: "auto"
62
+ },
63
+ fileListHeader: {
64
+ display: "flex",
65
+ alignItems: "center",
66
+ justifyContent: "space-between",
67
+ marginBottom: theme.spacing(1)
68
+ },
69
+ fileCount: {
70
+ fontSize: "0.875rem",
71
+ color: theme.palette.text.secondary
72
+ },
73
+ dialogActions: {
74
+ padding: "16px 24px",
75
+ justifyContent: "flex-end",
76
+ gap: theme.spacing(1)
77
+ },
78
+ addButton: {
79
+ textTransform: "none"
80
+ },
81
+ cancelButton: {
82
+ textTransform: "none"
53
83
  }
54
84
  }));
55
85
  const AddDocumentModal = ({
@@ -60,42 +90,63 @@ const AddDocumentModal = ({
60
90
  onFilesUploading,
61
91
  onUploadStarted,
62
92
  onUploadFailed,
63
- onDuplicatesFound
93
+ onDuplicatesFound,
94
+ filesToAdd,
95
+ onFilesAdded
64
96
  }) => {
65
97
  const classes = useStyles();
66
98
  const { t } = useTranslation();
67
99
  const uploadMutation = useUploadDocument();
68
100
  const [validationErrors, setValidationErrors] = useState([]);
101
+ const [selectedFiles, setSelectedFiles] = useState([]);
102
+ const totalExistingAndSelected = existingDocumentNames.length + selectedFiles.length;
103
+ const remainingSlots = NOTEBOOK_MAX_FILES - totalExistingAndSelected;
104
+ useEffect(() => {
105
+ if (filesToAdd && filesToAdd.length > 0) {
106
+ setSelectedFiles((prev) => [...prev, ...filesToAdd]);
107
+ onFilesAdded?.();
108
+ }
109
+ }, [filesToAdd, onFilesAdded]);
69
110
  const handleFileDrop = (_event, files) => {
70
111
  setValidationErrors([]);
71
- const { valid, errors } = validateFiles(
72
- files,
73
- existingDocumentNames.length
74
- );
112
+ const { valid, errors } = validateFiles(files, totalExistingAndSelected);
75
113
  if (errors.length > 0) {
76
114
  setValidationErrors(errors);
77
115
  return;
78
116
  }
79
117
  if (valid.length === 0) return;
80
- const existingNamesSet = new Set(existingDocumentNames);
118
+ const existingNamesSet = /* @__PURE__ */ new Set([
119
+ ...existingDocumentNames,
120
+ ...selectedFiles.map((f) => f.name)
121
+ ]);
81
122
  const newFiles = valid.filter((f) => !existingNamesSet.has(f.name));
82
- const duplicateFiles = valid.filter((f) => existingNamesSet.has(f.name));
83
- if (newFiles.length > 0) {
84
- onFilesUploading?.(newFiles);
85
- for (const file of newFiles) {
86
- uploadMutation.mutateAsync({ sessionId, file }).then((data) => {
87
- onUploadStarted?.({
88
- fileName: file.name,
89
- documentId: data.document_id
90
- });
91
- }).catch(() => {
92
- onUploadFailed?.(file.name);
93
- });
94
- }
95
- }
123
+ const duplicateFiles = valid.filter(
124
+ (f) => existingDocumentNames.includes(f.name)
125
+ );
96
126
  if (duplicateFiles.length > 0) {
97
127
  onDuplicatesFound?.(duplicateFiles);
98
128
  }
129
+ if (newFiles.length > 0) {
130
+ setSelectedFiles((prev) => [...prev, ...newFiles]);
131
+ }
132
+ };
133
+ const handleRemoveFile = (index) => {
134
+ setSelectedFiles((prev) => prev.filter((_, i) => i !== index));
135
+ };
136
+ const handleAddFiles = () => {
137
+ if (selectedFiles.length === 0) return;
138
+ onFilesUploading?.(selectedFiles);
139
+ for (const file of selectedFiles) {
140
+ uploadMutation.mutateAsync({ sessionId, file }).then((data) => {
141
+ onUploadStarted?.({
142
+ fileName: file.name,
143
+ documentId: data.document_id
144
+ });
145
+ }).catch(() => {
146
+ onUploadFailed?.(file.name);
147
+ });
148
+ }
149
+ setSelectedFiles([]);
99
150
  setValidationErrors([]);
100
151
  onClose();
101
152
  };
@@ -108,6 +159,7 @@ const AddDocumentModal = ({
108
159
  }
109
160
  };
110
161
  const handleClose = () => {
162
+ setSelectedFiles([]);
111
163
  setValidationErrors([]);
112
164
  onClose();
113
165
  };
@@ -122,7 +174,10 @@ const AddDocumentModal = ({
122
174
  },
123
175
  children: [
124
176
  /* @__PURE__ */ jsxs(DialogTitle, { className: classes.dialogTitle, children: [
125
- /* @__PURE__ */ jsx(Typography, { component: "h2", className: classes.titleText, children: t("notebook.upload.modal.title") }),
177
+ /* @__PURE__ */ jsxs(Typography, { component: "h2", className: classes.titleText, children: [
178
+ t("notebook.upload.modal.title"),
179
+ selectedFiles.length > 0 && ` (${selectedFiles.length}/${NOTEBOOK_MAX_FILES - existingDocumentNames.length})`
180
+ ] }),
126
181
  /* @__PURE__ */ jsx(
127
182
  IconButton,
128
183
  {
@@ -139,7 +194,7 @@ const AddDocumentModal = ({
139
194
  const message = t(errorKey);
140
195
  return errorKey === "notebook.upload.error.tooManyFiles" ? message.replace("{{max}}", String(NOTEBOOK_MAX_FILES)) : message;
141
196
  }).join("\n") }),
142
- /* @__PURE__ */ jsx(
197
+ remainingSlots > 0 && /* @__PURE__ */ jsx(
143
198
  MultipleFileUpload,
144
199
  {
145
200
  className: classes.dropzone,
@@ -159,6 +214,50 @@ const AddDocumentModal = ({
159
214
  }
160
215
  )
161
216
  }
217
+ ),
218
+ selectedFiles.length > 0 && /* @__PURE__ */ jsxs(Box, { className: classes.fileListContainer, children: [
219
+ /* @__PURE__ */ jsx(Box, { className: classes.fileListHeader, children: /* @__PURE__ */ jsx(Typography, { className: classes.fileCount, children: t("notebook.upload.modal.selectedFiles", {
220
+ count: selectedFiles.length,
221
+ max: NOTEBOOK_MAX_FILES - existingDocumentNames.length
222
+ }) }) }),
223
+ selectedFiles.map((file, index) => /* @__PURE__ */ jsx(
224
+ FileListItem,
225
+ {
226
+ file,
227
+ onRemove: () => handleRemoveFile(index),
228
+ removeAriaLabel: t(
229
+ "notebook.upload.modal.removeFile",
230
+ {
231
+ fileName: file.name
232
+ }
233
+ )
234
+ },
235
+ `${file.name}-${index}`
236
+ ))
237
+ ] })
238
+ ] }),
239
+ /* @__PURE__ */ jsxs(DialogActions, { className: classes.dialogActions, children: [
240
+ /* @__PURE__ */ jsx(
241
+ Button,
242
+ {
243
+ onClick: handleClose,
244
+ className: classes.cancelButton,
245
+ color: "inherit",
246
+ children: t("common.cancel")
247
+ }
248
+ ),
249
+ /* @__PURE__ */ jsx(
250
+ Button,
251
+ {
252
+ onClick: handleAddFiles,
253
+ className: classes.addButton,
254
+ variant: "contained",
255
+ color: "primary",
256
+ disabled: selectedFiles.length === 0,
257
+ children: t("notebook.upload.modal.addButton", {
258
+ count: selectedFiles.length
259
+ })
260
+ }
162
261
  )
163
262
  ] })
164
263
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"AddDocumentModal.esm.js","sources":["../../../src/components/notebooks/AddDocumentModal.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useState } from 'react';\nimport { FileRejection } from 'react-dropzone';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport CloseIcon from '@mui/icons-material/Close';\nimport Alert from '@mui/material/Alert';\nimport Dialog from '@mui/material/Dialog';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport IconButton from '@mui/material/IconButton';\nimport Typography from '@mui/material/Typography';\nimport {\n MultipleFileUpload,\n MultipleFileUploadMain,\n} from '@patternfly/react-core';\nimport { UploadIcon } from '@patternfly/react-icons';\n\nimport { NOTEBOOK_MAX_FILES } from '../../const';\nimport { useUploadDocument } from '../../hooks/notebooks/useUploadDocument';\nimport { useTranslation } from '../../hooks/useTranslation';\nimport {\n getNotebookAcceptedFileTypes,\n validateFiles,\n} from '../../utils/notebook-upload-utils';\n\nconst useStyles = makeStyles(theme => ({\n dialogPaper: {\n borderRadius: 24,\n maxWidth: 578,\n },\n dialogTitle: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '24px 24px 16px',\n },\n titleText: {\n fontWeight: 500,\n fontSize: '1.25rem',\n lineHeight: '1.625rem',\n letterSpacing: '-0.25px',\n },\n closeButton: {\n color: theme.palette.grey[700],\n },\n dialogContent: {\n padding: '0 24px 24px',\n },\n errorAlert: {\n marginBottom: theme.spacing(2),\n },\n dropzone: {\n '& .pf-v6-c-multiple-file-upload__main': {\n borderColor: 'var(--pf-t--global--border--color--brand--default)',\n transition: 'background-color 0.2s ease',\n cursor: 'pointer',\n },\n '& .pf-v6-c-multiple-file-upload__main:hover': {\n backgroundColor:\n 'color-mix(in srgb, var(--pf-t--global--color--brand--default) 10%, transparent)',\n },\n },\n}));\n\ntype AddDocumentModalProps = {\n isOpen: boolean;\n onClose: () => void;\n sessionId: string;\n existingDocumentNames: string[];\n onFilesUploading?: (files: File[]) => void;\n onUploadStarted?: (info: { fileName: string; documentId: string }) => void;\n onUploadFailed?: (fileName: string) => void;\n onDuplicatesFound?: (files: File[]) => void;\n};\n\nexport const AddDocumentModal = ({\n isOpen,\n onClose,\n sessionId,\n existingDocumentNames,\n onFilesUploading,\n onUploadStarted,\n onUploadFailed,\n onDuplicatesFound,\n}: AddDocumentModalProps) => {\n const classes = useStyles();\n const { t } = useTranslation();\n const uploadMutation = useUploadDocument();\n const [validationErrors, setValidationErrors] = useState<string[]>([]);\n\n const handleFileDrop = (_event: unknown, files: File[]) => {\n setValidationErrors([]);\n\n const { valid, errors } = validateFiles(\n files,\n existingDocumentNames.length,\n );\n\n if (errors.length > 0) {\n setValidationErrors(errors);\n return;\n }\n\n if (valid.length === 0) return;\n\n const existingNamesSet = new Set(existingDocumentNames);\n const newFiles = valid.filter(f => !existingNamesSet.has(f.name));\n const duplicateFiles = valid.filter(f => existingNamesSet.has(f.name));\n\n if (newFiles.length > 0) {\n onFilesUploading?.(newFiles);\n for (const file of newFiles) {\n uploadMutation\n .mutateAsync({ sessionId, file })\n .then(data => {\n onUploadStarted?.({\n fileName: file.name,\n documentId: data.document_id,\n });\n })\n .catch(() => {\n onUploadFailed?.(file.name);\n });\n }\n }\n\n if (duplicateFiles.length > 0) {\n onDuplicatesFound?.(duplicateFiles);\n }\n\n setValidationErrors([]);\n onClose();\n };\n\n const handleDropRejected = (rejections: FileRejection[]) => {\n const hasInvalidType = rejections.some(r =>\n r.errors.some(e => e.code === 'file-invalid-type'),\n );\n if (hasInvalidType) {\n setValidationErrors(['notebook.upload.error.unsupportedType']);\n }\n };\n\n const handleClose = () => {\n setValidationErrors([]);\n onClose();\n };\n\n return (\n <Dialog\n open={isOpen}\n onClose={handleClose}\n aria-labelledby=\"add-document-modal-title\"\n PaperProps={{\n className: classes.dialogPaper,\n }}\n >\n <DialogTitle className={classes.dialogTitle}>\n <Typography component=\"h2\" className={classes.titleText}>\n {t('notebook.upload.modal.title')}\n </Typography>\n <IconButton\n aria-label={t('common.close')}\n onClick={handleClose}\n className={classes.closeButton}\n size=\"small\"\n >\n <CloseIcon />\n </IconButton>\n </DialogTitle>\n\n <DialogContent className={classes.dialogContent}>\n {validationErrors.length > 0 && (\n <Alert severity=\"error\" className={classes.errorAlert}>\n {validationErrors\n .map(errorKey => {\n const message = (t as Function)(errorKey) as string;\n return errorKey === 'notebook.upload.error.tooManyFiles'\n ? message.replace('{{max}}', String(NOTEBOOK_MAX_FILES))\n : message;\n })\n .join('\\n')}\n </Alert>\n )}\n\n <MultipleFileUpload\n className={classes.dropzone}\n dropzoneProps={{\n accept: getNotebookAcceptedFileTypes(),\n onDropRejected: handleDropRejected,\n }}\n onFileDrop={handleFileDrop}\n >\n <MultipleFileUploadMain\n titleIcon={<UploadIcon />}\n titleText={t('notebook.upload.modal.dragDropTitle')}\n titleTextSeparator={t('notebook.upload.modal.separator')}\n infoText={t('notebook.upload.modal.infoText')}\n browseButtonText={t('notebook.upload.modal.browseButton')}\n />\n </MultipleFileUpload>\n </DialogContent>\n </Dialog>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AddDocumentModal.esm.js","sources":["../../../src/components/notebooks/AddDocumentModal.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect, useState } from 'react';\nimport { FileRejection } from 'react-dropzone';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport CloseIcon from '@mui/icons-material/Close';\nimport Alert from '@mui/material/Alert';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport IconButton from '@mui/material/IconButton';\nimport Typography from '@mui/material/Typography';\nimport {\n MultipleFileUpload,\n MultipleFileUploadMain,\n} from '@patternfly/react-core';\nimport { UploadIcon } from '@patternfly/react-icons';\n\nimport { NOTEBOOK_MAX_FILES } from '../../const';\nimport { useUploadDocument } from '../../hooks/notebooks/useUploadDocument';\nimport { useTranslation } from '../../hooks/useTranslation';\nimport {\n getNotebookAcceptedFileTypes,\n validateFiles,\n} from '../../utils/notebook-upload-utils';\nimport { FileListItem } from './FileListItem';\n\nconst useStyles = makeStyles(theme => ({\n dialogPaper: {\n borderRadius: 24,\n maxWidth: 578,\n },\n dialogTitle: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '24px 24px 16px',\n },\n titleText: {\n fontWeight: 500,\n fontSize: '1.25rem',\n lineHeight: '1.625rem',\n letterSpacing: '-0.25px',\n },\n closeButton: {\n color: theme.palette.grey[700],\n },\n dialogContent: {\n padding: '0 24px 24px',\n },\n errorAlert: {\n marginBottom: theme.spacing(2),\n },\n dropzone: {\n '& .pf-v6-c-multiple-file-upload__main': {\n borderColor: 'var(--pf-t--global--border--color--brand--default)',\n transition: 'background-color 0.2s ease',\n cursor: 'pointer',\n },\n '& .pf-v6-c-multiple-file-upload__main:hover': {\n backgroundColor:\n 'color-mix(in srgb, var(--pf-t--global--color--brand--default) 10%, transparent)',\n },\n },\n fileListContainer: {\n marginTop: theme.spacing(2),\n maxHeight: 200,\n overflowY: 'auto',\n },\n fileListHeader: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: theme.spacing(1),\n },\n fileCount: {\n fontSize: '0.875rem',\n color: theme.palette.text.secondary,\n },\n dialogActions: {\n padding: '16px 24px',\n justifyContent: 'flex-end',\n gap: theme.spacing(1),\n },\n addButton: {\n textTransform: 'none',\n },\n cancelButton: {\n textTransform: 'none',\n },\n}));\n\ntype AddDocumentModalProps = {\n isOpen: boolean;\n onClose: () => void;\n sessionId: string;\n existingDocumentNames: string[];\n onFilesUploading?: (files: File[]) => void;\n onUploadStarted?: (info: { fileName: string; documentId: string }) => void;\n onUploadFailed?: (fileName: string) => void;\n onDuplicatesFound?: (files: File[]) => void;\n filesToAdd?: File[];\n onFilesAdded?: () => void;\n};\n\nexport const AddDocumentModal = ({\n isOpen,\n onClose,\n sessionId,\n existingDocumentNames,\n onFilesUploading,\n onUploadStarted,\n onUploadFailed,\n onDuplicatesFound,\n filesToAdd,\n onFilesAdded,\n}: AddDocumentModalProps) => {\n const classes = useStyles();\n const { t } = useTranslation();\n const uploadMutation = useUploadDocument();\n const [validationErrors, setValidationErrors] = useState<string[]>([]);\n const [selectedFiles, setSelectedFiles] = useState<File[]>([]);\n\n const totalExistingAndSelected =\n existingDocumentNames.length + selectedFiles.length;\n const remainingSlots = NOTEBOOK_MAX_FILES - totalExistingAndSelected;\n\n useEffect(() => {\n if (filesToAdd && filesToAdd.length > 0) {\n setSelectedFiles(prev => [...prev, ...filesToAdd]);\n onFilesAdded?.();\n }\n }, [filesToAdd, onFilesAdded]);\n\n const handleFileDrop = (_event: unknown, files: File[]) => {\n setValidationErrors([]);\n\n const { valid, errors } = validateFiles(files, totalExistingAndSelected);\n\n if (errors.length > 0) {\n setValidationErrors(errors);\n return;\n }\n\n if (valid.length === 0) return;\n\n const existingNamesSet = new Set([\n ...existingDocumentNames,\n ...selectedFiles.map(f => f.name),\n ]);\n const newFiles = valid.filter(f => !existingNamesSet.has(f.name));\n const duplicateFiles = valid.filter(f =>\n existingDocumentNames.includes(f.name),\n );\n\n if (duplicateFiles.length > 0) {\n onDuplicatesFound?.(duplicateFiles);\n }\n\n if (newFiles.length > 0) {\n setSelectedFiles(prev => [...prev, ...newFiles]);\n }\n };\n\n const handleRemoveFile = (index: number) => {\n setSelectedFiles(prev => prev.filter((_, i) => i !== index));\n };\n\n const handleAddFiles = () => {\n if (selectedFiles.length === 0) return;\n\n onFilesUploading?.(selectedFiles);\n for (const file of selectedFiles) {\n uploadMutation\n .mutateAsync({ sessionId, file })\n .then(data => {\n onUploadStarted?.({\n fileName: file.name,\n documentId: data.document_id,\n });\n })\n .catch(() => {\n onUploadFailed?.(file.name);\n });\n }\n\n setSelectedFiles([]);\n setValidationErrors([]);\n onClose();\n };\n\n const handleDropRejected = (rejections: FileRejection[]) => {\n const hasInvalidType = rejections.some(r =>\n r.errors.some(e => e.code === 'file-invalid-type'),\n );\n if (hasInvalidType) {\n setValidationErrors(['notebook.upload.error.unsupportedType']);\n }\n };\n\n const handleClose = () => {\n setSelectedFiles([]);\n setValidationErrors([]);\n onClose();\n };\n\n return (\n <Dialog\n open={isOpen}\n onClose={handleClose}\n aria-labelledby=\"add-document-modal-title\"\n PaperProps={{\n className: classes.dialogPaper,\n }}\n >\n <DialogTitle className={classes.dialogTitle}>\n <Typography component=\"h2\" className={classes.titleText}>\n {t('notebook.upload.modal.title')}\n {selectedFiles.length > 0 &&\n ` (${selectedFiles.length}/${NOTEBOOK_MAX_FILES - existingDocumentNames.length})`}\n </Typography>\n <IconButton\n aria-label={t('common.close')}\n onClick={handleClose}\n className={classes.closeButton}\n size=\"small\"\n >\n <CloseIcon />\n </IconButton>\n </DialogTitle>\n\n <DialogContent className={classes.dialogContent}>\n {validationErrors.length > 0 && (\n <Alert severity=\"error\" className={classes.errorAlert}>\n {validationErrors\n .map(errorKey => {\n const message = (t as Function)(errorKey) as string;\n return errorKey === 'notebook.upload.error.tooManyFiles'\n ? message.replace('{{max}}', String(NOTEBOOK_MAX_FILES))\n : message;\n })\n .join('\\n')}\n </Alert>\n )}\n\n {remainingSlots > 0 && (\n <MultipleFileUpload\n className={classes.dropzone}\n dropzoneProps={{\n accept: getNotebookAcceptedFileTypes(),\n onDropRejected: handleDropRejected,\n }}\n onFileDrop={handleFileDrop}\n >\n <MultipleFileUploadMain\n titleIcon={<UploadIcon />}\n titleText={t('notebook.upload.modal.dragDropTitle')}\n titleTextSeparator={t('notebook.upload.modal.separator')}\n infoText={t('notebook.upload.modal.infoText')}\n browseButtonText={t('notebook.upload.modal.browseButton')}\n />\n </MultipleFileUpload>\n )}\n\n {selectedFiles.length > 0 && (\n <Box className={classes.fileListContainer}>\n <Box className={classes.fileListHeader}>\n <Typography className={classes.fileCount}>\n {(t as Function)('notebook.upload.modal.selectedFiles', {\n count: selectedFiles.length,\n max: NOTEBOOK_MAX_FILES - existingDocumentNames.length,\n })}\n </Typography>\n </Box>\n {selectedFiles.map((file, index) => (\n <FileListItem\n key={`${file.name}-${index}`}\n file={file}\n onRemove={() => handleRemoveFile(index)}\n removeAriaLabel={(t as Function)(\n 'notebook.upload.modal.removeFile',\n {\n fileName: file.name,\n },\n )}\n />\n ))}\n </Box>\n )}\n </DialogContent>\n\n <DialogActions className={classes.dialogActions}>\n <Button\n onClick={handleClose}\n className={classes.cancelButton}\n color=\"inherit\"\n >\n {t('common.cancel')}\n </Button>\n <Button\n onClick={handleAddFiles}\n className={classes.addButton}\n variant=\"contained\"\n color=\"primary\"\n disabled={selectedFiles.length === 0}\n >\n {(t as Function)('notebook.upload.modal.addButton', {\n count: selectedFiles.length,\n })}\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import { useState } from 'react';
3
3
  import { makeStyles, Typography } from '@material-ui/core';
4
4
  import { Tooltip, Button, Spinner, Dropdown, MenuToggle, DropdownList, DropdownItem } from '@patternfly/react-core';
5
5
  import { PlusCircleIcon, EllipsisVIcon } from '@patternfly/react-icons';
6
+ import { NOTEBOOK_MAX_FILES } from '../../const.esm.js';
6
7
  import { useTranslation } from '../../hooks/useTranslation.esm.js';
7
8
  import { FileTypeIcon } from './FileTypeIcon.esm.js';
8
9
  import { SidebarCollapseIcon } from './SidebarCollapseIcon.esm.js';
@@ -116,6 +117,7 @@ const DocumentSidebar = ({
116
117
  (name) => !uploadedNames.has(name)
117
118
  );
118
119
  const totalCount = documents.length + activePending.length;
120
+ const isAddDisabled = totalCount >= NOTEBOOK_MAX_FILES;
119
121
  return /* @__PURE__ */ jsxs("div", { className: classes.sidebar, children: [
120
122
  /* @__PURE__ */ jsxs("div", { className: classes.titleRow, children: [
121
123
  /* @__PURE__ */ jsx(Typography, { className: classes.title, children: notebookName }),
@@ -134,7 +136,23 @@ const DocumentSidebar = ({
134
136
  /* @__PURE__ */ jsx(Typography, { className: classes.documentCount, children: t("notebook.view.documents.count", {
135
137
  count: totalCount
136
138
  }) }),
137
- /* @__PURE__ */ jsx(
139
+ isAddDisabled ? /* @__PURE__ */ jsx(
140
+ Tooltip,
141
+ {
142
+ content: t("notebook.view.documents.maxReached"),
143
+ position: "top",
144
+ children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
145
+ Button,
146
+ {
147
+ variant: "link",
148
+ className: classes.addButton,
149
+ icon: /* @__PURE__ */ jsx(PlusCircleIcon, {}),
150
+ isDisabled: true,
151
+ children: t("notebook.view.documents.add")
152
+ }
153
+ ) })
154
+ }
155
+ ) : /* @__PURE__ */ jsx(
138
156
  Button,
139
157
  {
140
158
  variant: "link",
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentSidebar.esm.js","sources":["../../../src/components/notebooks/DocumentSidebar.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useState } from 'react';\n\nimport { makeStyles, Typography } from '@material-ui/core';\nimport {\n Button,\n Dropdown,\n DropdownItem,\n DropdownList,\n MenuToggle,\n Spinner,\n Tooltip,\n} from '@patternfly/react-core';\nimport { EllipsisVIcon, PlusCircleIcon } from '@patternfly/react-icons';\n\nimport { useTranslation } from '../../hooks/useTranslation';\nimport { SessionDocument } from '../../types';\nimport { FileTypeIcon } from './FileTypeIcon';\nimport { SidebarCollapseIcon } from './SidebarCollapseIcon';\n\nconst useStyles = makeStyles(theme => ({\n sidebar: {\n display: 'flex',\n flexDirection: 'column',\n width: '100%',\n height: '100%',\n padding: theme.spacing(2),\n overflow: 'hidden',\n },\n titleRow: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: theme.spacing(2),\n gap: theme.spacing(1),\n },\n title: {\n fontWeight: 500,\n fontSize: '1.25rem',\n lineHeight: '2rem',\n letterSpacing: '-0.25px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n flex: 1,\n minWidth: 0,\n },\n collapseButton: {\n flexShrink: 0,\n },\n documentsRow: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n },\n documentCount: {\n fontWeight: 700,\n fontSize: '1.125rem',\n lineHeight: '2rem',\n },\n addButton: {\n textTransform: 'none',\n },\n documentsList: {\n marginTop: theme.spacing(2),\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n overflowY: 'auto',\n flex: 1,\n },\n documentItem: {\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n padding: `${theme.spacing(1)}px ${theme.spacing(0.5)}px`,\n borderRadius: 4,\n },\n fileIcon: {\n flexShrink: 0,\n color: theme.palette.grey[500],\n fontSize: '1rem',\n },\n fileName: {\n flex: 1,\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n fontSize: '0.875rem',\n lineHeight: '1.25rem',\n },\n spinnerContainer: {\n flexShrink: 0,\n },\n kebabToggle: {\n padding: 0,\n flexShrink: 0,\n },\n kebabDropdownMenu: {\n '& .pf-v6-c-menu__list': {\n paddingInlineStart: 0,\n marginBlockStart: 0,\n marginBlockEnd: 0,\n },\n },\n}));\n\ntype DocumentSidebarProps = {\n notebookName: string;\n documents: SessionDocument[];\n uploadingFileNames: string[];\n completedFileNames?: Set<string>;\n deletingDocumentIds?: Set<string>;\n collapsed: boolean;\n onToggleCollapse: () => void;\n onAddDocument: () => void;\n onDeleteDocument?: (documentId: string) => void;\n};\n\nexport const DocumentSidebar = ({\n notebookName,\n documents,\n uploadingFileNames,\n completedFileNames,\n deletingDocumentIds,\n collapsed,\n onToggleCollapse,\n onAddDocument,\n onDeleteDocument,\n}: DocumentSidebarProps) => {\n const classes = useStyles();\n const { t } = useTranslation();\n const [openMenuDocId, setOpenMenuDocId] = useState<string | null>(null);\n\n if (collapsed) {\n return null;\n }\n\n const uploadedNames = new Set(documents.map(d => d.title));\n const activePending = uploadingFileNames.filter(\n name => !uploadedNames.has(name),\n );\n const totalCount = documents.length + activePending.length;\n\n return (\n <div className={classes.sidebar}>\n <div className={classes.titleRow}>\n <Typography className={classes.title}>{notebookName}</Typography>\n <Tooltip content={t('notebook.view.sidebar.collapse')} position=\"right\">\n <Button\n variant=\"plain\"\n className={classes.collapseButton}\n onClick={onToggleCollapse}\n aria-label={t('notebook.view.sidebar.collapse')}\n >\n <SidebarCollapseIcon />\n </Button>\n </Tooltip>\n </div>\n\n <div className={classes.documentsRow}>\n <Typography className={classes.documentCount}>\n {t('notebook.view.documents.count', {\n count: totalCount,\n } as any)}\n </Typography>\n <Button\n variant=\"link\"\n className={classes.addButton}\n icon={<PlusCircleIcon />}\n onClick={onAddDocument}\n >\n {t('notebook.view.documents.add')}\n </Button>\n </div>\n\n {(documents.length > 0 || activePending.length > 0) && (\n <div className={classes.documentsList}>\n {documents.map(doc => (\n <div key={doc.document_id} className={classes.documentItem}>\n <FileTypeIcon fileName={doc.title} />\n <Typography className={classes.fileName}>{doc.title}</Typography>\n {deletingDocumentIds?.has(doc.document_id) ? (\n <div className={classes.spinnerContainer}>\n <Spinner\n size=\"md\"\n aria-label={t('notebook.document.delete')}\n />\n </div>\n ) : (\n <Dropdown\n className={classes.kebabDropdownMenu}\n isOpen={openMenuDocId === doc.document_id}\n popperProps={{\n position: 'end',\n preventOverflow: true,\n }}\n onOpenChange={isOpen =>\n setOpenMenuDocId(isOpen ? doc.document_id : null)\n }\n toggle={toggleRef => (\n <MenuToggle\n ref={toggleRef}\n variant=\"plain\"\n className={classes.kebabToggle}\n isExpanded={openMenuDocId === doc.document_id}\n onClick={event => {\n event.stopPropagation();\n setOpenMenuDocId(current =>\n current === doc.document_id ? null : doc.document_id,\n );\n }}\n aria-label={t('notebook.document.delete')}\n >\n <EllipsisVIcon />\n </MenuToggle>\n )}\n >\n <DropdownList>\n <DropdownItem\n key=\"delete\"\n onClick={event => {\n event.stopPropagation();\n setOpenMenuDocId(null);\n onDeleteDocument?.(doc.document_id);\n }}\n >\n {t('notebook.document.delete')}\n </DropdownItem>\n </DropdownList>\n </Dropdown>\n )}\n </div>\n ))}\n {activePending.map(fileName => (\n <div key={`pending-${fileName}`} className={classes.documentItem}>\n <FileTypeIcon fileName={fileName} />\n <Typography className={classes.fileName}>{fileName}</Typography>\n {!completedFileNames?.has(fileName) && (\n <div className={classes.spinnerContainer}>\n <Spinner\n size=\"md\"\n aria-label={t('notebook.view.documents.uploading')}\n />\n </div>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DocumentSidebar.esm.js","sources":["../../../src/components/notebooks/DocumentSidebar.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useState } from 'react';\n\nimport { makeStyles, Typography } from '@material-ui/core';\nimport {\n Button,\n Dropdown,\n DropdownItem,\n DropdownList,\n MenuToggle,\n Spinner,\n Tooltip,\n} from '@patternfly/react-core';\nimport { EllipsisVIcon, PlusCircleIcon } from '@patternfly/react-icons';\n\nimport { NOTEBOOK_MAX_FILES } from '../../const';\nimport { useTranslation } from '../../hooks/useTranslation';\nimport { SessionDocument } from '../../types';\nimport { FileTypeIcon } from './FileTypeIcon';\nimport { SidebarCollapseIcon } from './SidebarCollapseIcon';\n\nconst useStyles = makeStyles(theme => ({\n sidebar: {\n display: 'flex',\n flexDirection: 'column',\n width: '100%',\n height: '100%',\n padding: theme.spacing(2),\n overflow: 'hidden',\n },\n titleRow: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: theme.spacing(2),\n gap: theme.spacing(1),\n },\n title: {\n fontWeight: 500,\n fontSize: '1.25rem',\n lineHeight: '2rem',\n letterSpacing: '-0.25px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n flex: 1,\n minWidth: 0,\n },\n collapseButton: {\n flexShrink: 0,\n },\n documentsRow: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n },\n documentCount: {\n fontWeight: 700,\n fontSize: '1.125rem',\n lineHeight: '2rem',\n },\n addButton: {\n textTransform: 'none',\n },\n documentsList: {\n marginTop: theme.spacing(2),\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n overflowY: 'auto',\n flex: 1,\n },\n documentItem: {\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n padding: `${theme.spacing(1)}px ${theme.spacing(0.5)}px`,\n borderRadius: 4,\n },\n fileIcon: {\n flexShrink: 0,\n color: theme.palette.grey[500],\n fontSize: '1rem',\n },\n fileName: {\n flex: 1,\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n fontSize: '0.875rem',\n lineHeight: '1.25rem',\n },\n spinnerContainer: {\n flexShrink: 0,\n },\n kebabToggle: {\n padding: 0,\n flexShrink: 0,\n },\n kebabDropdownMenu: {\n '& .pf-v6-c-menu__list': {\n paddingInlineStart: 0,\n marginBlockStart: 0,\n marginBlockEnd: 0,\n },\n },\n}));\n\ntype DocumentSidebarProps = {\n notebookName: string;\n documents: SessionDocument[];\n uploadingFileNames: string[];\n completedFileNames?: Set<string>;\n deletingDocumentIds?: Set<string>;\n collapsed: boolean;\n onToggleCollapse: () => void;\n onAddDocument: () => void;\n onDeleteDocument?: (documentId: string) => void;\n};\n\nexport const DocumentSidebar = ({\n notebookName,\n documents,\n uploadingFileNames,\n completedFileNames,\n deletingDocumentIds,\n collapsed,\n onToggleCollapse,\n onAddDocument,\n onDeleteDocument,\n}: DocumentSidebarProps) => {\n const classes = useStyles();\n const { t } = useTranslation();\n const [openMenuDocId, setOpenMenuDocId] = useState<string | null>(null);\n\n if (collapsed) {\n return null;\n }\n\n const uploadedNames = new Set(documents.map(d => d.title));\n const activePending = uploadingFileNames.filter(\n name => !uploadedNames.has(name),\n );\n const totalCount = documents.length + activePending.length;\n const isAddDisabled = totalCount >= NOTEBOOK_MAX_FILES;\n\n return (\n <div className={classes.sidebar}>\n <div className={classes.titleRow}>\n <Typography className={classes.title}>{notebookName}</Typography>\n <Tooltip content={t('notebook.view.sidebar.collapse')} position=\"right\">\n <Button\n variant=\"plain\"\n className={classes.collapseButton}\n onClick={onToggleCollapse}\n aria-label={t('notebook.view.sidebar.collapse')}\n >\n <SidebarCollapseIcon />\n </Button>\n </Tooltip>\n </div>\n\n <div className={classes.documentsRow}>\n <Typography className={classes.documentCount}>\n {t('notebook.view.documents.count', {\n count: totalCount,\n } as any)}\n </Typography>\n {isAddDisabled ? (\n <Tooltip\n content={t('notebook.view.documents.maxReached')}\n position=\"top\"\n >\n <span>\n <Button\n variant=\"link\"\n className={classes.addButton}\n icon={<PlusCircleIcon />}\n isDisabled\n >\n {t('notebook.view.documents.add')}\n </Button>\n </span>\n </Tooltip>\n ) : (\n <Button\n variant=\"link\"\n className={classes.addButton}\n icon={<PlusCircleIcon />}\n onClick={onAddDocument}\n >\n {t('notebook.view.documents.add')}\n </Button>\n )}\n </div>\n\n {(documents.length > 0 || activePending.length > 0) && (\n <div className={classes.documentsList}>\n {documents.map(doc => (\n <div key={doc.document_id} className={classes.documentItem}>\n <FileTypeIcon fileName={doc.title} />\n <Typography className={classes.fileName}>{doc.title}</Typography>\n {deletingDocumentIds?.has(doc.document_id) ? (\n <div className={classes.spinnerContainer}>\n <Spinner\n size=\"md\"\n aria-label={t('notebook.document.delete')}\n />\n </div>\n ) : (\n <Dropdown\n className={classes.kebabDropdownMenu}\n isOpen={openMenuDocId === doc.document_id}\n popperProps={{\n position: 'end',\n preventOverflow: true,\n }}\n onOpenChange={isOpen =>\n setOpenMenuDocId(isOpen ? doc.document_id : null)\n }\n toggle={toggleRef => (\n <MenuToggle\n ref={toggleRef}\n variant=\"plain\"\n className={classes.kebabToggle}\n isExpanded={openMenuDocId === doc.document_id}\n onClick={event => {\n event.stopPropagation();\n setOpenMenuDocId(current =>\n current === doc.document_id ? null : doc.document_id,\n );\n }}\n aria-label={t('notebook.document.delete')}\n >\n <EllipsisVIcon />\n </MenuToggle>\n )}\n >\n <DropdownList>\n <DropdownItem\n key=\"delete\"\n onClick={event => {\n event.stopPropagation();\n setOpenMenuDocId(null);\n onDeleteDocument?.(doc.document_id);\n }}\n >\n {t('notebook.document.delete')}\n </DropdownItem>\n </DropdownList>\n </Dropdown>\n )}\n </div>\n ))}\n {activePending.map(fileName => (\n <div key={`pending-${fileName}`} className={classes.documentItem}>\n <FileTypeIcon fileName={fileName} />\n <Typography className={classes.fileName}>{fileName}</Typography>\n {!completedFileNames?.has(fileName) && (\n <div className={classes.spinnerContainer}>\n <Spinner\n size=\"md\"\n aria-label={t('notebook.view.documents.uploading')}\n />\n </div>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { makeStyles } from '@material-ui/core/styles';
3
+ import CloseIcon from '@mui/icons-material/Close';
4
+ import Box from '@mui/material/Box';
5
+ import IconButton from '@mui/material/IconButton';
6
+ import Typography from '@mui/material/Typography';
7
+ import { FileTypeIcon } from './FileTypeIcon.esm.js';
8
+
9
+ const useStyles = makeStyles((theme) => ({
10
+ container: {
11
+ display: "flex",
12
+ alignItems: "center",
13
+ padding: "8px 12px",
14
+ borderRadius: 8,
15
+ backgroundColor: theme.palette.type === "dark" ? "#2a2a2a" : "#f5f5f5",
16
+ marginBottom: 8,
17
+ "&:last-child": {
18
+ marginBottom: 0
19
+ }
20
+ },
21
+ fileInfo: {
22
+ display: "flex",
23
+ alignItems: "center",
24
+ flex: 1,
25
+ minWidth: 0,
26
+ gap: 12
27
+ },
28
+ fileName: {
29
+ flex: 1,
30
+ minWidth: 0,
31
+ overflow: "hidden",
32
+ textOverflow: "ellipsis",
33
+ whiteSpace: "nowrap",
34
+ fontSize: "0.875rem"
35
+ },
36
+ fileSize: {
37
+ color: theme.palette.text.secondary,
38
+ fontSize: "0.75rem",
39
+ flexShrink: 0,
40
+ marginRight: 8
41
+ },
42
+ removeButton: {
43
+ padding: 4,
44
+ color: theme.palette.grey[600],
45
+ "&:hover": {
46
+ color: theme.palette.error.main
47
+ }
48
+ }
49
+ }));
50
+ const formatFileSize = (bytes) => {
51
+ if (bytes === 0) return "0 B";
52
+ const k = 1024;
53
+ const sizes = ["B", "KB", "MB", "GB"];
54
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
55
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
56
+ };
57
+ const MAX_FILENAME_LENGTH = 30;
58
+ const truncateFileName = (fileName, maxLength) => {
59
+ if (fileName.length <= maxLength) return fileName;
60
+ const lastDot = fileName.lastIndexOf(".");
61
+ const extension = lastDot >= 0 ? fileName.slice(lastDot) : "";
62
+ const baseName = lastDot >= 0 ? fileName.slice(0, lastDot) : fileName;
63
+ const availableLength = maxLength - extension.length - 3;
64
+ if (availableLength <= 0) return fileName;
65
+ return `${baseName.slice(0, availableLength)}...${extension}`;
66
+ };
67
+ const FileListItem = ({
68
+ file,
69
+ onRemove,
70
+ removeAriaLabel = "Remove file"
71
+ }) => {
72
+ const classes = useStyles();
73
+ const displayName = truncateFileName(file.name, MAX_FILENAME_LENGTH);
74
+ return /* @__PURE__ */ jsxs(Box, { className: classes.container, children: [
75
+ /* @__PURE__ */ jsxs(Box, { className: classes.fileInfo, children: [
76
+ /* @__PURE__ */ jsx(FileTypeIcon, { fileName: file.name }),
77
+ /* @__PURE__ */ jsx(Typography, { className: classes.fileName, title: file.name, children: displayName })
78
+ ] }),
79
+ /* @__PURE__ */ jsx(Typography, { className: classes.fileSize, children: formatFileSize(file.size) }),
80
+ /* @__PURE__ */ jsx(
81
+ IconButton,
82
+ {
83
+ className: classes.removeButton,
84
+ onClick: onRemove,
85
+ "aria-label": removeAriaLabel,
86
+ size: "small",
87
+ children: /* @__PURE__ */ jsx(CloseIcon, { fontSize: "small" })
88
+ }
89
+ )
90
+ ] });
91
+ };
92
+
93
+ export { FileListItem };
94
+ //# sourceMappingURL=FileListItem.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileListItem.esm.js","sources":["../../../src/components/notebooks/FileListItem.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport CloseIcon from '@mui/icons-material/Close';\nimport Box from '@mui/material/Box';\nimport IconButton from '@mui/material/IconButton';\nimport Typography from '@mui/material/Typography';\n\nimport { FileTypeIcon } from './FileTypeIcon';\n\nconst useStyles = makeStyles(theme => ({\n container: {\n display: 'flex',\n alignItems: 'center',\n padding: '8px 12px',\n borderRadius: 8,\n backgroundColor: theme.palette.type === 'dark' ? '#2a2a2a' : '#f5f5f5',\n marginBottom: 8,\n '&:last-child': {\n marginBottom: 0,\n },\n },\n fileInfo: {\n display: 'flex',\n alignItems: 'center',\n flex: 1,\n minWidth: 0,\n gap: 12,\n },\n fileName: {\n flex: 1,\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n fontSize: '0.875rem',\n },\n fileSize: {\n color: theme.palette.text.secondary,\n fontSize: '0.75rem',\n flexShrink: 0,\n marginRight: 8,\n },\n removeButton: {\n padding: 4,\n color: theme.palette.grey[600],\n '&:hover': {\n color: theme.palette.error.main,\n },\n },\n}));\n\ntype FileListItemProps = {\n file: File;\n onRemove: () => void;\n removeAriaLabel?: string;\n};\n\nconst formatFileSize = (bytes: number): string => {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\n};\n\nconst MAX_FILENAME_LENGTH = 30;\n\nconst truncateFileName = (fileName: string, maxLength: number): string => {\n if (fileName.length <= maxLength) return fileName;\n\n const lastDot = fileName.lastIndexOf('.');\n const extension = lastDot >= 0 ? fileName.slice(lastDot) : '';\n const baseName = lastDot >= 0 ? fileName.slice(0, lastDot) : fileName;\n\n const availableLength = maxLength - extension.length - 3;\n if (availableLength <= 0) return fileName;\n\n return `${baseName.slice(0, availableLength)}...${extension}`;\n};\n\nexport const FileListItem = ({\n file,\n onRemove,\n removeAriaLabel = 'Remove file',\n}: FileListItemProps) => {\n const classes = useStyles();\n const displayName = truncateFileName(file.name, MAX_FILENAME_LENGTH);\n\n return (\n <Box className={classes.container}>\n <Box className={classes.fileInfo}>\n <FileTypeIcon fileName={file.name} />\n <Typography className={classes.fileName} title={file.name}>\n {displayName}\n </Typography>\n </Box>\n <Typography className={classes.fileSize}>\n {formatFileSize(file.size)}\n </Typography>\n <IconButton\n className={classes.removeButton}\n onClick={onRemove}\n aria-label={removeAriaLabel}\n size=\"small\"\n >\n <CloseIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n );\n};\n"],"names":[],"mappings":"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"}