@red-hat-developer-hub/backstage-plugin-lightspeed 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +1 -0
  3. package/dist/alpha.d.ts +38 -7
  4. package/dist/api/LightspeedApiClient.esm.js +19 -0
  5. package/dist/api/LightspeedApiClient.esm.js.map +1 -1
  6. package/dist/api/api.esm.js.map +1 -1
  7. package/dist/components/DeleteModal.esm.js +86 -10
  8. package/dist/components/DeleteModal.esm.js.map +1 -1
  9. package/dist/components/LightSpeedChat.esm.js +146 -56
  10. package/dist/components/LightSpeedChat.esm.js.map +1 -1
  11. package/dist/components/LightspeedChatBox.esm.js +4 -0
  12. package/dist/components/LightspeedChatBox.esm.js.map +1 -1
  13. package/dist/components/LightspeedChatBoxHeader.esm.js +88 -23
  14. package/dist/components/LightspeedChatBoxHeader.esm.js.map +1 -1
  15. package/dist/components/PermissionRequiredState.esm.js +2 -1
  16. package/dist/components/PermissionRequiredState.esm.js.map +1 -1
  17. package/dist/components/RenameConversationModal.esm.js +139 -0
  18. package/dist/components/RenameConversationModal.esm.js.map +1 -0
  19. package/dist/hooks/useLightspeedUpdatePermission.esm.js +12 -0
  20. package/dist/hooks/useLightspeedUpdatePermission.esm.js.map +1 -0
  21. package/dist/hooks/useRenameConversation.esm.js +44 -0
  22. package/dist/hooks/useRenameConversation.esm.js.map +1 -0
  23. package/dist/translations/de.esm.js +40 -8
  24. package/dist/translations/de.esm.js.map +1 -1
  25. package/dist/translations/es.esm.js +40 -8
  26. package/dist/translations/es.esm.js.map +1 -1
  27. package/dist/translations/fr.esm.js +40 -8
  28. package/dist/translations/fr.esm.js.map +1 -1
  29. package/dist/translations/ref.esm.js +40 -8
  30. package/dist/translations/ref.esm.js.map +1 -1
  31. package/dist/utils/lightspeed-chatbox-utils.esm.js +24 -45
  32. package/dist/utils/lightspeed-chatbox-utils.esm.js.map +1 -1
  33. package/package.json +11 -12
