@clubmed/usg-chat-ui 1.2.7 → 1.3.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.
- package/README.md +36 -0
- package/assets/style.css +1 -1
- package/chunks/react.esm.js +2012 -1997
- package/chunks/react.esm.js.map +1 -1
- package/chunks/vi.2VT5v0um.js +1 -0
- package/config/chatLabels.d.ts +43 -0
- package/config/chatLabels.js +2 -0
- package/config/chatLabels.js.map +1 -0
- package/contexts/ChatLabelsContext.d.ts +13 -0
- package/contexts/ChatLabelsContext.js +24 -0
- package/contexts/ChatLabelsContext.js.map +1 -0
- package/contexts/ChatLabelsContext.test.d.ts +1 -0
- package/contexts/ChatLabelsContext.test.js +23 -0
- package/contexts/ChatLabelsContext.test.js.map +1 -0
- package/molecules/AiElements/Branch.js +45 -44
- package/molecules/AiElements/Branch.js.map +1 -1
- package/molecules/AiElements/PromptInput.js +60 -58
- package/molecules/AiElements/PromptInput.js.map +1 -1
- package/molecules/RichText/useCollaboration.test.js +1 -1
- package/organisms/canvas/CanvasLayout.d.ts +2 -1
- package/organisms/canvas/CanvasLayout.js +1249 -1248
- package/organisms/canvas/CanvasLayout.js.map +1 -1
- package/organisms/chat/Chat.d.ts +7 -1
- package/organisms/chat/Chat.js +67 -67
- package/organisms/chat/Chat.js.map +1 -1
- package/organisms/chat/ChatHeader.d.ts +4 -4
- package/organisms/chat/ChatHeader.js +41 -39
- package/organisms/chat/ChatHeader.js.map +1 -1
- package/organisms/chat/ChatHeader.test.d.ts +1 -0
- package/organisms/chat/ChatHeader.test.js +18 -0
- package/organisms/chat/ChatHeader.test.js.map +1 -0
- package/organisms/chat/ChatMessageList.d.ts +1 -2
- package/organisms/chat/ChatMessageList.js +73 -58
- package/organisms/chat/ChatMessageList.js.map +1 -1
- package/organisms/chat/ChatMessageList.test.d.ts +1 -0
- package/organisms/chat/ChatMessageList.test.js +67 -0
- package/organisms/chat/ChatMessageList.test.js.map +1 -0
- package/organisms/chat/ChatSettingsButton.d.ts +2 -0
- package/organisms/chat/ChatSettingsButton.js +24 -0
- package/organisms/chat/ChatSettingsButton.js.map +1 -0
- package/organisms/chat/ChatSettingsButton.test.d.ts +1 -0
- package/organisms/chat/ChatSettingsButton.test.js +16 -0
- package/organisms/chat/ChatSettingsButton.test.js.map +1 -0
- package/organisms/chat/ConversationSidebar.js +44 -43
- package/organisms/chat/ConversationSidebar.js.map +1 -1
- package/organisms/chat/MessageActions.js +104 -103
- package/organisms/chat/MessageActions.js.map +1 -1
- package/organisms/chat/MessageRenderers.js +1 -1
- package/organisms/chat/SidebarToggleButton.js +9 -7
- package/organisms/chat/SidebarToggleButton.js.map +1 -1
- package/organisms/chat/hooks/useChat.d.ts +1 -1
- package/organisms/chat/hooks/useChat.js +83 -83
- package/organisms/chat/hooks/useChat.js.map +1 -1
- package/package.json +1 -1
- package/utils/interpolate.d.ts +5 -0
- package/utils/interpolate.js +13 -0
- package/utils/interpolate.js.map +1 -0
- package/utils/interpolate.test.d.ts +1 -0
- package/utils/interpolate.test.js +21 -0
- package/utils/interpolate.test.js.map +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatMessageList.js","sources":["../../../lib/organisms/chat/ChatMessageList.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Branch,\n BranchMessages,\n BranchNext,\n BranchPage,\n BranchPrevious,\n BranchSelector,\n} from \"@clubmed/usg-chat-ui/molecules/AiElements/Branch\";\nimport {\n Conversation,\n ConversationContent,\n ConversationEmptyState,\n ConversationScrollButton,\n} from \"@clubmed/usg-chat-ui/molecules/AiElements/Conversation\";\nimport { Message, MessageContent } from \"@clubmed/usg-chat-ui/molecules/AiElements/Message\";\nimport {\n Reasoning,\n ReasoningContent,\n ReasoningTrigger,\n} from \"@clubmed/usg-chat-ui/molecules/AiElements/Reasoning\";\nimport { Response } from \"@clubmed/usg-chat-ui/molecules/AiElements/Response\";\nimport {\n Source,\n Sources,\n SourcesContent,\n SourcesTrigger,\n} from \"@clubmed/usg-chat-ui/molecules/AiElements/Sources\";\nimport { MessageRenderer } from \"@clubmed/usg-chat-ui/organisms/chat/MessageRenderers\";\nimport { MessageActions } from \"@clubmed/usg-chat-ui/organisms/chat/MessageActions\";\nimport { Wand2 } from \"lucide-react\";\nimport type { ChatMessage } from \"./types\";\n\ninterface ChatMessageListProps {\n chatMessages: ChatMessage[];\n isLoadingMessage: boolean;\n onFollowupClick: (question: string) => void;\n onRegenerate: (messageKey: string) => void;\n emptyStateGreeting?: string;\n}\n\nexport function ChatMessageList({\n chatMessages,\n isLoadingMessage,\n onFollowupClick,\n onRegenerate,\n emptyStateGreeting,\n}: ChatMessageListProps) {\n const renderMessageBranches = () =>\n chatMessages.map(({ versions, ...message }, index) => (\n <Branch defaultBranch={versions.length - 1} key={message.key}>\n <BranchMessages>\n {versions.map((version) => (\n <Message from={message.from} key={`${message.key}-${version.id}`}>\n <MessageContent>\n {message.sources && message.sources.length > 0 && (\n <Sources>\n <SourcesTrigger count={message.sources.length} />\n <SourcesContent>\n {message.sources.map((source) => (\n <Source href={source.href} key={source.href} title={source.title} />\n ))}\n </SourcesContent>\n </Sources>\n )}\n {message.reasoning && (\n <Reasoning duration={message.reasoning.duration}>\n <ReasoningTrigger />\n <ReasoningContent>{message.reasoning.content}</ReasoningContent>\n </Reasoning>\n )}\n {message.from === \"assistant\" ? (\n <>\n <MessageRenderer\n responseType={version.responseType || \"message\"}\n content={version.content}\n canvasData={version.canvasData}\n followupQuestions={version.followupQuestions}\n onQuestionClick={onFollowupClick}\n />\n <MessageActions\n content={version.content}\n messageId={version.id}\n responseType={version.responseType}\n canvasData={version.canvasData}\n onRegenerate={() => {\n const previous = chatMessages[index - 1];\n if (previous?.from === \"user\") {\n onRegenerate(message.key);\n }\n }}\n />\n </>\n ) : (\n <Response>{version.content}</Response>\n )}\n </MessageContent>\n </Message>\n ))}\n </BranchMessages>\n {versions.length > 1 && (\n <BranchSelector from={message.from}>\n <BranchPrevious />\n <BranchPage />\n <BranchNext />\n </BranchSelector>\n )}\n </Branch>\n ));\n\n return (\n <Conversation className=\"flex-1\">\n <ConversationContent>\n {chatMessages.length === 0 ? (\n <ConversationEmptyState\n greeting={emptyStateGreeting}\n title=\"Bienvenue dans votre assistant de product management\"\n description=\"Je vous aide à créer des user stories Jira de qualité, générer des release notes, répondre à vos questions sur l'API ClubMed, structurer vos besoins fonctionnels. Décrivez votre besoin et commençons !\"\n icon={\n <div className=\"relative mx-auto w-fit\">\n <div className=\"absolute inset-0 bg-foreground/10 blur-3xl\" />\n <div\n className=\"relative flex h-16 w-16 sm:h-20 sm:w-20 items-center justify-center rounded-2xl shadow-2xl ring-1 ring-border/40 transition-transform hover:scale-110 duration-500 overflow-hidden\"\n style={{\n background: \"linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 50%, #0f0f0f 100%)\",\n boxShadow: \"inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 8px 16px rgba(0, 0, 0, 0.4)\",\n }}\n >\n <div className=\"absolute inset-0 bg-gradient-to-br from-white/10 to-transparent pointer-events-none\" />\n <Wand2 className=\"h-8 w-8 sm:h-10 sm:w-10 text-white relative z-10\" strokeWidth={1.5} />\n </div>\n </div>\n }\n />\n ) : (\n <>\n {renderMessageBranches()}\n {isLoadingMessage && (\n <Message from=\"assistant\">\n <MessageContent variant=\"flat\">\n <span className=\"text-sm text-muted-foreground animate-pulse\">Réflexion en cours...</span>\n </MessageContent>\n </Message>\n )}\n </>\n )}\n </ConversationContent>\n <ConversationScrollButton />\n </Conversation>\n );\n}\n"],"names":["ChatMessageList","chatMessages","isLoadingMessage","onFollowupClick","onRegenerate","emptyStateGreeting","renderMessageBranches","versions","message","index","jsxs","Branch","jsx","BranchMessages","version","Message","MessageContent","Sources","SourcesTrigger","SourcesContent","source","Source","Reasoning","ReasoningTrigger","ReasoningContent","Fragment","MessageRenderer","MessageActions","previous","Response","BranchSelector","BranchPrevious","BranchPage","BranchNext","Conversation","ConversationContent","ConversationEmptyState","Wand2","ConversationScrollButton"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChatMessageList.js","sources":["../../../lib/organisms/chat/ChatMessageList.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Branch,\n BranchMessages,\n BranchNext,\n BranchPage,\n BranchPrevious,\n BranchSelector,\n} from \"@clubmed/usg-chat-ui/molecules/AiElements/Branch\";\nimport {\n Conversation,\n ConversationContent,\n ConversationEmptyState,\n ConversationScrollButton,\n} from \"@clubmed/usg-chat-ui/molecules/AiElements/Conversation\";\nimport {Message, MessageContent} from \"@clubmed/usg-chat-ui/molecules/AiElements/Message\";\nimport {Reasoning, ReasoningContent, ReasoningTrigger,} from \"@clubmed/usg-chat-ui/molecules/AiElements/Reasoning\";\nimport {Response} from \"@clubmed/usg-chat-ui/molecules/AiElements/Response\";\nimport {Source, Sources, SourcesContent, SourcesTrigger,} from \"@clubmed/usg-chat-ui/molecules/AiElements/Sources\";\nimport {MessageRenderer} from \"@clubmed/usg-chat-ui/organisms/chat/MessageRenderers\";\nimport {MessageActions} from \"@clubmed/usg-chat-ui/organisms/chat/MessageActions\";\nimport {Wand2} from \"lucide-react\";\nimport type {ChatMessage} from \"./types\";\nimport {useChatConfig} from \"@clubmed/usg-chat-ui/contexts/ChatContext\";\nimport {useChatLabels} from \"../../contexts/ChatLabelsContext\";\n\ninterface ChatMessageListProps {\n chatMessages: ChatMessage[];\n isLoadingMessage: boolean;\n onFollowupClick: (question: string) => void;\n onRegenerate: (messageKey: string) => void;\n}\n\nexport function ChatMessageList({\n chatMessages,\n isLoadingMessage,\n onFollowupClick,\n onRegenerate,\n }: ChatMessageListProps) {\n const {get, p} = useChatLabels();\n const {user} = useChatConfig();\n\n const renderMessageBranches = () =>\n chatMessages.map(({versions, ...message}, index) => (\n <Branch defaultBranch={versions.length - 1} key={message.key}>\n <BranchMessages>\n {versions.map((version) => (\n <Message from={message.from} key={`${message.key}-${version.id}`}>\n <MessageContent>\n {message.sources && message.sources.length > 0 && (\n <Sources>\n <SourcesTrigger count={message.sources.length}/>\n <SourcesContent>\n {message.sources.map((source) => (\n <Source href={source.href} key={source.href} title={source.title}/>\n ))}\n </SourcesContent>\n </Sources>\n )}\n {message.reasoning && (\n <Reasoning duration={message.reasoning.duration}>\n <ReasoningTrigger/>\n <ReasoningContent>{message.reasoning.content}</ReasoningContent>\n </Reasoning>\n )}\n {message.from === \"assistant\" ? (\n <>\n <MessageRenderer\n responseType={version.responseType || \"message\"}\n content={version.content}\n canvasData={version.canvasData}\n followupQuestions={version.followupQuestions}\n onQuestionClick={onFollowupClick}\n />\n <MessageActions\n content={version.content}\n messageId={version.id}\n responseType={version.responseType}\n canvasData={version.canvasData}\n onRegenerate={() => {\n const previous = chatMessages[index - 1];\n if (previous?.from === \"user\") {\n onRegenerate(message.key);\n }\n }}\n />\n </>\n ) : (\n <Response>{version.content}</Response>\n )}\n </MessageContent>\n </Message>\n ))}\n </BranchMessages>\n {versions.length > 1 && (\n <BranchSelector from={message.from}>\n <BranchPrevious/>\n <BranchPage/>\n <BranchNext/>\n </BranchSelector>\n )}\n </Branch>\n ));\n\n return (\n <Conversation className=\"flex-1\">\n <ConversationContent>\n {chatMessages.length === 0 ? (\n <ConversationEmptyState\n greeting={p(\n \"greetingTemplate\",\n \"Bonjour {{firstName}} 👋\",\n {firstName: user?.userName?.split(\" \")[0]}\n )}\n title={get(\n \"emptyStateTitle\",\n \"Bienvenue dans votre assistant de product management\"\n )}\n description={get(\n \"emptyStateDescription\",\n \"Je vous aide à créer des user stories Jira de qualité, générer des release notes, répondre à vos questions sur l'API ClubMed, structurer vos besoins fonctionnels. Décrivez votre besoin et commençons !\"\n )}\n icon={\n <div className=\"relative mx-auto w-fit\">\n <div className=\"absolute inset-0 bg-foreground/10 blur-3xl\"/>\n <div\n className=\"relative flex h-16 w-16 sm:h-20 sm:w-20 items-center justify-center rounded-2xl shadow-2xl ring-1 ring-border/40 transition-transform hover:scale-110 duration-500 overflow-hidden\"\n style={{\n background: \"linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 50%, #0f0f0f 100%)\",\n boxShadow: \"inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 8px 16px rgba(0, 0, 0, 0.4)\",\n }}\n >\n <div className=\"absolute inset-0 bg-gradient-to-br from-white/10 to-transparent pointer-events-none\"/>\n <Wand2 className=\"h-8 w-8 sm:h-10 sm:w-10 text-white relative z-10\" strokeWidth={1.5}/>\n </div>\n </div>\n }\n />\n ) : (\n <>\n {renderMessageBranches()}\n {isLoadingMessage && (\n <Message from=\"assistant\">\n <MessageContent variant=\"flat\">\n <span className=\"text-sm text-muted-foreground animate-pulse\">\n {get(\n \"assistantThinkingIndicator\",\n \"Réflexion en cours...\"\n )}\n </span>\n </MessageContent>\n </Message>\n )}\n </>\n )}\n </ConversationContent>\n <ConversationScrollButton/>\n </Conversation>\n );\n}\n"],"names":["ChatMessageList","chatMessages","isLoadingMessage","onFollowupClick","onRegenerate","get","p","useChatLabels","user","useChatConfig","renderMessageBranches","versions","message","index","jsxs","Branch","jsx","BranchMessages","version","Message","MessageContent","Sources","SourcesTrigger","SourcesContent","source","Source","Reasoning","ReasoningTrigger","ReasoningContent","Fragment","MessageRenderer","MessageActions","previous","Response","BranchSelector","BranchPrevious","BranchPage","BranchNext","Conversation","ConversationContent","ConversationEmptyState","_a","Wand2","ConversationScrollButton"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { jsx as i } from "react/jsx-runtime";
|
|
2
|
+
import { s as t, a as g } from "../../chunks/react.esm.js";
|
|
3
|
+
import { ChatMessageList as m } from "./ChatMessageList.js";
|
|
4
|
+
import { ChatLabelsProvider as l } from "../../contexts/ChatLabelsContext.js";
|
|
5
|
+
import { v as s, c as d, d as u, i as o, g as a } from "../../chunks/vi.2VT5v0um.js";
|
|
6
|
+
s.mock("@clubmed/usg-chat-ui/contexts/ChatContext", () => ({
|
|
7
|
+
useChatConfig: () => ({
|
|
8
|
+
user: {
|
|
9
|
+
userName: "Sam Example"
|
|
10
|
+
}
|
|
11
|
+
})
|
|
12
|
+
}));
|
|
13
|
+
s.mock("@clubmed/usg-chat-ui/organisms/chat/MessageRenderers", () => ({
|
|
14
|
+
MessageRenderer: ({ content: e }) => /* @__PURE__ */ i("div", { children: e })
|
|
15
|
+
}));
|
|
16
|
+
s.mock("@clubmed/usg-chat-ui/organisms/chat/MessageActions", () => ({
|
|
17
|
+
MessageActions: ({ onRegenerate: e }) => /* @__PURE__ */ i("button", { onClick: e, children: "Regenerate" })
|
|
18
|
+
}));
|
|
19
|
+
d(() => {
|
|
20
|
+
class e {
|
|
21
|
+
observe() {
|
|
22
|
+
}
|
|
23
|
+
unobserve() {
|
|
24
|
+
}
|
|
25
|
+
disconnect() {
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
s.stubGlobal("ResizeObserver", e);
|
|
29
|
+
});
|
|
30
|
+
const r = (e = {}, n) => {
|
|
31
|
+
const c = {
|
|
32
|
+
chatMessages: [],
|
|
33
|
+
isLoadingMessage: !1,
|
|
34
|
+
onFollowupClick: s.fn(),
|
|
35
|
+
onRegenerate: s.fn()
|
|
36
|
+
};
|
|
37
|
+
return g(
|
|
38
|
+
/* @__PURE__ */ i(l, { labels: n, children: /* @__PURE__ */ i(m, { ...c, ...e }) })
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
u("<ChatMessageList />", () => {
|
|
42
|
+
o("renders empty state with interpolated greeting and custom labels", () => {
|
|
43
|
+
r(void 0, {
|
|
44
|
+
greetingTemplate: "Hola {{firstName}}!",
|
|
45
|
+
emptyStateTitle: "Custom title",
|
|
46
|
+
emptyStateDescription: "Custom description",
|
|
47
|
+
assistantThinkingIndicator: "Processing..."
|
|
48
|
+
}), a(t.getByText("Custom title")).toBeInTheDocument(), a(t.getByText("Custom description")).toBeInTheDocument(), a(t.getByText("Hola Sam!")).toBeInTheDocument();
|
|
49
|
+
}), o("shows assistant thinking indicator when loading", () => {
|
|
50
|
+
r(
|
|
51
|
+
{
|
|
52
|
+
chatMessages: [{
|
|
53
|
+
key: "assistant-1",
|
|
54
|
+
from: "assistant",
|
|
55
|
+
avatar: "avatar-url",
|
|
56
|
+
name: "Assistant",
|
|
57
|
+
versions: [{ id: "v1", content: "Hello" }]
|
|
58
|
+
}],
|
|
59
|
+
isLoadingMessage: !0
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
assistantThinkingIndicator: "Working hard..."
|
|
63
|
+
}
|
|
64
|
+
), a(t.getByText("Working hard...")).toBeInTheDocument();
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
//# sourceMappingURL=ChatMessageList.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatMessageList.test.js","sources":["../../../lib/organisms/chat/ChatMessageList.test.tsx"],"sourcesContent":["import {render, screen} from \"@testing-library/react\";\nimport type {ComponentProps} from \"react\";\nimport {beforeAll, describe, expect, it, vi} from \"vitest\";\nimport {ChatMessageList} from \"./ChatMessageList\";\nimport {ChatLabelsProvider} from \"../../contexts/ChatLabelsContext\";\nimport type {ChatLabelOverrides} from \"../../config/chatLabels\";\nimport type {ChatMessage} from \"./types\";\n\nvi.mock(\"@clubmed/usg-chat-ui/contexts/ChatContext\", () => ({\n useChatConfig: () => ({\n user: {\n userName: \"Sam Example\",\n },\n }),\n}));\n\nvi.mock(\"@clubmed/usg-chat-ui/organisms/chat/MessageRenderers\", () => ({\n MessageRenderer: ({content}: {content: string}) => <div>{content}</div>,\n}));\n\nvi.mock(\"@clubmed/usg-chat-ui/organisms/chat/MessageActions\", () => ({\n MessageActions: ({onRegenerate}: {onRegenerate: () => void}) => (\n <button onClick={onRegenerate}>Regenerate</button>\n ),\n}));\n\nbeforeAll(() => {\n class ResizeObserverMock {\n observe() {}\n unobserve() {}\n disconnect() {}\n }\n vi.stubGlobal(\"ResizeObserver\", ResizeObserverMock);\n});\n\nconst renderWithProviders = (\n props: Partial<ComponentProps<typeof ChatMessageList>> = {},\n labels?: ChatLabelOverrides\n) => {\n const defaultProps = {\n chatMessages: [],\n isLoadingMessage: false,\n onFollowupClick: vi.fn(),\n onRegenerate: vi.fn(),\n };\n\n return render(\n <ChatLabelsProvider labels={labels}>\n <ChatMessageList {...defaultProps} {...props} />\n </ChatLabelsProvider>\n );\n};\n\ndescribe(\"<ChatMessageList />\", () => {\n it(\"renders empty state with interpolated greeting and custom labels\", () => {\n renderWithProviders(undefined, {\n greetingTemplate: \"Hola {{firstName}}!\",\n emptyStateTitle: \"Custom title\",\n emptyStateDescription: \"Custom description\",\n assistantThinkingIndicator: \"Processing...\",\n });\n\n expect(screen.getByText(\"Custom title\")).toBeInTheDocument();\n expect(screen.getByText(\"Custom description\")).toBeInTheDocument();\n expect(screen.getByText(\"Hola Sam!\")).toBeInTheDocument();\n });\n\n it(\"shows assistant thinking indicator when loading\", () => {\n const assistantMessage: ChatMessage = {\n key: \"assistant-1\",\n from: \"assistant\",\n avatar: \"avatar-url\",\n name: \"Assistant\",\n versions: [{id: \"v1\", content: \"Hello\"}],\n };\n\n renderWithProviders(\n {\n chatMessages: [assistantMessage],\n isLoadingMessage: true,\n },\n {\n assistantThinkingIndicator: \"Working hard...\",\n }\n );\n\n expect(screen.getByText(\"Working hard...\")).toBeInTheDocument();\n });\n});\n"],"names":["vi","content","jsx","onRegenerate","beforeAll","ResizeObserverMock","renderWithProviders","props","labels","defaultProps","render","ChatLabelsProvider","ChatMessageList","describe","it","expect","screen"],"mappings":";;;;;AAQAA,EAAG,KAAK,6CAA6C,OAAO;AAAA,EAC1D,eAAe,OAAO;AAAA,IACpB,MAAM;AAAA,MACJ,UAAU;AAAA,IAAA;AAAA,EACZ;AAEJ,EAAE;AAEFA,EAAG,KAAK,wDAAwD,OAAO;AAAA,EACrE,iBAAiB,CAAC,EAAC,SAAAC,QAAgC,gBAAAC,EAAC,SAAK,UAAAD,EAAA,CAAQ;AACnE,EAAE;AAEFD,EAAG,KAAK,sDAAsD,OAAO;AAAA,EACnE,gBAAgB,CAAC,EAAC,cAAAG,EAAA,MAChB,gBAAAD,EAAC,UAAA,EAAO,SAASC,GAAc,UAAA,aAAA,CAAU;AAE7C,EAAE;AAEFC,EAAU,MAAM;AAAA,EACd,MAAMC,EAAmB;AAAA,IACvB,UAAU;AAAA,IAAC;AAAA,IACX,YAAY;AAAA,IAAC;AAAA,IACb,aAAa;AAAA,IAAC;AAAA,EAAA;AAEhB,EAAAL,EAAG,WAAW,kBAAkBK,CAAkB;AACpD,CAAC;AAED,MAAMC,IAAsB,CAC1BC,IAAyD,CAAA,GACzDC,MACG;AACH,QAAMC,IAAe;AAAA,IACnB,cAAc,CAAA;AAAA,IACd,kBAAkB;AAAA,IAClB,iBAAiBT,EAAG,GAAA;AAAA,IACpB,cAAcA,EAAG,GAAA;AAAA,EAAG;AAGtB,SAAOU;AAAA,IACL,gBAAAR,EAACS,KAAmB,QAAAH,GAClB,UAAA,gBAAAN,EAACU,KAAiB,GAAGH,GAAe,GAAGF,EAAA,CAAO,EAAA,CAChD;AAAA,EAAA;AAEJ;AAEAM,EAAS,uBAAuB,MAAM;AACpC,EAAAC,EAAG,oEAAoE,MAAM;AAC3E,IAAAR,EAAoB,QAAW;AAAA,MAC7B,kBAAkB;AAAA,MAClB,iBAAiB;AAAA,MACjB,uBAAuB;AAAA,MACvB,4BAA4B;AAAA,IAAA,CAC7B,GAEDS,EAAOC,EAAO,UAAU,cAAc,CAAC,EAAE,kBAAA,GACzCD,EAAOC,EAAO,UAAU,oBAAoB,CAAC,EAAE,kBAAA,GAC/CD,EAAOC,EAAO,UAAU,WAAW,CAAC,EAAE,kBAAA;AAAA,EACxC,CAAC,GAEDF,EAAG,mDAAmD,MAAM;AAS1D,IAAAR;AAAA,MACE;AAAA,QACE,cAAc,CAVoB;AAAA,UACpC,KAAK;AAAA,UACL,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,UAAU,CAAC,EAAC,IAAI,MAAM,SAAS,SAAQ;AAAA,QAAA,CAKN;AAAA,QAC/B,kBAAkB;AAAA,MAAA;AAAA,MAEpB;AAAA,QACE,4BAA4B;AAAA,MAAA;AAAA,IAC9B,GAGFS,EAAOC,EAAO,UAAU,iBAAiB,CAAC,EAAE,kBAAA;AAAA,EAC9C,CAAC;AACH,CAAC;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
2
|
+
import { useChatLabels as n } from "../../contexts/ChatLabelsContext.js";
|
|
3
|
+
import { S as s } from "../../chunks/settings.js";
|
|
4
|
+
function m(t) {
|
|
5
|
+
const { get: o } = n(), e = o("chatSettingsButtonAriaLabel", "Paramètres");
|
|
6
|
+
return /* @__PURE__ */ r(
|
|
7
|
+
"button",
|
|
8
|
+
{
|
|
9
|
+
...t,
|
|
10
|
+
"aria-label": e,
|
|
11
|
+
className: "group relative flex h-9 w-9 sm:h-10 sm:w-10 items-center justify-center rounded-lg border border-border bg-card hover:bg-muted transition-all duration-200 hover:scale-105 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background",
|
|
12
|
+
children: /* @__PURE__ */ r(
|
|
13
|
+
s,
|
|
14
|
+
{
|
|
15
|
+
className: "h-4 w-4 sm:h-5 sm:w-5 text-muted-foreground group-hover:rotate-90 transition-transform duration-500"
|
|
16
|
+
}
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
m as ChatSettingsButton
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=ChatSettingsButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatSettingsButton.js","sources":["../../../lib/organisms/chat/ChatSettingsButton.tsx"],"sourcesContent":["import {Settings as SettingsIcon} from \"lucide-react\";\nimport type {ButtonHTMLAttributes} from \"react\";\nimport {useChatLabels} from \"../../contexts/ChatLabelsContext\";\n\nexport function ChatSettingsButton(props: ButtonHTMLAttributes<HTMLButtonElement>) {\n const {get} = useChatLabels();\n const ariaLabel = get(\"chatSettingsButtonAriaLabel\", \"Paramètres\");\n\n return (\n <button\n {...props}\n aria-label={ariaLabel}\n className=\"group relative flex h-9 w-9 sm:h-10 sm:w-10 items-center justify-center rounded-lg border border-border bg-card hover:bg-muted transition-all duration-200 hover:scale-105 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background\"\n >\n <SettingsIcon\n className=\"h-4 w-4 sm:h-5 sm:w-5 text-muted-foreground group-hover:rotate-90 transition-transform duration-500\"\n />\n </button>\n );\n}\n"],"names":["ChatSettingsButton","props","get","useChatLabels","ariaLabel","jsx","SettingsIcon"],"mappings":";;;AAIO,SAASA,EAAmBC,GAAgD;AACjF,QAAM,EAAC,KAAAC,EAAA,IAAOC,EAAA,GACRC,IAAYF,EAAI,+BAA+B,YAAY;AAEjE,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAGJ;AAAA,MACJ,cAAYG;AAAA,MACZ,WAAU;AAAA,MAEV,UAAA,gBAAAC;AAAA,QAACC;AAAAA,QAAA;AAAA,UACC,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,IACZ;AAAA,EAAA;AAGN;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as s } from "react/jsx-runtime";
|
|
2
|
+
import { a as r, s as a, f as o } from "../../chunks/react.esm.js";
|
|
3
|
+
import { ChatSettingsButton as i } from "./ChatSettingsButton.js";
|
|
4
|
+
import { ChatLabelsProvider as l } from "../../contexts/ChatLabelsContext.js";
|
|
5
|
+
import { d as c, i as m, v as d, g as n } from "../../chunks/vi.2VT5v0um.js";
|
|
6
|
+
c("<ChatSettingsButton />", () => {
|
|
7
|
+
m("forwards props and triggers handlers", () => {
|
|
8
|
+
const t = d.fn();
|
|
9
|
+
r(
|
|
10
|
+
/* @__PURE__ */ s(l, { labels: { chatSettingsButtonAriaLabel: "Open settings" }, children: /* @__PURE__ */ s(i, { onClick: t }) })
|
|
11
|
+
);
|
|
12
|
+
const e = a.getByLabelText("Open settings");
|
|
13
|
+
n(e).toBeInTheDocument(), o.click(e), n(t).toHaveBeenCalledTimes(1);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=ChatSettingsButton.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatSettingsButton.test.js","sources":["../../../lib/organisms/chat/ChatSettingsButton.test.tsx"],"sourcesContent":["import {fireEvent, render, screen} from \"@testing-library/react\";\nimport {describe, expect, it, vi} from \"vitest\";\nimport {ChatSettingsButton} from \"./ChatSettingsButton\";\nimport {ChatLabelsProvider} from \"../../contexts/ChatLabelsContext\";\n\ndescribe(\"<ChatSettingsButton />\", () => {\n it(\"forwards props and triggers handlers\", () => {\n const handleClick = vi.fn();\n render(\n <ChatLabelsProvider labels={{chatSettingsButtonAriaLabel: \"Open settings\"}}>\n <ChatSettingsButton onClick={handleClick} />\n </ChatLabelsProvider>\n );\n\n const button = screen.getByLabelText(\"Open settings\");\n expect(button).toBeInTheDocument();\n\n fireEvent.click(button);\n expect(handleClick).toHaveBeenCalledTimes(1);\n });\n});\n"],"names":["describe","it","handleClick","vi","render","jsx","ChatLabelsProvider","ChatSettingsButton","button","screen","expect","fireEvent"],"mappings":";;;;;AAKAA,EAAS,0BAA0B,MAAM;AACvC,EAAAC,EAAG,wCAAwC,MAAM;AAC/C,UAAMC,IAAcC,EAAG,GAAA;AACvB,IAAAC;AAAA,MACE,gBAAAC,EAACC,GAAA,EAAmB,QAAQ,EAAC,6BAA6B,gBAAA,GACxD,UAAA,gBAAAD,EAACE,GAAA,EAAmB,SAASL,EAAA,CAAa,EAAA,CAC5C;AAAA,IAAA;AAGF,UAAMM,IAASC,EAAO,eAAe,eAAe;AACpDC,IAAAA,EAAOF,CAAM,EAAE,kBAAA,GAEfG,EAAU,MAAMH,CAAM,GACtBE,EAAOR,CAAW,EAAE,sBAAsB,CAAC;AAAA,EAC7C,CAAC;AACH,CAAC;"}
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs as a, jsx as t } from "react/jsx-runtime";
|
|
3
|
-
import { useState as o, useEffect as
|
|
3
|
+
import { useState as o, useEffect as q } from "react";
|
|
4
4
|
import { Button as n } from "../../molecules/Buttons/Button.js";
|
|
5
|
-
import { ScrollArea as
|
|
6
|
-
import { cn as
|
|
7
|
-
import { useChatApiClient as
|
|
5
|
+
import { ScrollArea as V } from "../../molecules/ScrollAreas/ScrollArea.js";
|
|
6
|
+
import { cn as M } from "../../utils/cn.js";
|
|
7
|
+
import { useChatApiClient as _ } from "../../contexts/ChatContext.js";
|
|
8
|
+
import { useChatLabels as $ } from "../../contexts/ChatLabelsContext.js";
|
|
8
9
|
import { c as j } from "../../chunks/createLucideIcon.js";
|
|
9
|
-
import { R } from "../../chunks/refresh-cw.js";
|
|
10
|
-
import { P
|
|
11
|
-
import { L
|
|
10
|
+
import { R as F } from "../../chunks/refresh-cw.js";
|
|
11
|
+
import { P } from "../../chunks/panel-left.js";
|
|
12
|
+
import { L } from "../../chunks/loader-circle.js";
|
|
12
13
|
/**
|
|
13
14
|
* @license lucide-react v0.545.0 - ISC
|
|
14
15
|
*
|
|
15
16
|
* This source code is licensed under the ISC license.
|
|
16
17
|
* See the LICENSE file in the root directory of this source tree.
|
|
17
18
|
*/
|
|
18
|
-
const
|
|
19
|
+
const T = [
|
|
19
20
|
[
|
|
20
21
|
"path",
|
|
21
22
|
{
|
|
@@ -23,60 +24,60 @@ const _ = [
|
|
|
23
24
|
key: "18887p"
|
|
24
25
|
}
|
|
25
26
|
]
|
|
26
|
-
],
|
|
27
|
+
], I = j("message-square", T);
|
|
27
28
|
/**
|
|
28
29
|
* @license lucide-react v0.545.0 - ISC
|
|
29
30
|
*
|
|
30
31
|
* This source code is licensed under the ISC license.
|
|
31
32
|
* See the LICENSE file in the root directory of this source tree.
|
|
32
33
|
*/
|
|
33
|
-
const
|
|
34
|
+
const B = [
|
|
34
35
|
["path", { d: "M10 11v6", key: "nco0om" }],
|
|
35
36
|
["path", { d: "M14 11v6", key: "outv1u" }],
|
|
36
37
|
["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6", key: "miytrc" }],
|
|
37
38
|
["path", { d: "M3 6h18", key: "d0wm0j" }],
|
|
38
39
|
["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2", key: "e791ji" }]
|
|
39
|
-
],
|
|
40
|
-
function
|
|
40
|
+
], G = j("trash-2", B);
|
|
41
|
+
function re({
|
|
41
42
|
currentConversationId: h,
|
|
42
|
-
onSelectConversation:
|
|
43
|
-
onNewConversation:
|
|
44
|
-
refreshTrigger:
|
|
43
|
+
onSelectConversation: f,
|
|
44
|
+
onNewConversation: A,
|
|
45
|
+
refreshTrigger: D,
|
|
45
46
|
onClose: l
|
|
46
47
|
}) {
|
|
47
|
-
const
|
|
48
|
+
const u = _(), { get: p } = $(), S = p("conversationRefreshAriaLabel", "Rafraîchir"), z = p("conversationCloseHistoryAriaLabel", "Fermer l'historique"), [g, v] = o([]), [c, b] = o(!0), [N, x] = o(null), [y, w] = o(null), d = async () => {
|
|
48
49
|
try {
|
|
49
|
-
|
|
50
|
-
const e = await
|
|
51
|
-
console.log("[ConversationSidebar] Conversations received:", e, "count:", e.length),
|
|
50
|
+
b(!0), w(null), console.log("[ConversationSidebar] Fetching conversations (auth-based)");
|
|
51
|
+
const e = await u.listConversations();
|
|
52
|
+
console.log("[ConversationSidebar] Conversations received:", e, "count:", e.length), v(e);
|
|
52
53
|
} catch (e) {
|
|
53
|
-
|
|
54
|
+
w(e instanceof Error ? e.message : "Erreur lors du chargement");
|
|
54
55
|
} finally {
|
|
55
|
-
|
|
56
|
+
b(!1);
|
|
56
57
|
}
|
|
57
58
|
};
|
|
58
|
-
|
|
59
|
+
q(() => {
|
|
59
60
|
d();
|
|
60
|
-
}, [
|
|
61
|
-
const
|
|
61
|
+
}, [D]);
|
|
62
|
+
const E = async (e, r) => {
|
|
62
63
|
if (r.stopPropagation(), !!confirm("Voulez-vous vraiment supprimer cette conversation ?"))
|
|
63
64
|
try {
|
|
64
|
-
x(e), await
|
|
65
|
+
x(e), await u.deleteConversation({ conversationId: e }), v((i) => i.filter((s) => s.id !== e)), h === e && f(null), await d();
|
|
65
66
|
} catch (i) {
|
|
66
67
|
console.error("Error deleting conversation:", i), alert("Erreur lors de la suppression");
|
|
67
68
|
} finally {
|
|
68
69
|
x(null);
|
|
69
70
|
}
|
|
70
|
-
},
|
|
71
|
-
const r = new Date(e), s = (/* @__PURE__ */ new Date()).getTime() - r.getTime(), m = Math.floor(s / 6e4),
|
|
72
|
-
return m < 1 ? "À l'instant" : m < 60 ? `Il y a ${m} min` :
|
|
73
|
-
},
|
|
71
|
+
}, H = (e) => {
|
|
72
|
+
const r = new Date(e), s = (/* @__PURE__ */ new Date()).getTime() - r.getTime(), m = Math.floor(s / 6e4), C = Math.floor(s / 36e5), k = Math.floor(s / 864e5);
|
|
73
|
+
return m < 1 ? "À l'instant" : m < 60 ? `Il y a ${m} min` : C < 24 ? `Il y a ${C}h` : k < 7 ? `Il y a ${k}j` : r.toLocaleDateString("fr-FR", { day: "numeric", month: "short" });
|
|
74
|
+
}, R = () => {
|
|
74
75
|
l == null || l();
|
|
75
76
|
};
|
|
76
77
|
return /* @__PURE__ */ a("div", { className: "flex flex-col h-full w-64 border-r border-border bg-card relative", children: [
|
|
77
78
|
/* @__PURE__ */ a("div", { className: "flex items-center justify-between p-3 border-b border-border", children: [
|
|
78
79
|
/* @__PURE__ */ a("div", { className: "flex items-center gap-2", children: [
|
|
79
|
-
/* @__PURE__ */ t(
|
|
80
|
+
/* @__PURE__ */ t(I, { className: "h-4 w-4 text-muted-foreground" }),
|
|
80
81
|
/* @__PURE__ */ t("h2", { className: "text-sm font-semibold text-foreground", children: "Historique" })
|
|
81
82
|
] }),
|
|
82
83
|
/* @__PURE__ */ a("div", { className: "flex items-center gap-1", children: [
|
|
@@ -87,9 +88,9 @@ function X({
|
|
|
87
88
|
size: "icon",
|
|
88
89
|
onClick: () => d(),
|
|
89
90
|
className: "h-6 w-6",
|
|
90
|
-
"aria-label":
|
|
91
|
+
"aria-label": S,
|
|
91
92
|
disabled: c,
|
|
92
|
-
children: /* @__PURE__ */ t(
|
|
93
|
+
children: /* @__PURE__ */ t(F, { className: M("h-3 w-3", c && "animate-spin") })
|
|
93
94
|
}
|
|
94
95
|
),
|
|
95
96
|
/* @__PURE__ */ t(
|
|
@@ -97,10 +98,10 @@ function X({
|
|
|
97
98
|
{
|
|
98
99
|
variant: "ghost",
|
|
99
100
|
size: "icon",
|
|
100
|
-
onClick:
|
|
101
|
+
onClick: R,
|
|
101
102
|
className: "h-6 w-6",
|
|
102
|
-
"aria-label":
|
|
103
|
-
children: /* @__PURE__ */ t(
|
|
103
|
+
"aria-label": z,
|
|
104
|
+
children: /* @__PURE__ */ t(P, { className: "h-3 w-3" })
|
|
104
105
|
}
|
|
105
106
|
)
|
|
106
107
|
] })
|
|
@@ -110,33 +111,33 @@ function X({
|
|
|
110
111
|
{
|
|
111
112
|
variant: "default",
|
|
112
113
|
size: "sm",
|
|
113
|
-
onClick:
|
|
114
|
+
onClick: A,
|
|
114
115
|
className: "w-full",
|
|
115
116
|
children: "Nouvelle conversation"
|
|
116
117
|
}
|
|
117
118
|
) }),
|
|
118
|
-
/* @__PURE__ */ t(
|
|
119
|
+
/* @__PURE__ */ t(V, { className: "flex-1", children: c ? /* @__PURE__ */ t("div", { className: "flex items-center justify-center p-4", children: /* @__PURE__ */ t(L, { className: "h-4 w-4 animate-spin text-muted-foreground" }) }) : y ? /* @__PURE__ */ t("div", { className: "p-4 text-center text-sm text-destructive", children: y }) : g.length === 0 ? /* @__PURE__ */ t("div", { className: "p-4 text-center text-sm text-muted-foreground", children: "Aucune conversation" }) : /* @__PURE__ */ t("div", { className: "p-2", children: g.map((e) => /* @__PURE__ */ t(
|
|
119
120
|
"div",
|
|
120
121
|
{
|
|
121
|
-
onClick: () =>
|
|
122
|
-
className:
|
|
122
|
+
onClick: () => f(e),
|
|
123
|
+
className: M(
|
|
123
124
|
"group relative p-3 rounded-lg cursor-pointer transition-colors mb-1",
|
|
124
125
|
h === e.id ? "bg-muted" : "hover:bg-muted/50"
|
|
125
126
|
),
|
|
126
127
|
children: /* @__PURE__ */ a("div", { className: "flex items-start justify-between gap-2", children: [
|
|
127
128
|
/* @__PURE__ */ a("div", { className: "flex-1 min-w-0", children: [
|
|
128
129
|
/* @__PURE__ */ t("h3", { className: "text-sm font-medium text-foreground truncate", children: e.title || "Sans titre" }),
|
|
129
|
-
/* @__PURE__ */ t("p", { className: "text-xs text-muted-foreground mt-1", children:
|
|
130
|
+
/* @__PURE__ */ t("p", { className: "text-xs text-muted-foreground mt-1", children: H(e.updatedAt) })
|
|
130
131
|
] }),
|
|
131
132
|
/* @__PURE__ */ t(
|
|
132
133
|
n,
|
|
133
134
|
{
|
|
134
135
|
variant: "ghost",
|
|
135
136
|
size: "icon",
|
|
136
|
-
onClick: (r) =>
|
|
137
|
+
onClick: (r) => E(e.id, r),
|
|
137
138
|
className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity shrink-0",
|
|
138
139
|
disabled: N === e.id,
|
|
139
|
-
children: N === e.id ? /* @__PURE__ */ t(
|
|
140
|
+
children: N === e.id ? /* @__PURE__ */ t(L, { className: "h-3 w-3 animate-spin" }) : /* @__PURE__ */ t(G, { className: "h-3 w-3" })
|
|
140
141
|
}
|
|
141
142
|
)
|
|
142
143
|
] })
|
|
@@ -146,6 +147,6 @@ function X({
|
|
|
146
147
|
] });
|
|
147
148
|
}
|
|
148
149
|
export {
|
|
149
|
-
|
|
150
|
+
re as ConversationSidebar
|
|
150
151
|
};
|
|
151
152
|
//# sourceMappingURL=ConversationSidebar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationSidebar.js","sources":["../../../../../node_modules/.pnpm/lucide-react@0.545.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/message-square.js","../../../../../node_modules/.pnpm/lucide-react@0.545.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/trash-2.js","../../../lib/organisms/chat/ConversationSidebar.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z\",\n key: \"18887p\"\n }\n ]\n];\nconst MessageSquare = createLucideIcon(\"message-square\", __iconNode);\n\nexport { __iconNode, MessageSquare as default };\n//# sourceMappingURL=message-square.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M10 11v6\", key: \"nco0om\" }],\n [\"path\", { d: \"M14 11v6\", key: \"outv1u\" }],\n [\"path\", { d: \"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\", key: \"miytrc\" }],\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\", key: \"e791ji\" }]\n];\nconst Trash2 = createLucideIcon(\"trash-2\", __iconNode);\n\nexport { __iconNode, Trash2 as default };\n//# sourceMappingURL=trash-2.js.map\n","\"use client\";\n\nimport type {MouseEvent} from \"react\";\nimport {useEffect, useState} from \"react\";\nimport {Loader2, MessageSquare, PanelLeft, RefreshCw, Trash2} from \"lucide-react\";\nimport {Button} from \"@clubmed/usg-chat-ui/molecules/Buttons/Button\";\nimport {ScrollArea} from \"@clubmed/usg-chat-ui/molecules/ScrollAreas/ScrollArea\";\nimport {cn} from \"@clubmed/usg-chat-ui/utils/cn\";\nimport {useChatApiClient} from \"@clubmed/usg-chat-ui/contexts/ChatContext\";\nimport type {ConversationSummary} from \"@clubmed/usg-chat-ui/core/interfaces\";\n\ninterface ConversationSidebarProps {\n currentConversationId: string | null;\n onSelectConversation: (conversation: ConversationSummary | null) => void;\n onNewConversation: () => void;\n refreshTrigger?: number; // Trigger refresh when this changes\n onClose?: () => void; // Callback when sidebar is closed\n}\n\nexport function ConversationSidebar({\n currentConversationId,\n onSelectConversation,\n onNewConversation,\n refreshTrigger,\n onClose,\n }: ConversationSidebarProps) {\n const apiClient = useChatApiClient();\n const [conversations, setConversations] = useState<ConversationSummary[]>([]);\n const [loading, setLoading] = useState(true);\n const [deletingId, setDeletingId] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const loadConversations = async () => {\n try {\n setLoading(true);\n setError(null);\n\n console.log('[ConversationSidebar] Fetching conversations (auth-based)');\n const data = await apiClient.listConversations();\n console.log('[ConversationSidebar] Conversations received:', data, 'count:', data.length);\n\n setConversations(data);\n } catch (error) {\n setError(error instanceof Error ? error.message : \"Erreur lors du chargement\");\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n loadConversations();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [refreshTrigger]);\n\n const handleDelete = async (\n conversationId: string,\n event: MouseEvent<HTMLButtonElement>\n ) => {\n event.stopPropagation();\n if (!confirm(\"Voulez-vous vraiment supprimer cette conversation ?\")) {\n return;\n }\n\n try {\n setDeletingId(conversationId);\n\n await apiClient.deleteConversation({conversationId});\n\n setConversations((prev) => prev.filter((c) => c.id !== conversationId));\n if (currentConversationId === conversationId) {\n onSelectConversation(null);\n }\n // Reload conversations to ensure consistency\n await loadConversations();\n } catch (error) {\n console.error(\"Error deleting conversation:\", error);\n alert(\"Erreur lors de la suppression\");\n } finally {\n setDeletingId(null);\n }\n };\n\n const formatDate = (dateString: string) => {\n const date = new Date(dateString);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return \"À l'instant\";\n if (diffMins < 60) return `Il y a ${diffMins} min`;\n if (diffHours < 24) return `Il y a ${diffHours}h`;\n if (diffDays < 7) return `Il y a ${diffDays}j`;\n return date.toLocaleDateString(\"fr-FR\", {day: \"numeric\", month: \"short\"});\n };\n\n const handleClose = () => {\n onClose?.();\n };\n\n return (\n <div className=\"flex flex-col h-full w-64 border-r border-border bg-card relative\">\n {/* Header */}\n <div className=\"flex items-center justify-between p-3 border-b border-border\">\n <div className=\"flex items-center gap-2\">\n <MessageSquare className=\"h-4 w-4 text-muted-foreground\"/>\n <h2 className=\"text-sm font-semibold text-foreground\">Historique</h2>\n </div>\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => loadConversations()}\n className=\"h-6 w-6\"\n aria-label=\"Rafraîchir\"\n disabled={loading}\n >\n <RefreshCw className={cn(\"h-3 w-3\", loading && \"animate-spin\")}/>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={handleClose}\n className=\"h-6 w-6\"\n aria-label=\"Fermer l'historique\"\n >\n <PanelLeft className=\"h-3 w-3\"/>\n </Button>\n </div>\n </div>\n\n {/* New Conversation Button */}\n <div className=\"p-2 border-b border-border\">\n <Button\n variant=\"default\"\n size=\"sm\"\n onClick={onNewConversation}\n className=\"w-full\"\n >\n Nouvelle conversation\n </Button>\n </div>\n\n {/* Conversations List */}\n <ScrollArea className=\"flex-1\">\n {loading ? (\n <div className=\"flex items-center justify-center p-4\">\n <Loader2 className=\"h-4 w-4 animate-spin text-muted-foreground\"/>\n </div>\n ) : error ? (\n <div className=\"p-4 text-center text-sm text-destructive\">\n {error}\n </div>\n ) : conversations.length === 0 ? (\n <div className=\"p-4 text-center text-sm text-muted-foreground\">\n Aucune conversation\n </div>\n ) : (\n <div className=\"p-2\">\n {conversations.map((conversation) => (\n <div\n key={conversation.id}\n onClick={() => onSelectConversation(conversation)}\n className={cn(\n \"group relative p-3 rounded-lg cursor-pointer transition-colors mb-1\",\n currentConversationId === conversation.id\n ? \"bg-muted\"\n : \"hover:bg-muted/50\"\n )}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"text-sm font-medium text-foreground truncate\">\n {conversation.title || \"Sans titre\"}\n </h3>\n <p className=\"text-xs text-muted-foreground mt-1\">\n {formatDate(conversation.updatedAt)}\n </p>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={(event: MouseEvent<HTMLButtonElement>) =>\n handleDelete(conversation.id, event)\n }\n className=\"h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n disabled={deletingId === conversation.id}\n >\n {deletingId === conversation.id ? (\n <Loader2 className=\"h-3 w-3 animate-spin\"/>\n ) : (\n <Trash2 className=\"h-3 w-3\"/>\n )}\n </Button>\n </div>\n </div>\n ))}\n </div>\n )}\n </ScrollArea>\n </div>\n );\n}\n"],"names":["__iconNode","MessageSquare","createLucideIcon","Trash2","ConversationSidebar","currentConversationId","onSelectConversation","onNewConversation","refreshTrigger","onClose","apiClient","useChatApiClient","conversations","setConversations","useState","loading","setLoading","deletingId","setDeletingId","error","setError","loadConversations","data","useEffect","handleDelete","conversationId","event","prev","c","formatDate","dateString","date","diffMs","diffMins","diffHours","diffDays","handleClose","jsxs","jsx","Button","RefreshCw","cn","PanelLeft","ScrollArea","Loader2","conversation"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
1
|
+
{"version":3,"file":"ConversationSidebar.js","sources":["../../../../../node_modules/.pnpm/lucide-react@0.545.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/message-square.js","../../../../../node_modules/.pnpm/lucide-react@0.545.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/trash-2.js","../../../lib/organisms/chat/ConversationSidebar.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z\",\n key: \"18887p\"\n }\n ]\n];\nconst MessageSquare = createLucideIcon(\"message-square\", __iconNode);\n\nexport { __iconNode, MessageSquare as default };\n//# sourceMappingURL=message-square.js.map\n","/**\n * @license lucide-react v0.545.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M10 11v6\", key: \"nco0om\" }],\n [\"path\", { d: \"M14 11v6\", key: \"outv1u\" }],\n [\"path\", { d: \"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\", key: \"miytrc\" }],\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\", key: \"e791ji\" }]\n];\nconst Trash2 = createLucideIcon(\"trash-2\", __iconNode);\n\nexport { __iconNode, Trash2 as default };\n//# sourceMappingURL=trash-2.js.map\n","\"use client\";\n\nimport type {MouseEvent} from \"react\";\nimport {useEffect, useState} from \"react\";\nimport {Loader2, MessageSquare, PanelLeft, RefreshCw, Trash2} from \"lucide-react\";\nimport {Button} from \"@clubmed/usg-chat-ui/molecules/Buttons/Button\";\nimport {ScrollArea} from \"@clubmed/usg-chat-ui/molecules/ScrollAreas/ScrollArea\";\nimport {cn} from \"@clubmed/usg-chat-ui/utils/cn\";\nimport {useChatApiClient} from \"@clubmed/usg-chat-ui/contexts/ChatContext\";\nimport type {ConversationSummary} from \"@clubmed/usg-chat-ui/core/interfaces\";\nimport {useChatLabels} from \"../../contexts/ChatLabelsContext\";\n\ninterface ConversationSidebarProps {\n currentConversationId: string | null;\n onSelectConversation: (conversation: ConversationSummary | null) => void;\n onNewConversation: () => void;\n refreshTrigger?: number; // Trigger refresh when this changes\n onClose?: () => void; // Callback when sidebar is closed\n}\n\nexport function ConversationSidebar({\n currentConversationId,\n onSelectConversation,\n onNewConversation,\n refreshTrigger,\n onClose,\n}: ConversationSidebarProps) {\n const apiClient = useChatApiClient();\n const {get} = useChatLabels();\n const refreshLabel = get(\"conversationRefreshAriaLabel\", \"Rafraîchir\");\n const closeHistoryLabel = get(\"conversationCloseHistoryAriaLabel\", \"Fermer l'historique\");\n const [conversations, setConversations] = useState<ConversationSummary[]>([]);\n const [loading, setLoading] = useState(true);\n const [deletingId, setDeletingId] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const loadConversations = async () => {\n try {\n setLoading(true);\n setError(null);\n\n console.log('[ConversationSidebar] Fetching conversations (auth-based)');\n const data = await apiClient.listConversations();\n console.log('[ConversationSidebar] Conversations received:', data, 'count:', data.length);\n\n setConversations(data);\n } catch (error) {\n setError(error instanceof Error ? error.message : \"Erreur lors du chargement\");\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n loadConversations();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [refreshTrigger]);\n\n const handleDelete = async (\n conversationId: string,\n event: MouseEvent<HTMLButtonElement>\n ) => {\n event.stopPropagation();\n if (!confirm(\"Voulez-vous vraiment supprimer cette conversation ?\")) {\n return;\n }\n\n try {\n setDeletingId(conversationId);\n\n await apiClient.deleteConversation({conversationId});\n\n setConversations((prev) => prev.filter((c) => c.id !== conversationId));\n if (currentConversationId === conversationId) {\n onSelectConversation(null);\n }\n // Reload conversations to ensure consistency\n await loadConversations();\n } catch (error) {\n console.error(\"Error deleting conversation:\", error);\n alert(\"Erreur lors de la suppression\");\n } finally {\n setDeletingId(null);\n }\n };\n\n const formatDate = (dateString: string) => {\n const date = new Date(dateString);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return \"À l'instant\";\n if (diffMins < 60) return `Il y a ${diffMins} min`;\n if (diffHours < 24) return `Il y a ${diffHours}h`;\n if (diffDays < 7) return `Il y a ${diffDays}j`;\n return date.toLocaleDateString(\"fr-FR\", {day: \"numeric\", month: \"short\"});\n };\n\n const handleClose = () => {\n onClose?.();\n };\n\n return (\n <div className=\"flex flex-col h-full w-64 border-r border-border bg-card relative\">\n {/* Header */}\n <div className=\"flex items-center justify-between p-3 border-b border-border\">\n <div className=\"flex items-center gap-2\">\n <MessageSquare className=\"h-4 w-4 text-muted-foreground\"/>\n <h2 className=\"text-sm font-semibold text-foreground\">Historique</h2>\n </div>\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => loadConversations()}\n className=\"h-6 w-6\"\n aria-label={refreshLabel}\n disabled={loading}\n >\n <RefreshCw className={cn(\"h-3 w-3\", loading && \"animate-spin\")}/>\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={handleClose}\n className=\"h-6 w-6\"\n aria-label={closeHistoryLabel}\n >\n <PanelLeft className=\"h-3 w-3\"/>\n </Button>\n </div>\n </div>\n\n {/* New Conversation Button */}\n <div className=\"p-2 border-b border-border\">\n <Button\n variant=\"default\"\n size=\"sm\"\n onClick={onNewConversation}\n className=\"w-full\"\n >\n Nouvelle conversation\n </Button>\n </div>\n\n {/* Conversations List */}\n <ScrollArea className=\"flex-1\">\n {loading ? (\n <div className=\"flex items-center justify-center p-4\">\n <Loader2 className=\"h-4 w-4 animate-spin text-muted-foreground\"/>\n </div>\n ) : error ? (\n <div className=\"p-4 text-center text-sm text-destructive\">\n {error}\n </div>\n ) : conversations.length === 0 ? (\n <div className=\"p-4 text-center text-sm text-muted-foreground\">\n Aucune conversation\n </div>\n ) : (\n <div className=\"p-2\">\n {conversations.map((conversation) => (\n <div\n key={conversation.id}\n onClick={() => onSelectConversation(conversation)}\n className={cn(\n \"group relative p-3 rounded-lg cursor-pointer transition-colors mb-1\",\n currentConversationId === conversation.id\n ? \"bg-muted\"\n : \"hover:bg-muted/50\"\n )}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"text-sm font-medium text-foreground truncate\">\n {conversation.title || \"Sans titre\"}\n </h3>\n <p className=\"text-xs text-muted-foreground mt-1\">\n {formatDate(conversation.updatedAt)}\n </p>\n </div>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={(event: MouseEvent<HTMLButtonElement>) =>\n handleDelete(conversation.id, event)\n }\n className=\"h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n disabled={deletingId === conversation.id}\n >\n {deletingId === conversation.id ? (\n <Loader2 className=\"h-3 w-3 animate-spin\"/>\n ) : (\n <Trash2 className=\"h-3 w-3\"/>\n )}\n </Button>\n </div>\n </div>\n ))}\n </div>\n )}\n </ScrollArea>\n </div>\n );\n}\n"],"names":["__iconNode","MessageSquare","createLucideIcon","Trash2","ConversationSidebar","currentConversationId","onSelectConversation","onNewConversation","refreshTrigger","onClose","apiClient","useChatApiClient","get","useChatLabels","refreshLabel","closeHistoryLabel","conversations","setConversations","useState","loading","setLoading","deletingId","setDeletingId","error","setError","loadConversations","data","useEffect","handleDelete","conversationId","event","prev","c","formatDate","dateString","date","diffMs","diffMins","diffHours","diffDays","handleClose","jsxs","jsx","Button","RefreshCw","cn","PanelLeft","ScrollArea","Loader2","conversation"],"mappings":"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","x_google_ignoreList":[0,1]}
|