@red-hat-developer-hub/backstage-plugin-intelligent-assistant 5.0.1 → 5.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.
Files changed (121) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/alpha.d.ts +1 -9
  3. package/dist/components/Attachment.esm.js +10 -12
  4. package/dist/components/Attachment.esm.js.map +1 -1
  5. package/dist/components/CollapsedHistoryStrip.esm.js +46 -51
  6. package/dist/components/CollapsedHistoryStrip.esm.js.map +1 -1
  7. package/dist/components/FilePreview.esm.js +3 -2
  8. package/dist/components/FilePreview.esm.js.map +1 -1
  9. package/dist/components/LightSpeedChat.esm.js +655 -787
  10. package/dist/components/LightSpeedChat.esm.js.map +1 -1
  11. package/dist/components/LightspeedChatBox.esm.js +2 -3
  12. package/dist/components/LightspeedChatBox.esm.js.map +1 -1
  13. package/dist/components/LightspeedChatBoxHeader.esm.js +40 -35
  14. package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -1
  15. package/dist/components/LightspeedChatContainer.esm.js +43 -67
  16. package/dist/components/LightspeedChatContainer.esm.js.map +1 -1
  17. package/dist/components/LightspeedChatModelsState.esm.js +67 -73
  18. package/dist/components/LightspeedChatModelsState.esm.js.map +1 -1
  19. package/dist/components/LightspeedDrawerContext.esm.js.map +1 -1
  20. package/dist/components/LightspeedDrawerProvider.esm.js +13 -16
  21. package/dist/components/LightspeedDrawerProvider.esm.js.map +1 -1
  22. package/dist/components/LightspeedFABContent.esm.js +49 -9
  23. package/dist/components/LightspeedFABContent.esm.js.map +1 -1
  24. package/dist/components/LightspeedPage.esm.js +12 -12
  25. package/dist/components/LightspeedPage.esm.js.map +1 -1
  26. package/dist/components/McpConfigureServerModal.esm.js +81 -89
  27. package/dist/components/McpConfigureServerModal.esm.js.map +1 -1
  28. package/dist/components/McpServersSettings.esm.js +259 -239
  29. package/dist/components/McpServersSettings.esm.js.map +1 -1
  30. package/dist/components/MessageBarModelSelector.esm.js +29 -33
  31. package/dist/components/MessageBarModelSelector.esm.js.map +1 -1
  32. package/dist/components/RenameConversationModal.esm.js +38 -31
  33. package/dist/components/RenameConversationModal.esm.js.map +1 -1
  34. package/dist/components/Router.esm.js +4 -13
  35. package/dist/components/Router.esm.js.map +1 -1
  36. package/dist/components/ToastAlertGroup.esm.js +24 -40
  37. package/dist/components/ToastAlertGroup.esm.js.map +1 -1
  38. package/dist/components/ToolCallContent.esm.js +8 -11
  39. package/dist/components/ToolCallContent.esm.js.map +1 -1
  40. package/dist/components/notebooks/AddDocumentModal.esm.js +232 -252
  41. package/dist/components/notebooks/AddDocumentModal.esm.js.map +1 -1
  42. package/dist/components/notebooks/DeleteDocumentModal.esm.js +35 -77
  43. package/dist/components/notebooks/DeleteDocumentModal.esm.js.map +1 -1
  44. package/dist/components/notebooks/DeleteNotebookModal.esm.js +46 -81
  45. package/dist/components/notebooks/DeleteNotebookModal.esm.js.map +1 -1
  46. package/dist/components/notebooks/DocumentSidebar.esm.js +172 -196
  47. package/dist/components/notebooks/DocumentSidebar.esm.js.map +1 -1
  48. package/dist/components/notebooks/FileListItem.esm.js +69 -57
  49. package/dist/components/notebooks/FileListItem.esm.js.map +1 -1
  50. package/dist/components/notebooks/FileTypeIcon.esm.js +17 -27
  51. package/dist/components/notebooks/FileTypeIcon.esm.js.map +1 -1
  52. package/dist/components/notebooks/NotebookCard.esm.js +86 -25
  53. package/dist/components/notebooks/NotebookCard.esm.js.map +1 -1
  54. package/dist/components/notebooks/NotebookView.esm.js +367 -380
  55. package/dist/components/notebooks/NotebookView.esm.js.map +1 -1
  56. package/dist/components/notebooks/NotebooksTab.esm.js +93 -30
  57. package/dist/components/notebooks/NotebooksTab.esm.js.map +1 -1
  58. package/dist/components/notebooks/OverwriteConfirmModal.esm.js +142 -184
  59. package/dist/components/notebooks/OverwriteConfirmModal.esm.js.map +1 -1
  60. package/dist/components/notebooks/UploadResourceScreen.esm.js +58 -50
  61. package/dist/components/notebooks/UploadResourceScreen.esm.js.map +1 -1
  62. package/dist/components/notebooks/notebookDialogStyles.esm.js +33 -37
  63. package/dist/components/notebooks/notebookDialogStyles.esm.js.map +1 -1
  64. package/dist/const.esm.js +15 -2
  65. package/dist/const.esm.js.map +1 -1
  66. package/dist/hooks/useAllModels.esm.js +2 -1
  67. package/dist/hooks/useAllModels.esm.js.map +1 -1
  68. package/dist/hooks/useAutoScroll.esm.js +11 -11
  69. package/dist/hooks/useAutoScroll.esm.js.map +1 -1
  70. package/dist/hooks/useBufferedMessages.esm.js +5 -5
  71. package/dist/hooks/useBufferedMessages.esm.js.map +1 -1
  72. package/dist/hooks/useConversations.esm.js +2 -1
  73. package/dist/hooks/useConversations.esm.js.map +1 -1
  74. package/dist/hooks/useIaChatPermission.esm.js +15 -0
  75. package/dist/hooks/useIaChatPermission.esm.js.map +1 -0
  76. package/dist/hooks/useIaMcpToolsPermission.esm.js +15 -0
  77. package/dist/hooks/useIaMcpToolsPermission.esm.js.map +1 -0
  78. package/dist/hooks/{notebooks/useLightspeedNotebooksPermission.esm.js → useIaNotebooksPermission.esm.js} +4 -5
  79. package/dist/hooks/useIaNotebooksPermission.esm.js.map +1 -0
  80. package/dist/hooks/useIsMobile.esm.js +3 -3
  81. package/dist/hooks/useIsMobile.esm.js.map +1 -1
  82. package/dist/hooks/useMcpConfigureModal.esm.js +5 -9
  83. package/dist/hooks/useMcpConfigureModal.esm.js.map +1 -1
  84. package/dist/hooks/useNotebookConversationIds.esm.js +2 -1
  85. package/dist/hooks/useNotebookConversationIds.esm.js.map +1 -1
  86. package/dist/hooks/useQuestionValidation.esm.js +3 -2
  87. package/dist/hooks/useQuestionValidation.esm.js.map +1 -1
  88. package/dist/hooks/useWelcomePrompts.esm.js +2 -2
  89. package/dist/hooks/useWelcomePrompts.esm.js.map +1 -1
  90. package/dist/translations/de.esm.js +1 -9
  91. package/dist/translations/de.esm.js.map +1 -1
  92. package/dist/translations/es.esm.js +1 -9
  93. package/dist/translations/es.esm.js.map +1 -1
  94. package/dist/translations/fr.esm.js +1 -9
  95. package/dist/translations/fr.esm.js.map +1 -1
  96. package/dist/translations/it.esm.js +1 -9
  97. package/dist/translations/it.esm.js.map +1 -1
  98. package/dist/translations/ja.esm.js +1 -9
  99. package/dist/translations/ja.esm.js.map +1 -1
  100. package/dist/translations/ref.esm.js +1 -10
  101. package/dist/translations/ref.esm.js.map +1 -1
  102. package/dist/types.esm.js.map +1 -1
  103. package/dist/utils/fab-anchor-utils.esm.js +41 -0
  104. package/dist/utils/fab-anchor-utils.esm.js.map +1 -0
  105. package/dist/utils/scoped-dialog-utils.esm.js +6 -3
  106. package/dist/utils/scoped-dialog-utils.esm.js.map +1 -1
  107. package/package.json +5 -8
  108. package/dist/components/PermissionRequiredIcon.esm.js +0 -18
  109. package/dist/components/PermissionRequiredIcon.esm.js.map +0 -1
  110. package/dist/components/PermissionRequiredState.esm.js +0 -88
  111. package/dist/components/PermissionRequiredState.esm.js.map +0 -1
  112. package/dist/hooks/notebooks/useLightspeedNotebooksPermission.esm.js.map +0 -1
  113. package/dist/hooks/useLightspeedDeletePermission.esm.js +0 -12
  114. package/dist/hooks/useLightspeedDeletePermission.esm.js.map +0 -1
  115. package/dist/hooks/useLightspeedUpdatePermission.esm.js +0 -12
  116. package/dist/hooks/useLightspeedUpdatePermission.esm.js.map +0 -1
  117. package/dist/hooks/useLightspeedViewPermission.esm.js +0 -16
  118. package/dist/hooks/useLightspeedViewPermission.esm.js.map +0 -1
  119. package/dist/images/permission-required.svg +0 -319
  120. package/dist/utils/generateClassName.esm.js +0 -12
  121. package/dist/utils/generateClassName.esm.js.map +0 -1