@@ -1,3 +1,6 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import PushPinIcon from '@mui/icons-material/PushPin';
3
+
1
4
  const getFootnoteProps = (additionalClassName, t) => ({
2
5
  label: t?.("footer.accuracy.label") || "Always review AI generated content prior to use.",
3
6
  popover: {
@@ -28,7 +31,7 @@ const getTimestampVariablesString = (v) => {
28
31
  return `${v}`;
29
32
  };
30
33
  const getTimestamp = (unix_timestamp) => {
31
- if (typeof unix_timestamp !== "number" || isNaN(unix_timestamp)) {
34
+ if (typeof unix_timestamp !== "number" || Number.isNaN(unix_timestamp)) {
32
35
  console.error("Invalid Unix timestamp provided");
33
36
  return "";
34
37
  }
@@ -102,62 +105,38 @@ const transformDocumentsToSources = (referenced_documents) => {
102
105
  }))
103
106
  };
104
107
  };
105
- const getDayDifference = (sourceTime, targetTime) => {
106
- const sourceDate = new Date(sourceTime);
107
- const targetDate = new Date(targetTime);
108
- sourceDate.setHours(0, 0, 0, 0);
109
- targetDate.setHours(0, 0, 0, 0);
110
- const timeDifference = sourceDate.getTime() - targetDate.getTime();
111
- return Math.floor(timeDifference / (1e3 * 60 * 60 * 24));
112
- };
113
- const getCategorizeMessages = (messages, addProps, t) => {
114
- const now = /* @__PURE__ */ new Date();
115
- const today = now.toDateString();
108
+ const getCategorizeMessages = (messages, pinnedChats, addProps, t) => {
109
+ const pinnedChatsKey = t?.("conversation.category.pinnedChats") || "Pinned";
110
+ const recentKey = t?.("conversation.category.recent") || "Recent";
116
111
  const categorizedMessages = {
117
- [t?.("conversation.category.today") || "Today"]: [],
118
- [t?.("conversation.category.yesterday") || "Yesterday"]: [],
119
- [t?.("conversation.category.previous7Days") || "Previous 7 Days"]: [],
120
- [t?.("conversation.category.previous30Days") || "Previous 30 Days"]: []
112
+ [pinnedChatsKey]: [],
113
+ [recentKey]: []
121
114
  };
122
- messages.sort((a, b) => b.last_message_timestamp - a.last_message_timestamp).forEach((c) => {
123
- const messageDate = new Date(c.last_message_timestamp * 1e3);
124
- const messageDayString = messageDate.toDateString();
125
- const dayDifference = getDayDifference(
126
- now,
127
- c.last_message_timestamp * 1e3
128
- );
115
+ const sortedMessages = [...messages].sort(
116
+ (a, b) => b.last_message_timestamp - a.last_message_timestamp
117
+ );
118
+ sortedMessages.forEach((c) => {
129
119
  const message = {
130
120
  id: c.conversation_id,
131
121
  text: c.topic_summary,
132
122
  label: t?.("message.options.label") || "Options",
123
+ additionalProps: {
124
+ "aria-label": t?.("aria.options.label") || "Options"
125
+ },
133
126
  ...addProps(c)
134
127
  };
135
- if (messageDayString === today) {
136
- categorizedMessages[t?.("conversation.category.today") || "Today"].push(
137
- message
138
- );
139
- } else if (dayDifference === 1) {
140
- categorizedMessages[t?.("conversation.category.yesterday") || "Yesterday"].push(message);
141
- } else if (dayDifference <= 7) {
142
- categorizedMessages[t?.("conversation.category.previous7Days") || "Previous 7 Days"].push(message);
143
- } else if (dayDifference <= 30) {
144
- categorizedMessages[t?.("conversation.category.previous30Days") || "Previous 30 Days"].push(message);
145
- } else {
146
- const monthYear = messageDate.toLocaleString("default", {
147
- month: "long",
148
- year: "numeric"
128
+ if (pinnedChats.includes(c.conversation_id)) {
129
+ categorizedMessages[pinnedChatsKey].push({
130
+ ...message,
131
+ icon: /* @__PURE__ */ jsx(PushPinIcon, {})
149
132
  });
150
- if (!categorizedMessages[monthYear]) {
151
- categorizedMessages[monthYear] = [];
152
- }
153
- categorizedMessages[monthYear].push(message);
133
+ } else {
134
+ categorizedMessages[recentKey].push(message);
154
135
  }
155
136
  });
156
137
  const filteredCategories = Object.keys(categorizedMessages).reduce(
157
138
  (result, category) => {
158
- if (categorizedMessages[category].length > 0) {
159
- result[category] = categorizedMessages[category];
160
- }
139
+ result[category] = categorizedMessages[category];
161
140
  return result;
162
141
  },
163
142
  {}
@@ -165,5 +144,5 @@ const getCategorizeMessages = (messages, addProps, t) => {
165
144
  return filteredCategories;
166
145
  };
167
146
 
168
- export { createBotMessage, createMessage, createUserMessage, getCategorizeMessages, getConversationsData, getDayDifference, getFootnoteProps, getTimestamp, getTimestampVariablesString, transformDocumentsToSources };
147
+ export { createBotMessage, createMessage, createUserMessage, getCategorizeMessages, getConversationsData, getFootnoteProps, getTimestamp, getTimestampVariablesString, transformDocumentsToSources };
169
148
  //# sourceMappingURL=lightspeed-chatbox-utils.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lightspeed-chatbox-utils.esm.js","sources":["../../src/utils/lightspeed-chatbox-utils.ts"],"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 */\nimport { Conversation, SourcesCardProps } from '@patternfly/chatbot';\nimport { PopoverProps } from '@patternfly/react-core';\n\nimport {\n BaseMessage,\n ConversationList,\n ConversationSummary,\n LCSConversation,\n ReferencedDocument,\n ReferencedDocuments,\n} from '../types';\n\nexport const getFootnoteProps = (\n additionalClassName: string,\n t?: (key: string, params?: any) => string,\n) => ({\n label:\n t?.('footer.accuracy.label') ||\n 'Always review AI generated content prior to use.',\n popover: {\n popoverProps: {\n className: additionalClassName ?? '',\n } as PopoverProps,\n title: t?.('footer.accuracy.popover.title') || 'Verify accuracy',\n description:\n t?.('footer.accuracy.popover.description') ||\n `While Developer Lightspeed strives for accuracy, there's always a possibility of errors. It's a good practice to verify critical information from reliable sources, especially if it's crucial for decision-making or actions.`,\n bannerImage: {\n src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',\n alt:\n t?.('footer.accuracy.popover.image.alt') ||\n 'Example image for footnote popover',\n },\n cta: {\n label: t?.('footer.accuracy.popover.cta.label') || 'Got it',\n onClick: () => {},\n },\n link: {\n label: t?.('footer.accuracy.popover.link.label') || 'Learn more',\n url: 'https://www.redhat.com/',\n },\n },\n});\n\nexport const getTimestampVariablesString = (v: number) => {\n if (v < 10) {\n return `0${v}`;\n }\n return `${v}`;\n};\n\nexport const getTimestamp = (unix_timestamp: number) => {\n if (typeof unix_timestamp !== 'number' || isNaN(unix_timestamp)) {\n // eslint-disable-next-line no-console\n console.error('Invalid Unix timestamp provided');\n return '';\n }\n\n const a = new Date(unix_timestamp);\n const month = getTimestampVariablesString(a.getMonth() + 1);\n const year = a.getFullYear();\n const date = getTimestampVariablesString(a.getDate());\n const hour = getTimestampVariablesString(a.getHours());\n const min = getTimestampVariablesString(a.getMinutes());\n const sec = getTimestampVariablesString(a.getSeconds());\n const time = `${date}/${month}/${year}, ${hour}:${min}:${sec}`;\n return time;\n};\n\nexport const splitJsonStrings = (jsonString: string): string[] => {\n const chunks = jsonString.split('}{');\n\n if (chunks.length <= 1) {\n return [jsonString];\n }\n\n return chunks.map((chunk, index, arr) => {\n if (index === 0) {\n return `${chunk}}`;\n } else if (index === arr.length - 1) {\n return `{${chunk}`;\n }\n return `{${chunk}}`;\n });\n};\n\ntype MessageProps = {\n content: string;\n timestamp: string;\n name?: string;\n avatar?: string | any;\n isLoading?: boolean;\n error?: {\n title: string;\n };\n sources?: SourcesCardProps;\n};\n\nexport const createMessage = ({\n role,\n name,\n avatar,\n isLoading = false,\n content,\n timestamp,\n error,\n sources,\n defaultUserName = 'Guest',\n}: MessageProps & { role: 'user' | 'bot'; defaultUserName?: string }) => ({\n role,\n name: name || defaultUserName,\n avatar,\n isLoading,\n content,\n timestamp,\n error,\n sources,\n});\n\nexport const createUserMessage = (\n props: MessageProps & { defaultUserName?: string },\n) =>\n createMessage({\n ...props,\n role: 'user',\n defaultUserName: props.defaultUserName,\n });\n\nexport const createBotMessage = (props: MessageProps) =>\n createMessage({\n ...props,\n role: 'bot',\n });\n\nexport const getConversationsData = (\n conversation: LCSConversation,\n): [BaseMessage, BaseMessage] => {\n const [userMessage, botMessage] = conversation.messages || [];\n return [\n {\n ...userMessage,\n timestamp: getTimestamp(\n conversation.started_at\n ? new Date(conversation.started_at).getTime()\n : Date.now(),\n ),\n },\n {\n ...botMessage,\n timestamp: getTimestamp(\n conversation.completed_at\n ? new Date(conversation.completed_at).getTime()\n : Date.now(),\n ),\n referenced_documents: botMessage?.referenced_documents ?? [],\n },\n ];\n};\n\nexport const transformDocumentsToSources = (\n referenced_documents: ReferencedDocuments,\n): SourcesCardProps | undefined => {\n if (!referenced_documents || referenced_documents?.length === 0) {\n return undefined;\n }\n return {\n sources: referenced_documents.map((doc: ReferencedDocument) => ({\n body: doc.doc_description,\n title: doc.doc_title,\n link: doc?.doc_url,\n isExternal: true,\n })),\n };\n};\n\nexport const getDayDifference = (sourceTime: number, targetTime: number) => {\n const sourceDate = new Date(sourceTime);\n const targetDate = new Date(targetTime);\n\n sourceDate.setHours(0, 0, 0, 0);\n targetDate.setHours(0, 0, 0, 0);\n\n const timeDifference = sourceDate.getTime() - targetDate.getTime();\n\n return Math.floor(timeDifference / (1000 * 60 * 60 * 24));\n};\n\nexport const getCategorizeMessages = (\n messages: ConversationList,\n addProps: (c: ConversationSummary) => { [k: string]: any },\n t?: (key: string, params?: any) => string,\n): { [k: string]: Conversation[] } => {\n const now: any = new Date();\n const today = now.toDateString();\n\n const categorizedMessages: { [k: string]: Conversation[] } = {\n [t?.('conversation.category.today') || 'Today']: [],\n [t?.('conversation.category.yesterday') || 'Yesterday']: [],\n [t?.('conversation.category.previous7Days') || 'Previous 7 Days']: [],\n [t?.('conversation.category.previous30Days') || 'Previous 30 Days']: [],\n };\n messages\n .sort((a, b) => b.last_message_timestamp - a.last_message_timestamp)\n .forEach(c => {\n const messageDate = new Date(c.last_message_timestamp * 1000);\n const messageDayString = messageDate.toDateString();\n const dayDifference = getDayDifference(\n now,\n c.last_message_timestamp * 1000,\n );\n const message: Conversation = {\n id: c.conversation_id,\n text: c.topic_summary,\n label: t?.('message.options.label') || 'Options',\n ...addProps(c),\n };\n\n if (messageDayString === today) {\n categorizedMessages[t?.('conversation.category.today') || 'Today'].push(\n message,\n );\n } else if (dayDifference === 1) {\n categorizedMessages[\n t?.('conversation.category.yesterday') || 'Yesterday'\n ].push(message);\n } else if (dayDifference <= 7) {\n categorizedMessages[\n t?.('conversation.category.previous7Days') || 'Previous 7 Days'\n ].push(message);\n } else if (dayDifference <= 30) {\n categorizedMessages[\n t?.('conversation.category.previous30Days') || 'Previous 30 Days'\n ].push(message);\n } else {\n // handle month-wise grouping\n const monthYear = messageDate.toLocaleString('default', {\n month: 'long',\n year: 'numeric',\n });\n if (!categorizedMessages[monthYear]) {\n categorizedMessages[monthYear] = [];\n }\n categorizedMessages[monthYear].push(message);\n }\n });\n\n const filteredCategories = Object.keys(categorizedMessages).reduce(\n (result, category) => {\n if (categorizedMessages[category].length > 0) {\n result[category] = categorizedMessages[category];\n }\n return result;\n },\n {} as any,\n );\n\n return filteredCategories;\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lightspeed-chatbox-utils.esm.js","sources":["../../src/utils/lightspeed-chatbox-utils.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 */\nimport PushPinIcon from '@mui/icons-material/PushPin';\nimport { Conversation, SourcesCardProps } from '@patternfly/chatbot';\nimport { PopoverProps } from '@patternfly/react-core';\n\nimport {\n BaseMessage,\n ConversationList,\n ConversationSummary,\n LCSConversation,\n ReferencedDocument,\n ReferencedDocuments,\n} from '../types';\n\nexport const getFootnoteProps = (\n additionalClassName: string,\n t?: (key: string, params?: any) => string,\n) => ({\n label:\n t?.('footer.accuracy.label') ||\n 'Always review AI generated content prior to use.',\n popover: {\n popoverProps: {\n className: additionalClassName ?? '',\n } as PopoverProps,\n title: t?.('footer.accuracy.popover.title') || 'Verify accuracy',\n description:\n t?.('footer.accuracy.popover.description') ||\n `While Developer Lightspeed strives for accuracy, there's always a possibility of errors. It's a good practice to verify critical information from reliable sources, especially if it's crucial for decision-making or actions.`,\n bannerImage: {\n src: 'https://cdn.dribbble.com/userupload/10651749/file/original-8a07b8e39d9e8bf002358c66fce1223e.gif',\n alt:\n t?.('footer.accuracy.popover.image.alt') ||\n 'Example image for footnote popover',\n },\n cta: {\n label: t?.('footer.accuracy.popover.cta.label') || 'Got it',\n onClick: () => {},\n },\n link: {\n label: t?.('footer.accuracy.popover.link.label') || 'Learn more',\n url: 'https://www.redhat.com/',\n },\n },\n});\n\nexport const getTimestampVariablesString = (v: number) => {\n if (v < 10) {\n return `0${v}`;\n }\n return `${v}`;\n};\n\nexport const getTimestamp = (unix_timestamp: number) => {\n if (typeof unix_timestamp !== 'number' || Number.isNaN(unix_timestamp)) {\n // eslint-disable-next-line no-console\n console.error('Invalid Unix timestamp provided');\n return '';\n }\n\n const a = new Date(unix_timestamp);\n const month = getTimestampVariablesString(a.getMonth() + 1);\n const year = a.getFullYear();\n const date = getTimestampVariablesString(a.getDate());\n const hour = getTimestampVariablesString(a.getHours());\n const min = getTimestampVariablesString(a.getMinutes());\n const sec = getTimestampVariablesString(a.getSeconds());\n const time = `${date}/${month}/${year}, ${hour}:${min}:${sec}`;\n return time;\n};\n\nexport const splitJsonStrings = (jsonString: string): string[] => {\n const chunks = jsonString.split('}{');\n\n if (chunks.length <= 1) {\n return [jsonString];\n }\n\n return chunks.map((chunk, index, arr) => {\n if (index === 0) {\n return `${chunk}}`;\n } else if (index === arr.length - 1) {\n return `{${chunk}`;\n }\n return `{${chunk}}`;\n });\n};\n\ntype MessageProps = {\n content: string;\n timestamp: string;\n name?: string;\n avatar?: string | any;\n isLoading?: boolean;\n error?: {\n title: string;\n };\n sources?: SourcesCardProps;\n};\n\nexport const createMessage = ({\n role,\n name,\n avatar,\n isLoading = false,\n content,\n timestamp,\n error,\n sources,\n defaultUserName = 'Guest',\n}: MessageProps & { role: 'user' | 'bot'; defaultUserName?: string }) => ({\n role,\n name: name || defaultUserName,\n avatar,\n isLoading,\n content,\n timestamp,\n error,\n sources,\n});\n\nexport const createUserMessage = (\n props: MessageProps & { defaultUserName?: string },\n) =>\n createMessage({\n ...props,\n role: 'user',\n defaultUserName: props.defaultUserName,\n });\n\nexport const createBotMessage = (props: MessageProps) =>\n createMessage({\n ...props,\n role: 'bot',\n });\n\nexport const getConversationsData = (\n conversation: LCSConversation,\n): [BaseMessage, BaseMessage] => {\n const [userMessage, botMessage] = conversation.messages || [];\n return [\n {\n ...userMessage,\n timestamp: getTimestamp(\n conversation.started_at\n ? new Date(conversation.started_at).getTime()\n : Date.now(),\n ),\n },\n {\n ...botMessage,\n timestamp: getTimestamp(\n conversation.completed_at\n ? new Date(conversation.completed_at).getTime()\n : Date.now(),\n ),\n referenced_documents: botMessage?.referenced_documents ?? [],\n },\n ];\n};\n\nexport const transformDocumentsToSources = (\n referenced_documents: ReferencedDocuments,\n): SourcesCardProps | undefined => {\n if (!referenced_documents || referenced_documents?.length === 0) {\n return undefined;\n }\n return {\n sources: referenced_documents.map((doc: ReferencedDocument) => ({\n body: doc.doc_description,\n title: doc.doc_title,\n link: doc?.doc_url,\n isExternal: true,\n })),\n };\n};\n\nexport const getCategorizeMessages = (\n messages: ConversationList,\n pinnedChats: string[],\n addProps: (c: ConversationSummary) => { [k: string]: any },\n t?: (key: string, params?: any) => string,\n): { [k: string]: Conversation[] } => {\n const pinnedChatsKey = t?.('conversation.category.pinnedChats') || 'Pinned';\n const recentKey = t?.('conversation.category.recent') || 'Recent';\n const categorizedMessages: { [k: string]: Conversation[] } = {\n [pinnedChatsKey]: [],\n [recentKey]: [],\n };\n const sortedMessages = [...messages].sort(\n (a, b) => b.last_message_timestamp - a.last_message_timestamp,\n );\n sortedMessages.forEach(c => {\n const message: Conversation = {\n id: c.conversation_id,\n text: c.topic_summary,\n label: t?.('message.options.label') || 'Options',\n additionalProps: {\n 'aria-label': t?.('aria.options.label') || 'Options',\n },\n ...addProps(c),\n };\n\n if (pinnedChats.includes(c.conversation_id)) {\n categorizedMessages[pinnedChatsKey].push({\n ...message,\n icon: <PushPinIcon />,\n });\n } else {\n categorizedMessages[recentKey].push(message);\n }\n });\n\n const filteredCategories = Object.keys(categorizedMessages).reduce(\n (result, category) => {\n result[category] = categorizedMessages[category];\n return result;\n },\n {} as any,\n );\n\n return filteredCategories;\n};\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@red-hat-developer-hub/backstage-plugin-lightspeed",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "main": "./dist/index.esm.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -32,7 +32,6 @@
32
32
  },
33
33
  "backstage": {
34
34
  "role": "frontend-plugin",
35
- "supported-versions": "1.35.1",
36
35
  "pluginId": "lightspeed",
37
36
  "pluginPackage": "@red-hat-developer-hub/backstage-plugin-lightspeed",
38
37
  "pluginPackages": [
@@ -58,17 +57,18 @@
58
57
  "prettier:fix": "prettier --ignore-unknown --write ."
59
58
  },
60
59
  "dependencies": {
61
- "@backstage/core-components": "^0.17.5",
62
- "@backstage/core-plugin-api": "^1.10.9",
63
- "@backstage/plugin-permission-react": "^0.4.36",
64
- "@backstage/theme": "^0.6.8",
60
+ "@backstage/core-components": "^0.18.3",
61
+ "@backstage/core-plugin-api": "^1.12.0",
62
+ "@backstage/plugin-permission-react": "^0.4.38",
63
+ "@backstage/theme": "^0.7.0",
65
64
  "@material-ui/core": "^4.9.13",
66
65
  "@material-ui/lab": "^4.0.0-alpha.61",
67
66
  "@mui/icons-material": "^6.1.8",
67
+ "@mui/material": "^5.12.2",
68
68
  "@patternfly/chatbot": "6.4.1",
69
69
  "@patternfly/react-core": "6.4.0",
70
70
  "@patternfly/react-icons": "^6.3.1",
71
- "@red-hat-developer-hub/backstage-plugin-lightspeed-common": "^1.0.3",
71
+ "@red-hat-developer-hub/backstage-plugin-lightspeed-common": "^1.1.0",
72
72
  "@tanstack/react-query": "^5.59.15",
73
73
  "react-markdown": "^9.0.1",
74
74
  "react-use": "^17.2.4"
@@ -78,10 +78,10 @@
78
78
  "react-router-dom": "^6.0.0"
79
79
  },
80
80
  "devDependencies": {
81
- "@backstage/cli": "^0.34.1",
82
- "@backstage/core-app-api": "^1.18.0",
83
- "@backstage/dev-utils": "^1.1.13",
84
- "@backstage/test-utils": "^1.7.11",
81
+ "@backstage/cli": "^0.34.5",
82
+ "@backstage/core-app-api": "^1.19.2",
83
+ "@backstage/dev-utils": "^1.1.17",
84
+ "@backstage/test-utils": "^1.7.13",
85
85
  "@emotion/is-prop-valid": "^1.3.1",
86
86
  "@ianvs/prettier-plugin-sort-imports": "^4.4.0",
87
87
  "@spotify/prettier-config": "^15.0.0",
@@ -116,7 +116,6 @@
116
116
  "directory": "workspaces/lightspeed/plugins/lightspeed"
117
117
  },
118
118
  "keywords": [
119
- "lifecycle:active",
120
119
  "backstage",
121
120
  "plugin"
122
121
  ],