@lastbrain/ai-ui-react 1.0.72 → 1.0.74
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/AiChipLabel.d.ts.map +1 -1
- package/dist/components/AiChipLabel.js +10 -7
- package/dist/components/AiContextButton.d.ts +1 -1
- package/dist/components/AiContextButton.d.ts.map +1 -1
- package/dist/components/AiContextButton.js +25 -12
- package/dist/components/AiImageButton.d.ts.map +1 -1
- package/dist/components/AiImageButton.js +32 -16
- package/dist/components/AiInput.d.ts.map +1 -1
- package/dist/components/AiInput.js +15 -5
- package/dist/components/AiModelSelect.d.ts.map +1 -1
- package/dist/components/AiModelSelect.js +3 -1
- package/dist/components/AiPromptPanel.d.ts.map +1 -1
- package/dist/components/AiPromptPanel.js +72 -47
- package/dist/components/AiSelect.d.ts.map +1 -1
- package/dist/components/AiSelect.js +8 -3
- package/dist/components/AiStatusButton.d.ts.map +1 -1
- package/dist/components/AiStatusButton.js +55 -28
- package/dist/components/AiTextarea.d.ts.map +1 -1
- package/dist/components/AiTextarea.js +19 -6
- package/dist/components/ErrorToast.d.ts.map +1 -1
- package/dist/components/ErrorToast.js +4 -2
- package/dist/components/LBApiKeySelector.d.ts.map +1 -1
- package/dist/components/LBApiKeySelector.js +13 -5
- package/dist/components/LBConnectButton.d.ts.map +1 -1
- package/dist/components/LBConnectButton.js +8 -3
- package/dist/components/LBKeyPicker.d.ts.map +1 -1
- package/dist/components/LBKeyPicker.js +8 -4
- package/dist/components/LBSigninModal.d.ts.map +1 -1
- package/dist/components/LBSigninModal.js +13 -7
- package/dist/components/UsageToast.d.ts.map +1 -1
- package/dist/components/UsageToast.js +4 -2
- package/dist/context/I18nContext.d.ts +15 -0
- package/dist/context/I18nContext.d.ts.map +1 -0
- package/dist/context/I18nContext.js +44 -0
- package/dist/context/LBAuthProvider.d.ts +4 -1
- package/dist/context/LBAuthProvider.d.ts.map +1 -1
- package/dist/context/LBAuthProvider.js +3 -2
- package/dist/hooks/useAiCallImage.d.ts.map +1 -1
- package/dist/hooks/useAiCallImage.js +1 -107
- package/dist/hooks/useAiCallText.d.ts.map +1 -1
- package/dist/hooks/useAiCallText.js +1 -25
- package/dist/hooks/useLoadingTimer.d.ts +5 -0
- package/dist/hooks/useLoadingTimer.d.ts.map +1 -0
- package/dist/hooks/useLoadingTimer.js +27 -0
- package/dist/i18n/de.json +62 -0
- package/dist/i18n/en.json +128 -0
- package/dist/i18n/es.json +70 -0
- package/dist/i18n/fr.json +128 -0
- package/dist/i18n/it.json +62 -0
- package/dist/i18n/pt.json +62 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/styles.css +142 -1
- package/package.json +3 -3
- package/src/components/AiChipLabel.tsx +17 -8
- package/src/components/AiContextButton.tsx +44 -20
- package/src/components/AiImageButton.tsx +52 -25
- package/src/components/AiInput.tsx +20 -5
- package/src/components/AiModelSelect.tsx +3 -1
- package/src/components/AiPromptPanel.tsx +177 -59
- package/src/components/AiSelect.tsx +8 -3
- package/src/components/AiStatusButton.tsx +100 -57
- package/src/components/AiTextarea.tsx +24 -6
- package/src/components/ErrorToast.tsx +4 -2
- package/src/components/LBApiKeySelector.tsx +33 -13
- package/src/components/LBConnectButton.tsx +9 -3
- package/src/components/LBKeyPicker.tsx +10 -4
- package/src/components/LBSigninModal.tsx +31 -15
- package/src/components/UsageToast.tsx +4 -2
- package/src/context/I18nContext.tsx +71 -0
- package/src/context/LBAuthProvider.tsx +9 -1
- package/src/hooks/useAiCallImage.ts +1 -149
- package/src/hooks/useAiCallText.ts +1 -30
- package/src/hooks/useLoadingTimer.ts +32 -0
- package/src/i18n/de.json +62 -0
- package/src/i18n/en.json +128 -0
- package/src/i18n/es.json +70 -0
- package/src/i18n/fr.json +128 -0
- package/src/i18n/it.json +62 -0
- package/src/i18n/pt.json +62 -0
- package/src/index.ts +2 -0
- package/src/styles.css +142 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiChipLabel.d.ts","sourceRoot":"","sources":["../../src/components/AiChipLabel.tsx"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAC5B,OAAO,KAA0C,MAAM,OAAO,CAAC;AAS/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"AiChipLabel.d.ts","sourceRoot":"","sources":["../../src/components/AiChipLabel.tsx"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAC5B,OAAO,KAA0C,MAAM,OAAO,CAAC;AAS/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGjD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,OAAmB,EACnB,IAAW,EACX,MAAe,EACf,SAAS,EACT,KAAK,EAAE,WAAW,GACnB,EAAE,gBAAgB,2CAiBlB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,QAAQ,CAAC;CACnB;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAU,EACV,QAAQ,EACR,WAAW,EACX,OAAO,EACP,QAAQ,EACR,eAAuB,EACvB,SAAS,EACT,YAAY,EACZ,aAAa,EACb,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,YAAY,EACtB,IAAW,EACX,MAAe,GAChB,EAAE,gBAAgB,2CA6MlB"}
|
|
@@ -10,6 +10,7 @@ import { useAiModels } from "../hooks/useAiModels";
|
|
|
10
10
|
import { useAiContext } from "../context/AiProvider";
|
|
11
11
|
import { useLB } from "../context/LBAuthProvider";
|
|
12
12
|
import { handleAIError } from "../utils/errorHandler";
|
|
13
|
+
import { useI18n } from "../context/I18nContext";
|
|
13
14
|
export function AiChipLabel({ children, variant = "default", size = "md", radius = "full", className, style: customStyle, }) {
|
|
14
15
|
const variantClassMap = {
|
|
15
16
|
default: "",
|
|
@@ -20,7 +21,8 @@ export function AiChipLabel({ children, variant = "default", size = "md", radius
|
|
|
20
21
|
};
|
|
21
22
|
return (_jsx("span", { style: customStyle, className: `ai-chip ai-size-${size} ai-radius-${radius} ${variantClassMap[variant]} ${className || ""}`, children: children }));
|
|
22
23
|
}
|
|
23
|
-
export function AiChipInput({ value = [], onChange, placeholder
|
|
24
|
+
export function AiChipInput({ value = [], onChange, placeholder, context, maxChips, allowDuplicates = false, className, storeOutputs, artifactTitle, baseUrl: propBaseUrl, apiKeyId: propApiKeyId, size = "md", radius = "full", }) {
|
|
25
|
+
const { t } = useI18n();
|
|
24
26
|
const [inputValue, setInputValue] = useState("");
|
|
25
27
|
const [showPromptPanel, setShowPromptPanel] = useState(false);
|
|
26
28
|
const [showSigninModal, setShowSigninModal] = useState(false);
|
|
@@ -91,7 +93,7 @@ Exemple de réponse attendue: javascript, react, frontend, api, development`;
|
|
|
91
93
|
model,
|
|
92
94
|
prompt: instruction,
|
|
93
95
|
storeOutputs,
|
|
94
|
-
artifactTitle: artifactTitle || "
|
|
96
|
+
artifactTitle: artifactTitle || t("ai.chips.artifactTitle", "AI generated tags"),
|
|
95
97
|
});
|
|
96
98
|
const chips = parseChipsFromResponse(response.text);
|
|
97
99
|
// Fermer le modal immédiatement
|
|
@@ -125,7 +127,8 @@ Exemple de réponse attendue: javascript, react, frontend, api, development`;
|
|
|
125
127
|
};
|
|
126
128
|
const sizeClass = `ai-size-${size}`;
|
|
127
129
|
const radiusClass = `ai-radius-${radius}`;
|
|
128
|
-
return (_jsxs("div", { className: className, children: [_jsx("div", { className: "ai-control-group ai-glow mb-2", children: _jsxs("div", { className: `ai-shell ${sizeClass} ${radiusClass}`, children: [_jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: (e) => setInputValue(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder
|
|
130
|
+
return (_jsxs("div", { className: className, children: [_jsx("div", { className: "ai-control-group ai-glow mb-2", children: _jsxs("div", { className: `ai-shell ${sizeClass} ${radiusClass}`, children: [_jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: (e) => setInputValue(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder ||
|
|
131
|
+
t("ai.chips.placeholder", "Type and press Enter to add tags..."), className: `ai-control ai-control-input ai-control-input--with-action ${sizeClass} ${radiusClass}` }), _jsx("button", { onClick: () => {
|
|
129
132
|
if (isAuthenticated) {
|
|
130
133
|
handleGenerateChips();
|
|
131
134
|
}
|
|
@@ -133,8 +136,8 @@ Exemple de réponse attendue: javascript, react, frontend, api, development`;
|
|
|
133
136
|
setShowSigninModal(true);
|
|
134
137
|
}
|
|
135
138
|
}, className: `ai-control-action ai-spark ${sizeClass} ${radiusClass}`, "aria-label": isAuthenticated
|
|
136
|
-
? "
|
|
137
|
-
: "
|
|
138
|
-
? "
|
|
139
|
-
: "
|
|
139
|
+
? t("ai.chips.generate", "Generate tags with AI")
|
|
140
|
+
: t("auth.connectRequired", "Connection required"), title: isAuthenticated
|
|
141
|
+
? t("ai.chips.generate", "Generate tags with AI")
|
|
142
|
+
: t("auth.connectToUseAi", "Sign in to use AI"), children: isAuthenticated ? _jsx(Sparkles, { size: 16 }) : _jsx(Lock, { size: 16 }) })] }) }), value.length > 0 && (_jsx("div", { className: "ai-chip-input", children: value.map((chip, index) => (_jsxs("div", { className: `ai-chip ai-chip--with-close ${sizeClass} ${radiusClass}`, children: [_jsx("span", { children: chip }), _jsx("button", { onClick: () => removeChip(index), className: "ai-chip-remover", title: t("ai.chips.remove", "Remove"), children: _jsx(X, { size: 14 }) })] }, index))) })), _jsx(AiPromptPanel, { isOpen: showPromptPanel, onClose: () => setShowPromptPanel(false), onSubmit: handlePromptSubmit, models: models || undefined, baseUrl: baseUrl, sourceText: context ? `Contexte: ${context}` : undefined, enableModelManagement: true, showOnlyUserModels: true }), _jsx(LBSigninModal, { isOpen: showSigninModal, onClose: () => setShowSigninModal(false) })] }));
|
|
140
143
|
}
|
|
@@ -22,6 +22,6 @@ export interface AiContextButtonProps extends Omit<BaseAiProps, "onValue" | "typ
|
|
|
22
22
|
radius?: AiRadius;
|
|
23
23
|
variant?: AiVariant;
|
|
24
24
|
}
|
|
25
|
-
export declare function AiContextButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode, contextData, contextDescription, onResult, onToast, disabled, className, children, resultModalTitle, size, radius, variant, context: _context, ...buttonProps }: AiContextButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export declare function AiContextButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode, contextData, contextDescription, onResult, onToast, disabled, className, children, resultModalTitle, storeOutputs, artifactTitle, size, radius, variant, context: _context, ...buttonProps }: AiContextButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
26
26
|
export {};
|
|
27
27
|
//# sourceMappingURL=AiContextButton.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiContextButton.d.ts","sourceRoot":"","sources":["../../src/components/AiContextButton.tsx"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAC5B,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"AiContextButton.d.ts","sourceRoot":"","sources":["../../src/components/AiContextButton.tsx"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAC5B,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAY5D,KAAK,WAAW,GACZ,MAAM,GACN,MAAM,GACN,OAAO,GACP,MAAM,GACN,OAAO,EAAE,GACT;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAE/B,MAAM,WAAW,oBACf,SACE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,CAAC,EACrC,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACvE,WAAW,EAAE,WAAW,CAAC;IACzB,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;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,YAAY,EACtB,MAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,IAAW,EACX,MAAe,EACf,OAAmB,EACnB,OAAO,EAAE,QAAQ,EACjB,GAAG,WAAW,EACf,EAAE,oBAAoB,2CAoStB"}
|
|
@@ -11,13 +11,16 @@ import { useAiContext } from "../context/AiProvider";
|
|
|
11
11
|
import { handleAIError } from "../utils/errorHandler";
|
|
12
12
|
import { useLB } from "../context/LBAuthProvider";
|
|
13
13
|
import { LBSigninModal } from "./LBSigninModal";
|
|
14
|
-
|
|
14
|
+
import { useI18n } from "../context/I18nContext";
|
|
15
|
+
export function AiContextButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode = "modal", contextData, contextDescription, onResult, onToast, disabled, className, children, resultModalTitle, storeOutputs, artifactTitle, size = "md", radius = "full", variant = "default", context: _context, ...buttonProps }) {
|
|
16
|
+
const { t, lang } = useI18n();
|
|
15
17
|
const [isOpen, setIsOpen] = useState(false);
|
|
16
18
|
const [showAuthModal, setShowAuthModal] = useState(false);
|
|
17
19
|
const [isResultOpen, setIsResultOpen] = useState(false);
|
|
18
20
|
const [analysisResult, setAnalysisResult] = useState(null);
|
|
19
21
|
const { showUsageToast } = useUsageToast();
|
|
20
22
|
const { showErrorToast, errorData, errorKey, clearError } = useErrorToast();
|
|
23
|
+
const resolvedContextDescription = contextDescription || t("ai.context.description", "Data to analyze");
|
|
21
24
|
let lbStatus;
|
|
22
25
|
try {
|
|
23
26
|
const lbContext = useLB();
|
|
@@ -53,13 +56,15 @@ export function AiContextButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId,
|
|
|
53
56
|
const handleSubmit = async (selectedModel, selectedPrompt) => {
|
|
54
57
|
try {
|
|
55
58
|
const contextString = formatContextData(contextData);
|
|
56
|
-
const fullPrompt = `${selectedPrompt}\n\nCONTEXTE (${
|
|
59
|
+
const fullPrompt = `${selectedPrompt}\n\nCONTEXTE (${resolvedContextDescription}):\n${contextString}\n\n${t("ai.context.analyzeStructured", "Analyze this data and respond in a clear, structured way.")}`;
|
|
57
60
|
const result = await callText({
|
|
58
61
|
prompt: fullPrompt,
|
|
59
62
|
model: selectedModel || "gpt-4o-mini",
|
|
60
63
|
context: _context || undefined,
|
|
61
64
|
maxTokens: 4000,
|
|
62
65
|
temperature: 0.7,
|
|
66
|
+
storeOutputs,
|
|
67
|
+
artifactTitle,
|
|
63
68
|
});
|
|
64
69
|
if (!result.text) {
|
|
65
70
|
return;
|
|
@@ -83,7 +88,9 @@ export function AiContextButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId,
|
|
|
83
88
|
});
|
|
84
89
|
onToast?.({
|
|
85
90
|
type: "success",
|
|
86
|
-
message:
|
|
91
|
+
message: t("ai.analysisDoneCost", "Analysis completed - Cost: {cost}", {
|
|
92
|
+
cost: `$${(apiKeyId?.includes("dev") ? 0 : actualCost).toFixed(6)}`,
|
|
93
|
+
}),
|
|
87
94
|
});
|
|
88
95
|
showUsageToast({
|
|
89
96
|
requestId: result.requestId,
|
|
@@ -108,14 +115,18 @@ export function AiContextButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId,
|
|
|
108
115
|
if (!analysisResult) {
|
|
109
116
|
return;
|
|
110
117
|
}
|
|
118
|
+
const locale = lang === "fr" ? "fr-FR" : "en-US";
|
|
111
119
|
const currentDate = new Date()
|
|
112
|
-
.toLocaleDateString(
|
|
120
|
+
.toLocaleDateString(locale)
|
|
113
121
|
.replace(/\//g, "-");
|
|
114
|
-
const defaultName =
|
|
115
|
-
|
|
116
|
-
|
|
122
|
+
const defaultName = t("ai.context.fileNameBase", "analysis-{date}.txt", {
|
|
123
|
+
date: currentDate,
|
|
124
|
+
});
|
|
125
|
+
const fileName = prompt(t("ai.context.saveFileNamePrompt", "File name:"), defaultName) ||
|
|
126
|
+
defaultName;
|
|
127
|
+
const content = `${t("ai.context.fileHeader", "DATA ANALYSIS")} - ${new Date().toLocaleString(locale)}\n\n${t("common.promptUsed", "Prompt used").toUpperCase()} :\n${analysisResult.prompt}\n\n${t("common.result", "Result").toUpperCase()} :\n${analysisResult.content}\n\n--- ${t("ai.context.metadata", "METADATA")} ---\n${t("ai.context.tokensUsed", "Tokens used")}: ${analysisResult.tokens.toLocaleString()}\n${t("ai.context.cost", "Cost")}: $${(apiKeyId?.includes("dev")
|
|
117
128
|
? 0
|
|
118
|
-
: analysisResult.cost).toFixed(6)}\
|
|
129
|
+
: analysisResult.cost).toFixed(6)}\n${t("ai.context.requestId", "Request ID")}: ${analysisResult.requestId || "N/A"}`;
|
|
119
130
|
const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
|
|
120
131
|
const url = URL.createObjectURL(blob);
|
|
121
132
|
const anchor = document.createElement("a");
|
|
@@ -129,15 +140,17 @@ export function AiContextButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId,
|
|
|
129
140
|
const sizeClass = `ai-size-${size}`;
|
|
130
141
|
const radiusClass = `ai-radius-${radius}`;
|
|
131
142
|
const variantClass = variant === "light" ? "ai-btn--light" : "";
|
|
132
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "relative inline-block ai-glow", children: [_jsx("button", { ...buttonProps, onClick: handleOpenPanel, disabled: disabled || loading || !isAuthReady, className: `ai-btn ai-context-btn ${variantClass} ${sizeClass} ${radiusClass} ${className || ""}`, title: !isAuthReady
|
|
143
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "relative inline-block ai-glow", children: [_jsx("button", { ...buttonProps, onClick: handleOpenPanel, disabled: disabled || loading || !isAuthReady, className: `ai-btn ai-context-btn ${variantClass} ${sizeClass} ${radiusClass} ${className || ""}`, title: !isAuthReady
|
|
144
|
+
? t("auth.required", "Authentication required")
|
|
145
|
+
: t("ai.analyze", "Analyze with AI"), children: loading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 16, className: "ai-spinner" }), _jsx("span", { children: t("ai.analyzing", "Analyzing...") })] })) : !isAuthReady ? (_jsxs(_Fragment, { children: [_jsx(Lock, { size: 16 }), children || (_jsx("span", { children: t("auth.connectRequired", "Connection required") }))] })) : (_jsxs(_Fragment, { children: [_jsx(Sparkles, { size: 16 }), children || _jsx("span", { children: t("ai.context.buttonAnalyze", "Analyze") })] })) }), isOpen ? (_jsx(AiPromptPanel, { isOpen: isOpen, onClose: () => setIsOpen(false), onSubmit: handleSubmit, uiMode: uiMode, models: [], enableModelManagement: true, modelCategory: "text", baseUrl: baseUrl, apiKey: apiKeyId })) : null] }), isResultOpen && analysisResult ? (_jsx("div", { className: "ai-signin-overlay ai-overlay-panel", onClick: (e) => {
|
|
133
146
|
if (e.target === e.currentTarget) {
|
|
134
147
|
setIsResultOpen(false);
|
|
135
148
|
setAnalysisResult(null);
|
|
136
149
|
}
|
|
137
|
-
}, children: _jsxs("div", { className: "ai-popover ai-result-modal", onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { className: "ai-result-header", children: [_jsxs("div", { className: "ai-row", children: [_jsx(FileText, { size: 18 }), _jsx("h2", { className: "ai-result-title", children: resultModalTitle })] }), _jsxs("div", { className: "ai-row", children: [_jsxs("button", { type: "button", className: `ai-btn ai-btn--ghost ai-btn--compact ${sizeClass} ${radiusClass}`, onClick: saveToFile, children: [_jsx(Download, { size: 14 }), "
|
|
150
|
+
}, children: _jsxs("div", { className: "ai-popover ai-result-modal", onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { className: "ai-result-header", children: [_jsxs("div", { className: "ai-row", children: [_jsx(FileText, { size: 18 }), _jsx("h2", { className: "ai-result-title", children: resultModalTitle || t("ai.context.resultTitle", "Analysis result") })] }), _jsxs("div", { className: "ai-row", children: [_jsxs("button", { type: "button", className: `ai-btn ai-btn--ghost ai-btn--compact ${sizeClass} ${radiusClass}`, onClick: saveToFile, children: [_jsx(Download, { size: 14 }), t("common.save", "Save")] }), _jsx("button", { type: "button", className: "ai-icon-btn", onClick: () => {
|
|
138
151
|
setIsResultOpen(false);
|
|
139
152
|
setAnalysisResult(null);
|
|
140
|
-
}, "aria-label": "
|
|
153
|
+
}, "aria-label": t("common.closeLabel", "Close"), children: _jsx(X, { size: 16 }) })] })] }), _jsxs("div", { className: "ai-result-body", children: [_jsxs("div", { className: "ai-result-block", children: [_jsx("h3", { className: "ai-result-subtitle", children: t("common.promptUsed", "Prompt used") }), _jsx("pre", { className: "ai-result-code", children: analysisResult.prompt })] }), _jsxs("div", { className: "ai-result-block", children: [_jsx("h3", { className: "ai-result-subtitle", children: t("common.result", "Result") }), _jsx("div", { className: "ai-result-content", children: analysisResult.content })] }), _jsxs("div", { className: "ai-result-meta ai-between", children: [_jsxs("span", { children: [t("ai.context.cost", "Cost"), ": $", (apiKeyId?.includes("dev")
|
|
141
154
|
? 0
|
|
142
|
-
: analysisResult.cost).toFixed(6)] }), _jsxs("span", { children: ["ID: ", analysisResult.requestId?.slice(-8) || "N/A"] })] })] })] }) })) : null, _jsx(LBSigninModal, { isOpen: showAuthModal, onClose: () => setShowAuthModal(false) }), _jsx(ErrorToast, { error: errorData, onComplete: clearError }, errorKey)] }));
|
|
155
|
+
: analysisResult.cost).toFixed(6)] }), _jsxs("span", { children: [t("ai.context.requestId", "Request ID"), ":", " ", analysisResult.requestId?.slice(-8) || "N/A"] })] })] })] }) })) : null, _jsx(LBSigninModal, { isOpen: showAuthModal, onClose: () => setShowAuthModal(false) }), _jsx(ErrorToast, { error: errorData, onComplete: clearError }, errorKey)] }));
|
|
143
156
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiImageButton.d.ts","sourceRoot":"","sources":["../../src/components/AiImageButton.tsx"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAC5B,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAS5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"AiImageButton.d.ts","sourceRoot":"","sources":["../../src/components/AiImageButton.tsx"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAC5B,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAS5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAY5D,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;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;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,IAAW,EACX,MAAe,EACf,OAAmB,EACnB,GAAG,WAAW,EACf,EAAE,kBAAkB,2CA8QpB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx,
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import "../styles/register";
|
|
4
4
|
import { useState } from "react";
|
|
5
5
|
import { ImageIcon, Loader2, Download, ExternalLink, X, Lock, } from "lucide-react";
|
|
@@ -11,7 +11,10 @@ import { useAiContext } from "../context/AiProvider";
|
|
|
11
11
|
import { handleAIError } from "../utils/errorHandler";
|
|
12
12
|
import { useLB } from "../context/LBAuthProvider";
|
|
13
13
|
import { LBSigninModal } from "./LBSigninModal";
|
|
14
|
+
import { useI18n } from "../context/I18nContext";
|
|
15
|
+
import { useLoadingTimer } from "../hooks/useLoadingTimer";
|
|
14
16
|
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, size = "md", radius = "full", variant = "default", ...buttonProps }) {
|
|
17
|
+
const { t } = useI18n();
|
|
15
18
|
const [isOpen, setIsOpen] = useState(false);
|
|
16
19
|
const [showAuthModal, setShowAuthModal] = useState(false);
|
|
17
20
|
const [generatedImage, setGeneratedImage] = useState(null);
|
|
@@ -32,6 +35,7 @@ export function AiImageButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, ui
|
|
|
32
35
|
const baseUrl = propBaseUrl ?? aiContext.baseUrl;
|
|
33
36
|
const apiKeyId = propApiKeyId ?? aiContext.apiKeyId;
|
|
34
37
|
const { generateImage, loading } = useAiCallImage({ baseUrl, apiKeyId });
|
|
38
|
+
const { formatted: loadingElapsed } = useLoadingTimer(loading);
|
|
35
39
|
const isAuthReady = lbStatus === "ready" || Boolean(process.env.LB_API_KEY);
|
|
36
40
|
const handleOpenPanel = () => {
|
|
37
41
|
if (!isAuthReady) {
|
|
@@ -57,10 +61,13 @@ export function AiImageButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, ui
|
|
|
57
61
|
return;
|
|
58
62
|
try {
|
|
59
63
|
await onImageSave(generatedImage.url);
|
|
60
|
-
onToast?.({ type: "success", message: "Image
|
|
64
|
+
onToast?.({ type: "success", message: t("ai.image.savedSuccess", "Image saved") });
|
|
61
65
|
}
|
|
62
66
|
catch (_error) {
|
|
63
|
-
onToast?.({
|
|
67
|
+
onToast?.({
|
|
68
|
+
type: "error",
|
|
69
|
+
message: t("ai.image.saveError", "Error while saving"),
|
|
70
|
+
});
|
|
64
71
|
}
|
|
65
72
|
};
|
|
66
73
|
const handleCloseImage = () => {
|
|
@@ -82,30 +89,35 @@ export function AiImageButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, ui
|
|
|
82
89
|
requestId: result.requestId,
|
|
83
90
|
});
|
|
84
91
|
if (result.url) {
|
|
92
|
+
const safeRequestId = result.requestId || `img-${Date.now()}`;
|
|
93
|
+
const safeTokens = result.debitTokens || 0;
|
|
85
94
|
// Stocker l'image générée
|
|
86
95
|
const imageData = {
|
|
87
96
|
url: result.url,
|
|
88
97
|
prompt: selectedPrompt,
|
|
89
|
-
requestId:
|
|
90
|
-
tokens:
|
|
98
|
+
requestId: safeRequestId,
|
|
99
|
+
tokens: safeTokens,
|
|
91
100
|
};
|
|
92
101
|
setGeneratedImage(imageData);
|
|
93
102
|
console.log("[AiImageButton] Image data stored:", imageData);
|
|
94
103
|
onImage?.(result.url, {
|
|
95
|
-
requestId:
|
|
96
|
-
tokens:
|
|
104
|
+
requestId: safeRequestId,
|
|
105
|
+
tokens: safeTokens,
|
|
106
|
+
});
|
|
107
|
+
onToast?.({
|
|
108
|
+
type: "success",
|
|
109
|
+
message: t("ai.image.generatedSuccess", "Image generated successfully"),
|
|
97
110
|
});
|
|
98
|
-
onToast?.({ type: "success", message: "Image générée avec succès" });
|
|
99
111
|
// Afficher le toast de coût même en mode dev
|
|
100
112
|
showUsageToast({
|
|
101
|
-
requestId:
|
|
102
|
-
debitTokens:
|
|
113
|
+
requestId: safeRequestId,
|
|
114
|
+
debitTokens: safeTokens,
|
|
103
115
|
usage: {
|
|
104
|
-
total_tokens:
|
|
105
|
-
prompt_tokens: Math.floor(
|
|
106
|
-
completion_tokens: Math.floor(
|
|
116
|
+
total_tokens: safeTokens,
|
|
117
|
+
prompt_tokens: Math.floor(safeTokens * 0.8),
|
|
118
|
+
completion_tokens: Math.floor(safeTokens * 0.2),
|
|
107
119
|
},
|
|
108
|
-
cost: apiKeyId?.includes("dev") ? 0 :
|
|
120
|
+
cost: apiKeyId?.includes("dev") ? 0 : safeTokens * 0.002, // Coût simulé
|
|
109
121
|
});
|
|
110
122
|
}
|
|
111
123
|
}
|
|
@@ -119,7 +131,11 @@ export function AiImageButton({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, ui
|
|
|
119
131
|
const sizeClass = `ai-size-${size}`;
|
|
120
132
|
const radiusClass = `ai-radius-${radius}`;
|
|
121
133
|
const variantClass = variant === "light" ? "ai-btn--light" : "";
|
|
122
|
-
return (_jsxs("div", { className: "flex items-start gap-4", children: [_jsxs("div", { className: "relative inline-block ai-glow", children: [_jsx("button", { ...buttonProps, onClick: handleOpenPanel, disabled: disabled || loading || !isAuthReady, className: `ai-btn ai-image-btn ${variantClass} ${sizeClass} ${radiusClass} ${className || ""}`, style: buttonProps.style, "data-ai-image-button": true, title: !isAuthReady
|
|
134
|
+
return (_jsxs("div", { className: "flex items-start gap-4", children: [_jsxs("div", { className: "relative inline-block ai-glow", children: [_jsx("button", { ...buttonProps, onClick: handleOpenPanel, disabled: disabled || loading || !isAuthReady, className: `ai-btn ai-image-btn ${variantClass} ${sizeClass} ${radiusClass} ${className || ""}`, style: buttonProps.style, "data-ai-image-button": true, title: !isAuthReady
|
|
135
|
+
? t("auth.required", "Authentication required")
|
|
136
|
+
: t("ai.image.generate", "Generate image"), children: loading ? (_jsxs("span", { className: "ai-loading-stack", children: [_jsxs("span", { className: "ai-loading-row", children: [_jsx(Loader2, { size: 18, className: "ai-spinner" }), _jsx("span", { className: "ai-text-microtracking", children: t("ai.image.generating", "Generating...") })] }), _jsx("span", { className: "ai-loading-meta", children: t("ai.loading.elapsed", "{seconds}", {
|
|
137
|
+
seconds: loadingElapsed,
|
|
138
|
+
}) })] })) : !isAuthReady ? (_jsxs(_Fragment, { children: [_jsx(Lock, { size: 18 }), children || (_jsx("span", { children: t("auth.connectRequired", "Connection required") }))] })) : (_jsxs(_Fragment, { children: [_jsx(ImageIcon, { size: 18 }), _jsx("span", { className: "ai-text-microtracking", children: children || t("ai.image.generate", "Generate 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: "ai-surface ai-image-card relative", children: [_jsxs("div", { className: "flex items-start justify-between mb-3", children: [_jsx("h3", { className: "font-medium text-sm leading-tight max-w-[calc(100%-32px)]", title: generatedImage.prompt, children: generatedImage.prompt.length > 60
|
|
123
139
|
? `${generatedImage.prompt.substring(0, 60)}...`
|
|
124
|
-
: generatedImage.prompt }), _jsx("button", { onClick: handleCloseImage, className: "ai-icon-btn flex-shrink-0", children: _jsx(X, { size: 16 }) })] }), _jsx("div", { className: "ai-image-frame", children: _jsx("img", { src: generatedImage.url, alt: generatedImage.prompt, className: "ai-image-preview" }) }), _jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsxs("button", { onClick: handleDownload, className: "ai-btn ai-btn--primary", title: "
|
|
140
|
+
: generatedImage.prompt }), _jsx("button", { onClick: handleCloseImage, className: "ai-icon-btn flex-shrink-0", children: _jsx(X, { size: 16 }) })] }), _jsx("div", { className: "ai-image-frame", children: _jsx("img", { src: generatedImage.url, alt: generatedImage.prompt, className: "ai-image-preview" }) }), _jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsxs("button", { onClick: handleDownload, className: "ai-btn ai-btn--primary", title: t("ai.image.download", "Download image"), children: [_jsx(Download, { size: 16 }), t("ai.image.download", "Download image")] }), onImageSave && (_jsxs("button", { onClick: handleSave, className: "ai-btn", title: t("ai.image.saveToDb", "Save to database"), children: [_jsx(ExternalLink, { size: 14 }), t("common.save", "Save")] }))] }), _jsx("div", { className: "ai-image-meta", children: _jsx("div", { className: "flex justify-center", children: _jsxs("span", { children: ["ID: ", (generatedImage.requestId || "N/A").slice(-8)] }) }) })] })), _jsx(LBSigninModal, { isOpen: showAuthModal, onClose: () => setShowAuthModal(false) }), _jsx(ErrorToast, { error: errorData, onComplete: clearError }, errorKey)] }));
|
|
125
141
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiInput.d.ts","sourceRoot":"","sources":["../../src/components/AiInput.tsx"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAC5B,OAAc,EAAoB,KAAK,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAE1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"AiInput.d.ts","sourceRoot":"","sources":["../../src/components/AiInput.tsx"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAC5B,OAAc,EAAoB,KAAK,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAE1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAY9D,MAAM,WAAW,YACf,SACE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EACzB,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACjE,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC5B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,QAAQ,CAAC;CACnB;AAED,wBAAgB,OAAO,CAAC,EACtB,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,YAAY,EACtB,MAAgB,EAChB,IAAW,EACX,MAAe,EACf,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"}
|
|
@@ -11,7 +11,10 @@ import { handleAIError } from "../utils/errorHandler";
|
|
|
11
11
|
import { useLB } from "../context/LBAuthProvider";
|
|
12
12
|
import { LBSigninModal } from "./LBSigninModal";
|
|
13
13
|
import { useAiContext } from "../context/AiProvider";
|
|
14
|
+
import { useI18n } from "../context/I18nContext";
|
|
15
|
+
import { useLoadingTimer } from "../hooks/useLoadingTimer";
|
|
14
16
|
export function AiInput({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode = "modal", size = "md", radius = "full", context, model, prompt, editMode = false, enableModelManagement = true, storeOutputs, artifactTitle, onValue, onToast, disabled, className, ...inputProps }) {
|
|
17
|
+
const { t } = useI18n();
|
|
15
18
|
const [isOpen, setIsOpen] = useState(false);
|
|
16
19
|
const [showAuthModal, setShowAuthModal] = useState(false);
|
|
17
20
|
const [inputValue, setInputValue] = useState(inputProps.value?.toString() || inputProps.defaultValue?.toString() || "");
|
|
@@ -46,6 +49,7 @@ export function AiInput({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode =
|
|
|
46
49
|
modelType: "text-or-language",
|
|
47
50
|
});
|
|
48
51
|
const { generateText, loading } = useAiCallText({ baseUrl, apiKeyId });
|
|
52
|
+
const { formatted: loadingElapsed } = useLoadingTimer(loading);
|
|
49
53
|
const hasConfiguration = Boolean(model && prompt);
|
|
50
54
|
const isAuthReady = lbStatus === "ready" || Boolean(process.env.LB_API_KEY);
|
|
51
55
|
const shouldShowSparkles = isAuthReady && !disabled;
|
|
@@ -80,7 +84,10 @@ export function AiInput({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode =
|
|
|
80
84
|
inputRef.current.value = result.text;
|
|
81
85
|
}
|
|
82
86
|
onValue?.(result.text);
|
|
83
|
-
onToast?.({
|
|
87
|
+
onToast?.({
|
|
88
|
+
type: "success",
|
|
89
|
+
message: t("ai.generationSuccess", "AI generation successful"),
|
|
90
|
+
});
|
|
84
91
|
}
|
|
85
92
|
}
|
|
86
93
|
catch (error) {
|
|
@@ -112,7 +119,10 @@ export function AiInput({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode =
|
|
|
112
119
|
inputRef.current.value = result.text;
|
|
113
120
|
}
|
|
114
121
|
onValue?.(result.text);
|
|
115
|
-
onToast?.({
|
|
122
|
+
onToast?.({
|
|
123
|
+
type: "success",
|
|
124
|
+
message: t("ai.generationSuccess", "AI generation successful"),
|
|
125
|
+
});
|
|
116
126
|
}
|
|
117
127
|
}
|
|
118
128
|
catch (error) {
|
|
@@ -132,8 +142,8 @@ export function AiInput({ baseUrl: propBaseUrl, apiKeyId: propApiKeyId, uiMode =
|
|
|
132
142
|
}, onBlur: (e) => {
|
|
133
143
|
inputProps.onBlur?.(e);
|
|
134
144
|
}, "aria-invalid": Boolean(inputProps["aria-invalid"]), disabled: disabled || loading }), _jsx("button", { className: `ai-control-action ai-spark ${sizeClass} ${radiusClass}`, onClick: hasConfiguration ? handleQuickGenerate : handleOpenPanel, disabled: disabled || loading, type: "button", title: !isAuthReady
|
|
135
|
-
? "Authentication required"
|
|
145
|
+
? t("auth.required", "Authentication required")
|
|
136
146
|
: hasConfiguration
|
|
137
|
-
? "Generate with AI"
|
|
138
|
-
: "Setup AI", children: loading ? (_jsx(Loader2, { size: 16, className: "ai-spinner" })) : shouldShowSparkles ? (_jsx(Sparkles, { size: 16 })) : (_jsx(Lock, { size: 16 })) })] }), isOpen && (_jsx(AiPromptPanel, { isOpen: isOpen, onClose: handleClosePanel, onSubmit: handleSubmit, uiMode: uiMode, models: [], modelCategory: "text", sourceText: inputValue || undefined, apiKey: apiKeyId, baseUrl: baseUrl, enableModelManagement: enableModelManagement, showOnlyUserModels: true })), _jsx(LBSigninModal, { isOpen: showAuthModal, onClose: () => setShowAuthModal(false) }), Boolean(toastData) && (_jsx(UsageToast, { result: toastData, position: "bottom-right", onComplete: clearToast }, toastKey))] }));
|
|
147
|
+
? t("ai.generate", "Generate with AI")
|
|
148
|
+
: t("ai.setup", "Setup AI"), children: loading ? (_jsx(Loader2, { size: 16, className: "ai-spinner" })) : shouldShowSparkles ? (_jsx(Sparkles, { size: 16 })) : (_jsx(Lock, { size: 16 })) })] }), loading ? (_jsx("span", { className: "ai-control-timer", children: t("ai.loading.elapsed", "{seconds}", { seconds: loadingElapsed }) })) : null, isOpen && (_jsx(AiPromptPanel, { isOpen: isOpen, onClose: handleClosePanel, onSubmit: handleSubmit, uiMode: uiMode, models: [], modelCategory: "text", sourceText: inputValue || undefined, apiKey: apiKeyId, baseUrl: baseUrl, enableModelManagement: enableModelManagement, showOnlyUserModels: true })), _jsx(LBSigninModal, { isOpen: showAuthModal, onClose: () => setShowAuthModal(false) }), Boolean(toastData) && (_jsx(UsageToast, { result: toastData, position: "bottom-right", onComplete: clearToast }, toastKey))] }));
|
|
139
149
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiModelSelect.d.ts","sourceRoot":"","sources":["../../src/components/AiModelSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"AiModelSelect.d.ts","sourceRoot":"","sources":["../../src/components/AiModelSelect.tsx"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGtD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE,kBAAkB,2CAkBpB"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import "../styles/register";
|
|
4
|
+
import { useI18n } from "../context/I18nContext";
|
|
4
5
|
export function AiModelSelect({ models, value, onChange, className, disabled, }) {
|
|
5
|
-
|
|
6
|
+
const { t } = useI18n();
|
|
7
|
+
return (_jsxs("select", { value: value, onChange: (e) => onChange(e.target.value), className: className, disabled: disabled, "data-ai-model-select": true, children: [_jsx("option", { value: "", children: t("ai.select.modelPlaceholder", "Select a model") }), models.map((model) => (_jsx("option", { value: model.id, children: model.name }, model.id)))] }));
|
|
6
8
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiPromptPanel.d.ts","sourceRoot":"","sources":["../../src/components/AiPromptPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAC5B,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"AiPromptPanel.d.ts","sourceRoot":"","sources":["../../src/components/AiPromptPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC;AAC5B,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAWf,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AASvC,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAKrD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,SAAS,CAAC;IAE1D,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,IAAI,CAAC;IAExB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CA0BtD"}
|