@@ -1,36 +1,52 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { useState, useCallback, useEffect } from 'react';
3
3
  import { useApi, configApiRef, fetchApiRef } from '@backstage/core-plugin-api';
4
- import { usePermission } from '@backstage/plugin-permission-react';
5
- import { makeStyles } from '@material-ui/core';
4
+ import GlobalStyles from '@mui/material/GlobalStyles';
5
+ import { styled } from '@mui/material/styles';
6
6
  import Typography from '@mui/material/Typography';
7
7
  import { Title, Button, Alert, Switch, Tooltip } from '@patternfly/react-core';
8
8
  import { TimesIcon, PencilAltIcon, SortAmountDownIcon, KeyIcon, InfoCircleIcon, ExclamationCircleIcon, CheckCircleIcon, SortAmountUpIcon } from '@patternfly/react-icons';
9
9
  import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
10
- import { iaMcpToolsPermission } from '@red-hat-developer-hub/backstage-plugin-intelligent-assistant-common';
10
+ import { useIaMcpToolsPermission } from '../hooks/useIaMcpToolsPermission.esm.js';
11
11
  import { useMcpConfigureModal } from '../hooks/useMcpConfigureModal.esm.js';
12
12
  import { useTranslation } from '../hooks/useTranslation.esm.js';
