@red-hat-developer-hub/backstage-plugin-intelligent-assistant 3.2.0 → 4.1.0
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/CHANGELOG.md +87 -0
- package/README.md +7 -10
- package/config.d.ts +27 -0
- package/dist/alpha.d.ts +21 -7
- package/dist/api/NotebooksApiClient.esm.js +10 -0
- package/dist/api/NotebooksApiClient.esm.js.map +1 -1
- package/dist/api/notebooksApi.esm.js.map +1 -1
- package/dist/components/LightSpeedChat.esm.js +50 -37
- package/dist/components/LightSpeedChat.esm.js.map +1 -1
- package/dist/components/LightspeedChatContainer.esm.js +7 -5
- package/dist/components/LightspeedChatContainer.esm.js.map +1 -1
- package/dist/components/McpServersSettings.esm.js +4 -3
- package/dist/components/McpServersSettings.esm.js.map +1 -1
- package/dist/components/notebooks/AddDocumentModal.esm.js +181 -66
- package/dist/components/notebooks/AddDocumentModal.esm.js.map +1 -1
- package/dist/components/notebooks/DocumentSidebar.esm.js +258 -27
- package/dist/components/notebooks/DocumentSidebar.esm.js.map +1 -1
- package/dist/components/notebooks/FileListItem.esm.js +15 -9
- package/dist/components/notebooks/FileListItem.esm.js.map +1 -1
- package/dist/components/notebooks/NotebookCard.esm.js +71 -14
- package/dist/components/notebooks/NotebookCard.esm.js.map +1 -1
- package/dist/components/notebooks/NotebookView.esm.js +202 -42
- package/dist/components/notebooks/NotebookView.esm.js.map +1 -1
- package/dist/components/notebooks/NotebooksTab.esm.js.map +1 -1
- package/dist/components/notebooks/OverwriteConfirmModal.esm.js +122 -42
- package/dist/components/notebooks/OverwriteConfirmModal.esm.js.map +1 -1
- package/dist/components/notebooks/UploadResourceScreen.esm.js +0 -1
- package/dist/components/notebooks/UploadResourceScreen.esm.js.map +1 -1
- package/dist/const.esm.js +2 -1
- package/dist/const.esm.js.map +1 -1
- package/dist/hooks/notebooks/useInlineEdit.esm.js +60 -0
- package/dist/hooks/notebooks/useInlineEdit.esm.js.map +1 -0
- package/dist/hooks/notebooks/useLightspeedNotebooksPermission.esm.js +4 -3
- package/dist/hooks/notebooks/useLightspeedNotebooksPermission.esm.js.map +1 -1
- package/dist/hooks/notebooks/useRenameDocument.esm.js +50 -0
- package/dist/hooks/notebooks/useRenameDocument.esm.js.map +1 -0
- package/dist/hooks/notebooks/useRenameNotebook.esm.js +48 -1
- package/dist/hooks/notebooks/useRenameNotebook.esm.js.map +1 -1
- package/dist/hooks/notebooks/useRenameNotebookWithAlert.esm.js +34 -0
- package/dist/hooks/notebooks/useRenameNotebookWithAlert.esm.js.map +1 -0
- package/dist/hooks/useLightspeedDeletePermission.esm.js +2 -2
- package/dist/hooks/useLightspeedDeletePermission.esm.js.map +1 -1
- package/dist/hooks/useLightspeedUpdatePermission.esm.js +2 -2
- package/dist/hooks/useLightspeedUpdatePermission.esm.js.map +1 -1
- package/dist/hooks/useLightspeedViewPermission.esm.js +6 -4
- package/dist/hooks/useLightspeedViewPermission.esm.js.map +1 -1
- package/dist/translations/de.esm.js +31 -17
- package/dist/translations/de.esm.js.map +1 -1
- package/dist/translations/es.esm.js +31 -17
- package/dist/translations/es.esm.js.map +1 -1
- package/dist/translations/fr.esm.js +31 -17
- package/dist/translations/fr.esm.js.map +1 -1
- package/dist/translations/it.esm.js +31 -17
- package/dist/translations/it.esm.js.map +1 -1
- package/dist/translations/ja.esm.js +31 -17
- package/dist/translations/ja.esm.js.map +1 -1
- package/dist/translations/ref.esm.js +32 -18
- package/dist/translations/ref.esm.js.map +1 -1
- package/dist/utils/notebook-upload-runner.esm.js +16 -0
- package/dist/utils/notebook-upload-runner.esm.js.map +1 -0
- package/package.json +4 -3
- package/dist/components/notebooks/RenameNotebookModal.esm.js +0 -187
- package/dist/components/notebooks/RenameNotebookModal.esm.js.map +0 -1
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useCallback } from 'react';
|
|
2
3
|
import Typography from '@mui/material/Typography';
|
|
3
|
-
import { Card, CardHeader, CardTitle, Dropdown, DropdownList, DropdownItem, MenuToggle, CardBody } from '@patternfly/react-core';
|
|
4
|
-
import { EllipsisVIcon } from '@patternfly/react-icons';
|
|
5
|
-
import {
|
|
4
|
+
import { Card, CardHeader, CardTitle, TextInput, Dropdown, DropdownList, DropdownItem, MenuToggle, CardBody } from '@patternfly/react-core';
|
|
5
|
+
import { CatalogIcon, PenIcon, TrashIcon, EllipsisVIcon } from '@patternfly/react-icons';
|
|
6
|
+
import { useInlineEdit } from '../../hooks/notebooks/useInlineEdit.esm.js';
|
|
6
7
|
import { formatUpdatedLabel } from '../../utils/notebooks-utils.esm.js';
|
|
7
8
|
|
|
9
|
+
const titleInputStyle = {
|
|
10
|
+
"--pf-v6-c-form-control--before--BorderStyle": "none",
|
|
11
|
+
"--pf-v6-c-form-control--after--BorderColor": "var(--pf-t--global--text--color--brand--default)",
|
|
12
|
+
"--pf-v6-c-form-control--FontSize": "1.25rem",
|
|
13
|
+
"--pf-v6-c-form-control--PaddingBlockStart": "2px",
|
|
14
|
+
"--pf-v6-c-form-control--PaddingBlockEnd": "2px",
|
|
15
|
+
"--pf-v6-c-form-control--PaddingInlineStart": "6px",
|
|
16
|
+
"--pf-v6-c-form-control--PaddingInlineEnd": "6px",
|
|
17
|
+
"--pf-v6-c-form-control--OutlineOffset": "0",
|
|
18
|
+
width: "100%",
|
|
19
|
+
minWidth: 0,
|
|
20
|
+
fontWeight: 500
|
|
21
|
+
};
|
|
8
22
|
const NotebookCard = ({
|
|
9
23
|
notebook,
|
|
10
24
|
classes,
|
|
@@ -16,8 +30,26 @@ const NotebookCard = ({
|
|
|
16
30
|
t
|
|
17
31
|
}) => {
|
|
18
32
|
const isMenuOpen = openNotebookMenuId === notebook.session_id;
|
|
33
|
+
const {
|
|
34
|
+
isEditing,
|
|
35
|
+
editValue: editName,
|
|
36
|
+
setEditValue: setEditName,
|
|
37
|
+
inputRef,
|
|
38
|
+
startEditing,
|
|
39
|
+
save: saveRename,
|
|
40
|
+
handleKeyDown
|
|
41
|
+
} = useInlineEdit({
|
|
42
|
+
currentName: notebook.name,
|
|
43
|
+
onSave: (newName) => onRename(notebook.session_id, newName),
|
|
44
|
+
onStart: () => setOpenNotebookMenuId(null)
|
|
45
|
+
});
|
|
46
|
+
const handleCardClick = useCallback(() => {
|
|
47
|
+
if (!isEditing) {
|
|
48
|
+
onClick(notebook);
|
|
49
|
+
}
|
|
50
|
+
}, [isEditing, onClick, notebook]);
|
|
19
51
|
const handleCardKeyDown = (e) => {
|
|
20
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
52
|
+
if (!isEditing && (e.key === "Enter" || e.key === " ")) {
|
|
21
53
|
e.preventDefault();
|
|
22
54
|
onClick(notebook);
|
|
23
55
|
}
|
|
@@ -28,8 +60,10 @@ const NotebookCard = ({
|
|
|
28
60
|
className: classes.notebookCard,
|
|
29
61
|
component: "div",
|
|
30
62
|
tabIndex: 0,
|
|
31
|
-
"aria-label": t("notebooks.card.openAria", {
|
|
32
|
-
|
|
63
|
+
"aria-label": t("notebooks.card.openAria", {
|
|
64
|
+
name: notebook.name
|
|
65
|
+
}),
|
|
66
|
+
onClick: handleCardClick,
|
|
33
67
|
onKeyDown: handleCardKeyDown,
|
|
34
68
|
children: [
|
|
35
69
|
/* @__PURE__ */ jsx(
|
|
@@ -69,10 +103,10 @@ const NotebookCard = ({
|
|
|
69
103
|
DropdownItem,
|
|
70
104
|
{
|
|
71
105
|
className: classes.notebookDropdownItem,
|
|
106
|
+
icon: /* @__PURE__ */ jsx(PenIcon, {}),
|
|
72
107
|
onClick: (event) => {
|
|
73
108
|
event.stopPropagation();
|
|
74
|
-
|
|
75
|
-
setOpenNotebookMenuId(null);
|
|
109
|
+
startEditing();
|
|
76
110
|
},
|
|
77
111
|
children: t("notebooks.actions.rename")
|
|
78
112
|
}
|
|
@@ -81,6 +115,7 @@ const NotebookCard = ({
|
|
|
81
115
|
DropdownItem,
|
|
82
116
|
{
|
|
83
117
|
className: classes.notebookDropdownItem,
|
|
118
|
+
icon: /* @__PURE__ */ jsx(TrashIcon, {}),
|
|
84
119
|
onClick: (event) => {
|
|
85
120
|
event.stopPropagation();
|
|
86
121
|
onDelete(notebook.session_id);
|
|
@@ -96,17 +131,39 @@ const NotebookCard = ({
|
|
|
96
131
|
},
|
|
97
132
|
children: /* @__PURE__ */ jsxs(CardTitle, { className: classes.notebookTitle, children: [
|
|
98
133
|
/* @__PURE__ */ jsx(CatalogIcon, {}),
|
|
99
|
-
/* @__PURE__ */ jsx(
|
|
134
|
+
isEditing ? /* @__PURE__ */ jsx(
|
|
135
|
+
TextInput,
|
|
136
|
+
{
|
|
137
|
+
ref: inputRef,
|
|
138
|
+
style: titleInputStyle,
|
|
139
|
+
value: editName,
|
|
140
|
+
onChange: (_event, value) => setEditName(value),
|
|
141
|
+
onBlur: saveRename,
|
|
142
|
+
onKeyDown: handleKeyDown,
|
|
143
|
+
"aria-label": t("notebooks.rename.inline.tooltip"),
|
|
144
|
+
onClick: (e) => e.stopPropagation()
|
|
145
|
+
}
|
|
146
|
+
) : /* @__PURE__ */ jsx(
|
|
147
|
+
Typography,
|
|
148
|
+
{
|
|
149
|
+
component: "span",
|
|
150
|
+
className: classes.notebookTitleText,
|
|
151
|
+
title: t("notebooks.rename.inline.tooltip"),
|
|
152
|
+
onClick: (e) => {
|
|
153
|
+
e.stopPropagation();
|
|
154
|
+
startEditing();
|
|
155
|
+
},
|
|
156
|
+
children: notebook.name
|
|
157
|
+
}
|
|
158
|
+
)
|
|
100
159
|
] })
|
|
101
160
|
}
|
|
102
161
|
),
|
|
103
162
|
/* @__PURE__ */ jsx("div", { className: classes.notebookCardDivider }),
|
|
104
163
|
/* @__PURE__ */ jsx(CardBody, { className: classes.notebookCardBody, children: /* @__PURE__ */ jsxs("div", { children: [
|
|
105
|
-
/* @__PURE__ */ jsx("div", { className: classes.notebookDocuments, children: /* @__PURE__ */
|
|
106
|
-
notebook.document_count ?? 0
|
|
107
|
-
|
|
108
|
-
t("notebooks.documents")
|
|
109
|
-
] }) }),
|
|
164
|
+
/* @__PURE__ */ jsx("div", { className: classes.notebookDocuments, children: /* @__PURE__ */ jsx(Typography, { variant: "body2", children: t("notebooks.documents", {
|
|
165
|
+
count: notebook.document_count ?? 0
|
|
166
|
+
}) }) }),
|
|
110
167
|
/* @__PURE__ */ jsx("div", { className: classes.notebookUpdated, children: /* @__PURE__ */ jsx(Typography, { variant: "caption", children: formatUpdatedLabel(notebook.updated_at, t) }) })
|
|
111
168
|
] }) })
|
|
112
169
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotebookCard.esm.js","sources":["../../../src/components/notebooks/NotebookCard.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 type { TranslationFunction } from '@backstage/core-plugin-api/alpha';\n\nimport Typography from '@mui/material/Typography';\nimport {\n Card,\n CardBody,\n CardHeader,\n CardTitle,\n Dropdown,\n DropdownItem,\n DropdownList,\n MenuToggle,\n} from '@patternfly/react-core';\nimport { EllipsisVIcon } from '@patternfly/react-icons';\nimport { CatalogIcon } from '@patternfly/react-icons/dist/esm/icons';\n\nimport { intelligentAssistantTranslationRef } from '../../translations/ref';\nimport { NotebookSession } from '../../types';\nimport { formatUpdatedLabel } from '../../utils/notebooks-utils';\n\ntype NotebookCardProps = {\n notebook: NotebookSession;\n classes: Record<string, string>;\n openNotebookMenuId: string | null;\n setOpenNotebookMenuId: React.Dispatch<React.SetStateAction<string | null>>;\n onClick: (notebook: NotebookSession) => void;\n onRename: (sessionId: string) => void;\n onDelete: (sessionId: string) => void;\n t: TranslationFunction<typeof intelligentAssistantTranslationRef.T>;\n};\n\nexport const NotebookCard = ({\n notebook,\n classes,\n openNotebookMenuId,\n setOpenNotebookMenuId,\n onClick,\n onRename,\n onDelete,\n t,\n}: NotebookCardProps) => {\n const isMenuOpen = openNotebookMenuId === notebook.session_id;\n\n const handleCardKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onClick(notebook);\n }\n };\n\n return (\n <Card\n className={classes.notebookCard}\n component=\"div\"\n tabIndex={0}\n aria-label={t('notebooks.card.openAria' as any, { name: notebook.name })}\n onClick={() => onClick(notebook)}\n onKeyDown={handleCardKeyDown}\n >\n <CardHeader\n className={classes.notebookCardHeader}\n actions={{\n actions: (\n <Dropdown\n className={classes.notebookDropdownMenu}\n isOpen={isMenuOpen}\n popperProps={{\n position: 'end',\n preventOverflow: true,\n }}\n onOpenChange={isOpen =>\n setOpenNotebookMenuId(isOpen ? notebook.session_id : null)\n }\n toggle={toggleRef => (\n <MenuToggle\n ref={toggleRef}\n variant=\"plain\"\n className={classes.notebookMenuButton}\n aria-label={t('aria.options.label')}\n isExpanded={isMenuOpen}\n onClick={event => {\n event.stopPropagation();\n setOpenNotebookMenuId(current =>\n current === notebook.session_id\n ? null\n : notebook.session_id,\n );\n }}\n >\n <EllipsisVIcon />\n </MenuToggle>\n )}\n >\n <DropdownList className={classes.notebookDropdownList}>\n <DropdownItem\n className={classes.notebookDropdownItem}\n onClick={event => {\n event.stopPropagation();\n onRename(notebook.session_id);\n setOpenNotebookMenuId(null);\n }}\n >\n {t('notebooks.actions.rename')}\n </DropdownItem>\n <DropdownItem\n className={classes.notebookDropdownItem}\n onClick={event => {\n event.stopPropagation();\n onDelete(notebook.session_id);\n setOpenNotebookMenuId(null);\n }}\n >\n {t('notebooks.actions.delete')}\n </DropdownItem>\n </DropdownList>\n </Dropdown>\n ),\n className: classes.notebookCardHeaderActions,\n }}\n >\n <CardTitle className={classes.notebookTitle}>\n <CatalogIcon />\n <Typography component=\"span\" className={classes.notebookTitleText}>\n {notebook.name}\n </Typography>\n </CardTitle>\n </CardHeader>\n <div className={classes.notebookCardDivider} />\n <CardBody className={classes.notebookCardBody}>\n <div>\n <div className={classes.notebookDocuments}>\n <Typography variant=\"body2\">\n {notebook.document_count ?? 0} {t('notebooks.documents')}\n </Typography>\n </div>\n <div className={classes.notebookUpdated}>\n <Typography variant=\"caption\">\n {formatUpdatedLabel(notebook.updated_at, t)}\n </Typography>\n </div>\n </div>\n </CardBody>\n </Card>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"NotebookCard.esm.js","sources":["../../../src/components/notebooks/NotebookCard.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 { useCallback } from 'react';\n\nimport type { TranslationFunction } from '@backstage/core-plugin-api/alpha';\n\nimport Typography from '@mui/material/Typography';\nimport {\n Card,\n CardBody,\n CardHeader,\n CardTitle,\n Dropdown,\n DropdownItem,\n DropdownList,\n MenuToggle,\n TextInput,\n} from '@patternfly/react-core';\nimport {\n CatalogIcon,\n EllipsisVIcon,\n PenIcon,\n TrashIcon,\n} from '@patternfly/react-icons';\n\nimport { useInlineEdit } from '../../hooks/notebooks/useInlineEdit';\nimport { intelligentAssistantTranslationRef } from '../../translations/ref';\nimport { NotebookSession } from '../../types';\nimport { formatUpdatedLabel } from '../../utils/notebooks-utils';\n\ntype NotebookCardProps = {\n notebook: NotebookSession;\n classes: Record<string, string>;\n openNotebookMenuId: string | null;\n setOpenNotebookMenuId: React.Dispatch<React.SetStateAction<string | null>>;\n onClick: (notebook: NotebookSession) => void;\n onRename: (sessionId: string, newName: string) => void;\n onDelete: (sessionId: string) => void;\n t: TranslationFunction<typeof intelligentAssistantTranslationRef.T>;\n};\n\nconst titleInputStyle: React.CSSProperties = {\n '--pf-v6-c-form-control--before--BorderStyle': 'none',\n '--pf-v6-c-form-control--after--BorderColor':\n 'var(--pf-t--global--text--color--brand--default)',\n '--pf-v6-c-form-control--FontSize': '1.25rem',\n '--pf-v6-c-form-control--PaddingBlockStart': '2px',\n '--pf-v6-c-form-control--PaddingBlockEnd': '2px',\n '--pf-v6-c-form-control--PaddingInlineStart': '6px',\n '--pf-v6-c-form-control--PaddingInlineEnd': '6px',\n '--pf-v6-c-form-control--OutlineOffset': '0',\n width: '100%',\n minWidth: 0,\n fontWeight: 500,\n} as React.CSSProperties;\n\nexport const NotebookCard = ({\n notebook,\n classes,\n openNotebookMenuId,\n setOpenNotebookMenuId,\n onClick,\n onRename,\n onDelete,\n t,\n}: NotebookCardProps) => {\n const isMenuOpen = openNotebookMenuId === notebook.session_id;\n\n const {\n isEditing,\n editValue: editName,\n setEditValue: setEditName,\n inputRef,\n startEditing,\n save: saveRename,\n handleKeyDown,\n } = useInlineEdit({\n currentName: notebook.name,\n onSave: newName => onRename(notebook.session_id, newName),\n onStart: () => setOpenNotebookMenuId(null),\n });\n\n const handleCardClick = useCallback(() => {\n if (!isEditing) {\n onClick(notebook);\n }\n }, [isEditing, onClick, notebook]);\n\n const handleCardKeyDown = (e: React.KeyboardEvent) => {\n if (!isEditing && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n onClick(notebook);\n }\n };\n\n return (\n <Card\n className={classes.notebookCard}\n component=\"div\"\n tabIndex={0}\n aria-label={(t as Function)('notebooks.card.openAria', {\n name: notebook.name,\n })}\n onClick={handleCardClick}\n onKeyDown={handleCardKeyDown}\n >\n <CardHeader\n className={classes.notebookCardHeader}\n actions={{\n actions: (\n <Dropdown\n className={classes.notebookDropdownMenu}\n isOpen={isMenuOpen}\n popperProps={{\n position: 'end',\n preventOverflow: true,\n }}\n onOpenChange={isOpen =>\n setOpenNotebookMenuId(isOpen ? notebook.session_id : null)\n }\n toggle={toggleRef => (\n <MenuToggle\n ref={toggleRef}\n variant=\"plain\"\n className={classes.notebookMenuButton}\n aria-label={t('aria.options.label')}\n isExpanded={isMenuOpen}\n onClick={event => {\n event.stopPropagation();\n setOpenNotebookMenuId(current =>\n current === notebook.session_id\n ? null\n : notebook.session_id,\n );\n }}\n >\n <EllipsisVIcon />\n </MenuToggle>\n )}\n >\n <DropdownList className={classes.notebookDropdownList}>\n <DropdownItem\n className={classes.notebookDropdownItem}\n icon={<PenIcon />}\n onClick={event => {\n event.stopPropagation();\n startEditing();\n }}\n >\n {t('notebooks.actions.rename')}\n </DropdownItem>\n <DropdownItem\n className={classes.notebookDropdownItem}\n icon={<TrashIcon />}\n onClick={event => {\n event.stopPropagation();\n onDelete(notebook.session_id);\n setOpenNotebookMenuId(null);\n }}\n >\n {t('notebooks.actions.delete')}\n </DropdownItem>\n </DropdownList>\n </Dropdown>\n ),\n className: classes.notebookCardHeaderActions,\n }}\n >\n <CardTitle className={classes.notebookTitle}>\n <CatalogIcon />\n {isEditing ? (\n <TextInput\n ref={inputRef}\n style={titleInputStyle}\n value={editName}\n onChange={(_event, value) => setEditName(value)}\n onBlur={saveRename}\n onKeyDown={handleKeyDown}\n aria-label={t('notebooks.rename.inline.tooltip')}\n onClick={e => e.stopPropagation()}\n />\n ) : (\n <Typography\n component=\"span\"\n className={classes.notebookTitleText}\n title={t('notebooks.rename.inline.tooltip')}\n onClick={e => {\n e.stopPropagation();\n startEditing();\n }}\n >\n {notebook.name}\n </Typography>\n )}\n </CardTitle>\n </CardHeader>\n <div className={classes.notebookCardDivider} />\n <CardBody className={classes.notebookCardBody}>\n <div>\n <div className={classes.notebookDocuments}>\n <Typography variant=\"body2\">\n {(t as Function)('notebooks.documents', {\n count: notebook.document_count ?? 0,\n })}\n </Typography>\n </div>\n <div className={classes.notebookUpdated}>\n <Typography variant=\"caption\">\n {formatUpdatedLabel(notebook.updated_at, t)}\n </Typography>\n </div>\n </div>\n </CardBody>\n </Card>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { useState, useCallback, useEffect
|
|
2
|
+
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
3
3
|
import { useApi, configApiRef } from '@backstage/core-plugin-api';
|
|
4
4
|
import { makeStyles, Typography } from '@material-ui/core';
|
|
5
5
|
import { ChatbotFooter, MessageBar, ChatbotContent } from '@patternfly/chatbot';
|
|
6
6
|
import { DrawerPanelContent, AlertGroup, Alert, AlertVariant, AlertActionCloseButton, Drawer, DrawerContent, DrawerContentBody, Tooltip, Button } from '@patternfly/react-core';
|
|
7
|
-
import { TimesIcon } from '@patternfly/react-icons';
|
|
7
|
+
import { TimesIcon, PlusIcon } from '@patternfly/react-icons';
|
|
8
8
|
import { useQueryClient } from '@tanstack/react-query';
|
|
9
9
|
import { notebooksApiRef } from '../../api/notebooksApi.esm.js';
|
|
10
10
|
import { TEMP_CONVERSATION_ID, UNTITLED_NOTEBOOK_NAME, NOTEBOOK_MAX_FILES } from '../../const.esm.js';
|
|
11
11
|
import { useCreateNotebookMessage } from '../../hooks/notebooks/useCreateNotebookMessage.esm.js';
|
|
12
12
|
import { useDocumentStatusPolling } from '../../hooks/notebooks/useDocumentStatusPolling.esm.js';
|
|
13
|
+
import { useRenameDocument } from '../../hooks/notebooks/useRenameDocument.esm.js';
|
|
14
|
+
import { useRenameNotebookWithAlert } from '../../hooks/notebooks/useRenameNotebookWithAlert.esm.js';
|
|
15
|
+
import { useUploadDocument } from '../../hooks/notebooks/useUploadDocument.esm.js';
|
|
13
16
|
import { useConversationMessages } from '../../hooks/useConversationMessages.esm.js';
|
|
14
17
|
import { useNotebookWelcomePrompts } from '../../hooks/useNotebookWelcomePrompts.esm.js';
|
|
18
|
+
import { useStopConversation } from '../../hooks/useStopConversation.esm.js';
|
|
15
19
|
import { useTranslation } from '../../hooks/useTranslation.esm.js';
|
|
16
20
|
import { ChatbotFootnoteWithIcon } from '../../utils/lightspeed-chatbox-utils.esm.js';
|
|
21
|
+
import { runFileUploads } from '../../utils/notebook-upload-runner.esm.js';
|
|
17
22
|
import { LightspeedChatBox } from '../LightspeedChatBox.esm.js';
|
|
18
23
|
import { AddDocumentModal } from './AddDocumentModal.esm.js';
|
|
19
24
|
import { DeleteDocumentModal } from './DeleteDocumentModal.esm.js';
|
|
@@ -197,11 +202,33 @@ const useStyles = makeStyles((theme) => ({
|
|
|
197
202
|
"& .pf-chatbot__message-bar": {
|
|
198
203
|
backgroundColor: theme.palette.type === "light" ? theme.palette.grey[100] : "var(--pf-t--global--background--color--secondary--default)"
|
|
199
204
|
},
|
|
200
|
-
"& .pf-chatbot__button--send, & .pf-chatbot__button--microphone": {
|
|
205
|
+
"& .pf-chatbot__button--stop, & .pf-chatbot__button--attach, & .pf-chatbot__button--send, & .pf-chatbot__button--microphone": {
|
|
201
206
|
"--pf-v6-c-button--BorderRadius": "var(--pf-t--global--border--radius--pill)",
|
|
202
207
|
borderRadius: "var(--pf-t--global--border--radius--pill) !important"
|
|
203
208
|
}
|
|
204
209
|
},
|
|
210
|
+
messageBar: {
|
|
211
|
+
border: "1px solid var(--pf-t--global--border--color--default)",
|
|
212
|
+
borderRadius: 24,
|
|
213
|
+
padding: theme.spacing(0.5),
|
|
214
|
+
"&::after": {
|
|
215
|
+
display: "none"
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
addResourceButton: {
|
|
219
|
+
background: "none",
|
|
220
|
+
border: "none",
|
|
221
|
+
cursor: "pointer",
|
|
222
|
+
padding: 4,
|
|
223
|
+
display: "inline-flex",
|
|
224
|
+
alignItems: "center",
|
|
225
|
+
color: "inherit",
|
|
226
|
+
"&:focus-visible": {
|
|
227
|
+
outline: "2px solid var(--pf-t--global--border--color--brand--default)",
|
|
228
|
+
outlineOffset: 2
|
|
229
|
+
},
|
|
230
|
+
marginLeft: theme.spacing(2)
|
|
231
|
+
},
|
|
205
232
|
chatContent: {
|
|
206
233
|
minHeight: 0,
|
|
207
234
|
display: "flex",
|
|
@@ -236,6 +263,16 @@ const NotebookView = ({
|
|
|
236
263
|
metadata?.conversation_id ?? TEMP_CONVERSATION_ID
|
|
237
264
|
);
|
|
238
265
|
const [isSendButtonDisabled, setIsSendButtonDisabled] = useState(false);
|
|
266
|
+
const [requestId, setRequestId] = useState("");
|
|
267
|
+
const { mutate: stopConversation } = useStopConversation();
|
|
268
|
+
const wasStoppedByUserRef = useRef(false);
|
|
269
|
+
const autoDeleteRef = useRef({
|
|
270
|
+
isUntitled: false,
|
|
271
|
+
isEmpty: true,
|
|
272
|
+
noPending: true,
|
|
273
|
+
noUploading: true,
|
|
274
|
+
noChat: true
|
|
275
|
+
});
|
|
239
276
|
const [announcement, setAnnouncement] = useState(
|
|
240
277
|
void 0
|
|
241
278
|
);
|
|
@@ -246,10 +283,14 @@ const NotebookView = ({
|
|
|
246
283
|
const handleDeleteDocument = useCallback((documentId) => {
|
|
247
284
|
setDeleteDocumentTarget({ id: documentId, name: documentId });
|
|
248
285
|
}, []);
|
|
286
|
+
const { mutateAsync: renameDocument } = useRenameDocument();
|
|
249
287
|
const onComplete = useCallback(
|
|
250
288
|
(message) => {
|
|
251
289
|
setIsSendButtonDisabled(false);
|
|
252
|
-
|
|
290
|
+
if (!wasStoppedByUserRef.current) {
|
|
291
|
+
setAnnouncement(`Message from Bot: ${message}`);
|
|
292
|
+
}
|
|
293
|
+
wasStoppedByUserRef.current = false;
|
|
253
294
|
queryClient.invalidateQueries({
|
|
254
295
|
queryKey: ["conversationMessages", conversationId]
|
|
255
296
|
});
|
|
@@ -268,6 +309,9 @@ const NotebookView = ({
|
|
|
268
309
|
},
|
|
269
310
|
[notebookCreateMessage, sessionId]
|
|
270
311
|
);
|
|
312
|
+
const onRequestIdReady = useCallback((rid) => {
|
|
313
|
+
setRequestId(rid);
|
|
314
|
+
}, []);
|
|
271
315
|
const { conversationMessages, handleInputPrompt, scrollToBottomRef } = useConversationMessages(
|
|
272
316
|
conversationId,
|
|
273
317
|
userName,
|
|
@@ -276,7 +320,8 @@ const NotebookView = ({
|
|
|
276
320
|
avatar,
|
|
277
321
|
onComplete,
|
|
278
322
|
onStart,
|
|
279
|
-
createMessageAdapter
|
|
323
|
+
createMessageAdapter,
|
|
324
|
+
onRequestIdReady
|
|
280
325
|
);
|
|
281
326
|
const [messages, setMessages] = useState(conversationMessages);
|
|
282
327
|
useEffect(() => {
|
|
@@ -284,6 +329,7 @@ const NotebookView = ({
|
|
|
284
329
|
}, [conversationMessages]);
|
|
285
330
|
const sendMessage = useCallback(
|
|
286
331
|
(message) => {
|
|
332
|
+
wasStoppedByUserRef.current = false;
|
|
287
333
|
setAnnouncement(
|
|
288
334
|
t("conversation.announcement.userMessage", {
|
|
289
335
|
prompt: message.toString()
|
|
@@ -294,11 +340,21 @@ const NotebookView = ({
|
|
|
294
340
|
},
|
|
295
341
|
[handleInputPrompt, t]
|
|
296
342
|
);
|
|
343
|
+
const handleStopButton = useCallback(() => {
|
|
344
|
+
wasStoppedByUserRef.current = true;
|
|
345
|
+
if (requestId) {
|
|
346
|
+
stopConversation(requestId);
|
|
347
|
+
setRequestId("");
|
|
348
|
+
}
|
|
349
|
+
setIsSendButtonDisabled(false);
|
|
350
|
+
setAnnouncement(t("conversation.announcement.responseStopped"));
|
|
351
|
+
}, [requestId, stopConversation, t]);
|
|
297
352
|
const notebookPrompts = useNotebookWelcomePrompts();
|
|
298
353
|
const welcomePrompts = notebookPrompts.map((title) => ({
|
|
299
354
|
title,
|
|
300
355
|
onClick: () => sendMessage(title)
|
|
301
356
|
}));
|
|
357
|
+
const uploadMutation = useUploadDocument();
|
|
302
358
|
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
|
|
303
359
|
const [isUploadModalOpen, setIsUploadModalOpen] = useState(false);
|
|
304
360
|
const [uploadingFileNames, setUploadingFileNames] = useState([]);
|
|
@@ -309,8 +365,56 @@ const NotebookView = ({
|
|
|
309
365
|
/* @__PURE__ */ new Set()
|
|
310
366
|
);
|
|
311
367
|
const [filesToOverwrite, setFilesToOverwrite] = useState([]);
|
|
368
|
+
const [allFilesForOverwrite, setAllFilesForOverwrite] = useState([]);
|
|
312
369
|
const [isOverwriteModalOpen, setIsOverwriteModalOpen] = useState(false);
|
|
313
370
|
const [filesToAddToModal, setFilesToAddToModal] = useState([]);
|
|
371
|
+
autoDeleteRef.current = {
|
|
372
|
+
isUntitled: notebookName === UNTITLED_NOTEBOOK_NAME,
|
|
373
|
+
isEmpty: documents.length === 0 && completedFileNames.size === 0,
|
|
374
|
+
noPending: !pendingUploads.length,
|
|
375
|
+
noUploading: !uploadingFileNames.length,
|
|
376
|
+
noChat: conversationId === TEMP_CONVERSATION_ID
|
|
377
|
+
};
|
|
378
|
+
useEffect(() => {
|
|
379
|
+
return () => {
|
|
380
|
+
const currentNotebook = autoDeleteRef.current;
|
|
381
|
+
if (currentNotebook.isUntitled && currentNotebook.isEmpty && currentNotebook.noPending && currentNotebook.noUploading && currentNotebook.noChat) {
|
|
382
|
+
notebooksApi.deleteSession(sessionId).then(() => {
|
|
383
|
+
queryClient.invalidateQueries({
|
|
384
|
+
queryKey: ["notebooks", "sessions"]
|
|
385
|
+
});
|
|
386
|
+
}).catch(() => {
|
|
387
|
+
});
|
|
388
|
+
} else {
|
|
389
|
+
queryClient.invalidateQueries({
|
|
390
|
+
queryKey: ["notebooks", "sessions"]
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
}, [notebooksApi, sessionId, queryClient]);
|
|
395
|
+
const handleRenameDocument = useCallback(
|
|
396
|
+
async (documentId, newTitle) => {
|
|
397
|
+
try {
|
|
398
|
+
await renameDocument({ sessionId, documentId, newTitle });
|
|
399
|
+
} catch {
|
|
400
|
+
setToastAlerts((prev) => [
|
|
401
|
+
{
|
|
402
|
+
key: Date.now() + documentId,
|
|
403
|
+
title: t("notebook.document.rename.error", {
|
|
404
|
+
documentName: documentId
|
|
405
|
+
}),
|
|
406
|
+
variant: "danger"
|
|
407
|
+
},
|
|
408
|
+
...prev
|
|
409
|
+
]);
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
[renameDocument, sessionId, t]
|
|
413
|
+
);
|
|
414
|
+
const handleRenameNotebook = useRenameNotebookWithAlert({
|
|
415
|
+
setAlerts: setToastAlerts,
|
|
416
|
+
getNotebookName: () => notebookName
|
|
417
|
+
});
|
|
314
418
|
const confirmDeleteDocument = useCallback(async () => {
|
|
315
419
|
if (!deleteDocumentTarget) return;
|
|
316
420
|
const { id: documentId, name: documentName } = deleteDocumentTarget;
|
|
@@ -341,6 +445,9 @@ const NotebookView = ({
|
|
|
341
445
|
}, [deleteDocumentTarget, notebooksApi, sessionId, queryClient, t]);
|
|
342
446
|
const handleOpenUploadModal = () => setIsUploadModalOpen(true);
|
|
343
447
|
const handleCloseUploadModal = () => setIsUploadModalOpen(false);
|
|
448
|
+
const handleCloseNotebook = () => {
|
|
449
|
+
onClose();
|
|
450
|
+
};
|
|
344
451
|
const handleFilesUploading = (files) => {
|
|
345
452
|
setUploadingFileNames((prev) => {
|
|
346
453
|
const newNames = files.map((f) => f.name).filter((name) => !prev.includes(name));
|
|
@@ -367,23 +474,37 @@ const NotebookView = ({
|
|
|
367
474
|
...prev
|
|
368
475
|
]);
|
|
369
476
|
};
|
|
370
|
-
const handleDuplicatesFound = (
|
|
371
|
-
setFilesToOverwrite(
|
|
477
|
+
const handleDuplicatesFound = (duplicateFiles, allFiles) => {
|
|
478
|
+
setFilesToOverwrite(duplicateFiles);
|
|
479
|
+
setAllFilesForOverwrite(allFiles);
|
|
480
|
+
setIsUploadModalOpen(false);
|
|
372
481
|
setIsOverwriteModalOpen(true);
|
|
373
482
|
};
|
|
374
|
-
const handleOverwriteConfirm = () => {
|
|
375
|
-
const files = filesToOverwrite;
|
|
483
|
+
const handleOverwriteConfirm = (filesToUpload) => {
|
|
376
484
|
setIsOverwriteModalOpen(false);
|
|
377
485
|
setFilesToOverwrite([]);
|
|
378
|
-
|
|
379
|
-
|
|
486
|
+
setAllFilesForOverwrite([]);
|
|
487
|
+
if (filesToUpload.length === 0) return;
|
|
488
|
+
runFileUploads(uploadMutation, sessionId, filesToUpload, {
|
|
489
|
+
onUploading: handleFilesUploading,
|
|
490
|
+
onStarted: handleUploadStarted,
|
|
491
|
+
onFailed: handleUploadFailed
|
|
492
|
+
});
|
|
380
493
|
};
|
|
381
494
|
const handleFilesAddedToModal = () => {
|
|
382
495
|
setFilesToAddToModal([]);
|
|
383
496
|
};
|
|
497
|
+
const handleOverwriteBack = () => {
|
|
498
|
+
setIsOverwriteModalOpen(false);
|
|
499
|
+
setFilesToAddToModal(allFilesForOverwrite);
|
|
500
|
+
setFilesToOverwrite([]);
|
|
501
|
+
setAllFilesForOverwrite([]);
|
|
502
|
+
setIsUploadModalOpen(true);
|
|
503
|
+
};
|
|
384
504
|
const handleOverwriteCancel = () => {
|
|
385
505
|
setIsOverwriteModalOpen(false);
|
|
386
506
|
setFilesToOverwrite([]);
|
|
507
|
+
setAllFilesForOverwrite([]);
|
|
387
508
|
};
|
|
388
509
|
const pollingResults = useDocumentStatusPolling(sessionId, pendingUploads);
|
|
389
510
|
useEffect(() => {
|
|
@@ -452,7 +573,9 @@ const NotebookView = ({
|
|
|
452
573
|
hasUploadsInProgress,
|
|
453
574
|
onToggleCollapse: () => setSidebarCollapsed((prev) => !prev),
|
|
454
575
|
onAddDocument: handleOpenUploadModal,
|
|
455
|
-
onDeleteDocument: handleDeleteDocument
|
|
576
|
+
onDeleteDocument: handleDeleteDocument,
|
|
577
|
+
onRenameDocument: handleRenameDocument,
|
|
578
|
+
onRenameNotebook: (newName) => handleRenameNotebook(sessionId, newName)
|
|
456
579
|
}
|
|
457
580
|
)
|
|
458
581
|
}
|
|
@@ -594,7 +717,7 @@ const NotebookView = ({
|
|
|
594
717
|
{
|
|
595
718
|
variant: "link",
|
|
596
719
|
className: classes.closeButton,
|
|
597
|
-
onClick:
|
|
720
|
+
onClick: handleCloseNotebook,
|
|
598
721
|
icon: /* @__PURE__ */ jsx(TimesIcon, {}),
|
|
599
722
|
iconPosition: "end",
|
|
600
723
|
children: t("notebook.view.close")
|
|
@@ -603,35 +726,70 @@ const NotebookView = ({
|
|
|
603
726
|
/* @__PURE__ */ jsx("div", { className: classes.mainContent, children: renderMainContent() }),
|
|
604
727
|
hasNoDocuments && messages.length === 0 && renderNotebookDisclaimerAlert(),
|
|
605
728
|
/* @__PURE__ */ jsxs(ChatbotFooter, { className: classes.footer, children: [
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
729
|
+
(() => {
|
|
730
|
+
const addResourceAction = /* @__PURE__ */ jsx(
|
|
731
|
+
"button",
|
|
732
|
+
{
|
|
733
|
+
type: "button",
|
|
734
|
+
onClick: () => handleOpenUploadModal(),
|
|
735
|
+
"aria-label": t("notebook.view.documents.add"),
|
|
736
|
+
className: classes.addResourceButton,
|
|
737
|
+
children: /* @__PURE__ */ jsx(PlusIcon, { style: { width: 16, height: 16 } })
|
|
738
|
+
}
|
|
739
|
+
);
|
|
740
|
+
return hasNoDocuments ? /* @__PURE__ */ jsx(
|
|
741
|
+
Tooltip,
|
|
742
|
+
{
|
|
743
|
+
content: t("notebook.view.input.disabledTooltip"),
|
|
744
|
+
position: "top",
|
|
745
|
+
children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
|
|
746
|
+
MessageBar,
|
|
747
|
+
{
|
|
748
|
+
className: classes.messageBar,
|
|
749
|
+
hasAttachButton: false,
|
|
750
|
+
hasMicrophoneButton: false,
|
|
751
|
+
hasStopButton: false,
|
|
752
|
+
isSendButtonDisabled: true,
|
|
753
|
+
isDisabled: true,
|
|
754
|
+
onSendMessage: sendMessage,
|
|
755
|
+
placeholder: t("notebook.view.input.placeholder"),
|
|
756
|
+
forceMultilineLayout: true,
|
|
757
|
+
additionalActions: addResourceAction,
|
|
758
|
+
buttonProps: {
|
|
759
|
+
send: {
|
|
760
|
+
tooltipContent: t("tooltip.send")
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
) })
|
|
765
|
+
}
|
|
766
|
+
) : /* @__PURE__ */ jsx(
|
|
767
|
+
MessageBar,
|
|
768
|
+
{
|
|
769
|
+
className: classes.messageBar,
|
|
770
|
+
hasAttachButton: false,
|
|
771
|
+
hasMicrophoneButton: true,
|
|
772
|
+
hasStopButton: isSendButtonDisabled,
|
|
773
|
+
handleStopButton: isSendButtonDisabled ? handleStopButton : void 0,
|
|
774
|
+
isSendButtonDisabled,
|
|
775
|
+
onSendMessage: sendMessage,
|
|
776
|
+
placeholder: t("notebook.view.input.placeholder"),
|
|
777
|
+
forceMultilineLayout: true,
|
|
778
|
+
additionalActions: addResourceAction,
|
|
779
|
+
buttonProps: {
|
|
780
|
+
microphone: {
|
|
781
|
+
tooltipContent: {
|
|
782
|
+
active: t("tooltip.microphone.active"),
|
|
783
|
+
inactive: t("tooltip.microphone.inactive")
|
|
784
|
+
}
|
|
785
|
+
},
|
|
786
|
+
send: {
|
|
787
|
+
tooltipContent: t("tooltip.send")
|
|
788
|
+
}
|
|
621
789
|
}
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
)
|
|
625
|
-
MessageBar,
|
|
626
|
-
{
|
|
627
|
-
hasAttachButton: false,
|
|
628
|
-
hasMicrophoneButton: true,
|
|
629
|
-
hasStopButton: false,
|
|
630
|
-
isSendButtonDisabled,
|
|
631
|
-
onSendMessage: sendMessage,
|
|
632
|
-
placeholder: t("notebook.view.input.placeholder")
|
|
633
|
-
}
|
|
634
|
-
),
|
|
790
|
+
}
|
|
791
|
+
);
|
|
792
|
+
})(),
|
|
635
793
|
/* @__PURE__ */ jsx(ChatbotFootnoteWithIcon, { label: t("footer.accuracy.label") })
|
|
636
794
|
] })
|
|
637
795
|
] })
|
|
@@ -662,7 +820,9 @@ const NotebookView = ({
|
|
|
662
820
|
isOpen: isOverwriteModalOpen,
|
|
663
821
|
onClose: handleOverwriteCancel,
|
|
664
822
|
onConfirm: handleOverwriteConfirm,
|
|
665
|
-
|
|
823
|
+
onBack: handleOverwriteBack,
|
|
824
|
+
allFiles: allFilesForOverwrite,
|
|
825
|
+
duplicateFileNames: filesToOverwrite.map((f) => f.name)
|
|
666
826
|
}
|
|
667
827
|
),
|
|
668
828
|
/* @__PURE__ */ jsx(
|