@eventcatalog/core 2.35.2 → 2.35.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.
- package/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +1 -1
- package/dist/analytics/log-build.js +3 -3
- package/dist/catalog-to-astro-content-directory.cjs +5 -0
- package/dist/catalog-to-astro-content-directory.js +2 -2
- package/dist/{chunk-7SI5EVOX.js → chunk-5ZG43YD2.js} +4 -1
- package/dist/{chunk-OXVJOENQ.js → chunk-66QXZSU5.js} +1 -1
- package/dist/{chunk-YGROHR26.js → chunk-BQ5AYBCA.js} +1 -1
- package/dist/{chunk-UKJ7F5WR.js → chunk-DCLTVJDP.js} +1 -1
- package/dist/{chunk-ZUPEUUST.js → chunk-DGPXNBAU.js} +1 -1
- package/dist/{chunk-HAYFEAB4.js → chunk-EXAALOQA.js} +2 -0
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +19 -1
- package/dist/eventcatalog.js +19 -6
- package/dist/map-catalog-to-astro.cjs +2 -0
- package/dist/map-catalog-to-astro.js +1 -1
- package/dist/watcher.cjs +2 -0
- package/dist/watcher.js +2 -2
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/ChatMessage.tsx +25 -0
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/InputModal.tsx +20 -9
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/WelcomePromptArea.tsx +132 -44
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/default-prompts.ts +93 -0
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/hooks/ChatProvider.tsx +1 -0
- package/eventcatalog/src/enterprise/eventcatalog-chat/components/windows/ChatWindow.server.tsx +3 -4
- package/eventcatalog/src/enterprise/eventcatalog-chat/pages/chat/index.astro +0 -6
- package/eventcatalog/src/pages/chat/index.astro +5 -0
- package/package.json +2 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
log_build_default
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-DGPXNBAU.js";
|
|
4
|
+
import "../chunk-66QXZSU5.js";
|
|
5
|
+
import "../chunk-BQ5AYBCA.js";
|
|
6
6
|
import "../chunk-E7TXTI7G.js";
|
|
7
7
|
export {
|
|
8
8
|
log_build_default as default
|
|
@@ -155,6 +155,8 @@ function isCatalogRelated(filePath) {
|
|
|
155
155
|
// custom components
|
|
156
156
|
"public",
|
|
157
157
|
// public assets
|
|
158
|
+
".env",
|
|
159
|
+
// env file
|
|
158
160
|
...COLLECTION_KEYS
|
|
159
161
|
].includes(filePathArr[0])) {
|
|
160
162
|
return true;
|
|
@@ -200,6 +202,9 @@ var copyFiles = async (source, target) => {
|
|
|
200
202
|
windowsPathsNoEscape: import_node_os.default.platform() == "win32",
|
|
201
203
|
ignore: ["node_modules/**", "**/dist/**", "**/teams", "**/users", "**/*.mdx", "**/*.md", "**/package.json", "**/Dockerfile"]
|
|
202
204
|
});
|
|
205
|
+
if (import_fs.default.existsSync(path3.join(source, ".env"))) {
|
|
206
|
+
files.push(path3.join(source, ".env"));
|
|
207
|
+
}
|
|
203
208
|
for (const file of files) {
|
|
204
209
|
mapCatalogToAstro({
|
|
205
210
|
filePath: file,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
catalogToAstro,
|
|
3
3
|
checkAndConvertMdToMdx
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-5ZG43YD2.js";
|
|
5
5
|
import "./chunk-E7TXTI7G.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-EXAALOQA.js";
|
|
7
7
|
export {
|
|
8
8
|
catalogToAstro,
|
|
9
9
|
checkAndConvertMdToMdx
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-E7TXTI7G.js";
|
|
4
4
|
import {
|
|
5
5
|
mapCatalogToAstro
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-EXAALOQA.js";
|
|
7
7
|
|
|
8
8
|
// src/catalog-to-astro-content-directory.js
|
|
9
9
|
import { glob } from "glob";
|
|
@@ -19,6 +19,9 @@ var copyFiles = async (source, target) => {
|
|
|
19
19
|
windowsPathsNoEscape: os.platform() == "win32",
|
|
20
20
|
ignore: ["node_modules/**", "**/dist/**", "**/teams", "**/users", "**/*.mdx", "**/*.md", "**/package.json", "**/Dockerfile"]
|
|
21
21
|
});
|
|
22
|
+
if (fs.existsSync(path.join(source, ".env"))) {
|
|
23
|
+
files.push(path.join(source, ".env"));
|
|
24
|
+
}
|
|
22
25
|
for (const file of files) {
|
|
23
26
|
mapCatalogToAstro({
|
|
24
27
|
filePath: file,
|
package/dist/constants.cjs
CHANGED
package/dist/constants.js
CHANGED
package/dist/eventcatalog.cjs
CHANGED
|
@@ -157,7 +157,7 @@ var import_axios = __toESM(require("axios"), 1);
|
|
|
157
157
|
var import_os = __toESM(require("os"), 1);
|
|
158
158
|
|
|
159
159
|
// package.json
|
|
160
|
-
var version = "2.35.
|
|
160
|
+
var version = "2.35.3";
|
|
161
161
|
|
|
162
162
|
// src/constants.ts
|
|
163
163
|
var VERSION = version;
|
|
@@ -261,6 +261,8 @@ function isCatalogRelated(filePath) {
|
|
|
261
261
|
// custom components
|
|
262
262
|
"public",
|
|
263
263
|
// public assets
|
|
264
|
+
".env",
|
|
265
|
+
// env file
|
|
264
266
|
...COLLECTION_KEYS
|
|
265
267
|
].includes(filePathArr[0])) {
|
|
266
268
|
return true;
|
|
@@ -392,6 +394,9 @@ var copyFiles = async (source, target) => {
|
|
|
392
394
|
windowsPathsNoEscape: import_node_os.default.platform() == "win32",
|
|
393
395
|
ignore: ["node_modules/**", "**/dist/**", "**/teams", "**/users", "**/*.mdx", "**/*.md", "**/package.json", "**/Dockerfile"]
|
|
394
396
|
});
|
|
397
|
+
if (import_fs.default.existsSync(path5.join(source, ".env"))) {
|
|
398
|
+
files.push(path5.join(source, ".env"));
|
|
399
|
+
}
|
|
395
400
|
for (const file of files) {
|
|
396
401
|
mapCatalogToAstro({
|
|
397
402
|
filePath: file,
|
|
@@ -608,6 +613,7 @@ var isEventCatalogStarterEnabled = async (licenseKey) => {
|
|
|
608
613
|
// src/eventcatalog.ts
|
|
609
614
|
var import_update_notifier = __toESM(require("update-notifier"), 1);
|
|
610
615
|
var import_stream = __toESM(require("stream"), 1);
|
|
616
|
+
var import_dotenv = __toESM(require("dotenv"), 1);
|
|
611
617
|
var currentDir = import_node_path7.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl));
|
|
612
618
|
var program = new import_commander.Command().version(VERSION);
|
|
613
619
|
var dir = import_node_path7.default.resolve(process.env.PROJECT_DIR || process.cwd());
|
|
@@ -685,6 +691,9 @@ Run npm i @eventcatalog/core to update`;
|
|
|
685
691
|
};
|
|
686
692
|
program.command("dev").description("Run development server of EventCatalog").option("-d, --debug", "Output EventCatalog application information into your terminal").option("--force-recreate", "Recreate the eventcatalog-core directory", false).action(async (options, command) => {
|
|
687
693
|
console.log("Setting up EventCatalog....");
|
|
694
|
+
if (import_fs2.default.existsSync(import_node_path7.default.join(dir, ".env"))) {
|
|
695
|
+
import_dotenv.default.config({ path: import_node_path7.default.join(dir, ".env") });
|
|
696
|
+
}
|
|
688
697
|
if (options.debug) {
|
|
689
698
|
console.log("Debug mode enabled");
|
|
690
699
|
console.log("PROJECT_DIR", dir);
|
|
@@ -741,6 +750,9 @@ program.command("dev").description("Run development server of EventCatalog").opt
|
|
|
741
750
|
});
|
|
742
751
|
program.command("build").description("Run build of EventCatalog").action(async (options, command) => {
|
|
743
752
|
console.log("Building EventCatalog...");
|
|
753
|
+
if (import_fs2.default.existsSync(import_node_path7.default.join(dir, ".env"))) {
|
|
754
|
+
import_dotenv.default.config({ path: import_node_path7.default.join(dir, ".env") });
|
|
755
|
+
}
|
|
744
756
|
copyCore();
|
|
745
757
|
await copyServerFiles();
|
|
746
758
|
const canEmbedPages = await isBackstagePluginEnabled();
|
|
@@ -782,6 +794,9 @@ var previewCatalog = ({
|
|
|
782
794
|
};
|
|
783
795
|
program.command("preview").description("Serves the contents of your eventcatalog build directory").action(async (options, command) => {
|
|
784
796
|
console.log("Starting preview of your build...");
|
|
797
|
+
if (import_fs2.default.existsSync(import_node_path7.default.join(dir, ".env"))) {
|
|
798
|
+
import_dotenv.default.config({ path: import_node_path7.default.join(dir, ".env") });
|
|
799
|
+
}
|
|
785
800
|
const canEmbedPages = await isBackstagePluginEnabled();
|
|
786
801
|
const isEventCatalogStarter = await isEventCatalogStarterEnabled();
|
|
787
802
|
const isEventCatalogScale = await isEventCatalogScaleEnabled();
|
|
@@ -790,6 +805,9 @@ program.command("preview").description("Serves the contents of your eventcatalog
|
|
|
790
805
|
});
|
|
791
806
|
program.command("start").description("Serves the contents of your eventcatalog build directory").action(async (options, command) => {
|
|
792
807
|
console.log("Starting preview of your build...");
|
|
808
|
+
if (import_fs2.default.existsSync(import_node_path7.default.join(dir, ".env"))) {
|
|
809
|
+
import_dotenv.default.config({ path: import_node_path7.default.join(dir, ".env") });
|
|
810
|
+
}
|
|
793
811
|
const canEmbedPages = await isBackstagePluginEnabled();
|
|
794
812
|
const isEventCatalogStarter = await isEventCatalogStarterEnabled();
|
|
795
813
|
const isEventCatalogScale = await isEventCatalogScaleEnabled();
|
package/dist/eventcatalog.js
CHANGED
|
@@ -3,18 +3,18 @@ import {
|
|
|
3
3
|
} from "./chunk-BLDONK5J.js";
|
|
4
4
|
import {
|
|
5
5
|
watch
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DCLTVJDP.js";
|
|
7
7
|
import {
|
|
8
8
|
log_build_default
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-DGPXNBAU.js";
|
|
10
|
+
import "./chunk-66QXZSU5.js";
|
|
11
11
|
import {
|
|
12
12
|
catalogToAstro,
|
|
13
13
|
checkAndConvertMdToMdx
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-5ZG43YD2.js";
|
|
15
15
|
import {
|
|
16
16
|
VERSION
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-BQ5AYBCA.js";
|
|
18
18
|
import {
|
|
19
19
|
isBackstagePluginEnabled,
|
|
20
20
|
isEventCatalogScaleEnabled,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
generate
|
|
26
26
|
} from "./chunk-YEQVKHST.js";
|
|
27
27
|
import "./chunk-E7TXTI7G.js";
|
|
28
|
-
import "./chunk-
|
|
28
|
+
import "./chunk-EXAALOQA.js";
|
|
29
29
|
|
|
30
30
|
// src/eventcatalog.ts
|
|
31
31
|
import { Command } from "commander";
|
|
@@ -38,6 +38,7 @@ import concurrently from "concurrently";
|
|
|
38
38
|
import boxen from "boxen";
|
|
39
39
|
import updateNotifier from "update-notifier";
|
|
40
40
|
import stream from "stream";
|
|
41
|
+
import dotenv from "dotenv";
|
|
41
42
|
var currentDir = path.dirname(fileURLToPath(import.meta.url));
|
|
42
43
|
var program = new Command().version(VERSION);
|
|
43
44
|
var dir = path.resolve(process.env.PROJECT_DIR || process.cwd());
|
|
@@ -115,6 +116,9 @@ Run npm i @eventcatalog/core to update`;
|
|
|
115
116
|
};
|
|
116
117
|
program.command("dev").description("Run development server of EventCatalog").option("-d, --debug", "Output EventCatalog application information into your terminal").option("--force-recreate", "Recreate the eventcatalog-core directory", false).action(async (options, command) => {
|
|
117
118
|
console.log("Setting up EventCatalog....");
|
|
119
|
+
if (fs.existsSync(path.join(dir, ".env"))) {
|
|
120
|
+
dotenv.config({ path: path.join(dir, ".env") });
|
|
121
|
+
}
|
|
118
122
|
if (options.debug) {
|
|
119
123
|
console.log("Debug mode enabled");
|
|
120
124
|
console.log("PROJECT_DIR", dir);
|
|
@@ -171,6 +175,9 @@ program.command("dev").description("Run development server of EventCatalog").opt
|
|
|
171
175
|
});
|
|
172
176
|
program.command("build").description("Run build of EventCatalog").action(async (options, command) => {
|
|
173
177
|
console.log("Building EventCatalog...");
|
|
178
|
+
if (fs.existsSync(path.join(dir, ".env"))) {
|
|
179
|
+
dotenv.config({ path: path.join(dir, ".env") });
|
|
180
|
+
}
|
|
174
181
|
copyCore();
|
|
175
182
|
await copyServerFiles();
|
|
176
183
|
const canEmbedPages = await isBackstagePluginEnabled();
|
|
@@ -212,6 +219,9 @@ var previewCatalog = ({
|
|
|
212
219
|
};
|
|
213
220
|
program.command("preview").description("Serves the contents of your eventcatalog build directory").action(async (options, command) => {
|
|
214
221
|
console.log("Starting preview of your build...");
|
|
222
|
+
if (fs.existsSync(path.join(dir, ".env"))) {
|
|
223
|
+
dotenv.config({ path: path.join(dir, ".env") });
|
|
224
|
+
}
|
|
215
225
|
const canEmbedPages = await isBackstagePluginEnabled();
|
|
216
226
|
const isEventCatalogStarter = await isEventCatalogStarterEnabled();
|
|
217
227
|
const isEventCatalogScale = await isEventCatalogScaleEnabled();
|
|
@@ -220,6 +230,9 @@ program.command("preview").description("Serves the contents of your eventcatalog
|
|
|
220
230
|
});
|
|
221
231
|
program.command("start").description("Serves the contents of your eventcatalog build directory").action(async (options, command) => {
|
|
222
232
|
console.log("Starting preview of your build...");
|
|
233
|
+
if (fs.existsSync(path.join(dir, ".env"))) {
|
|
234
|
+
dotenv.config({ path: path.join(dir, ".env") });
|
|
235
|
+
}
|
|
223
236
|
const canEmbedPages = await isBackstagePluginEnabled();
|
|
224
237
|
const isEventCatalogStarter = await isEventCatalogStarterEnabled();
|
|
225
238
|
const isEventCatalogScale = await isEventCatalogScaleEnabled();
|
package/dist/watcher.cjs
CHANGED
package/dist/watcher.js
CHANGED
|
@@ -34,6 +34,7 @@ const ChatMessage = React.memo(({ message }: ChatMessageProps) => {
|
|
|
34
34
|
const [modalContent, setModalContent] = useState<{ language: string; code: string } | null>(null);
|
|
35
35
|
const [copiedStates, setCopiedStates] = useState<Record<string, boolean>>({}); // State for copy feedback
|
|
36
36
|
const [isResourcesCollapsed, setIsResourcesCollapsed] = useState(true); // State for resource section collapse
|
|
37
|
+
const [isContextCollapsed, setIsContextCollapsed] = useState(true); // State for additional context collapse
|
|
37
38
|
|
|
38
39
|
// Helper to get display name for resource, ensuring a fallback
|
|
39
40
|
const getResourceDisplayName = (resource: Resource): string => {
|
|
@@ -137,6 +138,30 @@ const ChatMessage = React.memo(({ message }: ChatMessageProps) => {
|
|
|
137
138
|
</ReactMarkdown>
|
|
138
139
|
</div>
|
|
139
140
|
|
|
141
|
+
{/* Additional Context section (for user messages) */}
|
|
142
|
+
{message.isUser && message.additionalContext && (
|
|
143
|
+
<div className="mt-3 pt-3 border-t border-purple-700/50">
|
|
144
|
+
{' '}
|
|
145
|
+
{/* Adjusted border color for subtlety */}
|
|
146
|
+
<button
|
|
147
|
+
className="flex items-center text-xs text-purple-300 mb-1 w-full text-left focus:outline-none" // Adjusted text color for subtlety
|
|
148
|
+
onClick={() => setIsContextCollapsed(!isContextCollapsed)}
|
|
149
|
+
aria-expanded={!isContextCollapsed}
|
|
150
|
+
aria-controls="additional-context-content"
|
|
151
|
+
>
|
|
152
|
+
{isContextCollapsed ? <ChevronRight size={14} className="mr-1" /> : <ChevronDown size={14} className="mr-1" />}
|
|
153
|
+
Prompt used:
|
|
154
|
+
</button>
|
|
155
|
+
{!isContextCollapsed && (
|
|
156
|
+
<div className="text-[10px] mt-1 pl-5 prose prose-sm prose-invert" id="additional-context-content">
|
|
157
|
+
{' '}
|
|
158
|
+
{/* Removed max-w-none */}
|
|
159
|
+
<pre className="whitespace-pre-wrap break-words">{message.additionalContext}</pre> {/* Use pre for formatting */}
|
|
160
|
+
</div>
|
|
161
|
+
)}
|
|
162
|
+
</div>
|
|
163
|
+
)}
|
|
164
|
+
|
|
140
165
|
{/* Resource section */}
|
|
141
166
|
{!message.isUser && message.resources && message.resources.length > 0 && (
|
|
142
167
|
<div className="mt-3 pt-3 border-t border-gray-200">
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useState, useMemo } from 'react';
|
|
2
2
|
import * as Dialog from '@radix-ui/react-dialog';
|
|
3
|
+
import { Wand2 } from 'lucide-react';
|
|
3
4
|
// TODO: Import ChatPrompt and ChatPromptInput from a central types location
|
|
4
5
|
import type { ChatPrompt } from '@enterprise/eventcatalog-chat/utils/chat-prompts';
|
|
5
6
|
|
|
@@ -111,9 +112,9 @@ const InputModal: React.FC<InputModalProps> = ({ isOpen, onClose, prompt, onSubm
|
|
|
111
112
|
<Dialog.Root open={isOpen} onOpenChange={onClose}>
|
|
112
113
|
<Dialog.Portal>
|
|
113
114
|
<Dialog.Overlay className="fixed inset-0 bg-black/50 data-[state=open]:animate-overlayShow z-50" />
|
|
114
|
-
<Dialog.Content className="fixed top-1/2 left-1/2 w-[90vw] max-w-
|
|
115
|
-
<Dialog.Title className="text-lg font-semibold text-gray-
|
|
116
|
-
<Dialog.Description className="mt-1 mb-
|
|
115
|
+
<Dialog.Content className="fixed top-1/2 left-1/2 w-[90vw] max-w-lg -translate-x-1/2 -translate-y-1/2 rounded-lg bg-gray-50 p-8 shadow-xl focus:outline-none data-[state=open]:animate-contentShow z-[100]">
|
|
116
|
+
<Dialog.Title className="text-lg font-semibold text-gray-800 mb-3">{prompt.data.title}</Dialog.Title>
|
|
117
|
+
<Dialog.Description className="mt-1 mb-6 text-sm text-gray-600">
|
|
117
118
|
Please provide the following details:
|
|
118
119
|
</Dialog.Description>
|
|
119
120
|
<form onSubmit={handleSubmit} className="space-y-4">
|
|
@@ -127,7 +128,7 @@ const InputModal: React.FC<InputModalProps> = ({ isOpen, onClose, prompt, onSubm
|
|
|
127
128
|
|
|
128
129
|
return (
|
|
129
130
|
<div key={input.id}>
|
|
130
|
-
<label htmlFor={input.id} className="block text-sm font-medium text-gray-700 mb-1">
|
|
131
|
+
<label htmlFor={input.id} className="block text-sm font-medium text-gray-700 mb-1.5">
|
|
131
132
|
{input.label}
|
|
132
133
|
</label>
|
|
133
134
|
{isResourceList ? (
|
|
@@ -137,7 +138,7 @@ const InputModal: React.FC<InputModalProps> = ({ isOpen, onClose, prompt, onSubm
|
|
|
137
138
|
value={inputValues[input.id] || ''}
|
|
138
139
|
onChange={(e) => handleInputChange(input.id, e.target.value)}
|
|
139
140
|
required
|
|
140
|
-
className="w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-purple-500 focus:outline-none focus:ring-
|
|
141
|
+
className="w-full rounded-md border border-gray-300 bg-white px-3 py-2 shadow-sm focus:border-purple-500 focus:outline-none focus:ring-2 focus:ring-purple-300 focus:ring-offset-1 sm:text-sm transition duration-150 ease-in-out"
|
|
141
142
|
>
|
|
142
143
|
<option value="" disabled>
|
|
143
144
|
Select a {resourceType}...
|
|
@@ -160,7 +161,7 @@ const InputModal: React.FC<InputModalProps> = ({ isOpen, onClose, prompt, onSubm
|
|
|
160
161
|
value={inputValues[input.id] || ''}
|
|
161
162
|
onChange={(e) => handleInputChange(input.id, e.target.value)}
|
|
162
163
|
required
|
|
163
|
-
className="w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-purple-500 focus:outline-none focus:ring-
|
|
164
|
+
className="w-full rounded-md border border-gray-300 bg-white px-3 py-2 shadow-sm focus:border-purple-500 focus:outline-none focus:ring-2 focus:ring-purple-300 focus:ring-offset-1 sm:text-sm transition duration-150 ease-in-out"
|
|
164
165
|
>
|
|
165
166
|
<option value="" disabled>
|
|
166
167
|
Select an option...
|
|
@@ -184,9 +185,18 @@ const InputModal: React.FC<InputModalProps> = ({ isOpen, onClose, prompt, onSubm
|
|
|
184
185
|
name={input.id}
|
|
185
186
|
value={inputValues[input.id] || ''}
|
|
186
187
|
onChange={(e) => handleInputChange(input.id, e.target.value)}
|
|
188
|
+
onKeyDown={(e) => {
|
|
189
|
+
// Prevent form submission on Enter key press unless Shift is held
|
|
190
|
+
if (e.key === 'Enter' && !e.shiftKey) {
|
|
191
|
+
e.preventDefault();
|
|
192
|
+
// Optionally, you could trigger submission here if needed,
|
|
193
|
+
// but the default behavior is just to prevent it.
|
|
194
|
+
handleSubmit(e); // Example: trigger submit manually
|
|
195
|
+
}
|
|
196
|
+
}}
|
|
187
197
|
required
|
|
188
198
|
rows={isCode ? 6 : 3} // More rows for code input
|
|
189
|
-
className={`w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-purple-500 focus:outline-none focus:ring-
|
|
199
|
+
className={`w-full rounded-md border border-gray-300 bg-white px-3 py-2 shadow-sm focus:border-purple-500 focus:outline-none focus:ring-2 focus:ring-purple-300 focus:ring-offset-1 sm:text-sm transition duration-150 ease-in-out ${isCode ? 'font-mono text-sm' : ''}`}
|
|
190
200
|
placeholder={isCode ? 'Paste your code here...' : ''}
|
|
191
201
|
/>
|
|
192
202
|
) : (
|
|
@@ -197,7 +207,7 @@ const InputModal: React.FC<InputModalProps> = ({ isOpen, onClose, prompt, onSubm
|
|
|
197
207
|
value={inputValues[input.id] || ''}
|
|
198
208
|
onChange={(e) => handleInputChange(input.id, e.target.value)}
|
|
199
209
|
required
|
|
200
|
-
className="w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-purple-500 focus:outline-none focus:ring-
|
|
210
|
+
className="w-full rounded-md border border-gray-300 bg-white px-3 py-2 shadow-sm focus:border-purple-500 focus:outline-none focus:ring-2 focus:ring-purple-300 focus:ring-offset-1 sm:text-sm transition duration-150 ease-in-out"
|
|
201
211
|
/>
|
|
202
212
|
)}
|
|
203
213
|
</>
|
|
@@ -217,8 +227,9 @@ const InputModal: React.FC<InputModalProps> = ({ isOpen, onClose, prompt, onSubm
|
|
|
217
227
|
</Dialog.Close>
|
|
218
228
|
<button
|
|
219
229
|
type="submit"
|
|
220
|
-
className="inline-flex justify-center rounded-md border border-transparent bg-purple-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
|
|
230
|
+
className="inline-flex items-center justify-center gap-1.5 rounded-md border border-transparent bg-purple-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2"
|
|
221
231
|
>
|
|
232
|
+
<Wand2 size={16} />
|
|
222
233
|
Submit
|
|
223
234
|
</button>
|
|
224
235
|
</div>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React, { useMemo } from 'react';
|
|
2
|
-
import { HelpCircle } from 'lucide-react';
|
|
1
|
+
import React, { useState, useMemo } from 'react';
|
|
3
2
|
import * as icons from 'lucide-react'; // Import all icons
|
|
4
3
|
import type { ChatPromptCategoryGroup, ChatPrompt } from '@enterprise/eventcatalog-chat/utils/chat-prompts';
|
|
4
|
+
import { defaultPrompts } from './default-prompts';
|
|
5
5
|
|
|
6
6
|
// Removed the static iconMap
|
|
7
7
|
|
|
@@ -26,60 +26,148 @@ interface WelcomePromptAreaProps {
|
|
|
26
26
|
isProcessing: boolean; // Combined thinking/streaming state
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
// Helper function to group default prompts by category label
|
|
30
|
+
const groupDefaultPrompts = (prompts: ChatPrompt[]): ChatPromptCategoryGroup[] => {
|
|
31
|
+
const groups: { [key: string]: { label: string; icon?: string; items: ChatPrompt[] } } = {};
|
|
32
|
+
|
|
33
|
+
prompts.forEach((prompt) => {
|
|
34
|
+
const categoryLabel = prompt.data.category.label;
|
|
35
|
+
const categoryIcon = prompt.data.category.icon; // Get icon from prompt data
|
|
36
|
+
|
|
37
|
+
if (!groups[categoryLabel]) {
|
|
38
|
+
groups[categoryLabel] = { label: categoryLabel, icon: categoryIcon, items: [] };
|
|
39
|
+
}
|
|
40
|
+
groups[categoryLabel].items.push(prompt);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Convert the groups object into an array matching ChatPromptCategoryGroup structure
|
|
44
|
+
return Object.values(groups);
|
|
45
|
+
};
|
|
46
|
+
|
|
29
47
|
const WelcomePromptArea: React.FC<WelcomePromptAreaProps> = ({
|
|
30
48
|
chatPrompts,
|
|
31
|
-
activeCategory,
|
|
32
|
-
setActiveCategory,
|
|
49
|
+
activeCategory: activeCustomCategory, // Rename to avoid conflict
|
|
50
|
+
setActiveCategory: setActiveCustomCategory, // Rename to avoid conflict
|
|
33
51
|
onPromptClick,
|
|
34
52
|
isProcessing,
|
|
35
53
|
}) => {
|
|
54
|
+
// Group default prompts and derive initial state only once
|
|
55
|
+
const defaultPromptGroups = useMemo(() => groupDefaultPrompts(defaultPrompts), []);
|
|
56
|
+
const [activeDefaultCategory, setActiveDefaultCategory] = useState<string>(() => defaultPromptGroups[0]?.label || '');
|
|
57
|
+
|
|
36
58
|
// Find the currently active category's questions from chatPrompts
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
const activeGroup = chatPrompts.find((group) => group.label ===
|
|
40
|
-
|
|
59
|
+
const activeCustomQuestions: ChatPrompt[] = useMemo(() => {
|
|
60
|
+
if (!chatPrompts || chatPrompts.length === 0) return [];
|
|
61
|
+
const activeGroup = chatPrompts.find((group) => group.label === activeCustomCategory);
|
|
62
|
+
return activeGroup?.items || (chatPrompts[0]?.items ?? []);
|
|
63
|
+
}, [activeCustomCategory, chatPrompts]);
|
|
64
|
+
|
|
65
|
+
// Find the currently active category's default questions
|
|
66
|
+
const activeDefaultQuestions: ChatPrompt[] = useMemo(() => {
|
|
67
|
+
if (!defaultPromptGroups || defaultPromptGroups.length === 0) return [];
|
|
68
|
+
const activeGroup = defaultPromptGroups.find((group) => group.label === activeDefaultCategory);
|
|
41
69
|
return activeGroup?.items || [];
|
|
42
|
-
}, [
|
|
70
|
+
}, [activeDefaultCategory, defaultPromptGroups]);
|
|
43
71
|
|
|
44
72
|
return (
|
|
45
73
|
<div className="h-full flex flex-col justify-center items-center px-4 pb-4 pt-0">
|
|
46
|
-
{' '}
|
|
47
|
-
{/* Use h-full and flex centering */}
|
|
48
74
|
<div className="max-w-2xl w-full text-left">
|
|
49
75
|
<h2 className="text-2xl font-semibold mb-6 text-gray-800">How can I help you?</h2>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
76
|
+
|
|
77
|
+
{/* Conditional Rendering: Custom Prompts OR Default Prompts */}
|
|
78
|
+
{chatPrompts && chatPrompts.length > 0 ? (
|
|
79
|
+
/* --- CUSTOM PROMPTS UI --- */
|
|
80
|
+
<>
|
|
81
|
+
{/* Category Tabs - Use chatPrompts */}
|
|
82
|
+
<div className="flex flex-wrap justify-left gap-2 mb-6 border-b border-gray-200 pb-4">
|
|
83
|
+
{chatPrompts.map((categoryGroup) => (
|
|
84
|
+
<button
|
|
85
|
+
key={categoryGroup.label}
|
|
86
|
+
onClick={() => setActiveCustomCategory(categoryGroup.label)}
|
|
87
|
+
disabled={isProcessing}
|
|
88
|
+
className={`flex items-center px-3 py-2 rounded-md text-sm font-medium transition-colors duration-150 focus:outline-none focus:ring-2 focus:ring-purple-400 focus:ring-offset-2 focus:ring-offset-white disabled:opacity-50 ${
|
|
89
|
+
activeCustomCategory === categoryGroup.label
|
|
90
|
+
? 'bg-purple-600 text-white'
|
|
91
|
+
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
|
|
92
|
+
}`}
|
|
93
|
+
>
|
|
94
|
+
{getCategoryIcon(categoryGroup.icon)}
|
|
95
|
+
{categoryGroup.label}
|
|
96
|
+
</button>
|
|
97
|
+
))}
|
|
98
|
+
</div>
|
|
99
|
+
{/* Questions List - Use activeCustomQuestions */}
|
|
100
|
+
<div className="space-y-2 text-left">
|
|
101
|
+
{activeCustomQuestions.map((item) => (
|
|
102
|
+
<button
|
|
103
|
+
key={item.id}
|
|
104
|
+
onClick={() => onPromptClick(item)}
|
|
105
|
+
className="block w-full text-left px-3 py-2 text-gray-700 hover:bg-gray-100 rounded-md text-sm transition-colors duration-150 focus:outline-none focus:ring-1 focus:ring-purple-400 disabled:opacity-50"
|
|
106
|
+
disabled={isProcessing}
|
|
107
|
+
>
|
|
108
|
+
{item.data.title}
|
|
109
|
+
</button>
|
|
110
|
+
))}
|
|
111
|
+
</div>
|
|
112
|
+
</>
|
|
113
|
+
) : (
|
|
114
|
+
/* --- DEFAULT PROMPTS UI (Grouped) --- */
|
|
115
|
+
<>
|
|
116
|
+
{/* Default Category Tabs - Use defaultPromptGroups */}
|
|
117
|
+
<div className="flex flex-wrap justify-left gap-2 mb-6 border-b border-gray-200 pb-4">
|
|
118
|
+
{defaultPromptGroups.map((categoryGroup) => (
|
|
119
|
+
<button
|
|
120
|
+
key={categoryGroup.label} // Use label as key
|
|
121
|
+
onClick={() => setActiveDefaultCategory(categoryGroup.label)}
|
|
122
|
+
disabled={isProcessing}
|
|
123
|
+
className={`flex items-center px-3 py-2 rounded-md text-sm font-medium transition-colors duration-150 focus:outline-none focus:ring-2 focus:ring-purple-400 focus:ring-offset-2 focus:ring-offset-white disabled:opacity-50 ${
|
|
124
|
+
activeDefaultCategory === categoryGroup.label
|
|
125
|
+
? 'bg-purple-600 text-white'
|
|
126
|
+
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
|
|
127
|
+
}`}
|
|
128
|
+
>
|
|
129
|
+
{/* Use the icon mapping function */}
|
|
130
|
+
{getCategoryIcon(categoryGroup.icon)}
|
|
131
|
+
{categoryGroup.label}
|
|
132
|
+
</button>
|
|
133
|
+
))}
|
|
134
|
+
</div>
|
|
135
|
+
{/* Default Questions List - Use activeDefaultQuestions */}
|
|
136
|
+
<div className="space-y-2 text-left">
|
|
137
|
+
{activeDefaultQuestions.map((item) => (
|
|
138
|
+
<button
|
|
139
|
+
key={item.id}
|
|
140
|
+
onClick={() => onPromptClick(item)}
|
|
141
|
+
className="block w-full text-left px-3 py-2 text-gray-700 hover:bg-gray-100 rounded-md text-sm transition-colors duration-150 focus:outline-none focus:ring-1 focus:ring-purple-400 disabled:opacity-50"
|
|
142
|
+
disabled={isProcessing}
|
|
143
|
+
>
|
|
144
|
+
{item.data.title}
|
|
145
|
+
</button>
|
|
146
|
+
))}
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
{/* Enhanced Bring Your Own Prompts section */}
|
|
150
|
+
<div className="bg-purple-50 border border-purple-200 rounded-lg p-4 mt-6 text-gray-700 text-sm">
|
|
151
|
+
<p className="flex items-center">
|
|
152
|
+
<icons.Wand2 size={18} className="text-purple-600 mr-2 flex-shrink-0" /> {/* Added Icon */}
|
|
153
|
+
<span>
|
|
154
|
+
Want to tailor these suggestions?{' '}
|
|
155
|
+
<a
|
|
156
|
+
href="https://www.eventcatalog.dev/docs/development/guides/eventcatlaog-chat/what-is-eventcatalog-chat"
|
|
157
|
+
target="_blank"
|
|
158
|
+
rel="noopener noreferrer"
|
|
159
|
+
className="text-purple-700 hover:underline font-semibold"
|
|
160
|
+
>
|
|
161
|
+
{' '}
|
|
162
|
+
{/* Added target and rel */}
|
|
163
|
+
Bring your own prompts!
|
|
164
|
+
</a>{' '}
|
|
165
|
+
Easily configure this list with relevant questions for your teams and organization.
|
|
166
|
+
</span>
|
|
167
|
+
</p>
|
|
168
|
+
</div>
|
|
169
|
+
</>
|
|
170
|
+
)}
|
|
83
171
|
</div>
|
|
84
172
|
</div>
|
|
85
173
|
);
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { ChatPrompt } from '@enterprise/eventcatalog-chat/utils/chat-prompts';
|
|
2
|
+
|
|
3
|
+
export const defaultPrompts: ChatPrompt[] = [
|
|
4
|
+
{
|
|
5
|
+
id: 'default-events',
|
|
6
|
+
collection: 'chatPrompts', // Required field
|
|
7
|
+
body: 'List all events.', // The actual prompt text
|
|
8
|
+
data: {
|
|
9
|
+
title: 'What events do we have in our architecture?', // Text displayed on the button
|
|
10
|
+
type: 'text', // Default type
|
|
11
|
+
category: { id: 'general', label: 'General', icon: 'HelpCircle' },
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: 'default-events-by-domain-feature',
|
|
16
|
+
collection: 'chatPrompts',
|
|
17
|
+
body: 'What events are relevant to this feature {{feature-description}}?',
|
|
18
|
+
data: {
|
|
19
|
+
title: 'Im building a new feature, what events are relevant to this feature?',
|
|
20
|
+
type: 'text',
|
|
21
|
+
inputs: [
|
|
22
|
+
{
|
|
23
|
+
id: 'feature-description',
|
|
24
|
+
label: 'Feature Description',
|
|
25
|
+
type: 'text-area',
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
category: { id: 'general', label: 'General', icon: 'HelpCircle' },
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 'default-events-by-domain-service',
|
|
33
|
+
collection: 'chatPrompts',
|
|
34
|
+
body: 'Review the given service {{service-name}}, and let me know how it works? You are an expert in the domain and architecture of the service.',
|
|
35
|
+
data: {
|
|
36
|
+
title: 'Review the given service, and let me know how it works?',
|
|
37
|
+
type: 'text',
|
|
38
|
+
inputs: [
|
|
39
|
+
{
|
|
40
|
+
id: 'service-name',
|
|
41
|
+
label: 'Service Name',
|
|
42
|
+
type: 'resource-list-services',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
category: { id: 'general', label: 'General', icon: 'HelpCircle' },
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'default-services',
|
|
50
|
+
collection: 'chatPrompts',
|
|
51
|
+
body: 'List all services.',
|
|
52
|
+
data: {
|
|
53
|
+
title: 'What services do we have in our architecture?',
|
|
54
|
+
type: 'text',
|
|
55
|
+
category: { id: 'general', label: 'General', icon: 'HelpCircle' },
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
// Example of another category
|
|
59
|
+
{
|
|
60
|
+
id: 'default-schema-json',
|
|
61
|
+
collection: 'chatPrompts',
|
|
62
|
+
body: 'Generate a JSON schema for {{event-name}}.',
|
|
63
|
+
data: {
|
|
64
|
+
title: 'Generate a JSON schema for the given event',
|
|
65
|
+
type: 'text',
|
|
66
|
+
inputs: [
|
|
67
|
+
{
|
|
68
|
+
id: 'event-name',
|
|
69
|
+
label: 'Event Name',
|
|
70
|
+
type: 'resource-list-events',
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
category: { id: 'code', label: 'Code Generation', icon: 'Code' },
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: 'default-schema-avro',
|
|
78
|
+
collection: 'chatPrompts',
|
|
79
|
+
body: 'Generate a Avro schema for {{event-name}}.',
|
|
80
|
+
data: {
|
|
81
|
+
title: 'Generate a Avro schema for the given event',
|
|
82
|
+
type: 'text',
|
|
83
|
+
inputs: [
|
|
84
|
+
{
|
|
85
|
+
id: 'event-name',
|
|
86
|
+
label: 'Event Name',
|
|
87
|
+
type: 'resource-list-events',
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
category: { id: 'code', label: 'Code Generation', icon: 'Code' },
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
];
|
package/eventcatalog/src/enterprise/eventcatalog-chat/components/windows/ChatWindow.server.tsx
CHANGED
|
@@ -211,7 +211,7 @@ const ChatWindow = ({
|
|
|
211
211
|
async (question: string, additionalContext?: string) => {
|
|
212
212
|
if (!question.trim() || isStreaming || isThinking) return;
|
|
213
213
|
|
|
214
|
-
const userMessage: Message = { content: question, isUser: true, timestamp: Date.now() };
|
|
214
|
+
const userMessage: Message = { content: question, isUser: true, timestamp: Date.now(), additionalContext };
|
|
215
215
|
const isFirstMessage = messages.length === 0;
|
|
216
216
|
|
|
217
217
|
setMessages((prev) => [...prev, userMessage]);
|
|
@@ -252,7 +252,6 @@ const ChatWindow = ({
|
|
|
252
252
|
const handleSubmitWithInputs = useCallback(
|
|
253
253
|
(prompt: ChatPrompt, inputValues: Record<string, string>) => {
|
|
254
254
|
let finalBody = prompt.body || ''; // Start with the original body
|
|
255
|
-
|
|
256
255
|
// Ensure prompt and prompt.data exist before accessing properties
|
|
257
256
|
if (!prompt || !prompt.data) {
|
|
258
257
|
console.error('handleSubmitWithInputs called without a valid prompt.');
|
|
@@ -264,10 +263,10 @@ const ChatWindow = ({
|
|
|
264
263
|
for (const [key, value] of Object.entries(inputValues)) {
|
|
265
264
|
const placeholder = `{{${key}}}`;
|
|
266
265
|
// Replace all occurrences of the placeholder in the body
|
|
267
|
-
finalBody = finalBody.replaceAll(placeholder, value);
|
|
266
|
+
finalBody = finalBody.replaceAll(placeholder, `"${value}"`);
|
|
268
267
|
}
|
|
269
268
|
|
|
270
|
-
// Submit the
|
|
269
|
+
// Submit the processed title and the processed body as additional context
|
|
271
270
|
submitQuestion(prompt.data.title, finalBody);
|
|
272
271
|
|
|
273
272
|
setIsInputModalOpen(false); // Close modal
|
|
@@ -5,13 +5,11 @@ import { getChatPromptsGroupedByCategory } from '@enterprise/eventcatalog-chat/u
|
|
|
5
5
|
import config from '@config';
|
|
6
6
|
import path from 'node:path';
|
|
7
7
|
import fs from 'node:fs';
|
|
8
|
-
import { isEventCatalogChatEnabled } from '@utils/feature';
|
|
9
8
|
import { Code } from 'astro-expressive-code/components';
|
|
10
9
|
import { getDomains } from '@utils/collections/domains';
|
|
11
10
|
import { getEvents } from '@utils/events';
|
|
12
11
|
import { getCommands } from '@utils/commands';
|
|
13
12
|
import { getServices } from '@utils/collections/services';
|
|
14
|
-
import { buildUrl } from '@utils/url-builder';
|
|
15
13
|
|
|
16
14
|
const isEnabled = config.chat?.enabled || false;
|
|
17
15
|
const chatConfig = config.chat || {};
|
|
@@ -44,10 +42,6 @@ const generatorConfig = `
|
|
|
44
42
|
],
|
|
45
43
|
],
|
|
46
44
|
`;
|
|
47
|
-
|
|
48
|
-
if (!isEventCatalogChatEnabled()) {
|
|
49
|
-
return Astro.redirect(buildUrl('/chat/feature'));
|
|
50
|
-
}
|
|
51
45
|
---
|
|
52
46
|
|
|
53
47
|
<VerticalSideBarLayout title="AI Chat">
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
import ChatPage from '@enterprise/eventcatalog-chat/pages/chat/index.astro';
|
|
3
|
+
import { isEventCatalogChatEnabled } from '@utils/feature';
|
|
4
|
+
import { buildUrl } from '@utils/url-builder';
|
|
5
|
+
if (!isEventCatalogChatEnabled()) {
|
|
6
|
+
return Astro.redirect(buildUrl('/chat/feature'));
|
|
7
|
+
}
|
|
3
8
|
---
|
|
4
9
|
|
|
5
10
|
<ChatPage />
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"url": "https://github.com/event-catalog/eventcatalog.git"
|
|
7
7
|
},
|
|
8
8
|
"type": "module",
|
|
9
|
-
"version": "2.35.
|
|
9
|
+
"version": "2.35.3",
|
|
10
10
|
"publishConfig": {
|
|
11
11
|
"access": "public"
|
|
12
12
|
},
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"date-fns": "^4.1.0",
|
|
64
64
|
"diff": "^7.0.0",
|
|
65
65
|
"diff2html": "^3.4.48",
|
|
66
|
+
"dotenv": "^16.5.0",
|
|
66
67
|
"glob": "^10.4.1",
|
|
67
68
|
"gray-matter": "^4.0.3",
|
|
68
69
|
"html-to-image": "^1.11.11",
|