13
13
  import { McpConfigureServerModal } from './McpConfigureServerModal.esm.js';
14
14
  import { formatApiError, getDisplayStatus, compareMcpServers, getDisplayDetail, getEnabledToggleChecked, isEnabledToggleUnavailable } from './mcpServersDisplayUtils.esm.js';
15
15
 
16
- const useStyles = makeStyles((theme) => ({
17
- "@global": {
18
- ".pf-v6-c-backdrop": {
19
- zIndex: "1400 !important"
20
- },
21
- ".pf-v5-c-backdrop": {
22
- zIndex: "1400 !important"
23
- }
24
- },
25
- root: {
26
- padding: 0,
27
- height: "100%",
28
- minHeight: 0,
29
- flex: 1,
30
- width: "100%",
31
- overflow: "auto"
32
- },
33
- headerRow: {
16
+ const mcpClasses = {
17
+ headerRow: "ia-mcp-headerRow",
18
+ selectedCount: "ia-mcp-selectedCount",
19
+ title: "ia-mcp-title",
20
+ closeButton: "ia-mcp-closeButton",
21
+ nameHeaderButton: "ia-mcp-nameHeaderButton",
22
+ statusHeaderButton: "ia-mcp-statusHeaderButton",
23
+ sortHeaderIconActive: "ia-mcp-sortHeaderIconActive",
24
+ sortHeaderIconInactive: "ia-mcp-sortHeaderIconInactive",
25
+ nameHeaderText: "ia-mcp-nameHeaderText",
26
+ nameCell: "ia-mcp-nameCell",
27
+ statusHeader: "ia-mcp-statusHeader",
28
+ statusColumnCell: "ia-mcp-statusColumnCell",
29
+ rowName: "ia-mcp-rowName",
30
+ nameValue: "ia-mcp-nameValue",
31
+ statusCell: "ia-mcp-statusCell",
32
+ statusValue: "ia-mcp-statusValue",
33
+ statusOk: "ia-mcp-statusOk",
34
+ statusWarn: "ia-mcp-statusWarn",
35
+ statusDisabled: "ia-mcp-statusDisabled",
36
+ actionButton: "ia-mcp-actionButton",
37
+ tableRow: "ia-mcp-tableRow",
38
+ toggleCell: "ia-mcp-toggleCell",
39
+ table: "ia-mcp-table",
40
+ alert: "ia-mcp-alert"
41
+ };
42
+ const StyledMcpRoot = styled("div")(({ theme }) => ({
43
+ padding: 0,
44
+ height: "100%",
45
+ minHeight: 0,
46
+ flex: 1,
47
+ width: "100%",
48
+ overflow: "auto",
49
+ [`& .${mcpClasses.headerRow}`]: {
34
50
  display: "flex",
35
51
  alignItems: "flex-start",
36
52
  justifyContent: "space-between",
@@ -39,20 +55,20 @@ const useStyles = makeStyles((theme) => ({
39
55
  marginLeft: theme.spacing(3),
40
56
  marginRight: theme.spacing(2)
41
57
  },
42
- selectedCount: {
58
+ [`& .${mcpClasses.selectedCount}`]: {
43
59
  color: theme.palette.text.secondary,
44
60
  marginTop: theme.spacing(0.5),
45
61
  fontSize: "0.75rem"
46
62
  },
47
- title: {
63
+ [`& .${mcpClasses.title}`]: {
48
64
  fontSize: "1.125rem"
49
65
  },
50
- closeButton: {
51
- marginTop: -theme.spacing(1),
52
- marginRight: -theme.spacing(1),
66
+ [`& .${mcpClasses.closeButton}`]: {
67
+ marginTop: theme.spacing(-1),
68
+ marginRight: theme.spacing(-1),
53
69
  color: theme.palette.text.primary
54
70
  },
55
- nameHeaderButton: {
71
+ [`& .${mcpClasses.nameHeaderButton}`]: {
56
72
  paddingLeft: 0,
57
73
  paddingTop: 0,
58
74
  paddingBottom: 0,
@@ -66,7 +82,7 @@ const useStyles = makeStyles((theme) => ({
66
82
  display: "inline-flex",
67
83
  alignItems: "center"
68
84
  },
69
- statusHeaderButton: {
85
+ [`& .${mcpClasses.statusHeaderButton}`]: {
70
86
  paddingLeft: 0,
71
87
  paddingTop: 0,
72
88
  paddingBottom: 0,
@@ -79,68 +95,66 @@ const useStyles = makeStyles((theme) => ({
79
95
  display: "inline-flex",
80
96
  alignItems: "center"
81
97
  },
82
- sortHeaderIconActive: {
98
+ [`& .${mcpClasses.sortHeaderIconActive}`]: {
83
99
  color: "var(--pf-t--global--icon--color--brand--default)"
84
100
  },
85
- sortHeaderIconInactive: {
101
+ [`& .${mcpClasses.sortHeaderIconInactive}`]: {
86
102
  color: "var(--pf-t--global--icon--color--subtle)"
87
103
  },
88
- nameHeaderText: {
104
+ [`& .${mcpClasses.nameHeaderText}`]: {
89
105
  paddingLeft: "7px",
90
106
  fontSize: "0.75rem",
91
107
  lineHeight: "1.25rem",
92
108
  fontWeight: 600
93
109
  },
94
- nameCell: {
110
+ [`& .${mcpClasses.nameCell}`]: {
95
111
  paddingLeft: "8px !important"
96
112
  },
97
- statusHeader: {
113
+ [`& .${mcpClasses.statusHeader}`]: {
98
114
  paddingLeft: "0 !important"
99
115
  },
100
- statusColumnCell: {
116
+ [`& .${mcpClasses.statusColumnCell}`]: {
101
117
  paddingLeft: "0 !important"
102
118
  },
103
- rowName: {
119
+ [`& .${mcpClasses.rowName}`]: {
104
120
  fontSize: "1rem",
105
121
  fontWeight: 500,
106
122
  whiteSpace: "nowrap"
107
123
  },
108
- nameValue: {
124
+ [`& .${mcpClasses.nameValue}`]: {
109
125
  fontSize: "0.875rem",
110
126
  fontWeight: 500
111
127
  },
112
- statusCell: {
128
+ [`& .${mcpClasses.statusCell}`]: {
113
129
  display: "flex",
114
130
  alignItems: "center",
115
131
  gap: theme.spacing(1),
116
132
  whiteSpace: "nowrap"
117
133
  },
118
- statusValue: {
134
+ [`& .${mcpClasses.statusValue}`]: {
119
135
  fontSize: "0.875rem"
120
136
  },
121
- statusOk: {
137
+ [`& .${mcpClasses.statusOk}`]: {
122
138
  color: "var(--pf-t--global--icon--color--status--custom--default)"
123
139
  },
124
- statusWarn: {
140
+ [`& .${mcpClasses.statusWarn}`]: {
125
141
  color: "var(--pf-t--global--icon--color--status--danger--default)"
126
142
  },
127
- statusDisabled: {
143
+ [`& .${mcpClasses.statusDisabled}`]: {
128
144
  color: "var(--pf-t--global--icon--color--subtle)"
129
145
  },
130
- actionButton: {
146
+ [`& .${mcpClasses.actionButton}`]: {
131
147
  color: theme.palette.text.secondary,
132
148
  opacity: 0,
133
149
  transition: "opacity 0.15s ease-in-out"
134
150
  },
135
- tableRow: {
136
- "&:hover $actionButton, &:focus-within $actionButton": {
137
- opacity: 1
138
- }
151
+ [`& .${mcpClasses.tableRow}:hover .${mcpClasses.actionButton}, & .${mcpClasses.tableRow}:focus-within .${mcpClasses.actionButton}`]: {
152
+ opacity: 1
139
153
  },
140
- toggleCell: {
154
+ [`& .${mcpClasses.toggleCell}`]: {
141
155
  paddingRight: "0 !important"
142
156
  },
143
- table: {
157
+ [`& .${mcpClasses.table}`]: {
144
158
  width: "100%",
145
159
  backgroundColor: "transparent",
146
160
  "--pf-v6-c-table--BackgroundColor": "transparent",
@@ -163,7 +177,7 @@ const useStyles = makeStyles((theme) => ({
163
177
  verticalAlign: "middle"
164
178
  }
165
179
  },
166
- alert: {
180
+ [`& .${mcpClasses.alert}`]: {
167
181
  marginLeft: theme.spacing(3),
168
182
  marginRight: theme.spacing(3),
169
183
  marginBottom: theme.spacing(2)
@@ -193,14 +207,10 @@ const McpServersSettings = ({
193
207
  onClose,
194
208
  backgroundColor
195
209
  }) => {
196
- const classes = useStyles();
197
210
  const { t } = useTranslation();
198
211
  const configApi = useApi(configApiRef);
199
212
  const fetchApi = useApi(fetchApiRef);
200
- const mcpToolsPermission = usePermission({
201
- permission: iaMcpToolsPermission
202
- });
203
- const canManageMcp = mcpToolsPermission.allowed;
213
+ const { allowed: hasMcpToolsAccess, loading: mcpToolsPermissionLoading } = useIaMcpToolsPermission();
204
214
  const [servers, setServers] = useState([]);
205
215
  const [sortColumn, setSortColumn] = useState("name");
206
216
  const [sortAsc, setSortAsc] = useState(true);
@@ -289,20 +299,18 @@ const McpServersSettings = ({
289
299
  );
290
300
  const uiServers = (data.servers ?? []).map((server) => toUiServer(server));
291
301
  setServers(uiServers);
292
- if (canManageMcp) {
293
- const serversToValidate = uiServers.filter((server) => server.hasToken);
294
- void Promise.allSettled(
295
- serversToValidate.map(async (server) => {
296
- try {
297
- await validateServer(server.name);
298
- } catch (validationError) {
299
- setError(
300
- (prev) => prev ?? (validationError instanceof Error ? validationError.message : `Failed to validate ${server.name}`)
301
- );
302
- }
303
- })
304
- );
305
- }
302
+ const serversToValidate = uiServers.filter((server) => server.hasToken);
303
+ void Promise.allSettled(
304
+ serversToValidate.map(async (server) => {
305
+ try {
306
+ await validateServer(server.name);
307
+ } catch (validationError) {
308
+ setError(
309
+ (prev) => prev ?? (validationError instanceof Error ? validationError.message : `Failed to validate ${server.name}`)
310
+ );
311
+ }
312
+ })
313
+ );
306
314
  } catch (e) {
307
315
  setError(
308
316
  e instanceof Error ? e.message : "Failed to load MCP server settings"
@@ -310,15 +318,15 @@ const McpServersSettings = ({
310
318
  } finally {
311
319
  setIsLoading(false);
312
320
  }
313
- }, [canManageMcp, fetchJson, getBaseUrl, validateServer]);
321
+ }, [fetchJson, getBaseUrl, validateServer]);
314
322
  useEffect(() => {
323
+ if (mcpToolsPermissionLoading || !hasMcpToolsAccess) {
324
+ return;
325
+ }
315
326
  loadServers();
316
- }, [loadServers]);
327
+ }, [loadServers, mcpToolsPermissionLoading, hasMcpToolsAccess]);
317
328
  const patchServer = useCallback(
318
329
  async (serverName, body) => {
319
- if (!canManageMcp) {
320
- return;
321
- }
322
330
  setError(null);
323
331
  setIsSaving((prev) => ({ ...prev, [serverName]: true }));
324
332
  try {
@@ -348,11 +356,10 @@ const McpServersSettings = ({
348
356
  setIsSaving((prev) => ({ ...prev, [serverName]: false }));
349
357
  }
350
358
  },
351
- [canManageMcp, fetchJson, getBaseUrl, loadServers]
359
+ [fetchJson, getBaseUrl, loadServers]
352
360
  );
353
361
  const configureModal = useMcpConfigureModal({
354
362
  servers,
355
- canManageMcp,
356
363
  isSaving,
357
364
  patchServer,
358
365
  validateServer,
@@ -384,187 +391,200 @@ const McpServersSettings = ({
384
391
  return /* @__PURE__ */ jsx(
385
392
  Icon,
386
393
  {
387
- className: isActive ? classes.sortHeaderIconActive : classes.sortHeaderIconInactive
394
+ className: isActive ? mcpClasses.sortHeaderIconActive : mcpClasses.sortHeaderIconInactive
388
395
  }
389
396
  );
390
397
  };
391
- return /* @__PURE__ */ jsxs(
392
- "div",
393
- {
394
- className: classes.root,
395
- style: backgroundColor ? { backgroundColor } : void 0,
396
- children: [
397
- /* @__PURE__ */ jsxs("div", { className: classes.headerRow, children: [
398
- /* @__PURE__ */ jsxs("div", { children: [
399
- /* @__PURE__ */ jsx(Title, { headingLevel: "h2", size: "xl", className: classes.title, children: t("mcp.settings.title") }),
400
- /* @__PURE__ */ jsx("div", { className: classes.selectedCount, children: t("mcp.settings.selectedCount", {
401
- selectedCount: String(selectedCount),
402
- totalCount: String(servers.length)
403
- }) })
404
- ] }),
405
- /* @__PURE__ */ jsx(
406
- Button,
407
- {
408
- "aria-label": t("mcp.settings.closeAriaLabel"),
409
- icon: /* @__PURE__ */ jsx(TimesIcon, {}),
410
- variant: "plain",
411
- className: classes.closeButton,
412
- onClick: onClose
413
- }
414
- )
415
- ] }),
416
- error && /* @__PURE__ */ jsx(
417
- Alert,
418
- {
419
- variant: "danger",
420
- isInline: true,
421
- title: error,
422
- className: classes.alert
423
- }
424
- ),
425
- !mcpToolsPermission.loading && !canManageMcp && /* @__PURE__ */ jsx(
426
- Alert,
427
- {
428
- variant: "info",
429
- isInline: true,
430
- title: t("mcp.settings.readOnlyAccess"),
431
- className: classes.alert
398
+ if (mcpToolsPermissionLoading || !hasMcpToolsAccess) {
399
+ return null;
400
+ }
401
+ return /* @__PURE__ */ jsxs(StyledMcpRoot, { style: backgroundColor ? { backgroundColor } : void 0, children: [
402
+ /* @__PURE__ */ jsx(
403
+ GlobalStyles,
404
+ {
405
+ styles: {
406
+ ".pf-v6-c-backdrop": {
407
+ zIndex: "1400 !important"
408
+ },
409
+ ".pf-v5-c-backdrop": {
410
+ zIndex: "1400 !important"
432
411
  }
433
- ),
434
- /* @__PURE__ */ jsxs(
435
- Table,
436
- {
437
- variant: "compact",
438
- "aria-label": t("mcp.settings.tableAriaLabel"),
439
- className: classes.table,
440
- children: [
441
- /* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
442
- /* @__PURE__ */ jsx(Th, { width: 10, screenReaderText: t("mcp.settings.enabled") }),
443
- /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(
444
- Button,
412
+ }
413
+ }
414
+ ),
415
+ /* @__PURE__ */ jsxs("div", { className: mcpClasses.headerRow, children: [
416
+ /* @__PURE__ */ jsxs("div", { children: [
417
+ /* @__PURE__ */ jsx(Title, { headingLevel: "h2", size: "xl", className: mcpClasses.title, children: t("mcp.settings.title") }),
418
+ /* @__PURE__ */ jsx("div", { className: mcpClasses.selectedCount, children: t("mcp.settings.selectedCount", {
419
+ selectedCount: String(selectedCount),
420
+ totalCount: String(servers.length)
421
+ }) })
422
+ ] }),
423
+ /* @__PURE__ */ jsx(
424
+ Button,
425
+ {
426
+ "aria-label": t("mcp.settings.closeAriaLabel"),
427
+ icon: /* @__PURE__ */ jsx(TimesIcon, {}),
428
+ variant: "plain",
429
+ className: mcpClasses.closeButton,
430
+ onClick: onClose
431
+ }
432
+ )
433
+ ] }),
434
+ error && /* @__PURE__ */ jsx(
435
+ Alert,
436
+ {
437
+ variant: "danger",
438
+ isInline: true,
439
+ title: error,
440
+ className: mcpClasses.alert
441
+ }
442
+ ),
443
+ /* @__PURE__ */ jsxs(
444
+ Table,
445
+ {
446
+ variant: "compact",
447
+ "aria-label": t("mcp.settings.tableAriaLabel"),
448
+ className: mcpClasses.table,
449
+ children: [
450
+ /* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
451
+ /* @__PURE__ */ jsx(Th, { width: 10, screenReaderText: t("mcp.settings.enabled") }),
452
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(
453
+ Button,
454
+ {
455
+ variant: "link",
456
+ className: mcpClasses.nameHeaderButton,
457
+ icon: renderSortIcon("name"),
458
+ iconPosition: "right",
459
+ onClick: () => onSortColumnClick("name"),
460
+ children: /* @__PURE__ */ jsx(
461
+ Typography,
445
462
  {
446
- variant: "link",
447
- className: classes.nameHeaderButton,
448
- icon: renderSortIcon("name"),
449
- iconPosition: "right",
450
- onClick: () => onSortColumnClick("name"),
451
- children: /* @__PURE__ */ jsx(Typography, { component: "span", className: classes.nameHeaderText, children: t("mcp.settings.name") })
463
+ component: "span",
464
+ className: mcpClasses.nameHeaderText,
465
+ children: t("mcp.settings.name")
452
466
  }
453
- ) }),
454
- /* @__PURE__ */ jsx(Th, { className: classes.statusHeader, children: /* @__PURE__ */ jsx(
455
- Button,
467
+ )
468
+ }
469
+ ) }),
470
+ /* @__PURE__ */ jsx(Th, { className: mcpClasses.statusHeader, children: /* @__PURE__ */ jsx(
471
+ Button,
472
+ {
473
+ variant: "link",
474
+ className: mcpClasses.statusHeaderButton,
475
+ icon: renderSortIcon("status"),
476
+ iconPosition: "right",
477
+ onClick: () => onSortColumnClick("status"),
478
+ children: /* @__PURE__ */ jsx(
479
+ Typography,
456
480
  {
457
- variant: "link",
458
- className: classes.statusHeaderButton,
459
- icon: renderSortIcon("status"),
460
- iconPosition: "right",
461
- onClick: () => onSortColumnClick("status"),
462
- children: /* @__PURE__ */ jsx(Typography, { component: "span", className: classes.nameHeaderText, children: t("mcp.settings.status") })
463
- }
464
- ) }),
465
- /* @__PURE__ */ jsx(Th, { screenReaderText: t("mcp.settings.edit") })
466
- ] }) }),
467
- /* @__PURE__ */ jsxs(Tbody, { children: [
468
- isLoading && /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: 4, children: t("mcp.settings.loading") }) }),
469
- !isLoading && sortedServers.length === 0 && /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: 4, children: t("mcp.settings.noneAvailable") }) }),
470
- sortedServers.map((server) => {
471
- const displayStatus = getDisplayStatus(server);
472
- const displayDetail = getDisplayDetail(server, displayStatus, t);
473
- let statusClass = classes.statusWarn;
474
- if (displayStatus === "ok") {
475
- statusClass = classes.statusOk;
476
- } else if (displayStatus === "disabled") {
477
- statusClass = classes.statusDisabled;
481
+ component: "span",
482
+ className: mcpClasses.nameHeaderText,
483
+ children: t("mcp.settings.status")
478
484
  }
479
- return /* @__PURE__ */ jsxs(Tr, { className: classes.tableRow, children: [
480
- /* @__PURE__ */ jsx(Td, { width: 10, className: classes.toggleCell, children: (() => {
481
- const isUnavailable = isEnabledToggleUnavailable(displayStatus);
482
- const isChecked = getEnabledToggleChecked(
483
- server,
484
- displayStatus
485
- );
486
- const isRowSaving = Boolean(isSaving[server.name]);
487
- const isToggleDisabled = isUnavailable || isRowSaving || !canManageMcp;
488
- const switchControl = /* @__PURE__ */ jsx(
489
- Switch,
485
+ )
486
+ }
487
+ ) }),
488
+ /* @__PURE__ */ jsx(Th, { screenReaderText: t("mcp.settings.edit") })
489
+ ] }) }),
490
+ /* @__PURE__ */ jsxs(Tbody, { children: [
491
+ isLoading && /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: 4, children: t("mcp.settings.loading") }) }),
492
+ !isLoading && sortedServers.length === 0 && /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: 4, children: t("mcp.settings.noneAvailable") }) }),
493
+ sortedServers.map((server) => {
494
+ const displayStatus = getDisplayStatus(server);
495
+ const displayDetail = getDisplayDetail(server, displayStatus, t);
496
+ let statusClass = mcpClasses.statusWarn;
497
+ if (displayStatus === "ok") {
498
+ statusClass = mcpClasses.statusOk;
499
+ } else if (displayStatus === "disabled") {
500
+ statusClass = mcpClasses.statusDisabled;
501
+ }
502
+ return /* @__PURE__ */ jsxs(Tr, { className: mcpClasses.tableRow, children: [
503
+ /* @__PURE__ */ jsx(Td, { width: 10, className: mcpClasses.toggleCell, children: (() => {
504
+ const isUnavailable = isEnabledToggleUnavailable(displayStatus);
505
+ const isChecked = getEnabledToggleChecked(
506
+ server,
507
+ displayStatus
508
+ );
509
+ const isRowSaving = Boolean(isSaving[server.name]);
510
+ const isToggleDisabled = isUnavailable || isRowSaving;
511
+ const switchControl = /* @__PURE__ */ jsx(
512
+ Switch,
513
+ {
514
+ id: `mcp-switch-${server.id}`,
515
+ "aria-label": t(
516
+ "mcp.settings.toggleServerAriaLabel",
490
517
  {
491
- id: `mcp-switch-${server.id}`,
492
- "aria-label": t(
493
- "mcp.settings.toggleServerAriaLabel",
494
- {
495
- serverName: server.name
496
- }
497
- ),
498
- isChecked,
499
- isDisabled: isToggleDisabled,
500
- onChange: (_event, checked) => {
501
- void patchServer(server.name, {
502
- enabled: checked
503
- }).catch(() => {
504
- });
505
- }
518
+ serverName: server.name
506
519
  }
507
- );
508
- if (!isToggleDisabled) {
509
- return switchControl;
520
+ ),
521
+ isChecked,
522
+ isDisabled: isToggleDisabled,
523
+ onChange: (_event, checked) => {
524
+ void patchServer(server.name, {
525
+ enabled: checked
526
+ }).catch(() => {
527
+ });
510
528
  }
511
- return /* @__PURE__ */ jsx(Tooltip, { content: displayDetail, children: /* @__PURE__ */ jsx(Typography, { component: "span", children: switchControl }) });
512
- })() }),
513
- /* @__PURE__ */ jsx(
514
- Td,
515
- {
516
- width: 35,
517
- className: `${classes.rowName} ${classes.nameCell}`,
518
- children: /* @__PURE__ */ jsx(Typography, { component: "span", className: classes.nameValue, children: server.name })
519
- }
520
- ),
521
- /* @__PURE__ */ jsx(Td, { width: 40, className: classes.statusColumnCell, children: /* @__PURE__ */ jsxs("div", { className: classes.statusCell, children: [
522
- getStatusIcon(displayStatus, statusClass),
523
- displayStatus === "failed" ? /* @__PURE__ */ jsx(
524
- Tooltip,
525
- {
526
- content: server.validationError ?? t("mcp.settings.token.validationFailed"),
527
- children: /* @__PURE__ */ jsx(
528
- Typography,
529
- {
530
- component: "span",
531
- className: classes.statusValue,
532
- children: displayDetail
533
- }
534
- )
535
- }
536
- ) : /* @__PURE__ */ jsx(
529
+ }
530
+ );
531
+ if (!isToggleDisabled) {
532
+ return switchControl;
533
+ }
534
+ return /* @__PURE__ */ jsx(Tooltip, { content: displayDetail, children: /* @__PURE__ */ jsx(Typography, { component: "span", children: switchControl }) });
535
+ })() }),
536
+ /* @__PURE__ */ jsx(
537
+ Td,
538
+ {
539
+ width: 35,
540
+ className: `${mcpClasses.rowName} ${mcpClasses.nameCell}`,
541
+ children: /* @__PURE__ */ jsx(Typography, { component: "span", className: mcpClasses.nameValue, children: server.name })
542
+ }
543
+ ),
544
+ /* @__PURE__ */ jsx(Td, { width: 40, className: mcpClasses.statusColumnCell, children: /* @__PURE__ */ jsxs("div", { className: mcpClasses.statusCell, children: [
545
+ getStatusIcon(displayStatus, statusClass),
546
+ displayStatus === "failed" ? /* @__PURE__ */ jsx(
547
+ Tooltip,
548
+ {
549
+ content: server.validationError ?? t("mcp.settings.token.validationFailed"),
550
+ children: /* @__PURE__ */ jsx(
537
551
  Typography,
538
552
  {
539
553
  component: "span",
540
- className: classes.statusValue,
554
+ className: mcpClasses.statusValue,
541
555
  children: displayDetail
542
556
  }
543
557
  )
544
- ] }) }),
545
- /* @__PURE__ */ jsx(Td, { width: 15, isActionCell: true, style: { textAlign: "right" }, children: /* @__PURE__ */ jsx(
546
- Button,
547
- {
548
- "aria-label": t("mcp.settings.editServerAriaLabel", {
549
- serverName: server.name
550
- }),
551
- icon: /* @__PURE__ */ jsx(PencilAltIcon, {}),
552
- variant: "plain",
553
- className: classes.actionButton,
554
- isDisabled: !canManageMcp,
555
- onClick: () => configureModal.open(server)
556
- }
557
- ) })
558
- ] }, server.id);
559
- })
560
- ] })
561
- ]
562
- }
563
- ),
564
- /* @__PURE__ */ jsx(McpConfigureServerModal, { ...configureModal })
565
- ]
566
- }
567
- );
558
+ }
559
+ ) : /* @__PURE__ */ jsx(
560
+ Typography,
561
+ {
562
+ component: "span",
563
+ className: mcpClasses.statusValue,
564
+ children: displayDetail
565
+ }
566
+ )
567
+ ] }) }),
568
+ /* @__PURE__ */ jsx(Td, { width: 15, isActionCell: true, style: { textAlign: "right" }, children: /* @__PURE__ */ jsx(
569
+ Button,
570
+ {
571
+ "aria-label": t("mcp.settings.editServerAriaLabel", {
572
+ serverName: server.name
573
+ }),
574
+ icon: /* @__PURE__ */ jsx(PencilAltIcon, {}),
575
+ variant: "plain",
576
+ className: mcpClasses.actionButton,
577
+ onClick: () => configureModal.open(server)
578
+ }
579
+ ) })
580
+ ] }, server.id);
581
+ })
582
+ ] })
583
+ ]
584
+ }
585
+ ),
586
+ /* @__PURE__ */ jsx(McpConfigureServerModal, { ...configureModal })
587
+ ] });
568
588
  };
569
589
 
570
590
  export { McpServersSettings };