@cognizant-ai-lab/ui-common 1.3.3

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 (108) hide show
  1. package/dist/components/AgentChat/ChatCommon.d.ts +94 -0
  2. package/dist/components/AgentChat/ChatCommon.js +581 -0
  3. package/dist/components/AgentChat/ControlButtons.d.ts +16 -0
  4. package/dist/components/AgentChat/ControlButtons.js +24 -0
  5. package/dist/components/AgentChat/FormattedMarkdown.d.ts +32 -0
  6. package/dist/components/AgentChat/FormattedMarkdown.js +82 -0
  7. package/dist/components/AgentChat/Greetings.d.ts +1 -0
  8. package/dist/components/AgentChat/Greetings.js +38 -0
  9. package/dist/components/AgentChat/LlmChatButton.d.ts +12 -0
  10. package/dist/components/AgentChat/LlmChatButton.js +33 -0
  11. package/dist/components/AgentChat/SendButton.d.ts +12 -0
  12. package/dist/components/AgentChat/SendButton.js +28 -0
  13. package/dist/components/AgentChat/SyntaxHighlighterThemes.d.ts +14 -0
  14. package/dist/components/AgentChat/SyntaxHighlighterThemes.js +27 -0
  15. package/dist/components/AgentChat/Types.d.ts +17 -0
  16. package/dist/components/AgentChat/Types.js +26 -0
  17. package/dist/components/AgentChat/UserQueryDisplay.d.ts +5 -0
  18. package/dist/components/AgentChat/UserQueryDisplay.js +33 -0
  19. package/dist/components/AgentChat/Utils.d.ts +11 -0
  20. package/dist/components/AgentChat/Utils.js +64 -0
  21. package/dist/components/AgentChat/VoiceChat/MicrophoneButton.d.ts +29 -0
  22. package/dist/components/AgentChat/VoiceChat/MicrophoneButton.js +55 -0
  23. package/dist/components/AgentChat/VoiceChat/VoiceChat.d.ts +33 -0
  24. package/dist/components/AgentChat/VoiceChat/VoiceChat.js +180 -0
  25. package/dist/components/Authentication/Auth.d.ts +14 -0
  26. package/dist/components/Authentication/Auth.js +58 -0
  27. package/dist/components/ChatBot/ChatBot.d.ts +20 -0
  28. package/dist/components/ChatBot/ChatBot.js +75 -0
  29. package/dist/components/Common/Breadcrumbs.d.ts +6 -0
  30. package/dist/components/Common/Breadcrumbs.js +36 -0
  31. package/dist/components/Common/LlmChatOptionsButton.d.ts +9 -0
  32. package/dist/components/Common/LlmChatOptionsButton.js +31 -0
  33. package/dist/components/Common/LoadingSpinner.d.ts +10 -0
  34. package/dist/components/Common/LoadingSpinner.js +24 -0
  35. package/dist/components/Common/MUIAccordion.d.ts +17 -0
  36. package/dist/components/Common/MUIAccordion.js +76 -0
  37. package/dist/components/Common/MUIAlert.d.ts +11 -0
  38. package/dist/components/Common/MUIAlert.js +41 -0
  39. package/dist/components/Common/MUIDialog.d.ts +16 -0
  40. package/dist/components/Common/MUIDialog.js +40 -0
  41. package/dist/components/Common/Navbar.d.ts +15 -0
  42. package/dist/components/Common/Navbar.js +137 -0
  43. package/dist/components/Common/PageLoader.d.ts +5 -0
  44. package/dist/components/Common/PageLoader.js +26 -0
  45. package/dist/components/Common/Snackbar.d.ts +5 -0
  46. package/dist/components/Common/Snackbar.js +84 -0
  47. package/dist/components/Common/confirmationModal.d.ts +14 -0
  48. package/dist/components/Common/confirmationModal.js +65 -0
  49. package/dist/components/Common/notification.d.ts +18 -0
  50. package/dist/components/Common/notification.js +79 -0
  51. package/dist/components/ErrorPage/ErrorBoundary.d.ts +38 -0
  52. package/dist/components/ErrorPage/ErrorBoundary.js +77 -0
  53. package/dist/components/ErrorPage/ErrorPage.d.ts +12 -0
  54. package/dist/components/ErrorPage/ErrorPage.js +46 -0
  55. package/dist/components/MultiAgentAccelerator/AgentFlow.d.ts +21 -0
  56. package/dist/components/MultiAgentAccelerator/AgentFlow.js +394 -0
  57. package/dist/components/MultiAgentAccelerator/AgentNode.d.ts +18 -0
  58. package/dist/components/MultiAgentAccelerator/AgentNode.js +129 -0
  59. package/dist/components/MultiAgentAccelerator/GraphLayouts.d.ts +33 -0
  60. package/dist/components/MultiAgentAccelerator/GraphLayouts.js +297 -0
  61. package/dist/components/MultiAgentAccelerator/MultiAgentAccelerator.d.ts +17 -0
  62. package/dist/components/MultiAgentAccelerator/MultiAgentAccelerator.js +208 -0
  63. package/dist/components/MultiAgentAccelerator/PlasmaEdge.d.ts +3 -0
  64. package/dist/components/MultiAgentAccelerator/PlasmaEdge.js +124 -0
  65. package/dist/components/MultiAgentAccelerator/Sidebar.d.ts +12 -0
  66. package/dist/components/MultiAgentAccelerator/Sidebar.js +204 -0
  67. package/dist/components/MultiAgentAccelerator/ThoughtBubbleEdge.d.ts +12 -0
  68. package/dist/components/MultiAgentAccelerator/ThoughtBubbleEdge.js +15 -0
  69. package/dist/components/MultiAgentAccelerator/ThoughtBubbleOverlay.d.ts +11 -0
  70. package/dist/components/MultiAgentAccelerator/ThoughtBubbleOverlay.js +466 -0
  71. package/dist/components/MultiAgentAccelerator/const.d.ts +7 -0
  72. package/dist/components/MultiAgentAccelerator/const.js +39 -0
  73. package/dist/const.d.ts +10 -0
  74. package/dist/const.js +30 -0
  75. package/dist/controller/agent/Agent.d.ts +56 -0
  76. package/dist/controller/agent/Agent.js +162 -0
  77. package/dist/controller/llm/LlmChat.d.ts +18 -0
  78. package/dist/controller/llm/LlmChat.js +65 -0
  79. package/dist/controller/llm/endpoints.d.ts +1 -0
  80. package/dist/controller/llm/endpoints.js +17 -0
  81. package/dist/generated/neuro-san/NeuroSanClient.d.ts +413 -0
  82. package/dist/generated/neuro-san/NeuroSanClient.js +28 -0
  83. package/dist/index.d.ts +37 -0
  84. package/dist/index.js +52 -0
  85. package/dist/state/UserInfo.d.ts +16 -0
  86. package/dist/state/UserInfo.js +27 -0
  87. package/dist/state/environment.d.ts +18 -0
  88. package/dist/state/environment.js +33 -0
  89. package/dist/tsconfig.build.tsbuildinfo +1 -0
  90. package/dist/utils/Authentication.d.ts +31 -0
  91. package/dist/utils/Authentication.js +94 -0
  92. package/dist/utils/BrowserNavigation.d.ts +5 -0
  93. package/dist/utils/BrowserNavigation.js +22 -0
  94. package/dist/utils/Theme.d.ts +7 -0
  95. package/dist/utils/Theme.js +7 -0
  96. package/dist/utils/agentConversations.d.ts +24 -0
  97. package/dist/utils/agentConversations.js +113 -0
  98. package/dist/utils/text.d.ts +28 -0
  99. package/dist/utils/text.js +64 -0
  100. package/dist/utils/title.d.ts +1 -0
  101. package/dist/utils/title.js +20 -0
  102. package/dist/utils/types.d.ts +17 -0
  103. package/dist/utils/types.js +16 -0
  104. package/dist/utils/useLocalStorage.d.ts +1 -0
  105. package/dist/utils/useLocalStorage.js +55 -0
  106. package/dist/utils/zIndexLayers.d.ts +2 -0
  107. package/dist/utils/zIndexLayers.js +29 -0
  108. package/package.json +69 -0
