@lastbrain/ai-ui-react 1.0.40 → 1.0.42
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/components/AiContextButton.d.ts.map +1 -1
- package/dist/components/AiContextButton.js +33 -11
- package/dist/components/AiImageButton.d.ts.map +1 -1
- package/dist/components/AiImageButton.js +33 -11
- package/dist/components/AiInput.d.ts.map +1 -1
- package/dist/components/AiInput.js +24 -1
- package/dist/components/AiStatusButton.d.ts.map +1 -1
- package/dist/components/AiStatusButton.js +187 -13
- package/dist/components/AiTextarea.d.ts.map +1 -1
- package/dist/components/AiTextarea.js +24 -1
- package/dist/components/LBConnectButton.d.ts.map +1 -1
- package/dist/components/LBConnectButton.js +17 -16
- package/dist/components/LBSigninModal.d.ts +6 -0
- package/dist/components/LBSigninModal.d.ts.map +1 -0
- package/dist/components/LBSigninModal.js +232 -0
- package/dist/context/LBAuthProvider.d.ts +5 -2
- package/dist/context/LBAuthProvider.d.ts.map +1 -1
- package/dist/context/LBAuthProvider.js +67 -35
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +2 -2
- package/src/components/AiContextButton.tsx +55 -8
- package/src/components/AiImageButton.tsx +53 -8
- package/src/components/AiInput.tsx +44 -3
- package/src/components/AiStatusButton.tsx +356 -38
- package/src/components/AiTextarea.tsx +44 -3
- package/src/components/LBConnectButton.tsx +241 -101
- package/src/components/LBSigninModal.tsx +394 -0
- package/src/context/LBAuthProvider.tsx +86 -44
- package/src/index.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiContextButton.d.ts","sourceRoot":"","sources":["../../src/components/AiContextButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"AiContextButton.d.ts","sourceRoot":"","sources":["../../src/components/AiContextButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAW5C,MAAM,WAAW,oBACf,SACE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC,EACrC,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IAEvE,WAAW,EAAE,GAAG,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,CACT,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAC7C,IAAI,CAAC;IACV,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,YAAY,EACtB,MAAgB,EAChB,WAAW,EACX,kBAAyC,EACzC,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,gBAA0C,EAC1C,YAAY,EACZ,aAAa,EACb,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,EACf,GAAG,WAAW,EACf,EAAE,oBAAoB,2CAqiBtB"}
|
|
@@ -9,12 +9,25 @@ import { useErrorToast, ErrorToast } from "./ErrorToast";
|
|
|
9
9
|
import { aiStyles } from "../styles/inline";
|
|
10
10
|
import { useAiContext } from "../context/AiProvider";
|
|
11
11
|
import { handleAIError } from "../utils/errorHandler";
|
|
12
|
+
import { useLB } from "../context/LBAuthProvider";
|
|
13
|
+
import { LBSigninModal } from "./LBSigninModal";
|
|
12
14
|
export function AiContextButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode = "modal", contextData, contextDescription = "Données à analyser", onResult, onToast, disabled, className, children, resultModalTitle = "Résultat de l'analyse", storeOutputs, artifactTitle, context: _context, model: _model, prompt: _prompt, ...buttonProps }) {
|
|
13
15
|
const [isOpen, setIsOpen] = useState(false);
|
|
16
|
+
const [showAuthModal, setShowAuthModal] = useState(false);
|
|
14
17
|
const [isResultOpen, setIsResultOpen] = useState(false);
|
|
15
18
|
const [analysisResult, setAnalysisResult] = useState(null);
|
|
16
19
|
const { showUsageToast, toastData, toastKey, clearToast } = useUsageToast();
|
|
17
20
|
const { showErrorToast, errorData, errorKey, clearError } = useErrorToast();
|
|
21
|
+
// Rendre l'authentification optionnelle
|
|
22
|
+
let lbStatus;
|
|
23
|
+
try {
|
|
24
|
+
const lbContext = useLB();
|
|
25
|
+
lbStatus = lbContext.status;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// LBProvider n'est pas disponible, ignorer
|
|
29
|
+
lbStatus = undefined;
|
|
30
|
+
}
|
|
18
31
|
// Récupérer le contexte AiProvider avec fallback sur les props
|
|
19
32
|
const aiContext = useAiContext();
|
|
20
33
|
const baseUrl = propBaseUrl ?? aiContext.baseUrl;
|
|
@@ -23,7 +36,12 @@ export function AiContextButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId,
|
|
|
23
36
|
baseUrl,
|
|
24
37
|
apiKeyId,
|
|
25
38
|
});
|
|
39
|
+
const isAuthReady = lbStatus === "ready" || Boolean(process.env.LB_API_KEY);
|
|
26
40
|
const handleOpenPanel = () => {
|
|
41
|
+
if (!isAuthReady) {
|
|
42
|
+
setShowAuthModal(true);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
27
45
|
setIsOpen(true);
|
|
28
46
|
};
|
|
29
47
|
const handleClosePanel = () => {
|
|
@@ -160,14 +178,18 @@ Analyse ces données et réponds de manière structurée et claire.`;
|
|
|
160
178
|
setIsOpen(false);
|
|
161
179
|
}
|
|
162
180
|
};
|
|
163
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { style: { position: "relative", display: "inline-block" }, children: [_jsx("button", { ...buttonProps, onClick: handleOpenPanel, disabled: disabled || loading, className: className, style: {
|
|
181
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { style: { position: "relative", display: "inline-block" }, children: [_jsx("button", { ...buttonProps, onClick: handleOpenPanel, disabled: disabled || loading || !isAuthReady, className: className, style: {
|
|
164
182
|
...aiStyles.button,
|
|
165
183
|
display: "flex",
|
|
166
184
|
alignItems: "center",
|
|
167
185
|
gap: "8px",
|
|
168
|
-
cursor: disabled || loading ? "not-allowed" : "pointer",
|
|
169
|
-
opacity: disabled || loading ? 0.6 : 1,
|
|
170
|
-
backgroundColor: loading
|
|
186
|
+
cursor: disabled || loading || !isAuthReady ? "not-allowed" : "pointer",
|
|
187
|
+
opacity: disabled || loading || !isAuthReady ? 0.6 : 1,
|
|
188
|
+
backgroundColor: loading
|
|
189
|
+
? "#8b5cf6"
|
|
190
|
+
: !isAuthReady
|
|
191
|
+
? "#94a3b8"
|
|
192
|
+
: "#7c3aed",
|
|
171
193
|
color: "white",
|
|
172
194
|
border: "none",
|
|
173
195
|
borderRadius: "12px",
|
|
@@ -188,30 +210,30 @@ Analyse ces données et réponds de manière structurée et claire.`;
|
|
|
188
210
|
}),
|
|
189
211
|
...buttonProps.style,
|
|
190
212
|
}, onMouseEnter: (e) => {
|
|
191
|
-
if (!disabled && !loading) {
|
|
213
|
+
if (!disabled && !loading && isAuthReady) {
|
|
192
214
|
e.currentTarget.style.transform = "scale(1.02)";
|
|
193
215
|
e.currentTarget.style.boxShadow =
|
|
194
216
|
"0 6px 16px rgba(124, 58, 237, 0.3)";
|
|
195
217
|
}
|
|
196
218
|
}, onMouseLeave: (e) => {
|
|
197
|
-
if (!disabled && !loading) {
|
|
219
|
+
if (!disabled && !loading && isAuthReady) {
|
|
198
220
|
e.currentTarget.style.transform = "scale(1)";
|
|
199
221
|
e.currentTarget.style.boxShadow = loading
|
|
200
222
|
? "0 4px 12px rgba(139, 92, 246, 0.3)"
|
|
201
223
|
: "0 2px 8px rgba(124, 58, 237, 0.2)";
|
|
202
224
|
}
|
|
203
225
|
}, onMouseDown: (e) => {
|
|
204
|
-
if (!disabled && !loading) {
|
|
226
|
+
if (!disabled && !loading && isAuthReady) {
|
|
205
227
|
e.currentTarget.style.transform = "scale(0.98)";
|
|
206
228
|
}
|
|
207
229
|
}, onMouseUp: (e) => {
|
|
208
|
-
if (!disabled && !loading) {
|
|
230
|
+
if (!disabled && !loading && isAuthReady) {
|
|
209
231
|
e.currentTarget.style.transform = "scale(1.02)";
|
|
210
232
|
}
|
|
211
|
-
}, "data-ai-context-button": true, children: loading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 18, className: "animate-spin", style: {
|
|
233
|
+
}, "data-ai-context-button": true, title: !isAuthReady ? "Authentication required" : "Analyser avec l'IA", children: loading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 18, className: "animate-spin", style: {
|
|
212
234
|
color: "white",
|
|
213
235
|
filter: "drop-shadow(0 0 2px rgba(255,255,255,0.3))",
|
|
214
|
-
} }), _jsx("span", { style: { letterSpacing: "0.025em" }, children: "Analyse..." })] })) : (_jsx(_Fragment, { children: _jsx(Sparkle, { size: 18, style: {
|
|
236
|
+
} }), _jsx("span", { style: { letterSpacing: "0.025em" }, children: "Analyse..." })] })) : !isAuthReady ? (_jsxs(_Fragment, { children: [_jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), _jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })] }), children || _jsx("span", { children: "Connexion requise" })] })) : (_jsx(_Fragment, { children: _jsx(Sparkle, { size: 18, style: {
|
|
215
237
|
color: "white",
|
|
216
238
|
filter: "drop-shadow(0 0 2px rgba(255,255,255,0.2))",
|
|
217
239
|
} }) })) }), isOpen && (_jsx(AiPromptPanel, { isOpen: isOpen, onClose: handleClosePanel, onSubmit: handleSubmit, uiMode: uiMode, models: [], enableModelManagement: true, modelCategory: "text", baseUrl: baseUrl, apiKey: apiKeyId }))] }), isResultOpen && analysisResult && (_jsx("div", { style: {
|
|
@@ -332,5 +354,5 @@ Analyse ces données et réponds de manière structurée et claire.`;
|
|
|
332
354
|
...getThemeStyles().content,
|
|
333
355
|
}, children: [_jsxs("span", { children: ["Co\u00FBt: $", (apiKeyId?.includes("dev")
|
|
334
356
|
? 0
|
|
335
|
-
: analysisResult.cost).toFixed(6)] }), _jsxs("span", { children: ["ID: ", analysisResult.requestId?.slice(-8) || "N/A"] })] }) })] })] }) }) })), _jsx(ErrorToast, { error: errorData, onComplete: clearError }, errorKey)] }));
|
|
357
|
+
: analysisResult.cost).toFixed(6)] }), _jsxs("span", { children: ["ID: ", analysisResult.requestId?.slice(-8) || "N/A"] })] }) })] })] }) }) })), _jsx(LBSigninModal, { isOpen: showAuthModal, onClose: () => setShowAuthModal(false) }), _jsx(ErrorToast, { error: errorData, onComplete: clearError }, errorKey)] }));
|
|
336
358
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiImageButton.d.ts","sourceRoot":"","sources":["../../src/components/AiImageButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"AiImageButton.d.ts","sourceRoot":"","sources":["../../src/components/AiImageButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAW5C,MAAM,WAAW,kBACf,SACE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC,EACrC,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACvE,OAAO,CAAC,EAAE,CACR,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAC7C,IAAI,CAAC;IACV,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,YAAY,EACtB,MAAgB,EAChB,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,EACf,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,aAAoB,EACpB,WAAW,EACX,YAAY,EACZ,aAAa,EACb,GAAG,WAAW,EACf,EAAE,kBAAkB,2CAgapB"}
|
|
@@ -9,17 +9,35 @@ import { useErrorToast, ErrorToast } from "./ErrorToast";
|
|
|
9
9
|
import { aiStyles } from "../styles/inline";
|
|
10
10
|
import { useAiContext } from "../context/AiProvider";
|
|
11
11
|
import { handleAIError } from "../utils/errorHandler";
|
|
12
|
+
import { useLB } from "../context/LBAuthProvider";
|
|
13
|
+
import { LBSigninModal } from "./LBSigninModal";
|
|
12
14
|
export function AiImageButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode = "modal", context: _context, model: _model, prompt: _prompt, onImage, onToast, disabled, className, children, showImageCard = true, onImageSave, storeOutputs, artifactTitle, ...buttonProps }) {
|
|
13
15
|
const [isOpen, setIsOpen] = useState(false);
|
|
16
|
+
const [showAuthModal, setShowAuthModal] = useState(false);
|
|
14
17
|
const [generatedImage, setGeneratedImage] = useState(null);
|
|
15
18
|
const { showUsageToast, toastData, toastKey, clearToast } = useUsageToast();
|
|
16
19
|
const { showErrorToast, errorData, errorKey, clearError } = useErrorToast();
|
|
20
|
+
// Rendre l'authentification optionnelle
|
|
21
|
+
let lbStatus;
|
|
22
|
+
try {
|
|
23
|
+
const lbContext = useLB();
|
|
24
|
+
lbStatus = lbContext.status;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// LBProvider n'est pas disponible, ignorer
|
|
28
|
+
lbStatus = undefined;
|
|
29
|
+
}
|
|
17
30
|
// Récupérer le contexte AiProvider avec fallback sur les props
|
|
18
31
|
const aiContext = useAiContext();
|
|
19
32
|
const baseUrl = propBaseUrl ?? aiContext.baseUrl;
|
|
20
33
|
const apiKeyId = propApiKeyId ?? aiContext.apiKeyId;
|
|
21
34
|
const { generateImage, loading } = useAiCallImage({ baseUrl, apiKeyId });
|
|
35
|
+
const isAuthReady = lbStatus === "ready" || Boolean(process.env.LB_API_KEY);
|
|
22
36
|
const handleOpenPanel = () => {
|
|
37
|
+
if (!isAuthReady) {
|
|
38
|
+
setShowAuthModal(true);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
23
41
|
setIsOpen(true);
|
|
24
42
|
};
|
|
25
43
|
const handleClosePanel = () => {
|
|
@@ -134,14 +152,18 @@ export function AiImageButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, ui
|
|
|
134
152
|
setIsOpen(false);
|
|
135
153
|
}
|
|
136
154
|
};
|
|
137
|
-
return (_jsxs("div", { className: "flex items-start gap-4", children: [_jsxs("div", { style: { position: "relative", display: "inline-block" }, children: [_jsx("button", { ...buttonProps, onClick: handleOpenPanel, disabled: disabled || loading, className: className, style: {
|
|
155
|
+
return (_jsxs("div", { className: "flex items-start gap-4", children: [_jsxs("div", { style: { position: "relative", display: "inline-block" }, children: [_jsx("button", { ...buttonProps, onClick: handleOpenPanel, disabled: disabled || loading || !isAuthReady, className: className, style: {
|
|
138
156
|
...aiStyles.button,
|
|
139
157
|
display: "flex",
|
|
140
158
|
alignItems: "center",
|
|
141
159
|
gap: "8px",
|
|
142
|
-
cursor: disabled || loading ? "not-allowed" : "pointer",
|
|
143
|
-
opacity: disabled || loading ? 0.6 : 1,
|
|
144
|
-
backgroundColor: loading
|
|
160
|
+
cursor: disabled || loading || !isAuthReady ? "not-allowed" : "pointer",
|
|
161
|
+
opacity: disabled || loading || !isAuthReady ? 0.6 : 1,
|
|
162
|
+
backgroundColor: loading
|
|
163
|
+
? "#8b5cf6"
|
|
164
|
+
: !isAuthReady
|
|
165
|
+
? "#94a3b8"
|
|
166
|
+
: "#6366f1",
|
|
145
167
|
color: "white",
|
|
146
168
|
border: "none",
|
|
147
169
|
borderRadius: "12px",
|
|
@@ -161,30 +183,30 @@ export function AiImageButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, ui
|
|
|
161
183
|
}),
|
|
162
184
|
...buttonProps.style,
|
|
163
185
|
}, onMouseEnter: (e) => {
|
|
164
|
-
if (!disabled && !loading) {
|
|
186
|
+
if (!disabled && !loading && isAuthReady) {
|
|
165
187
|
e.currentTarget.style.transform = "scale(1.02)";
|
|
166
188
|
e.currentTarget.style.boxShadow =
|
|
167
189
|
"0 6px 16px rgba(99, 102, 241, 0.3)";
|
|
168
190
|
}
|
|
169
191
|
}, onMouseLeave: (e) => {
|
|
170
|
-
if (!disabled && !loading) {
|
|
192
|
+
if (!disabled && !loading && isAuthReady) {
|
|
171
193
|
e.currentTarget.style.transform = "scale(1)";
|
|
172
194
|
e.currentTarget.style.boxShadow = loading
|
|
173
195
|
? "0 4px 12px rgba(139, 92, 246, 0.3)"
|
|
174
196
|
: "0 2px 8px rgba(99, 102, 241, 0.2)";
|
|
175
197
|
}
|
|
176
198
|
}, onMouseDown: (e) => {
|
|
177
|
-
if (!disabled && !loading) {
|
|
199
|
+
if (!disabled && !loading && isAuthReady) {
|
|
178
200
|
e.currentTarget.style.transform = "scale(0.98)";
|
|
179
201
|
}
|
|
180
202
|
}, onMouseUp: (e) => {
|
|
181
|
-
if (!disabled && !loading) {
|
|
203
|
+
if (!disabled && !loading && isAuthReady) {
|
|
182
204
|
e.currentTarget.style.transform = "scale(1.02)";
|
|
183
205
|
}
|
|
184
|
-
}, "data-ai-image-button": true, children: loading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 18, className: "animate-spin", style: {
|
|
206
|
+
}, "data-ai-image-button": true, title: !isAuthReady ? "Authentication required" : "Générer une image", children: loading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 18, className: "animate-spin", style: {
|
|
185
207
|
color: "white",
|
|
186
208
|
filter: "drop-shadow(0 0 2px rgba(255,255,255,0.3))",
|
|
187
|
-
} }), _jsx("span", { style: { letterSpacing: "0.025em" }, children: "G\u00E9n\u00E9ration..." })] })) : (_jsxs(_Fragment, { children: [_jsx(ImageIcon, { size: 18, style: {
|
|
209
|
+
} }), _jsx("span", { style: { letterSpacing: "0.025em" }, children: "G\u00E9n\u00E9ration..." })] })) : !isAuthReady ? (_jsxs(_Fragment, { children: [_jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), _jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })] }), children || _jsx("span", { children: "Connexion requise" })] })) : (_jsxs(_Fragment, { children: [_jsx(ImageIcon, { size: 18, style: {
|
|
188
210
|
color: "white",
|
|
189
211
|
filter: "drop-shadow(0 0 2px rgba(255,255,255,0.2))",
|
|
190
212
|
} }), _jsx("span", { style: { letterSpacing: "0.025em" }, children: children || "Générer une image" })] })) }), isOpen && (_jsx(AiPromptPanel, { isOpen: isOpen, onClose: handleClosePanel, onSubmit: handleSubmit, uiMode: uiMode, enableModelManagement: true, modelCategory: "image", baseUrl: baseUrl, apiKey: apiKeyId, models: [] }))] }), showImageCard && generatedImage && (_jsxs("div", { className: "relative", style: {
|
|
@@ -231,5 +253,5 @@ export function AiImageButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, ui
|
|
|
231
253
|
e.currentTarget.style.boxShadow = "";
|
|
232
254
|
}, title: "T\u00E9l\u00E9charger l'image", children: [_jsx(Download, { size: 16 }), "T\u00E9l\u00E9charger l'image"] }), onImageSave && (_jsxs("button", { onClick: handleSave, className: "flex items-center gap-1 px-3 py-2 text-xs font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition-colors", title: "Sauvegarder en base", children: [_jsx(ExternalLink, { size: 14 }), "Sauvegarder"] }))] }), _jsx("div", { className: "mt-3 pt-3 text-xs", style: {
|
|
233
255
|
...getThemeStyles().metadata,
|
|
234
|
-
}, children: _jsx("div", { className: "flex justify-center", children: _jsxs("span", { children: ["ID: ", generatedImage.requestId.slice(-8)] }) }) })] })), _jsx(ErrorToast, { error: errorData, onComplete: clearError }, errorKey)] }));
|
|
256
|
+
}, children: _jsx("div", { className: "flex justify-center", children: _jsxs("span", { children: ["ID: ", generatedImage.requestId.slice(-8)] }) }) })] })), _jsx(LBSigninModal, { isOpen: showAuthModal, onClose: () => setShowAuthModal(false) }), _jsx(ErrorToast, { error: errorData, onComplete: clearError }, errorKey)] }));
|
|
235
257
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiInput.d.ts","sourceRoot":"","sources":["../../src/components/AiInput.tsx"],"names":[],"mappings":"AAEA,OAAc,EAAoB,KAAK,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAE1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"AiInput.d.ts","sourceRoot":"","sources":["../../src/components/AiInput.tsx"],"names":[],"mappings":"AAEA,OAAc,EAAoB,KAAK,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAE1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAU5C,MAAM,WAAW,YACf,SACE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EACzB,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,SAAS,CAAC;IACxD,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC5B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,QAAQ,EACR,MAAgB,EAChB,OAAO,EACP,KAAK,EACL,MAAM,EACN,QAAgB,EAChB,qBAA4B,EAC5B,YAAY,EACZ,aAAa,EACb,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,EACT,GAAG,UAAU,EACd,EAAE,YAAY,2CAyNd"}
|
|
@@ -8,13 +8,26 @@ import { AiPromptPanel } from "./AiPromptPanel";
|
|
|
8
8
|
import { UsageToast, useUsageToast } from "./UsageToast";
|
|
9
9
|
import { aiStyles } from "../styles/inline";
|
|
10
10
|
import { handleAIError } from "../utils/errorHandler";
|
|
11
|
+
import { useLB } from "../context/LBAuthProvider";
|
|
12
|
+
import { LBSigninModal } from "./LBSigninModal";
|
|
11
13
|
export function AiInput({ baseUrl, apiKeyId, uiMode = "modal", context, model, prompt, editMode = false, enableModelManagement = true, storeOutputs, artifactTitle, onValue, onToast, disabled, className, ...inputProps }) {
|
|
12
14
|
const [isOpen, setIsOpen] = useState(false);
|
|
15
|
+
const [showAuthModal, setShowAuthModal] = useState(false);
|
|
13
16
|
const [inputValue, setInputValue] = useState(inputProps.value?.toString() || inputProps.defaultValue?.toString() || "");
|
|
14
17
|
const [isFocused, setIsFocused] = useState(false);
|
|
15
18
|
const [isButtonHovered, setIsButtonHovered] = useState(false);
|
|
16
19
|
const inputRef = useRef(null);
|
|
17
20
|
const { showUsageToast, toastData, toastKey, clearToast } = useUsageToast();
|
|
21
|
+
// Rendre l'authentification optionnelle
|
|
22
|
+
let lbStatus;
|
|
23
|
+
try {
|
|
24
|
+
const lbContext = useLB();
|
|
25
|
+
lbStatus = lbContext.status;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// LBProvider n'est pas disponible, ignorer
|
|
29
|
+
lbStatus = undefined;
|
|
30
|
+
}
|
|
18
31
|
const { models } = useAiModels({
|
|
19
32
|
baseUrl,
|
|
20
33
|
apiKeyId,
|
|
@@ -22,7 +35,13 @@ export function AiInput({ baseUrl, apiKeyId, uiMode = "modal", context, model, p
|
|
|
22
35
|
});
|
|
23
36
|
const { generateText, loading } = useAiCallText({ baseUrl, apiKeyId });
|
|
24
37
|
const hasConfiguration = Boolean(model && prompt);
|
|
38
|
+
const isAuthReady = lbStatus === "ready" || Boolean(process.env.LB_API_KEY);
|
|
39
|
+
const shouldShowSparkles = isAuthReady && !disabled;
|
|
25
40
|
const handleOpenPanel = () => {
|
|
41
|
+
if (!isAuthReady) {
|
|
42
|
+
setShowAuthModal(true);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
26
45
|
setIsOpen(true);
|
|
27
46
|
};
|
|
28
47
|
const handleClosePanel = () => {
|
|
@@ -109,5 +128,9 @@ export function AiInput({ baseUrl, apiKeyId, uiMode = "modal", context, model, p
|
|
|
109
128
|
...(disabled || loading
|
|
110
129
|
? { opacity: 0.5, cursor: "not-allowed" }
|
|
111
130
|
: {}),
|
|
112
|
-
}, onClick: hasConfiguration ? handleQuickGenerate : handleOpenPanel, onMouseEnter: () => setIsButtonHovered(true), onMouseLeave: () => setIsButtonHovered(false), disabled: disabled || loading, type: "button", title:
|
|
131
|
+
}, onClick: hasConfiguration ? handleQuickGenerate : handleOpenPanel, onMouseEnter: () => setIsButtonHovered(true), onMouseLeave: () => setIsButtonHovered(false), disabled: disabled || loading || !isAuthReady, type: "button", title: !isAuthReady
|
|
132
|
+
? "Authentication required"
|
|
133
|
+
: hasConfiguration
|
|
134
|
+
? "Generate with AI"
|
|
135
|
+
: "Setup AI", children: loading ? (_jsx("svg", { style: aiStyles.spinner, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", children: _jsx("path", { d: "M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83" }) })) : shouldShowSparkles ? (_jsx(Sparkles, { size: 16 })) : (_jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), _jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })] })) }), isOpen && (_jsx(AiPromptPanel, { isOpen: isOpen, onClose: handleClosePanel, onSubmit: handleSubmit, uiMode: uiMode, models: [], modelCategory: "text", sourceText: inputValue || undefined, apiKey: apiKeyId, baseUrl: baseUrl, enableModelManagement: enableModelManagement })), _jsx(LBSigninModal, { isOpen: showAuthModal, onClose: () => setShowAuthModal(false) }), Boolean(toastData) && (_jsx(UsageToast, { result: toastData, position: "bottom-right", onComplete: clearToast }, toastKey))] }));
|
|
113
136
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiStatusButton.d.ts","sourceRoot":"","sources":["../../src/components/AiStatusButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"AiStatusButton.d.ts","sourceRoot":"","sources":["../../src/components/AiStatusButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAetD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,OAAe,EACf,SAAc,GACf,EAAE,mBAAmB,2CA41BrB"}
|
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useRef, useLayoutEffect } from "react";
|
|
4
4
|
import { createPortal } from "react-dom";
|
|
5
|
-
import { BarChart3, Settings, FileText, History as HistoryIcon, FolderPlus, } from "lucide-react";
|
|
5
|
+
import { BarChart3, Settings, FileText, History as HistoryIcon, FolderPlus, Power, } from "lucide-react";
|
|
6
6
|
import { aiStyles, calculateTooltipPosition } from "../styles/inline";
|
|
7
|
+
import { useLB } from "../context/LBAuthProvider";
|
|
8
|
+
import { LBSigninModal } from "./LBSigninModal";
|
|
7
9
|
export function AiStatusButton({ status, loading = false, className = "", }) {
|
|
10
|
+
// Rendre l'authentification optionnelle
|
|
11
|
+
let lbStatus;
|
|
12
|
+
let user;
|
|
13
|
+
let logout;
|
|
14
|
+
try {
|
|
15
|
+
const lbContext = useLB();
|
|
16
|
+
lbStatus = lbContext.status;
|
|
17
|
+
user = lbContext.user;
|
|
18
|
+
logout = lbContext.logout;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// LBProvider n'est pas disponible, ignorer
|
|
22
|
+
lbStatus = undefined;
|
|
23
|
+
user = undefined;
|
|
24
|
+
logout = undefined;
|
|
25
|
+
}
|
|
26
|
+
const [showSigninModal, setShowSigninModal] = useState(false);
|
|
8
27
|
const formatNumber = (value) => typeof value === "number" ? value.toLocaleString() : "0";
|
|
9
28
|
const formatFixed = (value, digits) => typeof value === "number" ? value.toFixed(digits) : "0.00";
|
|
10
29
|
const formatStorage = (valueMb) => {
|
|
@@ -139,17 +158,172 @@ export function AiStatusButton({ status, loading = false, className = "", }) {
|
|
|
139
158
|
}, className: className, disabled: true, children: _jsx("svg", { style: aiStyles.spinner, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", children: _jsx("path", { d: "M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83" }) }) }));
|
|
140
159
|
}
|
|
141
160
|
if (!status) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
161
|
+
// Si pas de statut API et pas de LBProvider, afficher message simple
|
|
162
|
+
if (!lbStatus && lbStatus !== "ready") {
|
|
163
|
+
return (_jsxs("div", { style: { position: "relative", display: "inline-block" }, children: [_jsx("button", { ref: buttonRef, style: {
|
|
164
|
+
...aiStyles.statusButton,
|
|
165
|
+
color: "#ef4444",
|
|
166
|
+
...(isHovered && aiStyles.statusButtonHover),
|
|
167
|
+
}, className: className, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", children: _jsx("polyline", { points: "22 12 18 12 15 21 9 3 6 12 2 12" }) }) }), showTooltip &&
|
|
168
|
+
canPortal &&
|
|
169
|
+
createPortal(_jsx("div", { ref: tooltipRef, style: {
|
|
170
|
+
...aiStyles.tooltip,
|
|
171
|
+
...tooltipPosition,
|
|
172
|
+
zIndex: 50,
|
|
173
|
+
}, onMouseEnter: () => setShowTooltip(true), onMouseLeave: handleMouseLeave, children: "No status available" }), document.body)] }));
|
|
174
|
+
}
|
|
175
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { style: { position: "relative", display: "inline-block" }, children: [_jsx("button", { ref: buttonRef, style: {
|
|
176
|
+
...aiStyles.statusButton,
|
|
177
|
+
color: lbStatus === "ready" ? "#10b981" : "#ef4444",
|
|
178
|
+
...(isHovered && aiStyles.statusButtonHover),
|
|
179
|
+
}, className: className, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onClick: () => {
|
|
180
|
+
if (lbStatus !== "ready") {
|
|
181
|
+
setShowSigninModal(true);
|
|
182
|
+
}
|
|
183
|
+
}, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", children: _jsx("polyline", { points: "22 12 18 12 15 21 9 3 6 12 2 12" }) }) }), showTooltip &&
|
|
184
|
+
canPortal &&
|
|
185
|
+
createPortal(_jsx("div", { ref: tooltipRef, style: {
|
|
186
|
+
...aiStyles.tooltip,
|
|
187
|
+
...tooltipPosition,
|
|
188
|
+
zIndex: 50,
|
|
189
|
+
}, onMouseEnter: () => setShowTooltip(true), onMouseLeave: handleMouseLeave, children: lbStatus === "ready" && user ? (_jsxs(_Fragment, { children: [_jsx("div", { style: aiStyles.tooltipHeader, children: "LastBrain Connected" }), _jsx("div", { style: {
|
|
190
|
+
...aiStyles.tooltipSection,
|
|
191
|
+
paddingBottom: "8px",
|
|
192
|
+
}, children: _jsxs("div", { style: aiStyles.tooltipRow, children: [_jsx("span", { style: aiStyles.tooltipLabel, children: "User:" }), _jsx("span", { style: aiStyles.tooltipValue, children: user.email })] }) }), _jsxs("div", { style: {
|
|
193
|
+
display: "flex",
|
|
194
|
+
gap: "8px",
|
|
195
|
+
borderTop: "1px solid var(--ai-border-primary, #374151)",
|
|
196
|
+
paddingTop: "12px",
|
|
197
|
+
}, children: [_jsx("button", { onClick: () => window.open("https://lastbrain.io/metrics", "_blank"), style: {
|
|
198
|
+
flex: 1,
|
|
199
|
+
background: "transparent",
|
|
200
|
+
border: "none",
|
|
201
|
+
padding: "14px",
|
|
202
|
+
cursor: "pointer",
|
|
203
|
+
display: "flex",
|
|
204
|
+
alignItems: "center",
|
|
205
|
+
justifyContent: "center",
|
|
206
|
+
color: "#8b5cf6",
|
|
207
|
+
transition: "all 0.2s ease",
|
|
208
|
+
}, onMouseEnter: (e) => {
|
|
209
|
+
Object.assign(e.currentTarget.style, {
|
|
210
|
+
background: "rgba(139, 92, 246, 0.1)",
|
|
211
|
+
});
|
|
212
|
+
}, onMouseLeave: (e) => {
|
|
213
|
+
Object.assign(e.currentTarget.style, {
|
|
214
|
+
background: "transparent",
|
|
215
|
+
});
|
|
216
|
+
}, title: "View Metrics", children: _jsx(BarChart3, { size: 18 }) }), _jsx("button", { onClick: () => window.open("https://lastbrain.io/settings", "_blank"), style: {
|
|
217
|
+
flex: 1,
|
|
218
|
+
background: "transparent",
|
|
219
|
+
border: "none",
|
|
220
|
+
padding: "14px",
|
|
221
|
+
cursor: "pointer",
|
|
222
|
+
display: "flex",
|
|
223
|
+
alignItems: "center",
|
|
224
|
+
justifyContent: "center",
|
|
225
|
+
color: "#8b5cf6",
|
|
226
|
+
transition: "all 0.2s ease",
|
|
227
|
+
}, onMouseEnter: (e) => {
|
|
228
|
+
Object.assign(e.currentTarget.style, {
|
|
229
|
+
background: "rgba(139, 92, 246, 0.1)",
|
|
230
|
+
});
|
|
231
|
+
}, onMouseLeave: (e) => {
|
|
232
|
+
Object.assign(e.currentTarget.style, {
|
|
233
|
+
background: "transparent",
|
|
234
|
+
});
|
|
235
|
+
}, title: "Settings", children: _jsx(Settings, { size: 18 }) }), _jsx("button", { onClick: () => window.open("https://prompt.lastbrain.io/auth/prompts", "_blank"), style: {
|
|
236
|
+
flex: 1,
|
|
237
|
+
background: "transparent",
|
|
238
|
+
border: "none",
|
|
239
|
+
padding: "14px",
|
|
240
|
+
cursor: "pointer",
|
|
241
|
+
display: "flex",
|
|
242
|
+
alignItems: "center",
|
|
243
|
+
justifyContent: "center",
|
|
244
|
+
color: "#8b5cf6",
|
|
245
|
+
transition: "all 0.2s ease",
|
|
246
|
+
}, onMouseEnter: (e) => {
|
|
247
|
+
Object.assign(e.currentTarget.style, {
|
|
248
|
+
background: "rgba(139, 92, 246, 0.1)",
|
|
249
|
+
});
|
|
250
|
+
}, onMouseLeave: (e) => {
|
|
251
|
+
Object.assign(e.currentTarget.style, {
|
|
252
|
+
background: "transparent",
|
|
253
|
+
});
|
|
254
|
+
}, title: "My Prompts", children: _jsx(FileText, { size: 18 }) }), _jsx("button", { onClick: () => window.open("https://prompt.lastbrain.io/auth/folder", "_blank"), style: {
|
|
255
|
+
flex: 1,
|
|
256
|
+
background: "transparent",
|
|
257
|
+
border: "none",
|
|
258
|
+
padding: "14px",
|
|
259
|
+
cursor: "pointer",
|
|
260
|
+
display: "flex",
|
|
261
|
+
alignItems: "center",
|
|
262
|
+
justifyContent: "center",
|
|
263
|
+
color: "#8b5cf6",
|
|
264
|
+
transition: "all 0.2s ease",
|
|
265
|
+
}, onMouseEnter: (e) => {
|
|
266
|
+
Object.assign(e.currentTarget.style, {
|
|
267
|
+
background: "rgba(139, 92, 246, 0.1)",
|
|
268
|
+
});
|
|
269
|
+
}, onMouseLeave: (e) => {
|
|
270
|
+
Object.assign(e.currentTarget.style, {
|
|
271
|
+
background: "transparent",
|
|
272
|
+
});
|
|
273
|
+
}, title: "New Folder", children: _jsx(FolderPlus, { size: 18 }) }), _jsx("button", { onClick: async () => {
|
|
274
|
+
if (logout) {
|
|
275
|
+
await logout();
|
|
276
|
+
}
|
|
277
|
+
setShowTooltip(false);
|
|
278
|
+
}, style: {
|
|
279
|
+
flex: 1,
|
|
280
|
+
background: "transparent",
|
|
281
|
+
border: "none",
|
|
282
|
+
padding: "14px",
|
|
283
|
+
cursor: "pointer",
|
|
284
|
+
display: "flex",
|
|
285
|
+
alignItems: "center",
|
|
286
|
+
justifyContent: "center",
|
|
287
|
+
color: "#ef4444",
|
|
288
|
+
transition: "all 0.2s ease",
|
|
289
|
+
}, onMouseEnter: (e) => {
|
|
290
|
+
Object.assign(e.currentTarget.style, {
|
|
291
|
+
background: "rgba(239, 68, 68, 0.1)",
|
|
292
|
+
});
|
|
293
|
+
}, onMouseLeave: (e) => {
|
|
294
|
+
Object.assign(e.currentTarget.style, {
|
|
295
|
+
background: "transparent",
|
|
296
|
+
});
|
|
297
|
+
}, title: "Logout", children: _jsx(Power, { size: 18 }) })] })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { style: aiStyles.tooltipHeader, children: "LastBrain Authentication" }), _jsx("div", { style: {
|
|
298
|
+
...aiStyles.tooltipSection,
|
|
299
|
+
paddingBottom: "12px",
|
|
300
|
+
}, children: _jsx("p", { style: {
|
|
301
|
+
margin: 0,
|
|
302
|
+
fontSize: "13px",
|
|
303
|
+
color: "var(--ai-text-secondary, #9ca3af)",
|
|
304
|
+
lineHeight: "1.5",
|
|
305
|
+
}, children: "Connectez-vous pour acc\u00E9der aux fonctionnalit\u00E9s IA" }) }), _jsx("button", { onClick: () => {
|
|
306
|
+
setShowSigninModal(true);
|
|
307
|
+
setShowTooltip(false);
|
|
308
|
+
}, style: {
|
|
309
|
+
width: "100%",
|
|
310
|
+
padding: "10px",
|
|
311
|
+
background: "linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%)",
|
|
312
|
+
border: "none",
|
|
313
|
+
borderRadius: "6px",
|
|
314
|
+
color: "#ffffff",
|
|
315
|
+
fontSize: "13px",
|
|
316
|
+
fontWeight: 600,
|
|
317
|
+
cursor: "pointer",
|
|
318
|
+
transition: "all 0.2s ease",
|
|
319
|
+
}, onMouseEnter: (e) => {
|
|
320
|
+
e.currentTarget.style.transform = "translateY(-1px)";
|
|
321
|
+
e.currentTarget.style.boxShadow =
|
|
322
|
+
"0 4px 12px rgba(139, 92, 246, 0.3)";
|
|
323
|
+
}, onMouseLeave: (e) => {
|
|
324
|
+
e.currentTarget.style.transform = "translateY(0)";
|
|
325
|
+
e.currentTarget.style.boxShadow = "none";
|
|
326
|
+
}, children: "\uD83D\uDD10 Se connecter" })] })) }), document.body)] }), _jsx(LBSigninModal, { isOpen: showSigninModal, onClose: () => setShowSigninModal(false) })] }));
|
|
153
327
|
}
|
|
154
328
|
return (_jsxs("div", { style: { position: "relative", display: "inline-block" }, children: [_jsx("button", { ref: buttonRef, style: {
|
|
155
329
|
...aiStyles.statusButton,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiTextarea.d.ts","sourceRoot":"","sources":["../../src/components/AiTextarea.tsx"],"names":[],"mappings":"AAEA,OAAc,EAIZ,KAAK,sBAAsB,EAC5B,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"AiTextarea.d.ts","sourceRoot":"","sources":["../../src/components/AiTextarea.tsx"],"names":[],"mappings":"AAEA,OAAc,EAIZ,KAAK,sBAAsB,EAC5B,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAU5C,MAAM,WAAW,eACf,SACE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EACzB,IAAI,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EAAE,SAAS,CAAC;IAC9D,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC7B;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,QAAQ,EACR,MAAgB,EAChB,OAAO,EACP,KAAK,EACL,MAAM,EACN,QAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,OAAO,EACP,OAAO,EACP,QAAQ,EACR,SAAS,EACT,GAAG,aAAa,EACjB,EAAE,eAAe,2CA0OjB"}
|
|
@@ -8,8 +8,11 @@ import { AiPromptPanel } from "./AiPromptPanel";
|
|
|
8
8
|
import { UsageToast, useUsageToast } from "./UsageToast";
|
|
9
9
|
import { aiStyles } from "../styles/inline";
|
|
10
10
|
import { handleAIError } from "../utils/errorHandler";
|
|
11
|
+
import { useLB } from "../context/LBAuthProvider";
|
|
12
|
+
import { LBSigninModal } from "./LBSigninModal";
|
|
11
13
|
export function AiTextarea({ baseUrl, apiKeyId, uiMode = "modal", context, model, prompt, editMode = false, enableModelManagement, storeOutputs, artifactTitle, onValue, onToast, disabled, className, ...textareaProps }) {
|
|
12
14
|
const [isOpen, setIsOpen] = useState(false);
|
|
15
|
+
const [showAuthModal, setShowAuthModal] = useState(false);
|
|
13
16
|
const [textareaValue, setTextareaValue] = useState(textareaProps.value?.toString() ||
|
|
14
17
|
textareaProps.defaultValue?.toString() ||
|
|
15
18
|
"");
|
|
@@ -17,6 +20,16 @@ export function AiTextarea({ baseUrl, apiKeyId, uiMode = "modal", context, model
|
|
|
17
20
|
const [isButtonHovered, setIsButtonHovered] = useState(false);
|
|
18
21
|
const textareaRef = useRef(null);
|
|
19
22
|
const { showUsageToast, toastData, toastKey, clearToast } = useUsageToast();
|
|
23
|
+
// Rendre l'authentification optionnelle
|
|
24
|
+
let lbStatus;
|
|
25
|
+
try {
|
|
26
|
+
const lbContext = useLB();
|
|
27
|
+
lbStatus = lbContext.status;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// LBProvider n'est pas disponible, ignorer
|
|
31
|
+
lbStatus = undefined;
|
|
32
|
+
}
|
|
20
33
|
const { models } = useAiModels({
|
|
21
34
|
baseUrl,
|
|
22
35
|
apiKeyId,
|
|
@@ -24,7 +37,13 @@ export function AiTextarea({ baseUrl, apiKeyId, uiMode = "modal", context, model
|
|
|
24
37
|
});
|
|
25
38
|
const { generateText, loading } = useAiCallText({ baseUrl, apiKeyId });
|
|
26
39
|
const hasConfiguration = Boolean(model && prompt);
|
|
40
|
+
const isAuthReady = lbStatus === "ready" || Boolean(process.env.LB_API_KEY);
|
|
41
|
+
const shouldShowSparkles = isAuthReady && !disabled;
|
|
27
42
|
const handleOpenPanel = () => {
|
|
43
|
+
if (!isAuthReady) {
|
|
44
|
+
setShowAuthModal(true);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
28
47
|
setIsOpen(true);
|
|
29
48
|
};
|
|
30
49
|
const handleClosePanel = () => {
|
|
@@ -123,5 +142,9 @@ export function AiTextarea({ baseUrl, apiKeyId, uiMode = "modal", context, model
|
|
|
123
142
|
...(disabled || loading
|
|
124
143
|
? { opacity: 0.5, cursor: "not-allowed" }
|
|
125
144
|
: {}),
|
|
126
|
-
}, onClick: hasConfiguration ? handleQuickGenerate : handleOpenPanel, onMouseEnter: () => setIsButtonHovered(true), onMouseLeave: () => setIsButtonHovered(false), disabled: disabled || loading, type: "button", title:
|
|
145
|
+
}, onClick: hasConfiguration ? handleQuickGenerate : handleOpenPanel, onMouseEnter: () => setIsButtonHovered(true), onMouseLeave: () => setIsButtonHovered(false), disabled: disabled || loading || !isAuthReady, type: "button", title: !isAuthReady
|
|
146
|
+
? "Authentication required"
|
|
147
|
+
: hasConfiguration
|
|
148
|
+
? "Generate with AI"
|
|
149
|
+
: "Setup AI", children: loading ? (_jsx("svg", { style: aiStyles.spinner, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", children: _jsx("path", { d: "M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83" }) })) : shouldShowSparkles ? (_jsx(Sparkles, { size: 16 })) : (_jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), _jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })] })) }), isOpen && (_jsx(AiPromptPanel, { isOpen: isOpen, onClose: handleClosePanel, onSubmit: handleSubmit, uiMode: uiMode, models: [], modelCategory: "text", sourceText: textareaValue || undefined, baseUrl: baseUrl, apiKey: apiKeyId, enableModelManagement: enableModelManagement })), Boolean(toastData) && (_jsx(UsageToast, { result: toastData, position: "bottom-right", onComplete: clearToast }, toastKey)), _jsx(LBSigninModal, { isOpen: showAuthModal, onClose: () => setShowAuthModal(false) })] }));
|
|
127
150
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LBConnectButton.d.ts","sourceRoot":"","sources":["../../src/components/LBConnectButton.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LBConnectButton.d.ts","sourceRoot":"","sources":["../../src/components/LBConnectButton.tsx"],"names":[],"mappings":"AAWA,UAAU,oBAAoB;IAC5B,sBAAsB;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAAC,EAC9B,KAAkC,EAClC,SAAc,EACd,WAAW,EACX,WAAW,GACZ,EAAE,oBAAoB,2CA4CtB;AAED;;GAEG;AACH,UAAU,gBAAgB;IACxB,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACrC;AAED,iBAAS,WAAW,CAAC,EAAE,OAAO,EAAE,EAAE,gBAAgB,2CA+RjD;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|