@red-hat-developer-hub/backstage-plugin-lightspeed 0.5.7 → 0.6.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 (59) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/components/Attachment.esm.js +71 -61
  3. package/dist/components/Attachment.esm.js.map +1 -1
  4. package/dist/components/AttachmentContext.esm.js +32 -23
  5. package/dist/components/AttachmentContext.esm.js.map +1 -1
  6. package/dist/components/DeleteModal.esm.js +24 -15
  7. package/dist/components/DeleteModal.esm.js.map +1 -1
  8. package/dist/components/FilePreview.esm.js +16 -13
  9. package/dist/components/FilePreview.esm.js.map +1 -1
  10. package/dist/components/LightSpeedChat.esm.js +172 -129
  11. package/dist/components/LightSpeedChat.esm.js.map +1 -1
  12. package/dist/components/LightspeedChatBox.esm.js +43 -34
  13. package/dist/components/LightspeedChatBox.esm.js.map +1 -1
  14. package/dist/components/LightspeedChatBoxHeader.esm.js +15 -12
  15. package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -1
  16. package/dist/components/LightspeedIcon.esm.js +11 -2
  17. package/dist/components/LightspeedIcon.esm.js.map +1 -1
  18. package/dist/components/LightspeedPage.esm.js +32 -26
  19. package/dist/components/LightspeedPage.esm.js.map +1 -1
  20. package/dist/components/PermissionRequiredIcon.esm.js +10 -2
  21. package/dist/components/PermissionRequiredIcon.esm.js.map +1 -1
  22. package/dist/components/PermissionRequiredState.esm.js +25 -11
  23. package/dist/components/PermissionRequiredState.esm.js.map +1 -1
  24. package/dist/components/Trans.esm.js +33 -0
  25. package/dist/components/Trans.esm.js.map +1 -0
  26. package/dist/const.esm.js +20 -43
  27. package/dist/const.esm.js.map +1 -1
  28. package/dist/hooks/useAutoScroll.esm.js +11 -11
  29. package/dist/hooks/useAutoScroll.esm.js.map +1 -1
  30. package/dist/hooks/useBufferedMessages.esm.js +5 -5
  31. package/dist/hooks/useBufferedMessages.esm.js.map +1 -1
  32. package/dist/hooks/useConversationMessages.esm.js +8 -8
  33. package/dist/hooks/useConversationMessages.esm.js.map +1 -1
  34. package/dist/hooks/useFeedbackActions.esm.js +47 -18
  35. package/dist/hooks/useFeedbackActions.esm.js.map +1 -1
  36. package/dist/hooks/useIsMobile.esm.js +3 -3
  37. package/dist/hooks/useIsMobile.esm.js.map +1 -1
  38. package/dist/hooks/useLastOpenedConversation.esm.js.map +1 -1
  39. package/dist/hooks/useTranslation.esm.js +7 -0
  40. package/dist/hooks/useTranslation.esm.js.map +1 -0
  41. package/dist/hooks/useWelcomePrompts.esm.js +21 -6
  42. package/dist/hooks/useWelcomePrompts.esm.js.map +1 -1
  43. package/dist/index.d.ts +11 -5
  44. package/dist/index.esm.js +1 -0
  45. package/dist/index.esm.js.map +1 -1
  46. package/dist/translations/de.esm.js +128 -0
  47. package/dist/translations/de.esm.js.map +1 -0
  48. package/dist/translations/es.esm.js +128 -0
  49. package/dist/translations/es.esm.js.map +1 -0
  50. package/dist/translations/fr.esm.js +128 -0
  51. package/dist/translations/fr.esm.js.map +1 -0
  52. package/dist/translations/index.esm.js +14 -0
  53. package/dist/translations/index.esm.js.map +1 -0
  54. package/dist/translations/translationRef.esm.js +128 -0
  55. package/dist/translations/translationRef.esm.js.map +1 -0
  56. package/dist/types.esm.js.map +1 -1
  57. package/dist/utils/lightspeed-chatbox-utils.esm.js +24 -21
  58. package/dist/utils/lightspeed-chatbox-utils.esm.js.map +1 -1
  59. package/package.json +12 -12
@@ -1,12 +1,13 @@
1
- import React__default from 'react';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { forwardRef, useRef, useImperativeHandle, useEffect, Fragment } from 'react';
2
3
  import { useApi, configApiRef } from '@backstage/core-plugin-api';
3
4
  import { makeStyles } from '@material-ui/core';
4
5
  import { MessageBox, ChatbotWelcomePrompt, Message } from '@patternfly/chatbot';
5
6
  import { Alert } from '@patternfly/react-core';
6
- import { FUNCTION_DISCLAIMER, FUNCTION_DISCLAIMER_WITHOUT_QUESTION_VALIDATION } from '../const.esm.js';
7
7
  import { useAutoScroll } from '../hooks/useAutoScroll.esm.js';
8
8
  import { useBufferedMessages } from '../hooks/useBufferedMessages.esm.js';
9
9
  import { useFeedbackActions } from '../hooks/useFeedbackActions.esm.js';
10
+ import { useTranslation } from '../hooks/useTranslation.esm.js';
10
11
 