@@ -0,0 +1,180 @@
1
+ /*
2
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ // #endregion: Types
17
+ // Check if browser is Chrome (excluding Edge). Only Chrome (on Mac OS and Windows) has full support for
18
+ // SpeechRecognition. Also, tested that this will exclude Firefox and Safari.
19
+ const isChrome = () => /Chrome/u.test(navigator.userAgent) && !/Edge/u.test(navigator.userAgent) && !/Edg\//u.test(navigator.userAgent);
20
+ // Check browser/platform support
21
+ export const checkSpeechSupport = () => {
22
+ if (typeof window === "undefined")
23
+ return false;
24
+ // Check if browser supports SpeechRecognition
25
+ const hasSpeechRecognition = "SpeechRecognition" in window;
26
+ // Only Chrome provides reliable speech recognition support
27
+ return hasSpeechRecognition && isChrome();
28
+ };
29
+ // Handle speech recognition start
30
+ const handleRecognitionStart = (setVoiceInputState) => () => {
31
+ setVoiceInputState((prev) => ({
32
+ ...prev,
33
+ currentTranscript: "",
34
+ isListening: true,
35
+ }));
36
+ };
37
+ // Handle speech recognition end
38
+ const handleRecognitionEnd = (setVoiceInputState) => () => {
39
+ setVoiceInputState((prev) => ({
40
+ ...prev,
41
+ isListening: false,
42
+ isProcessingSpeech: false,
43
+ }));
44
+ };
45
+ // Handle speech recognition results
46
+ const handleRecognitionResult = (setVoiceInputState, setChatInput) => (event) => {
47
+ // interimTranscript: accumulates live (non-final) results for real-time feedback (currentTranscript).
48
+ let interimTranscript = "";
49
+ // finalTranscript: accumulates finalized results for input (finalTranscript).
50
+ let finalTranscript = "";
51
+ for (let i = event.resultIndex; i < event.results.length; i += 1) {
52
+ const transcript = event.results[i][0].transcript;
53
+ if (event.results[i].isFinal) {
54
+ // Finalized segment, ready for input
55
+ finalTranscript += transcript;
56
+ }
57
+ else {
58
+ // Live segment, for real-time feedback
59
+ interimTranscript += transcript;
60
+ }
61
+ }
62
+ setVoiceInputState((prev) => ({
63
+ ...prev,
64
+ currentTranscript: interimTranscript,
65
+ finalTranscript,
66
+ // Always show loading indicator while listening, until final transcript or recognition end
67
+ isProcessingSpeech: true,
68
+ }));
69
+ // Process final transcript
70
+ if (finalTranscript) {
71
+ setVoiceInputState((prev) => ({
72
+ ...prev,
73
+ isProcessingSpeech: false,
74
+ }));
75
+ setChatInput((prev) => {
76
+ const needsSpace = prev && !prev.endsWith(" ");
77
+ return prev + (needsSpace ? " " : "") + finalTranscript;
78
+ });
79
+ }
80
+ };
81
+ // Handle speech recognition errors
82
+ const handleRecognitionError = (setVoiceInputState) => (event) => {
83
+ console.error("Speech recognition error:", event.error);
84
+ setVoiceInputState((prev) => ({
85
+ ...prev,
86
+ isListening: false,
87
+ isProcessingSpeech: false,
88
+ }));
89
+ };
90
+ // Remove speech recognition event handlers and stop speech recognition
91
+ export function cleanupAndStopSpeechRecognition(speechRecognitionRef, handlers) {
92
+ const speechRecognition = speechRecognitionRef.current;
93
+ if (!speechRecognition || !handlers)
94
+ return;
95
+ speechRecognition.removeEventListener("end", handlers.end);
96
+ speechRecognition.removeEventListener("error", handlers.error);
97
+ speechRecognition.removeEventListener("result", handlers.result);
98
+ speechRecognition.removeEventListener("start", handlers.start);
99
+ try {
100
+ speechRecognition.stop();
101
+ }
102
+ catch (error) {
103
+ console.warn("Error stopping speechRecognition:", error);
104
+ }
105
+ speechRecognitionRef.current = null;
106
+ }
107
+ export function setupSpeechRecognition(setChatInput, setVoiceInputState, speechRecognitionRef) {
108
+ const speechSupported = checkSpeechSupport();
109
+ if (speechSupported) {
110
+ const speechRecognition = new SpeechRecognition();
111
+ speechRecognition.continuous = true;
112
+ speechRecognition.interimResults = true;
113
+ speechRecognition.lang = navigator.language || "en-US";
114
+ // Create handler references
115
+ const handlers = {
116
+ end: handleRecognitionEnd(setVoiceInputState),
117
+ error: handleRecognitionError(setVoiceInputState),
118
+ result: handleRecognitionResult(setVoiceInputState, setChatInput),
119
+ start: handleRecognitionStart(setVoiceInputState),
120
+ };
121
+ speechRecognition.addEventListener("end", handlers.end);
122
+ speechRecognition.addEventListener("error", handlers.error);
123
+ speechRecognition.addEventListener("result", handlers.result);
124
+ speechRecognition.addEventListener("start", handlers.start);
125
+ speechRecognitionRef.current = speechRecognition;
126
+ return handlers;
127
+ }
128
+ else {
129
+ speechRecognitionRef.current = null;
130
+ return null;
131
+ }
132
+ }
133
+ // Request microphone permission
134
+ const requestMicrophonePermission = async () => {
135
+ if (!isChrome())
136
+ return false;
137
+ if ("mediaDevices" in navigator && "getUserMedia" in navigator.mediaDevices) {
138
+ try {
139
+ const stream = await navigator.mediaDevices.getUserMedia({
140
+ audio: {
141
+ echoCancellation: true,
142
+ noiseSuppression: true,
143
+ autoGainControl: true,
144
+ },
145
+ });
146
+ stream.getTracks().forEach((track) => track.stop());
147
+ return true;
148
+ }
149
+ catch (error) {
150
+ if (error instanceof Error &&
151
+ (error.name === "NotAllowedError" || error.name === "PermissionDeniedError")) {
152
+ return false;
153
+ }
154
+ // For other errors, still allow recognition to proceed (Chrome supports it)
155
+ return true;
156
+ }
157
+ }
158
+ return false;
159
+ };
160
+ // Toggle listening function
161
+ export const toggleListening = async (isMicOn, recognition) => {
162
+ if (!recognition)
163
+ return;
164
+ if (isMicOn) {
165
+ // Request microphone permission before starting
166
+ const hasPermission = await requestMicrophonePermission();
167
+ if (hasPermission) {
168
+ recognition.start();
169
+ }
170
+ }
171
+ else {
172
+ // Stop recognition immediately
173
+ try {
174
+ recognition.stop();
175
+ }
176
+ catch (error) {
177
+ console.warn("Error stopping speech recognition:", error);
178
+ }
179
+ }
180
+ };
@@ -0,0 +1,14 @@
1
+ import { ReactNode } from "react";
2
+ interface AuthProps {
3
+ children: ReactNode;
4
+ }
5
+ /**
6
+ * Higher-level component to wrap pages that require authentication.
7
+ *
8
+ * Taken from here: https://github.com/nextauthjs/next-auth/issues/1210#issuecomment-782630909
9
+ *
10
+ * @param children Contained components protected by the authentication guard
11
+ * @return children (protected) components if user is authenticated, otherwise "Loading" message.
12
+ */
13
+ export declare const Auth: ({ children }: AuthProps) => import("react/jsx-runtime").JSX.Element;
14
+ export {};
@@ -0,0 +1,58 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ /*
3
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ */
17
+ /**
18
+ * Utility functions relating to authentication
19
+ */
20
+ import { signIn, useSession } from "next-auth/react";
21
+ import { useEffect } from "react";
22
+ import { PageLoader } from "../Common/PageLoader.js";
23
+ // Use this provider for authentication via next-auth. It *must* correspond to one of those listed in
24
+ // ./pages/api/auth/[...nextauth].js
25
+ const AUTHENTICATION_PROVIDER = "auth0";
26
+ /**
27
+ * Higher-level component to wrap pages that require authentication.
28
+ *
29
+ * Taken from here: https://github.com/nextauthjs/next-auth/issues/1210#issuecomment-782630909
30
+ *
31
+ * @param children Contained components protected by the authentication guard
32
+ * @return children (protected) components if user is authenticated, otherwise "Loading" message.
33
+ */
34
+ export const Auth = ({ children }) => {
35
+ // Suppress no-shadow rule -- we have to use what the API gives us
36
+ // eslint-disable-next-line no-shadow
37
+ const { data: session, status } = useSession();
38
+ const isUser = Boolean(session?.user);
39
+ const loading = status === "loading";
40
+ useEffect(() => {
41
+ if (loading) {
42
+ // Do nothing while loading
43
+ return;
44
+ }
45
+ // If not authenticated, force log in.
46
+ // By explicitly specifying the provider here, it skips the annoying and unnecessary next-auth interstitial
47
+ // screen and goes straight to the login screen of AUTHENTICATION_PROVIDER.
48
+ if (!isUser) {
49
+ void signIn(AUTHENTICATION_PROVIDER);
50
+ }
51
+ }, [isUser, loading]);
52
+ if (isUser && !loading) {
53
+ return _jsx(_Fragment, { children: children });
54
+ }
55
+ // Session is being fetched, or no user.
56
+ // If no user, useEffect() will redirect.
57
+ return _jsx(PageLoader, { id: "authentication-page" });
58
+ };
@@ -0,0 +1,20 @@
1
+ import { FC } from "react";
2
+ interface ChatBotProps {
3
+ /**
4
+ * id HTML id to use for the outer component
5
+ */
6
+ readonly id: string;
7
+ /**
8
+ * Path to image for user avatar
9
+ */
10
+ readonly userAvatar: string;
11
+ /**
12
+ * Text about current page to help the LLM respond intelligently
13
+ */
14
+ readonly pageContext: string;
15
+ }
16
+ /**
17
+ * Site-wide Chatbot component.
18
+ */
19
+ export declare const ChatBot: FC<ChatBotProps>;
20
+ export {};
@@ -0,0 +1,75 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /*
3
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ */
17
+ import ContactSupportIcon from "@mui/icons-material/ContactSupport";
18
+ import { useColorScheme, useTheme } from "@mui/material";
19
+ import Box from "@mui/material/Box";
20
+ import Grow from "@mui/material/Grow";
21
+ import { useState } from "react";
22
+ import { CHATBOT_ENDPOINT } from "../../controller/llm/endpoints.js";
23
+ import { useAuthentication } from "../../utils/Authentication.js";
24
+ import { isDarkMode } from "../../utils/Theme.js";
25
+ import { getZIndex } from "../../utils/zIndexLayers.js";
26
+ import { ChatCommon } from "../AgentChat/ChatCommon.js";
27
+ import { LegacyAgentType } from "../AgentChat/Types.js";
28
+ /**
29
+ * Site-wide Chatbot component.
30
+ */
31
+ // Temporarily disabled but will be used once we migrated the backend to use Neuro-san RAG.
32
+ export const ChatBot = ({ id, userAvatar, pageContext }) => {
33
+ const [chatOpen, setChatOpen] = useState(false);
34
+ const [isAwaitingLlm, setIsAwaitingLlm] = useState(false);
35
+ const { user: { name: currentUser }, } = useAuthentication().data;
36
+ // MUI theme and dark mode
37
+ const theme = useTheme();
38
+ const { mode, systemMode } = useColorScheme();
39
+ const darkMode = isDarkMode(mode, systemMode);
40
+ // Shadow color for icon. TODO: use MUI theme system instead.
41
+ const shadowColor = darkMode ? "255, 255, 255" : "0, 0, 0";
42
+ return (_jsxs(_Fragment, { children: [_jsx(Grow, { id: `chatbot-window-animation-${id}`, in: chatOpen, timeout: 300, style: { transformOrigin: "bottom right" }, easing: "ease-in-out", children: _jsx(Box, { id: id, sx: {
43
+ position: "fixed",
44
+ bottom: 50,
45
+ right: "2rem",
46
+ height: "60%",
47
+ maxWidth: 400,
48
+ background: darkMode ? "var(--bs-dark-mode-dim)" : "var(--bs-white)",
49
+ boxShadow: `0 0px 2px 0 rgba(${shadowColor}, 0.15)`,
50
+ borderRadius: "var(--bs-border-radius)",
51
+ borderWidth: 1,
52
+ borderColor: darkMode ? "var(--bs-white)" : "var(--bs-gray-light)",
53
+ zIndex: getZIndex(2, theme),
54
+ }, children: _jsx(ChatCommon, { id: "chatbot-window", currentUser: currentUser, setIsAwaitingLlm: setIsAwaitingLlm, isAwaitingLlm: isAwaitingLlm, targetAgent: LegacyAgentType.ChatBot, userImage: userAvatar, legacyAgentEndpoint: CHATBOT_ENDPOINT, extraParams: { pageContext }, backgroundColor: darkMode ? "var(--bs-gray-dark)" : "var(--bs-tertiary-blue)", title: "Cognizant Neuro AI Assistant", onClose: () => setChatOpen(false) }) }) }), !chatOpen && (_jsx(Box, { id: `chatbot-icon-${id}`, sx: {
55
+ display: "flex",
56
+ alignItems: "center",
57
+ backgroundColor: darkMode ? "var(--bs-dark-mode-dim)" : "var(--bs-white)",
58
+ borderRadius: "50%",
59
+ bottom: 16,
60
+ // For now mimic MUI's default box shadow but change color based on dark mode.
61
+ // Eventually we should use MUI's theme system.
62
+ boxShadow: `
63
+ 0px 2px 4px -1px rgba(${shadowColor}, 0.2),
64
+ 0px 4px 5px 0px rgba(${shadowColor}, 0.14),
65
+ 0px 1px 10px 0px rgba(${shadowColor}, 0.12)
66
+ `,
67
+ cursor: "pointer",
68
+ height: 40,
69
+ justifyContent: "center",
70
+ maxWidth: 40,
71
+ padding: "1rem",
72
+ position: "fixed",
73
+ right: 16,
74
+ }, onClick: () => setChatOpen(true), children: _jsx(ContactSupportIcon, { id: `chatbot-icon-${id}` }) }))] }));
75
+ };
@@ -0,0 +1,6 @@
1
+ import { JSX as ReactJSX } from "react";
2
+ interface NeuroAIBreadcrumbsProps {
3
+ readonly pathname?: string;
4
+ }
5
+ export declare const NeuroAIBreadcrumbs: ({ pathname }: NeuroAIBreadcrumbsProps) => ReactJSX.Element;
6
+ export {};
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /*
3
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ */
17
+ import ChevronRightIcon from "@mui/icons-material/ChevronRight";
18
+ import { Typography } from "@mui/material";
19
+ import Breadcrumbs from "@mui/material/Breadcrumbs";
20
+ import Grid from "@mui/material/Grid";
21
+ import startCase from "lodash-es/startCase.js";
22
+ export const NeuroAIBreadcrumbs = ({ pathname }) => {
23
+ const urlPaths = pathname?.split("/").filter((path) => path !== "");
24
+ const pageName = startCase(urlPaths?.at(-1));
25
+ return (_jsx(Grid, { id: "nav-bar-breadcrumbs-row", container: true, sx: {
26
+ justifyContent: "flex-start",
27
+ width: "100%",
28
+ }, children: _jsxs(Breadcrumbs, { style: {
29
+ marginTop: "1rem",
30
+ }, id: "breadcrumb-nav", "aria-label": "breadcrumb", separator: _jsx(ChevronRightIcon, { id: "breadcrumb-separator", fontSize: "small" }), children: [_jsx("a", { id: "breadcrumb-link-home", href: "/", children: "Home" }), urlPaths?.slice(0, -1).map((urlPath, idx) => {
31
+ const redirectPath = urlPaths.slice(0, idx + 1).join("/");
32
+ return (_jsx("a", { id: `breadcrumb-link__${urlPath}`, style: {
33
+ textDecoration: "underlined",
34
+ }, href: `/${redirectPath}`, children: startCase(urlPath) }, urlPath));
35
+ }), _jsx(Typography, { id: "breadcrumb-link__current", children: pageName })] }) }));
36
+ };
@@ -0,0 +1,9 @@
1
+ type LLMChatGroupConfigBtnProps = {
2
+ enabled?: boolean;
3
+ posRight?: number;
4
+ posBottom?: number;
5
+ };
6
+ export declare const LlmChatOptionsButton: import("@emotion/styled").StyledComponent<import("@mui/material").ButtonOwnProps & Omit<import("@mui/material").ButtonBaseOwnProps, "classes"> & import("@mui/material/OverridableComponent").CommonProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
7
+ ref?: import("react").Ref<HTMLButtonElement>;
8
+ }, "className" | "style" | "classes" | "action" | "centerRipple" | "children" | "disabled" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "sx" | "tabIndex" | "TouchRippleProps" | "touchRippleRef" | "href" | "color" | "disableElevation" | "disableFocusRipple" | "endIcon" | "fullWidth" | "loading" | "loadingIndicator" | "loadingPosition" | "size" | "startIcon" | "variant"> & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & LLMChatGroupConfigBtnProps, {}, {}>;
9
+ export {};
@@ -0,0 +1,31 @@
1
+ /*
2
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+ import { styled } from "@mui/material";
17
+ import Button from "@mui/material/Button";
18
+ import { getZIndex } from "../../utils/zIndexLayers.js";
19
+ export const LlmChatOptionsButton = styled(Button, {
20
+ shouldForwardProp: (prop) => prop !== "enabled" && prop !== "posRight" && prop !== "posBottom",
21
+ })(({ enabled, posRight }) => ({
22
+ position: "absolute",
23
+ top: 10,
24
+ right: posRight || null,
25
+ zIndex: getZIndex(1, null), // Seems to only be needed on Analytics Chat, but apply to all.
26
+ background: `${enabled ? "var(--bs-primary)" : "darkgray"} !important`,
27
+ borderColor: `${enabled ? "var(--bs-primary)" : "darkgray"} !important`,
28
+ borderRadius: "var(--bs-border-radius)",
29
+ width: "30px",
30
+ height: "30px",
31
+ }));
@@ -0,0 +1,10 @@
1
+ import { FC } from "react";
2
+ interface LoadingSpinnerProps {
3
+ id: string;
4
+ }
5
+ /**
6
+ * A simple loading spinner component that displays a circular progress indicator
7
+ * @param id The id for the spinner and text elements, for testing
8
+ */
9
+ export declare const LoadingSpinner: FC<LoadingSpinnerProps>;
10
+ export {};
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /*
3
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ */
17
+ import CircularProgress from "@mui/material/CircularProgress";
18
+ /**
19
+ * A simple loading spinner component that displays a circular progress indicator
20
+ * @param id The id for the spinner and text elements, for testing
21
+ */
22
+ export const LoadingSpinner = ({ id }) => {
23
+ return (_jsxs("h3", { id: id, children: [_jsx(CircularProgress, { id: `${id}-spinner`, sx: { color: "var(--bs-primary)" }, size: 35 }), _jsx("span", { id: `${id}-loading-text`, style: { marginLeft: "1em" }, children: "Loading..." })] }));
24
+ };
@@ -0,0 +1,17 @@
1
+ import { SxProps } from "@mui/material";
2
+ import { FC, ReactNode } from "react";
3
+ interface MUIAccordionItem {
4
+ content: ReactNode;
5
+ disabled?: boolean;
6
+ title: ReactNode;
7
+ }
8
+ export interface MUIAccordionProps {
9
+ arrowPosition?: "left" | "right";
10
+ defaultExpandedPanelKey?: number;
11
+ expandOnlyOnePanel?: boolean;
12
+ id: string;
13
+ items: MUIAccordionItem[];
14
+ sx?: SxProps;
15
+ }
16
+ export declare const MUIAccordion: FC<MUIAccordionProps>;
17
+ export {};
@@ -0,0 +1,76 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /*
3
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ */
17
+ import ArrowForwardIosSharpIcon from "@mui/icons-material/ArrowForwardIosSharp";
18
+ import { styled, useColorScheme } from "@mui/material";
19
+ import MuiAccordion from "@mui/material/Accordion";
20
+ import MuiAccordionDetails from "@mui/material/AccordionDetails";
21
+ import MuiAccordionSummary, { accordionSummaryClasses } from "@mui/material/AccordionSummary";
22
+ import Typography from "@mui/material/Typography";
23
+ import { useCallback, useState } from "react";
24
+ import { isDarkMode } from "../../utils/Theme.js";
25
+ // #region: Styled Components
26
+ const Accordion = styled((props) => (_jsx(MuiAccordion, { disableGutters: true, elevation: 0, id: "mui-accordion", ...props })))(({ theme }) => ({
27
+ border: `1px solid ${theme.palette.divider}`,
28
+ "&::before": {
29
+ display: "none",
30
+ },
31
+ }));
32
+ const AccordionSummary = styled((props) => (_jsx(MuiAccordionSummary, { id: "mui-accordion-summary", expandIcon: _jsx(ArrowForwardIosSharpIcon, { id: "arrow-forward", sx: { fontSize: "0.9rem" } }), ...props })))(({ theme }) => ({
33
+ [`& .${accordionSummaryClasses.expandIconWrapper}.${accordionSummaryClasses.expanded}`]: {
34
+ transform: "rotate(90deg)",
35
+ },
36
+ [`& .${accordionSummaryClasses.content}`]: {
37
+ marginLeft: theme.spacing(1),
38
+ },
39
+ }));
40
+ const AccordionDetails = styled(MuiAccordionDetails)(({ theme }) => ({
41
+ borderTop: "1px solid rgba(0, 0, 0, .125)",
42
+ padding: theme.spacing(2),
43
+ }));
44
+ // #endregion: Types
45
+ export const MUIAccordion = ({ arrowPosition = "left", defaultExpandedPanelKey, expandOnlyOnePanel = false, id, items, sx, }) => {
46
+ // Dark mode
47
+ const { mode, systemMode } = useColorScheme();
48
+ const darkMode = isDarkMode(mode, systemMode);
49
+ const [expandedList, setExpandedList] = useState(defaultExpandedPanelKey ? [defaultExpandedPanelKey] : []);
50
+ const handleChange = useCallback((panelKey) => (_event, newExpanded) => {
51
+ setExpandedList((prevExpandedList) => {
52
+ if (!expandOnlyOnePanel) {
53
+ return newExpanded
54
+ ? [...prevExpandedList, panelKey]
55
+ : prevExpandedList.filter((key) => key !== panelKey);
56
+ }
57
+ else {
58
+ return newExpanded ? [panelKey] : [];
59
+ }
60
+ });
61
+ }, [expandOnlyOnePanel]);
62
+ const isExpanded = useCallback((panelKey) => expandedList.includes(panelKey), [expandedList]);
63
+ return (_jsx(_Fragment, { children: items.map(({ content, disabled = false, title }, index) => {
64
+ const panelKey = index + 1; // Start with index 1
65
+ const baseIdAndPanelKey = `${id}-${panelKey}`;
66
+ return (_jsxs(Accordion, { disabled: disabled, expanded: isExpanded(panelKey), id: `${baseIdAndPanelKey}-accordion`, onChange: handleChange(panelKey), sx: sx, children: [_jsx(AccordionSummary, { "aria-controls": `${baseIdAndPanelKey}-summary`, id: `${baseIdAndPanelKey}-summary`, sx: {
67
+ backgroundColor: darkMode ? "var(--bs-dark-mode-dim)" : "var(--bs-gray-background)",
68
+ color: darkMode ? "var(--bs-white)" : "var(--bs-primary)",
69
+ flexDirection: arrowPosition === "left" ? "row-reverse" : undefined,
70
+ }, children: _jsx(Typography, { component: "span", id: `${baseIdAndPanelKey}-summary-typography`, sx: { fontSize: "0.9rem" }, children: title }) }), _jsx(AccordionDetails, { id: `${baseIdAndPanelKey}-details`, sx: {
71
+ backgroundColor: darkMode ? "var(--bs-dark-mode-dim)" : "rgba(0, 0, 0, 0.02)",
72
+ borderColor: darkMode ? "var(--bs-white)" : "var(--bs-border-color)",
73
+ color: darkMode ? "var(--bs-white)" : "var(--bs-primary)",
74
+ }, children: _jsx(Typography, { component: "span", id: `${baseIdAndPanelKey}-details-typography`, sx: { fontSize: "0.85rem" }, children: content }) })] }, `${baseIdAndPanelKey}-accordion`));
75
+ }) }));
76
+ };
@@ -0,0 +1,11 @@
1
+ import { AlertColor, SxProps } from "@mui/material";
2
+ import { FC, ReactNode } from "react";
3
+ interface MUIAlertProps {
4
+ children: ReactNode;
5
+ closeable?: boolean;
6
+ id: string;
7
+ severity: AlertColor;
8
+ sx?: SxProps;
9
+ }
10
+ export declare const MUIAlert: FC<MUIAlertProps>;
11
+ export {};
@@ -0,0 +1,41 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /*
3
+ Copyright 2025 Cognizant Technology Solutions Corp, www.cognizant.com.
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ */
17
+ import CloseIcon from "@mui/icons-material/Close";
18
+ import { Alert, Collapse, IconButton, styled } from "@mui/material";
19
+ import { useState } from "react";
20
+ // #region: Styled Components
21
+ const StyledAlert = styled(Alert)({
22
+ fontSize: "large",
23
+ marginBottom: "1rem",
24
+ "& .MuiAlert-message": {
25
+ paddingTop: "0.25rem",
26
+ paddingBottom: "0.25rem",
27
+ },
28
+ });
29
+ // #endregion: Types
30
+ export const MUIAlert = ({ children, closeable = false, id, severity, sx }) => {
31
+ const [alertOpen, setAlertOpen] = useState(true);
32
+ const handleClose = () => {
33
+ setAlertOpen(false);
34
+ };
35
+ return (_jsx(Collapse, { id: `${id}-collapse`, in: alertOpen, children: _jsx(StyledAlert, { action: closeable && (_jsx(IconButton, { "aria-label": "close", color: "inherit", id: `${id}-icon-button`, onClick: () => {
36
+ setAlertOpen(false);
37
+ }, size: "small", sx: {
38
+ bottom: "2px",
39
+ position: "relative",
40
+ }, children: _jsx(CloseIcon, { fontSize: "inherit", id: `${id}-close-icon` }) })), id: id, onClose: closeable ? handleClose : undefined, severity: severity, sx: sx, children: children }) }));
41
+ };
@@ -0,0 +1,16 @@
1
+ import { SxProps } from "@mui/material";
2
+ import { FC, JSX as ReactJSX, ReactNode } from "react";
3
+ interface MUIDialogProps {
4
+ children: ReactNode;
5
+ className?: string;
6
+ closeable?: boolean;
7
+ contentSx?: SxProps;
8
+ footer?: ReactJSX.Element;
9
+ id: string;
10
+ isOpen: boolean;
11
+ onClose: () => void;
12
+ paperProps?: SxProps;
13
+ title?: ReactNode;
14
+ }
15
+ export declare const MUIDialog: FC<MUIDialogProps>;
16
+ export {};