11
12
  const useStyles = makeStyles((theme) => ({
12
13
  prompt: {
@@ -28,7 +29,7 @@ const useStyles = makeStyles((theme) => ({
28
29
  }
29
30
  }
30
31
  }));
31
- const LightspeedChatBox = React__default.forwardRef(
32
+ const LightspeedChatBox = forwardRef(
32
33
  ({
33
34
  userName,
34
35
  messages,
@@ -39,8 +40,9 @@ const LightspeedChatBox = React__default.forwardRef(
39
40
  isStreaming
40
41
  }, ref) => {
41
42
  const classes = useStyles();
42
- const scrollQueued = React__default.useRef(false);
43
- const containerRef = React__default.useRef(null);
43
+ const scrollQueued = useRef(false);
44
+ const containerRef = useRef(null);
45
+ const { t } = useTranslation();
44
46
  const configApi = useApi(configApiRef);
45
47
  const questionValidationEnabled = configApi.getOptionalBoolean("lightspeed.questionValidation") ?? true;
46
48
  const cmessages = useBufferedMessages(messages, 30);
@@ -50,7 +52,7 @@ const LightspeedChatBox = React__default.forwardRef(
50
52
  conversationId,
51
53
  isStreaming
52
54
  );
53
- React__default.useImperativeHandle(ref, () => ({
55
+ useImperativeHandle(ref, () => ({
54
56
  scrollToBottom: () => {
55
57
  if (scrollQueued.current) return;
56
58
  scrollQueued.current = true;
@@ -60,7 +62,7 @@ const LightspeedChatBox = React__default.forwardRef(
60
62
  });
61
63
  }
62
64
  }));
63
- React__default.useEffect(() => {
65
+ useEffect(() => {
64
66
  if (!autoScroll || scrollQueued.current) return undefined;
65
67
  scrollQueued.current = true;
66
68
  const rafId = requestAnimationFrame(() => {
@@ -80,39 +82,46 @@ const LightspeedChatBox = React__default.forwardRef(
80
82
  };
81
83
  }, [autoScroll, cmessages, containerRef]);
82
84
  const messageBoxClasses = `${classes.container} ${classes.userMessageText}`;
83
- return /* @__PURE__ */ React__default.createElement(
85
+ return /* @__PURE__ */ jsxs(
84
86
  MessageBox,
85
87
  {
86
88
  className: welcomePrompts.length ? `${messageBoxClasses} ${classes.prompt}` : messageBoxClasses,
87
89
  announcement,
88
90
  ref: containerRef,
89
91
  onScrollToTopClick: scrollToTop,
90
- onScrollToBottomClick: scrollToBottom
91
- },
92
- /* @__PURE__ */ React__default.createElement("div", null, /* @__PURE__ */ React__default.createElement(
93
- Alert,
94
- {
95
- title: "Important",
96
- variant: "info",
97
- isInline: true,
98
- className: classes.alert
99
- },
100
- questionValidationEnabled ? FUNCTION_DISCLAIMER : FUNCTION_DISCLAIMER_WITHOUT_QUESTION_VALIDATION
101
- ), /* @__PURE__ */ React__default.createElement("br", null)),
102
- welcomePrompts.length ? /* @__PURE__ */ React__default.createElement(
103
- ChatbotWelcomePrompt,
104
- {
105
- title: `Hello, ${profileLoading ? "..." : userName ?? "Guest"}`,
106
- description: "How can I help you today?",
107
- prompts: welcomePrompts
108
- }
109
- ) : /* @__PURE__ */ React__default.createElement("br", null),
110
- conversationMessages.map((message, index) => {
111
- if (index === cmessages.length - 1) {
112
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, { key: `${message.role}-${index}` }, /* @__PURE__ */ React__default.createElement(Message, { key: `${message.role}-${index}`, ...message }));
113
- }
114
- return /* @__PURE__ */ React__default.createElement(Message, { key: `${message.role}-${index}`, ...message });
115
- })
92
+ onScrollToBottomClick: scrollToBottom,
93
+ children: [
94
+ /* @__PURE__ */ jsxs("div", { children: [
95
+ /* @__PURE__ */ jsx(
96
+ Alert,
97
+ {
98
+ title: t("aria.important"),
99
+ variant: "info",
100
+ isInline: true,
101
+ className: classes.alert,
102
+ children: questionValidationEnabled ? t("disclaimer.withValidation") : t("disclaimer.withoutValidation")
103
+ }
104
+ ),
105
+ /* @__PURE__ */ jsx("br", {})
106
+ ] }),
107
+ welcomePrompts.length ? /* @__PURE__ */ jsx(
108
+ ChatbotWelcomePrompt,
109
+ {
110
+ title: t("chatbox.welcome.greeting", {
111
+ userName: profileLoading ? t("user.loading") : userName ?? t("user.guest")
112
+ }),
113
+ description: t("chatbox.welcome.description"),
114
+ prompts: welcomePrompts
115
+ }
116
+ ) : /* @__PURE__ */ jsx("br", {}),
117
+ conversationMessages.map((message, index) => {
118
+ if (index === cmessages.length - 1) {
119
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Message, { ...message }, `${message.role}-${index}`) }, `${message.role}-${index}`);
120
+ }
121
+ return /* @__PURE__ */ jsx(Message, { ...message }, `${message.role}-${index}`);
122
+ })
123
+ ]
124
+ }
116
125
  );
117
126
  }
118
127
  );
@@ -1 +1 @@
1
- {"version":3,"file":"LightspeedChatBox.esm.js","sources":["../../src/components/LightspeedChatBox.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 React from 'react';\n\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { makeStyles } from '@material-ui/core';\nimport {\n ChatbotWelcomePrompt,\n Message,\n MessageBox,\n MessageBoxHandle,\n MessageProps,\n WelcomePrompt,\n} from '@patternfly/chatbot';\nimport { Alert } from '@patternfly/react-core';\n\nimport {\n FUNCTION_DISCLAIMER,\n FUNCTION_DISCLAIMER_WITHOUT_QUESTION_VALIDATION,\n} from '../const';\nimport { useAutoScroll } from '../hooks/useAutoScroll';\nimport { useBufferedMessages } from '../hooks/useBufferedMessages';\nimport { useFeedbackActions } from '../hooks/useFeedbackActions';\n\nconst useStyles = makeStyles(theme => ({\n prompt: {\n 'justify-content': 'flex-end',\n },\n container: {\n maxWidth: 'unset !important',\n },\n alert: {\n background: 'unset !important',\n },\n userMessageText: {\n '& div.pf-chatbot__message--user': {\n '& div.pf-chatbot__message-text': {\n '& p': {\n color: theme.palette.common.white,\n },\n },\n },\n },\n}));\n\ntype LightspeedChatBoxProps = {\n userName?: string;\n messages: MessageProps[];\n profileLoading: boolean;\n announcement: string | undefined;\n welcomePrompts: WelcomePrompt[];\n conversationId: string;\n isStreaming: boolean;\n};\n\nexport interface ScrollContainerHandle {\n scrollToBottom: () => void;\n}\n\nexport const LightspeedChatBox = React.forwardRef(\n (\n {\n userName,\n messages,\n announcement,\n conversationId,\n profileLoading,\n welcomePrompts,\n isStreaming,\n }: LightspeedChatBoxProps,\n ref: React.ForwardedRef<ScrollContainerHandle>,\n ) => {\n const classes = useStyles();\n const scrollQueued = React.useRef(false);\n const containerRef = React.useRef<MessageBoxHandle>(null);\n\n const configApi = useApi(configApiRef);\n const questionValidationEnabled =\n configApi.getOptionalBoolean('lightspeed.questionValidation') ?? true;\n const cmessages = useBufferedMessages(messages, 30);\n const { autoScroll, scrollToBottom, scrollToTop } =\n useAutoScroll(containerRef);\n const conversationMessages = useFeedbackActions(\n cmessages,\n conversationId,\n isStreaming,\n );\n\n React.useImperativeHandle(ref, () => ({\n scrollToBottom: () => {\n if (scrollQueued.current) return;\n scrollQueued.current = true;\n\n requestAnimationFrame(() => {\n scrollToBottom();\n scrollQueued.current = false;\n });\n },\n }));\n\n // Auto-scrolls to the latest message\n React.useEffect(() => {\n if (!autoScroll || scrollQueued.current) return undefined;\n\n scrollQueued.current = true;\n\n const rafId = requestAnimationFrame(() => {\n const container = containerRef.current;\n if (!container) return;\n\n setTimeout(() => {\n container.scrollTo({\n top: container.scrollHeight,\n behavior: 'auto',\n });\n }, 0);\n\n scrollQueued.current = false;\n });\n\n return () => {\n cancelAnimationFrame(rafId);\n scrollQueued.current = false;\n };\n\n // eslint-disable-next-line\n }, [autoScroll, cmessages, containerRef]);\n\n const messageBoxClasses = `${classes.container} ${classes.userMessageText}`;\n return (\n <MessageBox\n className={\n welcomePrompts.length\n ? `${messageBoxClasses} ${classes.prompt}`\n : messageBoxClasses\n }\n announcement={announcement}\n ref={containerRef}\n onScrollToTopClick={scrollToTop}\n onScrollToBottomClick={scrollToBottom}\n >\n <div>\n <Alert\n title=\"Important\"\n variant=\"info\"\n isInline\n className={classes.alert}\n >\n {questionValidationEnabled\n ? FUNCTION_DISCLAIMER\n : FUNCTION_DISCLAIMER_WITHOUT_QUESTION_VALIDATION}\n </Alert>\n <br />\n </div>\n {welcomePrompts.length ? (\n <ChatbotWelcomePrompt\n title={`Hello, ${profileLoading ? '...' : (userName ?? 'Guest')}`}\n description=\"How can I help you today?\"\n prompts={welcomePrompts}\n />\n ) : (\n <br />\n )}\n {conversationMessages.map((message, index) => {\n if (index === cmessages.length - 1) {\n return (\n <React.Fragment key={`${message.role}-${index}`}>\n <Message key={`${message.role}-${index}`} {...message} />\n </React.Fragment>\n );\n }\n return <Message key={`${message.role}-${index}`} {...message} />;\n })}\n </MessageBox>\n );\n },\n);\n"],"names":["React"],"mappings":";;;;;;;;;;AAuCA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,MAAQ,EAAA;AAAA,IACN,iBAAmB,EAAA;AAAA,GACrB;AAAA,EACA,SAAW,EAAA;AAAA,IACT,QAAU,EAAA;AAAA,GACZ;AAAA,EACA,KAAO,EAAA;AAAA,IACL,UAAY,EAAA;AAAA,GACd;AAAA,EACA,eAAiB,EAAA;AAAA,IACf,iCAAmC,EAAA;AAAA,MACjC,gCAAkC,EAAA;AAAA,QAChC,KAAO,EAAA;AAAA,UACL,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,MAAO,CAAA;AAAA;AAC9B;AACF;AACF;AAEJ,CAAE,CAAA,CAAA;AAgBK,MAAM,oBAAoBA,cAAM,CAAA,UAAA;AAAA,EACrC,CACE;AAAA,IACE,QAAA;AAAA,IACA,QAAA;AAAA,IACA,YAAA;AAAA,IACA,cAAA;AAAA,IACA,cAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,KAEF,GACG,KAAA;AACH,IAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,IAAM,MAAA,YAAA,GAAeA,cAAM,CAAA,MAAA,CAAO,KAAK,CAAA;AACvC,IAAM,MAAA,YAAA,GAAeA,cAAM,CAAA,MAAA,CAAyB,IAAI,CAAA;AAExD,IAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA;AACrC,IAAA,MAAM,yBACJ,GAAA,SAAA,CAAU,kBAAmB,CAAA,+BAA+B,CAAK,IAAA,IAAA;AACnE,IAAM,MAAA,SAAA,GAAY,mBAAoB,CAAA,QAAA,EAAU,EAAE,CAAA;AAClD,IAAA,MAAM,EAAE,UAAY,EAAA,cAAA,EAAgB,WAAY,EAAA,GAC9C,cAAc,YAAY,CAAA;AAC5B,IAAA,MAAM,oBAAuB,GAAA,kBAAA;AAAA,MAC3B,SAAA;AAAA,MACA,cAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAMA,cAAA,CAAA,mBAAA,CAAoB,KAAK,OAAO;AAAA,MACpC,gBAAgB,MAAM;AACpB,QAAA,IAAI,aAAa,OAAS,EAAA;AAC1B,QAAA,YAAA,CAAa,OAAU,GAAA,IAAA;AAEvB,QAAA,qBAAA,CAAsB,MAAM;AAC1B,UAAe,cAAA,EAAA;AACf,UAAA,YAAA,CAAa,OAAU,GAAA,KAAA;AAAA,SACxB,CAAA;AAAA;AACH,KACA,CAAA,CAAA;AAGF,IAAAA,cAAA,CAAM,UAAU,MAAM;AACpB,MAAA,IAAI,CAAC,UAAA,IAAc,YAAa,CAAA,OAAA,EAAgB,OAAA,SAAA;AAEhD,MAAA,YAAA,CAAa,OAAU,GAAA,IAAA;AAEvB,MAAM,MAAA,KAAA,GAAQ,sBAAsB,MAAM;AACxC,QAAA,MAAM,YAAY,YAAa,CAAA,OAAA;AAC/B,QAAA,IAAI,CAAC,SAAW,EAAA;AAEhB,QAAA,UAAA,CAAW,MAAM;AACf,UAAA,SAAA,CAAU,QAAS,CAAA;AAAA,YACjB,KAAK,SAAU,CAAA,YAAA;AAAA,YACf,QAAU,EAAA;AAAA,WACX,CAAA;AAAA,WACA,CAAC,CAAA;AAEJ,QAAA,YAAA,CAAa,OAAU,GAAA,KAAA;AAAA,OACxB,CAAA;AAED,MAAA,OAAO,MAAM;AACX,QAAA,oBAAA,CAAqB,KAAK,CAAA;AAC1B,QAAA,YAAA,CAAa,OAAU,GAAA,KAAA;AAAA,OACzB;AAAA,KAGC,EAAA,CAAC,UAAY,EAAA,SAAA,EAAW,YAAY,CAAC,CAAA;AAExC,IAAA,MAAM,oBAAoB,CAAG,EAAA,OAAA,CAAQ,SAAS,CAAA,CAAA,EAAI,QAAQ,eAAe,CAAA,CAAA;AACzE,IACE,uBAAAA,cAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,SAAA,EACE,eAAe,MACX,GAAA,CAAA,EAAG,iBAAiB,CAAI,CAAA,EAAA,OAAA,CAAQ,MAAM,CACtC,CAAA,GAAA,iBAAA;AAAA,QAEN,YAAA;AAAA,QACA,GAAK,EAAA,YAAA;AAAA,QACL,kBAAoB,EAAA,WAAA;AAAA,QACpB,qBAAuB,EAAA;AAAA,OAAA;AAAA,mDAEtB,KACC,EAAA,IAAA,kBAAAA,cAAA,CAAA,aAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,KAAM,EAAA,WAAA;AAAA,UACN,OAAQ,EAAA,MAAA;AAAA,UACR,QAAQ,EAAA,IAAA;AAAA,UACR,WAAW,OAAQ,CAAA;AAAA,SAAA;AAAA,QAElB,4BACG,mBACA,GAAA;AAAA,OACN,kBACCA,cAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAG,CACN,CAAA;AAAA,MACC,eAAe,MACd,mBAAAA,cAAA,CAAA,aAAA;AAAA,QAAC,oBAAA;AAAA,QAAA;AAAA,UACC,KAAO,EAAA,CAAA,OAAA,EAAU,cAAiB,GAAA,KAAA,GAAS,YAAY,OAAQ,CAAA,CAAA;AAAA,UAC/D,WAAY,EAAA,2BAAA;AAAA,UACZ,OAAS,EAAA;AAAA;AAAA,OACX,gDAEC,IAAG,EAAA,IAAA,CAAA;AAAA,MAEL,oBAAqB,CAAA,GAAA,CAAI,CAAC,OAAA,EAAS,KAAU,KAAA;AAC5C,QAAI,IAAA,KAAA,KAAU,SAAU,CAAA,MAAA,GAAS,CAAG,EAAA;AAClC,UACE,uBAAAA,cAAA,CAAA,aAAA,CAACA,eAAM,QAAN,EAAA,EAAe,KAAK,CAAG,EAAA,OAAA,CAAQ,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAA,+CAC1C,OAAQ,EAAA,EAAA,GAAA,EAAK,GAAG,OAAQ,CAAA,IAAI,IAAI,KAAK,CAAA,CAAA,EAAK,GAAG,OAAA,EAAS,CACzD,CAAA;AAAA;AAGJ,QAAO,uBAAAA,cAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,GAAA,EAAK,CAAG,EAAA,OAAA,CAAQ,IAAI,CAAI,CAAA,EAAA,KAAK,CAAK,CAAA,EAAA,GAAG,OAAS,EAAA,CAAA;AAAA,OAC/D;AAAA,KACH;AAAA;AAGN;;;;"}
1
+ {"version":3,"file":"LightspeedChatBox.esm.js","sources":["../../src/components/LightspeedChatBox.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 {\n ForwardedRef,\n forwardRef,\n Fragment,\n useEffect,\n useImperativeHandle,\n useRef,\n} from 'react';\n\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { makeStyles } from '@material-ui/core';\nimport {\n ChatbotWelcomePrompt,\n Message,\n MessageBox,\n MessageBoxHandle,\n MessageProps,\n WelcomePrompt,\n} from '@patternfly/chatbot';\nimport { Alert } from '@patternfly/react-core';\n\nimport { useAutoScroll } from '../hooks/useAutoScroll';\nimport { useBufferedMessages } from '../hooks/useBufferedMessages';\nimport { useFeedbackActions } from '../hooks/useFeedbackActions';\nimport { useTranslation } from '../hooks/useTranslation';\n\nconst useStyles = makeStyles(theme => ({\n prompt: {\n 'justify-content': 'flex-end',\n },\n container: {\n maxWidth: 'unset !important',\n },\n alert: {\n background: 'unset !important',\n },\n userMessageText: {\n '& div.pf-chatbot__message--user': {\n '& div.pf-chatbot__message-text': {\n '& p': {\n color: theme.palette.common.white,\n },\n },\n },\n },\n}));\n\ntype LightspeedChatBoxProps = {\n userName?: string;\n messages: MessageProps[];\n profileLoading: boolean;\n announcement: string | undefined;\n welcomePrompts: WelcomePrompt[];\n conversationId: string;\n isStreaming: boolean;\n};\n\nexport interface ScrollContainerHandle {\n scrollToBottom: () => void;\n}\n\nexport const LightspeedChatBox = forwardRef(\n (\n {\n userName,\n messages,\n announcement,\n conversationId,\n profileLoading,\n welcomePrompts,\n isStreaming,\n }: LightspeedChatBoxProps,\n ref: ForwardedRef<ScrollContainerHandle>,\n ) => {\n const classes = useStyles();\n const scrollQueued = useRef(false);\n const containerRef = useRef<MessageBoxHandle>(null);\n const { t } = useTranslation();\n\n const configApi = useApi(configApiRef);\n const questionValidationEnabled =\n configApi.getOptionalBoolean('lightspeed.questionValidation') ?? true;\n const cmessages = useBufferedMessages(messages, 30);\n const { autoScroll, scrollToBottom, scrollToTop } =\n useAutoScroll(containerRef);\n const conversationMessages = useFeedbackActions(\n cmessages,\n conversationId,\n isStreaming,\n );\n\n useImperativeHandle(ref, () => ({\n scrollToBottom: () => {\n if (scrollQueued.current) return;\n scrollQueued.current = true;\n\n requestAnimationFrame(() => {\n scrollToBottom();\n scrollQueued.current = false;\n });\n },\n }));\n\n // Auto-scrolls to the latest message\n useEffect(() => {\n if (!autoScroll || scrollQueued.current) return undefined;\n\n scrollQueued.current = true;\n\n const rafId = requestAnimationFrame(() => {\n const container = containerRef.current;\n if (!container) return;\n\n setTimeout(() => {\n container.scrollTo({\n top: container.scrollHeight,\n behavior: 'auto',\n });\n }, 0);\n\n scrollQueued.current = false;\n });\n\n return () => {\n cancelAnimationFrame(rafId);\n scrollQueued.current = false;\n };\n\n // eslint-disable-next-line\n }, [autoScroll, cmessages, containerRef]);\n\n const messageBoxClasses = `${classes.container} ${classes.userMessageText}`;\n return (\n <MessageBox\n className={\n welcomePrompts.length\n ? `${messageBoxClasses} ${classes.prompt}`\n : messageBoxClasses\n }\n announcement={announcement}\n ref={containerRef}\n onScrollToTopClick={scrollToTop}\n onScrollToBottomClick={scrollToBottom}\n >\n <div>\n <Alert\n title={t('aria.important')}\n variant=\"info\"\n isInline\n className={classes.alert}\n >\n {questionValidationEnabled\n ? t('disclaimer.withValidation')\n : t('disclaimer.withoutValidation')}\n </Alert>\n <br />\n </div>\n {welcomePrompts.length ? (\n <ChatbotWelcomePrompt\n title={t('chatbox.welcome.greeting' as any, {\n userName: profileLoading\n ? t('user.loading')\n : (userName ?? t('user.guest')),\n })}\n description={t('chatbox.welcome.description')}\n prompts={welcomePrompts}\n />\n ) : (\n <br />\n )}\n {conversationMessages.map((message, index) => {\n if (index === cmessages.length - 1) {\n return (\n <Fragment key={`${message.role}-${index}`}>\n <Message key={`${message.role}-${index}`} {...message} />\n </Fragment>\n );\n }\n return <Message key={`${message.role}-${index}`} {...message} />;\n })}\n </MessageBox>\n );\n },\n);\n"],"names":[],"mappings":";;;;;;;;;;;AA2CA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,MAAQ,EAAA;AAAA,IACN,iBAAmB,EAAA;AAAA,GACrB;AAAA,EACA,SAAW,EAAA;AAAA,IACT,QAAU,EAAA;AAAA,GACZ;AAAA,EACA,KAAO,EAAA;AAAA,IACL,UAAY,EAAA;AAAA,GACd;AAAA,EACA,eAAiB,EAAA;AAAA,IACf,iCAAmC,EAAA;AAAA,MACjC,gCAAkC,EAAA;AAAA,QAChC,KAAO,EAAA;AAAA,UACL,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,MAAO,CAAA;AAAA;AAC9B;AACF;AACF;AAEJ,CAAE,CAAA,CAAA;AAgBK,MAAM,iBAAoB,GAAA,UAAA;AAAA,EAC/B,CACE;AAAA,IACE,QAAA;AAAA,IACA,QAAA;AAAA,IACA,YAAA;AAAA,IACA,cAAA;AAAA,IACA,cAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,KAEF,GACG,KAAA;AACH,IAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,IAAM,MAAA,YAAA,GAAe,OAAO,KAAK,CAAA;AACjC,IAAM,MAAA,YAAA,GAAe,OAAyB,IAAI,CAAA;AAClD,IAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAE7B,IAAM,MAAA,SAAA,GAAY,OAAO,YAAY,CAAA;AACrC,IAAA,MAAM,yBACJ,GAAA,SAAA,CAAU,kBAAmB,CAAA,+BAA+B,CAAK,IAAA,IAAA;AACnE,IAAM,MAAA,SAAA,GAAY,mBAAoB,CAAA,QAAA,EAAU,EAAE,CAAA;AAClD,IAAA,MAAM,EAAE,UAAY,EAAA,cAAA,EAAgB,WAAY,EAAA,GAC9C,cAAc,YAAY,CAAA;AAC5B,IAAA,MAAM,oBAAuB,GAAA,kBAAA;AAAA,MAC3B,SAAA;AAAA,MACA,cAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,mBAAA,CAAoB,KAAK,OAAO;AAAA,MAC9B,gBAAgB,MAAM;AACpB,QAAA,IAAI,aAAa,OAAS,EAAA;AAC1B,QAAA,YAAA,CAAa,OAAU,GAAA,IAAA;AAEvB,QAAA,qBAAA,CAAsB,MAAM;AAC1B,UAAe,cAAA,EAAA;AACf,UAAA,YAAA,CAAa,OAAU,GAAA,KAAA;AAAA,SACxB,CAAA;AAAA;AACH,KACA,CAAA,CAAA;AAGF,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,IAAI,CAAC,UAAA,IAAc,YAAa,CAAA,OAAA,EAAgB,OAAA,SAAA;AAEhD,MAAA,YAAA,CAAa,OAAU,GAAA,IAAA;AAEvB,MAAM,MAAA,KAAA,GAAQ,sBAAsB,MAAM;AACxC,QAAA,MAAM,YAAY,YAAa,CAAA,OAAA;AAC/B,QAAA,IAAI,CAAC,SAAW,EAAA;AAEhB,QAAA,UAAA,CAAW,MAAM;AACf,UAAA,SAAA,CAAU,QAAS,CAAA;AAAA,YACjB,KAAK,SAAU,CAAA,YAAA;AAAA,YACf,QAAU,EAAA;AAAA,WACX,CAAA;AAAA,WACA,CAAC,CAAA;AAEJ,QAAA,YAAA,CAAa,OAAU,GAAA,KAAA;AAAA,OACxB,CAAA;AAED,MAAA,OAAO,MAAM;AACX,QAAA,oBAAA,CAAqB,KAAK,CAAA;AAC1B,QAAA,YAAA,CAAa,OAAU,GAAA,KAAA;AAAA,OACzB;AAAA,KAGC,EAAA,CAAC,UAAY,EAAA,SAAA,EAAW,YAAY,CAAC,CAAA;AAExC,IAAA,MAAM,oBAAoB,CAAG,EAAA,OAAA,CAAQ,SAAS,CAAA,CAAA,EAAI,QAAQ,eAAe,CAAA,CAAA;AACzE,IACE,uBAAA,IAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,SAAA,EACE,eAAe,MACX,GAAA,CAAA,EAAG,iBAAiB,CAAI,CAAA,EAAA,OAAA,CAAQ,MAAM,CACtC,CAAA,GAAA,iBAAA;AAAA,QAEN,YAAA;AAAA,QACA,GAAK,EAAA,YAAA;AAAA,QACL,kBAAoB,EAAA,WAAA;AAAA,QACpB,qBAAuB,EAAA,cAAA;AAAA,QAEvB,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,KACC,EAAA,EAAA,QAAA,EAAA;AAAA,4BAAA,GAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACC,KAAA,EAAO,EAAE,gBAAgB,CAAA;AAAA,gBACzB,OAAQ,EAAA,MAAA;AAAA,gBACR,QAAQ,EAAA,IAAA;AAAA,gBACR,WAAW,OAAQ,CAAA,KAAA;AAAA,gBAElB,QACG,EAAA,yBAAA,GAAA,CAAA,CAAE,2BAA2B,CAAA,GAC7B,EAAE,8BAA8B;AAAA;AAAA,aACtC;AAAA,gCACC,IAAG,EAAA,EAAA;AAAA,WACN,EAAA,CAAA;AAAA,UACC,eAAe,MACd,mBAAA,GAAA;AAAA,YAAC,oBAAA;AAAA,YAAA;AAAA,cACC,KAAA,EAAO,EAAE,0BAAmC,EAAA;AAAA,gBAC1C,UAAU,cACN,GAAA,CAAA,CAAE,cAAc,CACf,GAAA,QAAA,IAAY,EAAE,YAAY;AAAA,eAChC,CAAA;AAAA,cACD,WAAA,EAAa,EAAE,6BAA6B,CAAA;AAAA,cAC5C,OAAS,EAAA;AAAA;AAAA,WACX,uBAEC,IAAG,EAAA,EAAA,CAAA;AAAA,UAEL,oBAAqB,CAAA,GAAA,CAAI,CAAC,OAAA,EAAS,KAAU,KAAA;AAC5C,YAAI,IAAA,KAAA,KAAU,SAAU,CAAA,MAAA,GAAS,CAAG,EAAA;AAClC,cAAA,2BACG,QACC,EAAA,EAAA,QAAA,kBAAA,GAAA,CAAC,WAA0C,GAAG,OAAA,EAAA,EAAhC,GAAG,OAAQ,CAAA,IAAI,CAAI,CAAA,EAAA,KAAK,EAAiB,CAD1C,EAAA,EAAA,CAAA,EAAG,QAAQ,IAAI,CAAA,CAAA,EAAI,KAAK,CAEvC,CAAA,CAAA;AAAA;AAGJ,YAAO,uBAAA,GAAA,CAAC,WAA0C,GAAG,OAAA,EAAA,EAAhC,GAAG,OAAQ,CAAA,IAAI,CAAI,CAAA,EAAA,KAAK,CAAiB,CAAA,CAAA;AAAA,WAC/D;AAAA;AAAA;AAAA,KACH;AAAA;AAGN;;;;"}
@@ -1,7 +1,9 @@
1
- import React__default from 'react';
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useState } from 'react';
2
3
  import { makeStyles, createStyles } from '@material-ui/core';
3
4
  import { ChatbotHeaderActions } from '@patternfly/chatbot';
4
5
  import { Dropdown, DropdownList, DropdownItem, MenuToggle } from '@patternfly/react-core';
6
+ import { useTranslation } from '../hooks/useTranslation.esm.js';
5
7
 
6
8
  const useStyles = makeStyles(
7
9
  () => createStyles({
@@ -18,20 +20,21 @@ const LightspeedChatBoxHeader = ({
18
20
  handleSelectedModel,
19
21
  models
20
22
  }) => {
21
- const [isOptionsMenuOpen, setIsOptionsMenuOpen] = React__default.useState(false);
23
+ const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);
24
+ const { t } = useTranslation();
22
25
  const styles = useStyles();
23
- const toggle = (toggleRef) => /* @__PURE__ */ React__default.createElement(
26
+ const toggle = (toggleRef) => /* @__PURE__ */ jsx(
24
27
  MenuToggle,
25
28
  {
26
29
  variant: "secondary",
27
- "aria-label": "Chatbot selector",
30
+ "aria-label": t("aria.chatbotSelector"),
28
31
  ref: toggleRef,
29
32
  isExpanded: isOptionsMenuOpen,
30
- onClick: () => setIsOptionsMenuOpen(!isOptionsMenuOpen)
31
- },
32
- selectedModel
33
+ onClick: () => setIsOptionsMenuOpen(!isOptionsMenuOpen),
34
+ children: selectedModel
35
+ }
33
36
  );
34
- return /* @__PURE__ */ React__default.createElement(ChatbotHeaderActions, null, /* @__PURE__ */ React__default.createElement(
37
+ return /* @__PURE__ */ jsx(ChatbotHeaderActions, { children: /* @__PURE__ */ jsx(
35
38
  Dropdown,
36
39
  {
37
40
  className: styles.dropdown,
@@ -44,10 +47,10 @@ const LightspeedChatBoxHeader = ({
44
47
  popperProps: { position: "right" },
45
48
  shouldFocusToggleOnSelect: true,
46
49
  shouldFocusFirstItemOnOpen: false,
47
- toggle
48
- },
49
- /* @__PURE__ */ React__default.createElement(DropdownList, null, models.map((m) => /* @__PURE__ */ React__default.createElement(DropdownItem, { value: m.value, key: m.value }, m.label)))
50
- ));
50
+ toggle,
51
+ children: /* @__PURE__ */ jsx(DropdownList, { children: models.map((m) => /* @__PURE__ */ jsx(DropdownItem, { value: m.value, children: m.label }, m.value)) })
52
+ }
53
+ ) });
51
54
  };
52
55
 
53
56
  export { LightspeedChatBoxHeader };
@@ -1 +1 @@
1
- {"version":3,"file":"LightspeedChatBoxHeader.esm.js","sources":["../../src/components/LightspeedChatBoxHeader.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 React from 'react';\n\nimport { createStyles, makeStyles } from '@material-ui/core';\nimport { ChatbotHeaderActions } from '@patternfly/chatbot';\nimport {\n Dropdown,\n DropdownItem,\n DropdownList,\n MenuToggle,\n MenuToggleElement,\n} from '@patternfly/react-core';\n\ntype LightspeedChatBoxHeaderProps = {\n selectedModel: string;\n handleSelectedModel: (item: string) => void;\n models: { label: string; value: string }[];\n};\n\nconst useStyles = makeStyles(() =>\n createStyles({\n dropdown: {\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\n },\n }),\n);\n\nexport const LightspeedChatBoxHeader = ({\n selectedModel,\n handleSelectedModel,\n models,\n}: LightspeedChatBoxHeaderProps) => {\n const [isOptionsMenuOpen, setIsOptionsMenuOpen] = React.useState(false);\n\n const styles = useStyles();\n\n const toggle = (toggleRef: React.Ref<MenuToggleElement>) => (\n <MenuToggle\n variant=\"secondary\"\n aria-label=\"Chatbot selector\"\n ref={toggleRef}\n isExpanded={isOptionsMenuOpen}\n onClick={() => setIsOptionsMenuOpen(!isOptionsMenuOpen)}\n >\n {selectedModel}\n </MenuToggle>\n );\n\n return (\n <ChatbotHeaderActions>\n <Dropdown\n className={styles.dropdown}\n isOpen={isOptionsMenuOpen}\n onSelect={(_e, value) => {\n handleSelectedModel(value as string);\n setIsOptionsMenuOpen(false);\n }}\n onOpenChange={isOpen => setIsOptionsMenuOpen(isOpen)}\n popperProps={{ position: 'right' }}\n shouldFocusToggleOnSelect\n shouldFocusFirstItemOnOpen={false}\n toggle={toggle}\n >\n <DropdownList>\n {models.map(m => (\n <DropdownItem value={m.value} key={m.value}>\n {m.label}\n </DropdownItem>\n ))}\n </DropdownList>\n </Dropdown>\n </ChatbotHeaderActions>\n );\n};\n"],"names":["React"],"mappings":";;;;;AAkCA,MAAM,SAAY,GAAA,UAAA;AAAA,EAAW,MAC3B,YAAa,CAAA;AAAA,IACX,QAAU,EAAA;AAAA,MACR,YAAc,EAAA;AAAA,QACZ,OAAS,EAAA,CAAA;AAAA,QACT,MAAQ,EAAA;AAAA;AACV;AACF,GACD;AACH,CAAA;AAEO,MAAM,0BAA0B,CAAC;AAAA,EACtC,aAAA;AAAA,EACA,mBAAA;AAAA,EACA;AACF,CAAoC,KAAA;AAClC,EAAA,MAAM,CAAC,iBAAmB,EAAA,oBAAoB,CAAI,GAAAA,cAAA,CAAM,SAAS,KAAK,CAAA;AAEtE,EAAA,MAAM,SAAS,SAAU,EAAA;AAEzB,EAAM,MAAA,MAAA,GAAS,CAAC,SACd,qBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,OAAQ,EAAA,WAAA;AAAA,MACR,YAAW,EAAA,kBAAA;AAAA,MACX,GAAK,EAAA,SAAA;AAAA,MACL,UAAY,EAAA,iBAAA;AAAA,MACZ,OAAS,EAAA,MAAM,oBAAqB,CAAA,CAAC,iBAAiB;AAAA,KAAA;AAAA,IAErD;AAAA,GACH;AAGF,EAAA,oDACG,oBACC,EAAA,IAAA,kBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,WAAW,MAAO,CAAA,QAAA;AAAA,MAClB,MAAQ,EAAA,iBAAA;AAAA,MACR,QAAA,EAAU,CAAC,EAAA,EAAI,KAAU,KAAA;AACvB,QAAA,mBAAA,CAAoB,KAAe,CAAA;AACnC,QAAA,oBAAA,CAAqB,KAAK,CAAA;AAAA,OAC5B;AAAA,MACA,YAAA,EAAc,CAAU,MAAA,KAAA,oBAAA,CAAqB,MAAM,CAAA;AAAA,MACnD,WAAA,EAAa,EAAE,QAAA,EAAU,OAAQ,EAAA;AAAA,MACjC,yBAAyB,EAAA,IAAA;AAAA,MACzB,0BAA4B,EAAA,KAAA;AAAA,MAC5B;AAAA,KAAA;AAAA,iDAEC,YACE,EAAA,IAAA,EAAA,MAAA,CAAO,GAAI,CAAA,CAAA,CAAA,kDACT,YAAa,EAAA,EAAA,KAAA,EAAO,CAAE,CAAA,KAAA,EAAO,KAAK,CAAE,CAAA,KAAA,EAAA,EAClC,CAAE,CAAA,KACL,CACD,CACH;AAAA,GAEJ,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"LightspeedChatBoxHeader.esm.js","sources":["../../src/components/LightspeedChatBoxHeader.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 { Ref, useState } from 'react';\n\nimport { createStyles, makeStyles } from '@material-ui/core';\nimport { ChatbotHeaderActions } from '@patternfly/chatbot';\nimport {\n Dropdown,\n DropdownItem,\n DropdownList,\n MenuToggle,\n MenuToggleElement,\n} from '@patternfly/react-core';\n\nimport { useTranslation } from '../hooks/useTranslation';\n\ntype LightspeedChatBoxHeaderProps = {\n selectedModel: string;\n handleSelectedModel: (item: string) => void;\n models: { label: string; value: string }[];\n};\n\nconst useStyles = makeStyles(() =>\n createStyles({\n dropdown: {\n '& ul, & li': {\n padding: 0,\n margin: 0,\n },\n },\n }),\n);\n\nexport const LightspeedChatBoxHeader = ({\n selectedModel,\n handleSelectedModel,\n models,\n}: LightspeedChatBoxHeaderProps) => {\n const [isOptionsMenuOpen, setIsOptionsMenuOpen] = useState(false);\n const { t } = useTranslation();\n\n const styles = useStyles();\n\n const toggle = (toggleRef: Ref<MenuToggleElement>) => (\n <MenuToggle\n variant=\"secondary\"\n aria-label={t('aria.chatbotSelector')}\n ref={toggleRef}\n isExpanded={isOptionsMenuOpen}\n onClick={() => setIsOptionsMenuOpen(!isOptionsMenuOpen)}\n >\n {selectedModel}\n </MenuToggle>\n );\n\n return (\n <ChatbotHeaderActions>\n <Dropdown\n className={styles.dropdown}\n isOpen={isOptionsMenuOpen}\n onSelect={(_e, value) => {\n handleSelectedModel(value as string);\n setIsOptionsMenuOpen(false);\n }}\n onOpenChange={isOpen => setIsOptionsMenuOpen(isOpen)}\n popperProps={{ position: 'right' }}\n shouldFocusToggleOnSelect\n shouldFocusFirstItemOnOpen={false}\n toggle={toggle}\n >\n <DropdownList>\n {models.map(m => (\n <DropdownItem value={m.value} key={m.value}>\n {m.label}\n </DropdownItem>\n ))}\n </DropdownList>\n </Dropdown>\n </ChatbotHeaderActions>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAoCA,MAAM,SAAY,GAAA,UAAA;AAAA,EAAW,MAC3B,YAAa,CAAA;AAAA,IACX,QAAU,EAAA;AAAA,MACR,YAAc,EAAA;AAAA,QACZ,OAAS,EAAA,CAAA;AAAA,QACT,MAAQ,EAAA;AAAA;AACV;AACF,GACD;AACH,CAAA;AAEO,MAAM,0BAA0B,CAAC;AAAA,EACtC,aAAA;AAAA,EACA,mBAAA;AAAA,EACA;AACF,CAAoC,KAAA;AAClC,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAI,SAAS,KAAK,CAAA;AAChE,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAE7B,EAAA,MAAM,SAAS,SAAU,EAAA;AAEzB,EAAM,MAAA,MAAA,GAAS,CAAC,SACd,qBAAA,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,OAAQ,EAAA,WAAA;AAAA,MACR,YAAA,EAAY,EAAE,sBAAsB,CAAA;AAAA,MACpC,GAAK,EAAA,SAAA;AAAA,MACL,UAAY,EAAA,iBAAA;AAAA,MACZ,OAAS,EAAA,MAAM,oBAAqB,CAAA,CAAC,iBAAiB,CAAA;AAAA,MAErD,QAAA,EAAA;AAAA;AAAA,GACH;AAGF,EAAA,2BACG,oBACC,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,WAAW,MAAO,CAAA,QAAA;AAAA,MAClB,MAAQ,EAAA,iBAAA;AAAA,MACR,QAAA,EAAU,CAAC,EAAA,EAAI,KAAU,KAAA;AACvB,QAAA,mBAAA,CAAoB,KAAe,CAAA;AACnC,QAAA,oBAAA,CAAqB,KAAK,CAAA;AAAA,OAC5B;AAAA,MACA,YAAA,EAAc,CAAU,MAAA,KAAA,oBAAA,CAAqB,MAAM,CAAA;AAAA,MACnD,WAAA,EAAa,EAAE,QAAA,EAAU,OAAQ,EAAA;AAAA,MACjC,yBAAyB,EAAA,IAAA;AAAA,MACzB,0BAA4B,EAAA,KAAA;AAAA,MAC5B,MAAA;AAAA,MAEA,QAAC,kBAAA,GAAA,CAAA,YAAA,EAAA,EACE,QAAO,EAAA,MAAA,CAAA,GAAA,CAAI,uBACT,GAAA,CAAA,YAAA,EAAA,EAAa,KAAO,EAAA,CAAA,CAAE,OACpB,QAAE,EAAA,CAAA,CAAA,KAAA,EAAA,EAD8B,CAAE,CAAA,KAErC,CACD,CACH,EAAA;AAAA;AAAA,GAEJ,EAAA,CAAA;AAEJ;;;;"}
@@ -1,8 +1,17 @@
1
- import * as React from 'react';
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useTranslation } from '../hooks/useTranslation.esm.js';
2
3
  import logo from '../images/logo-white.svg';
3
4
 
4
5
  const LightspeedIcon = () => {
5
- return /* @__PURE__ */ React.createElement("img", { src: logo, alt: "lightspeed icon", style: { height: "25px" } });
6
+ const { t } = useTranslation();
7
+ return /* @__PURE__ */ jsx(
8
+ "img",
9
+ {
10
+ src: logo,
11
+ alt: t("icon.lightspeed.alt"),
12
+ style: { height: "25px" }
13
+ }
14
+ );
6
15
  };
7
16
 
8
17
  export { LightspeedIcon };
@@ -1 +1 @@
1
- {"version":3,"file":"LightspeedIcon.esm.js","sources":["../../src/components/LightspeedIcon.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 * as React from 'react';\n\nimport logo from '../images/logo-white.svg';\n\n/**\n * @public\n * Lightspeed Icon\n */\nexport const LightspeedIcon = () => {\n return (\n <img src={logo as any} alt=\"lightspeed icon\" style={{ height: '25px' }} />\n );\n};\n"],"names":[],"mappings":";;;AAwBO,MAAM,iBAAiB,MAAM;AAClC,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,KAAI,EAAA,EAAA,GAAA,EAAK,IAAa,EAAA,GAAA,EAAI,mBAAkB,KAAO,EAAA,EAAE,MAAQ,EAAA,MAAA,EAAU,EAAA,CAAA;AAE5E;;;;"}
1
+ {"version":3,"file":"LightspeedIcon.esm.js","sources":["../../src/components/LightspeedIcon.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 { useTranslation } from '../hooks/useTranslation';\nimport logo from '../images/logo-white.svg';\n\n/**\n * @public\n * Lightspeed Icon\n */\nexport const LightspeedIcon = () => {\n const { t } = useTranslation();\n\n return (\n <img\n src={logo as any}\n alt={t('icon.lightspeed.alt')}\n style={{ height: '25px' }}\n />\n );\n};\n"],"names":[],"mappings":";;;;AAuBO,MAAM,iBAAiB,MAAM;AAClC,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAE7B,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAK,EAAA,IAAA;AAAA,MACL,GAAA,EAAK,EAAE,qBAAqB,CAAA;AAAA,MAC5B,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAO;AAAA;AAAA,GAC1B;AAEJ;;;;"}
@@ -1,4 +1,5 @@
1
- import React__default from 'react';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useState, useMemo, useEffect } from 'react';
2
3
  import { useAsync } from 'react-use';
3
4
  import { Page, Header, Content } from '@backstage/core-components';
4
5
  import { useApi, identityApiRef } from '@backstage/core-plugin-api';
@@ -6,6 +7,7 @@ import { makeStyles, createStyles, useTheme } from '@material-ui/core/styles';
6
7
  import { QueryClientProvider } from '@tanstack/react-query';
7
8
  import { useAllModels } from '../hooks/useAllModels.esm.js';
8
9
  import { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission.esm.js';
10
+ import { useTranslation } from '../hooks/useTranslation.esm.js';
9
11
  import queryClient from '../utils/queryClient.esm.js';
10
12
  import FileAttachmentContextProvider from './AttachmentContext.esm.js';
11
13
  import { LightspeedChat } from './LightSpeedChat.esm.js';
@@ -22,6 +24,7 @@ const THEME_DARK = "dark";
22
24
  const THEME_DARK_CLASS = "pf-v6-theme-dark";
23
25
  const LightspeedPageInner = () => {
24
26
  const classes = useStyles();
27
+ const { t } = useTranslation();
25
28
  const {
26
29
  palette: { type }
27
30
  } = useTheme();
@@ -31,12 +34,12 @@ const LightspeedPageInner = () => {
31
34
  const { value: profile, loading: profileLoading } = useAsync(
32
35
  async () => await identityApi.getProfileInfo()
33
36
  );
34
- const [selectedModel, setSelectedModel] = React__default.useState("");
35
- const modelsItems = React__default.useMemo(
37
+ const [selectedModel, setSelectedModel] = useState("");
38
+ const modelsItems = useMemo(
36
39
  () => models ? models.map((m) => ({ label: m.id, value: m.id })) : [],
37
40
  [models]
38
41
  );
39
- React__default.useEffect(() => {
42
+ useEffect(() => {
40
43
  const htmlTagElement = document.documentElement;
41
44
  if (type === THEME_DARK) {
42
45
  htmlTagElement.classList.add(THEME_DARK_CLASS);
@@ -44,35 +47,38 @@ const LightspeedPageInner = () => {
44
47
  htmlTagElement.classList.remove(THEME_DARK_CLASS);
45
48
  }
46
49
  }, [type]);
47
- React__default.useEffect(() => {
50
+ useEffect(() => {
48
51
  if (modelsItems.length > 0) setSelectedModel(modelsItems[0].value);
49
52
  }, [modelsItems]);
50
53
  if (loading) {
51
54
  return null;
52
55
  }
53
- return /* @__PURE__ */ React__default.createElement(Page, { themeId: "tool" }, /* @__PURE__ */ React__default.createElement(
54
- Header,
55
- {
56
- title: "Lightspeed",
57
- style: { display: "none" },
58
- pageTitleOverride: "Developer Lightspeed"
59
- }
60
- ), /* @__PURE__ */ React__default.createElement(Content, { className: classes.container }, !hasViewAccess ? /* @__PURE__ */ React__default.createElement(PermissionRequiredState, null) : /* @__PURE__ */ React__default.createElement(FileAttachmentContextProvider, null, /* @__PURE__ */ React__default.createElement(
61
- LightspeedChat,
62
- {
63
- selectedModel,
64
- handleSelectedModel: (item) => {
65
- setSelectedModel(item);
66
- },
67
- models: modelsItems,
68
- userName: profile?.displayName,
69
- avatar: profile?.picture,
70
- profileLoading
71
- }
72
- ))));
56
+ return /* @__PURE__ */ jsxs(Page, { themeId: "tool", children: [
57
+ /* @__PURE__ */ jsx(
58
+ Header,
59
+ {
60
+ title: t("page.title"),
61
+ style: { display: "none" },
62
+ pageTitleOverride: t("page.title")
63
+ }
64
+ ),
65
+ /* @__PURE__ */ jsx(Content, { className: classes.container, children: !hasViewAccess ? /* @__PURE__ */ jsx(PermissionRequiredState, {}) : /* @__PURE__ */ jsx(FileAttachmentContextProvider, { children: /* @__PURE__ */ jsx(
66
+ LightspeedChat,
67
+ {
68
+ selectedModel,
69
+ handleSelectedModel: (item) => {
70
+ setSelectedModel(item);
71
+ },
72
+ models: modelsItems,
73
+ userName: profile?.displayName,
74
+ avatar: profile?.picture,
75
+ profileLoading
76
+ }
77
+ ) }) })
78
+ ] });
73
79
  };
74
80
  const LightspeedPage = () => {
75
- return /* @__PURE__ */ React__default.createElement(QueryClientProvider, { client: queryClient }, /* @__PURE__ */ React__default.createElement(LightspeedPageInner, null));
81
+ return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(LightspeedPageInner, {}) });
76
82
  };
77
83
 
78
84
  export { LightspeedPage };
@@ -1 +1 @@
1
- {"version":3,"file":"LightspeedPage.esm.js","sources":["../../src/components/LightspeedPage.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 React from 'react';\nimport { useAsync } from 'react-use';\n\nimport { Content, Header, Page } from '@backstage/core-components';\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { createStyles, makeStyles, useTheme } from '@material-ui/core/styles';\nimport { QueryClientProvider } from '@tanstack/react-query';\n\nimport { useAllModels } from '../hooks/useAllModels';\nimport { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission';\nimport queryClient from '../utils/queryClient';\nimport FileAttachmentContextProvider from './AttachmentContext';\nimport { LightspeedChat } from './LightSpeedChat';\nimport PermissionRequiredState from './PermissionRequiredState';\n\nconst useStyles = makeStyles(() =>\n createStyles({\n container: {\n padding: '0px',\n },\n }),\n);\n\nconst THEME_DARK = 'dark';\nconst THEME_DARK_CLASS = 'pf-v6-theme-dark';\n\nconst LightspeedPageInner = () => {\n const classes = useStyles();\n const {\n palette: { type },\n } = useTheme();\n\n const identityApi = useApi(identityApiRef);\n\n const { data: models } = useAllModels();\n const { allowed: hasViewAccess, loading } = useLightspeedViewPermission();\n\n const { value: profile, loading: profileLoading } = useAsync(\n async () => await identityApi.getProfileInfo(),\n );\n\n const [selectedModel, setSelectedModel] = React.useState('');\n\n const modelsItems = React.useMemo(\n () => (models ? models.map(m => ({ label: m.id, value: m.id })) : []),\n [models],\n );\n\n React.useEffect(() => {\n const htmlTagElement = document.documentElement;\n if (type === THEME_DARK) {\n htmlTagElement.classList.add(THEME_DARK_CLASS);\n } else {\n htmlTagElement.classList.remove(THEME_DARK_CLASS);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [type]);\n\n React.useEffect(() => {\n if (modelsItems.length > 0) setSelectedModel(modelsItems[0].value);\n }, [modelsItems]);\n\n if (loading) {\n return null;\n }\n\n return (\n <Page themeId=\"tool\">\n <Header\n title=\"Lightspeed\"\n style={{ display: 'none' }}\n pageTitleOverride=\"Developer Lightspeed\"\n />\n <Content className={classes.container}>\n {!hasViewAccess ? (\n <PermissionRequiredState />\n ) : (\n <FileAttachmentContextProvider>\n <LightspeedChat\n selectedModel={selectedModel}\n handleSelectedModel={item => {\n setSelectedModel(item);\n }}\n models={modelsItems}\n userName={profile?.displayName}\n avatar={profile?.picture}\n profileLoading={profileLoading}\n />\n </FileAttachmentContextProvider>\n )}\n </Content>\n </Page>\n );\n};\n\nexport const LightspeedPage = () => {\n return (\n <QueryClientProvider client={queryClient}>\n <LightspeedPageInner />\n </QueryClientProvider>\n );\n};\n"],"names":["React"],"mappings":"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"}
1
+ {"version":3,"file":"LightspeedPage.esm.js","sources":["../../src/components/LightspeedPage.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect, useMemo, useState } from 'react';\nimport { useAsync } from 'react-use';\n\nimport { Content, Header, Page } from '@backstage/core-components';\nimport { identityApiRef, useApi } from '@backstage/core-plugin-api';\n\nimport { createStyles, makeStyles, useTheme } from '@material-ui/core/styles';\nimport { QueryClientProvider } from '@tanstack/react-query';\n\nimport { useAllModels } from '../hooks/useAllModels';\nimport { useLightspeedViewPermission } from '../hooks/useLightspeedViewPermission';\nimport { useTranslation } from '../hooks/useTranslation';\nimport queryClient from '../utils/queryClient';\nimport FileAttachmentContextProvider from './AttachmentContext';\nimport { LightspeedChat } from './LightSpeedChat';\nimport PermissionRequiredState from './PermissionRequiredState';\n\nconst useStyles = makeStyles(() =>\n createStyles({\n container: {\n padding: '0px',\n },\n }),\n);\n\nconst THEME_DARK = 'dark';\nconst THEME_DARK_CLASS = 'pf-v6-theme-dark';\n\nconst LightspeedPageInner = () => {\n const classes = useStyles();\n const { t } = useTranslation();\n const {\n palette: { type },\n } = useTheme();\n\n const identityApi = useApi(identityApiRef);\n\n const { data: models } = useAllModels();\n const { allowed: hasViewAccess, loading } = useLightspeedViewPermission();\n\n const { value: profile, loading: profileLoading } = useAsync(\n async () => await identityApi.getProfileInfo(),\n );\n\n const [selectedModel, setSelectedModel] = useState('');\n\n const modelsItems = useMemo(\n () => (models ? models.map(m => ({ label: m.id, value: m.id })) : []),\n [models],\n );\n\n useEffect(() => {\n const htmlTagElement = document.documentElement;\n if (type === THEME_DARK) {\n htmlTagElement.classList.add(THEME_DARK_CLASS);\n } else {\n htmlTagElement.classList.remove(THEME_DARK_CLASS);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [type]);\n\n useEffect(() => {\n if (modelsItems.length > 0) setSelectedModel(modelsItems[0].value);\n }, [modelsItems]);\n\n if (loading) {\n return null;\n }\n\n return (\n <Page themeId=\"tool\">\n <Header\n title={t('page.title')}\n style={{ display: 'none' }}\n pageTitleOverride={t('page.title')}\n />\n <Content className={classes.container}>\n {!hasViewAccess ? (\n <PermissionRequiredState />\n ) : (\n <FileAttachmentContextProvider>\n <LightspeedChat\n selectedModel={selectedModel}\n handleSelectedModel={item => {\n setSelectedModel(item);\n }}\n models={modelsItems}\n userName={profile?.displayName}\n avatar={profile?.picture}\n profileLoading={profileLoading}\n />\n </FileAttachmentContextProvider>\n )}\n </Content>\n </Page>\n );\n};\n\nexport const LightspeedPage = () => {\n return (\n <QueryClientProvider client={queryClient}>\n <LightspeedPageInner />\n </QueryClientProvider>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -1,8 +1,16 @@
1
- import * as React from 'react';
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useTranslation } from '../hooks/useTranslation.esm.js';
2
3
  import permissionRequired from '../images/permission-required.svg';
3
4
 
4
5
  const PermissionRequiredIcon = () => {
5
- return /* @__PURE__ */ React.createElement("img", { src: permissionRequired, alt: "permission required icon" });
6
+ const { t } = useTranslation();
7
+ return /* @__PURE__ */ jsx(
8
+ "img",
9
+ {
10
+ src: permissionRequired,
11
+ alt: t("icon.permissionRequired.alt")
12
+ }
13
+ );
6
14
  };
7
15
 
8
16
  export { PermissionRequiredIcon };
@@ -1 +1 @@
1
- {"version":3,"file":"PermissionRequiredIcon.esm.js","sources":["../../src/components/PermissionRequiredIcon.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 * as React from 'react';\n\nimport permissionRequired from '../images/permission-required.svg';\n\nexport const PermissionRequiredIcon = () => {\n return <img src={permissionRequired as any} alt=\"permission required icon\" />;\n};\n"],"names":[],"mappings":";;;AAoBO,MAAM,yBAAyB,MAAM;AAC1C,EAAA,uBAAQ,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,GAAK,EAAA,kBAAA,EAA2B,KAAI,0BAA2B,EAAA,CAAA;AAC7E;;;;"}
1
+ {"version":3,"file":"PermissionRequiredIcon.esm.js","sources":["../../src/components/PermissionRequiredIcon.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 { useTranslation } from '../hooks/useTranslation';\nimport permissionRequired from '../images/permission-required.svg';\n\nexport const PermissionRequiredIcon = () => {\n const { t } = useTranslation();\n\n return (\n <img\n src={permissionRequired as any}\n alt={t('icon.permissionRequired.alt')}\n />\n );\n};\n"],"names":[],"mappings":";;;;AAmBO,MAAM,yBAAyB,MAAM;AAC1C,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAE7B,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAK,EAAA,kBAAA;AAAA,MACL,GAAA,EAAK,EAAE,6BAA6B;AAAA;AAAA,GACtC;AAEJ;;;;"}
@@ -1,9 +1,11 @@
1
- import React__default from 'react';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { EmptyState } from '@backstage/core-components';
3
3
  import { Typography, Button } from '@material-ui/core';
4
4
  import { makeStyles, createStyles } from '@material-ui/core/styles';
5
5
  import OpenInNewIcon from '@mui/icons-material/OpenInNew';
6
+ import { useTranslation } from '../hooks/useTranslation.esm.js';
6
7
  import { PermissionRequiredIcon } from './PermissionRequiredIcon.esm.js';
8
+ import { Trans } from './Trans.esm.js';
7
9
 
8
10
  const useStyles = makeStyles(
9
11
  () => createStyles({
@@ -17,25 +19,37 @@ const useStyles = makeStyles(
17
19
  );
18
20
  const PermissionRequiredState = () => {
19
21
  const classes = useStyles();
20
- return /* @__PURE__ */ React__default.createElement("div", { className: classes.permissionError }, /* @__PURE__ */ React__default.createElement(
22
+ const { t } = useTranslation();
23
+ return /* @__PURE__ */ jsx("div", { className: classes.permissionError, children: /* @__PURE__ */ jsx(
21
24
  EmptyState,
22
25
  {
23
- title: "Missing permissions",
24
- description: /* @__PURE__ */ React__default.createElement(Typography, { variant: "subtitle1" }, "To view lightspeed plugin, contact your administrator to give the", " ", /* @__PURE__ */ React__default.createElement("b", null, "lightspeed.chat.read"), " and ", /* @__PURE__ */ React__default.createElement("b", null, "lightspeed.chat.create"), " ", "permissions."),
25
- missing: { customImage: /* @__PURE__ */ React__default.createElement(PermissionRequiredIcon, null) },
26
- action: /* @__PURE__ */ React__default.createElement(
26
+ title: t("permission.required.title"),
27
+ description: /* @__PURE__ */ jsx(Typography, { variant: "subtitle1", children: /* @__PURE__ */ jsx(
28
+ Trans,
29
+ {
30
+ message: "permission.required.description",
31
+ components: {
32
+ "<b>lightspeed.chat.read</b>": /* @__PURE__ */ jsx("b", { children: "lightspeed.chat.read" }),
33
+ "<b>lightspeed.chat.create</b>": /* @__PURE__ */ jsx("b", { children: "lightspeed.chat.create" })
34
+ }
35
+ }
36
+ ) }),
37
+ missing: { customImage: /* @__PURE__ */ jsx(PermissionRequiredIcon, {}) },
38
+ action: /* @__PURE__ */ jsxs(
27
39
  Button,
28
40
  {
29
41
  variant: "outlined",
30
42
  color: "primary",
31
43
  target: "_blank",
32
- href: "https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/lightspeed/plugins/lightspeed/README.md#permission-framework-support"
33
- },
34
- "Read more \xA0 ",
35
- /* @__PURE__ */ React__default.createElement(OpenInNewIcon, null)
44
+ href: "https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/lightspeed/plugins/lightspeed/README.md#permission-framework-support",
45
+ children: [
46
+ "Read more \xA0 ",
47
+ /* @__PURE__ */ jsx(OpenInNewIcon, {})
48
+ ]
49
+ }
36
50
  )
37
51
  }
38
- ));
52
+ ) });
39
53
  };
40
54
 
41
55
  export { PermissionRequiredState as default };
@@ -1 +1 @@
1
- {"version":3,"file":"PermissionRequiredState.esm.js","sources":["../../src/components/PermissionRequiredState.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 React from 'react';\n\nimport { EmptyState } from '@backstage/core-components';\n\nimport { Button, Typography } from '@material-ui/core';\nimport { createStyles, makeStyles } from '@material-ui/core/styles';\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew';\n\nimport { PermissionRequiredIcon } from './PermissionRequiredIcon';\n\nconst useStyles = makeStyles(() =>\n createStyles({\n permissionError: {\n display: 'flex',\n height: '100%',\n alignItems: 'center',\n padding: '100px',\n },\n }),\n);\n\nconst PermissionRequiredState = () => {\n const classes = useStyles();\n\n return (\n <div className={classes.permissionError}>\n <EmptyState\n title=\"Missing permissions\"\n description={\n <Typography variant=\"subtitle1\">\n To view lightspeed plugin, contact your administrator to give the{' '}\n <b>lightspeed.chat.read</b> and <b>lightspeed.chat.create</b>{' '}\n permissions.\n </Typography>\n }\n missing={{ customImage: <PermissionRequiredIcon /> }}\n action={\n <Button\n variant=\"outlined\"\n color=\"primary\"\n target=\"_blank\"\n href=\"https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/lightspeed/plugins/lightspeed/README.md#permission-framework-support\"\n >\n Read more &nbsp; <OpenInNewIcon />\n </Button>\n }\n />\n </div>\n );\n};\nexport default PermissionRequiredState;\n"],"names":["React"],"mappings":";;;;;;;AA0BA,MAAM,SAAY,GAAA,UAAA;AAAA,EAAW,MAC3B,YAAa,CAAA;AAAA,IACX,eAAiB,EAAA;AAAA,MACf,OAAS,EAAA,MAAA;AAAA,MACT,MAAQ,EAAA,MAAA;AAAA,MACR,UAAY,EAAA,QAAA;AAAA,MACZ,OAAS,EAAA;AAAA;AACX,GACD;AACH,CAAA;AAEA,MAAM,0BAA0B,MAAM;AACpC,EAAA,MAAM,UAAU,SAAU,EAAA;AAE1B,EAAA,uBACGA,cAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,OAAA,CAAQ,eACtB,EAAA,kBAAAA,cAAA,CAAA,aAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,KAAM,EAAA,qBAAA;AAAA,MACN,6BACGA,cAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,WAAA,EAAA,EAAY,qEACoC,GAClE,kBAAAA,cAAA,CAAA,aAAA,CAAC,GAAE,EAAA,IAAA,EAAA,sBAAoB,GAAI,OAAK,kBAAAA,cAAA,CAAA,aAAA,CAAC,WAAE,wBAAsB,CAAA,EAAK,KAAI,cAEpE,CAAA;AAAA,MAEF,OAAS,EAAA,EAAE,WAAa,kBAAAA,cAAA,CAAA,aAAA,CAAC,4BAAuB,CAAG,EAAA;AAAA,MACnD,MACE,kBAAAA,cAAA,CAAA,aAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,OAAQ,EAAA,UAAA;AAAA,UACR,KAAM,EAAA,SAAA;AAAA,UACN,MAAO,EAAA,QAAA;AAAA,UACP,IAAK,EAAA;AAAA,SAAA;AAAA,QACN,iBAAA;AAAA,qDACmB,aAAc,EAAA,IAAA;AAAA;AAClC;AAAA,GAGN,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"PermissionRequiredState.esm.js","sources":["../../src/components/PermissionRequiredState.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 { EmptyState } from '@backstage/core-components';\n\nimport { Button, Typography } from '@material-ui/core';\nimport { createStyles, makeStyles } from '@material-ui/core/styles';\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew';\n\nimport { useTranslation } from '../hooks/useTranslation';\nimport { PermissionRequiredIcon } from './PermissionRequiredIcon';\nimport { Trans } from './Trans';\n\nconst useStyles = makeStyles(() =>\n createStyles({\n permissionError: {\n display: 'flex',\n height: '100%',\n alignItems: 'center',\n padding: '100px',\n },\n }),\n);\n\nconst PermissionRequiredState = () => {\n const classes = useStyles();\n const { t } = useTranslation();\n\n return (\n <div className={classes.permissionError}>\n <EmptyState\n title={t('permission.required.title')}\n description={\n <Typography variant=\"subtitle1\">\n <Trans\n message=\"permission.required.description\"\n components={{\n '<b>lightspeed.chat.read</b>': <b>lightspeed.chat.read</b>,\n '<b>lightspeed.chat.create</b>': <b>lightspeed.chat.create</b>,\n }}\n />\n </Typography>\n }\n missing={{ customImage: <PermissionRequiredIcon /> }}\n action={\n <Button\n variant=\"outlined\"\n color=\"primary\"\n target=\"_blank\"\n href=\"https://github.com/redhat-developer/rhdh-plugins/blob/main/workspaces/lightspeed/plugins/lightspeed/README.md#permission-framework-support\"\n >\n Read more &nbsp; <OpenInNewIcon />\n </Button>\n }\n />\n </div>\n );\n};\nexport default PermissionRequiredState;\n"],"names":[],"mappings":";;;;;;;;;AA0BA,MAAM,SAAY,GAAA,UAAA;AAAA,EAAW,MAC3B,YAAa,CAAA;AAAA,IACX,eAAiB,EAAA;AAAA,MACf,OAAS,EAAA,MAAA;AAAA,MACT,MAAQ,EAAA,MAAA;AAAA,MACR,UAAY,EAAA,QAAA;AAAA,MACZ,OAAS,EAAA;AAAA;AACX,GACD;AACH,CAAA;AAEA,MAAM,0BAA0B,MAAM;AACpC,EAAA,MAAM,UAAU,SAAU,EAAA;AAC1B,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAE7B,EAAA,uBACG,GAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,OAAA,CAAQ,eACtB,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,EAAE,2BAA2B,CAAA;AAAA,MACpC,WACE,kBAAA,GAAA,CAAC,UAAW,EAAA,EAAA,OAAA,EAAQ,WAClB,EAAA,QAAA,kBAAA,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,OAAQ,EAAA,iCAAA;AAAA,UACR,UAAY,EAAA;AAAA,YACV,6BAAA,kBAAgC,GAAA,CAAA,GAAA,EAAA,EAAE,QAAoB,EAAA,sBAAA,EAAA,CAAA;AAAA,YACtD,+BAAA,kBAAkC,GAAA,CAAA,GAAA,EAAA,EAAE,QAAsB,EAAA,wBAAA,EAAA;AAAA;AAC5D;AAAA,OAEJ,EAAA,CAAA;AAAA,MAEF,OAAS,EAAA,EAAE,WAAa,kBAAA,GAAA,CAAC,0BAAuB,CAAG,EAAA;AAAA,MACnD,MACE,kBAAA,IAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UACC,OAAQ,EAAA,UAAA;AAAA,UACR,KAAM,EAAA,SAAA;AAAA,UACN,MAAO,EAAA,QAAA;AAAA,UACP,IAAK,EAAA,4IAAA;AAAA,UACN,QAAA,EAAA;AAAA,YAAA,iBAAA;AAAA,gCACmB,aAAc,EAAA,EAAA;AAAA;AAAA;AAAA;AAClC;AAAA,GAGN,EAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,33 @@
1
+ import { jsx, Fragment } from 'react/jsx-runtime';
2
+ import { cloneElement } from 'react';
3
+ import { useTranslation } from '../hooks/useTranslation.esm.js';
4
+
5
+ const Trans = ({ message, params, components }) => {
6
+ const { t } = useTranslation();
7
+ const translatedText = t(message, params || {});
8
+ if (!components) {
9
+ return /* @__PURE__ */ jsx(Fragment, { children: translatedText });
10
+ }
11
+ let result = translatedText;
12
+ const markers = {};
13
+ let markerIndex = 0;
14
+ for (const [placeholder, component] of Object.entries(components)) {
15
+ const marker = `__MARKER_${markerIndex}__`;
16
+ markers[marker] = component;
17
+ result = result.replace(new RegExp(escapeRegExp(placeholder), "g"), marker);
18
+ markerIndex++;
19
+ }
20
+ const parts = result.split(/(__MARKER_\d+__)/);
21
+ return /* @__PURE__ */ jsx(Fragment, { children: parts.map((part, index) => {
22
+ if (markers[part]) {
23
+ return cloneElement(markers[part], { key: index });
24
+ }
25
+ return part;
26
+ }) });
27
+ };
28
+ function escapeRegExp(string) {
29
+ return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
30
+ }
31
+
32
+ export { Trans };
33
+ //# sourceMappingURL=Trans.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Trans.esm.js","sources":["../../src/components/Trans.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 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 { cloneElement } from 'react';\n\nimport { useTranslation } from '../hooks/useTranslation';\n\ninterface TransProps {\n message: string;\n params?: Record<string, any>;\n components?: Record<string, React.ReactElement>;\n}\n\nexport const Trans = ({ message, params, components }: TransProps) => {\n const { t } = useTranslation();\n const translatedText = t(message as any, params || {});\n\n // If no components are provided, just return the text\n if (!components) {\n return <>{translatedText}</>;\n }\n\n // Simple string replacement approach - no regex, no security risks\n let result = translatedText;\n\n // Replace each placeholder with a unique marker\n const markers: Record<string, React.ReactElement> = {};\n let markerIndex = 0;\n\n for (const [placeholder, component] of Object.entries(components)) {\n const marker = `__MARKER_${markerIndex}__`;\n markers[marker] = component;\n result = result.replace(new RegExp(escapeRegExp(placeholder), 'g'), marker);\n markerIndex++;\n }\n\n // Split by markers and render components\n const parts = result.split(/(__MARKER_\\d+__)/);\n\n return (\n <>\n {parts.map((part: string, index: number) => {\n if (markers[part]) {\n return cloneElement(markers[part], { key: index });\n }\n return part;\n })}\n </>\n );\n};\n\n// Helper function to escape special regex characters\nfunction escapeRegExp(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n"],"names":[],"mappings":";;;;AA2BO,MAAM,QAAQ,CAAC,EAAE,OAAS,EAAA,MAAA,EAAQ,YAA6B,KAAA;AACpE,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAC7B,EAAA,MAAM,cAAiB,GAAA,CAAA,CAAE,OAAgB,EAAA,MAAA,IAAU,EAAE,CAAA;AAGrD,EAAA,IAAI,CAAC,UAAY,EAAA;AACf,IAAA,uCAAU,QAAe,EAAA,cAAA,EAAA,CAAA;AAAA;AAI3B,EAAA,IAAI,MAAS,GAAA,cAAA;AAGb,EAAA,MAAM,UAA8C,EAAC;AACrD,EAAA,IAAI,WAAc,GAAA,CAAA;AAElB,EAAA,KAAA,MAAW,CAAC,WAAa,EAAA,SAAS,KAAK,MAAO,CAAA,OAAA,CAAQ,UAAU,CAAG,EAAA;AACjE,IAAM,MAAA,MAAA,GAAS,YAAY,WAAW,CAAA,EAAA,CAAA;AACtC,IAAA,OAAA,CAAQ,MAAM,CAAI,GAAA,SAAA;AAClB,IAAS,MAAA,GAAA,MAAA,CAAO,QAAQ,IAAI,MAAA,CAAO,aAAa,WAAW,CAAA,EAAG,GAAG,CAAA,EAAG,MAAM,CAAA;AAC1E,IAAA,WAAA,EAAA;AAAA;AAIF,EAAM,MAAA,KAAA,GAAQ,MAAO,CAAA,KAAA,CAAM,kBAAkB,CAAA;AAE7C,EAAA,uBAEK,GAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA,KAAA,CAAM,GAAI,CAAA,CAAC,MAAc,KAAkB,KAAA;AAC1C,IAAI,IAAA,OAAA,CAAQ,IAAI,CAAG,EAAA;AACjB,MAAA,OAAO,aAAa,OAAQ,CAAA,IAAI,GAAG,EAAE,GAAA,EAAK,OAAO,CAAA;AAAA;AAEnD,IAAO,OAAA,IAAA;AAAA,GACR,CACH,EAAA,CAAA;AAEJ;AAGA,SAAS,aAAa,MAAwB,EAAA;AAC5C,EAAO,OAAA,MAAA,CAAO,OAAQ,CAAA,qBAAA,EAAuB,MAAM,CAAA;AACrD;;;;"}