@serhii.olishevskyi/docs 1.2.12 → 1.2.14
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/{UserPopoverComponent-K7CJNYYL.mjs → UserPopoverComponent-Z7YPC3AV.mjs} +1 -1
- package/dist/{chunk-FRDK4RQX.mjs → chunk-7WZQFX6U.mjs} +315 -136
- package/dist/index.d.mts +13 -8
- package/dist/index.d.ts +13 -8
- package/dist/index.js +263 -87
- package/dist/index.mjs +2 -4
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -408,28 +408,33 @@ declare const UI: {
|
|
|
408
408
|
};
|
|
409
409
|
|
|
410
410
|
type AIProviderType = 'gemini' | 'openai';
|
|
411
|
+
interface AIServiceConfig {
|
|
412
|
+
apiKey?: string;
|
|
413
|
+
modelName?: string;
|
|
414
|
+
}
|
|
415
|
+
interface AIConfig {
|
|
416
|
+
provider?: AIProviderType;
|
|
417
|
+
gemini?: AIServiceConfig;
|
|
418
|
+
openai?: AIServiceConfig;
|
|
419
|
+
}
|
|
411
420
|
interface AIGenerateOptions {
|
|
412
421
|
prompt: string;
|
|
413
422
|
systemInstruction?: string;
|
|
414
423
|
jsonMode?: boolean;
|
|
415
424
|
temperature?: number;
|
|
416
|
-
}
|
|
417
|
-
interface AIConfig {
|
|
418
|
-
apiKey?: string;
|
|
419
425
|
provider?: AIProviderType;
|
|
420
426
|
modelName?: string;
|
|
421
427
|
}
|
|
422
428
|
interface AIContextType {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
modelName: string;
|
|
426
|
-
/** Универсальный метод генерации (текст или JSON) */
|
|
429
|
+
activeProvider: AIProviderType;
|
|
430
|
+
config: AIConfig;
|
|
427
431
|
generate: <T = string>(options: AIGenerateOptions) => Promise<T | null>;
|
|
432
|
+
/** Метод для перезагрузки настроек из базы данных */
|
|
433
|
+
reloadConfig: () => Promise<void>;
|
|
428
434
|
}
|
|
429
435
|
interface AIProviderProps {
|
|
430
436
|
children: React__default.ReactNode;
|
|
431
437
|
config?: AIConfig;
|
|
432
|
-
apiKey?: string;
|
|
433
438
|
}
|
|
434
439
|
declare const AIProvider: React__default.FC<AIProviderProps>;
|
|
435
440
|
declare const useAI: () => AIContextType;
|
package/dist/index.d.ts
CHANGED
|
@@ -408,28 +408,33 @@ declare const UI: {
|
|
|
408
408
|
};
|
|
409
409
|
|
|
410
410
|
type AIProviderType = 'gemini' | 'openai';
|
|
411
|
+
interface AIServiceConfig {
|
|
412
|
+
apiKey?: string;
|
|
413
|
+
modelName?: string;
|
|
414
|
+
}
|
|
415
|
+
interface AIConfig {
|
|
416
|
+
provider?: AIProviderType;
|
|
417
|
+
gemini?: AIServiceConfig;
|
|
418
|
+
openai?: AIServiceConfig;
|
|
419
|
+
}
|
|
411
420
|
interface AIGenerateOptions {
|
|
412
421
|
prompt: string;
|
|
413
422
|
systemInstruction?: string;
|
|
414
423
|
jsonMode?: boolean;
|
|
415
424
|
temperature?: number;
|
|
416
|
-
}
|
|
417
|
-
interface AIConfig {
|
|
418
|
-
apiKey?: string;
|
|
419
425
|
provider?: AIProviderType;
|
|
420
426
|
modelName?: string;
|
|
421
427
|
}
|
|
422
428
|
interface AIContextType {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
modelName: string;
|
|
426
|
-
/** Универсальный метод генерации (текст или JSON) */
|
|
429
|
+
activeProvider: AIProviderType;
|
|
430
|
+
config: AIConfig;
|
|
427
431
|
generate: <T = string>(options: AIGenerateOptions) => Promise<T | null>;
|
|
432
|
+
/** Метод для перезагрузки настроек из базы данных */
|
|
433
|
+
reloadConfig: () => Promise<void>;
|
|
428
434
|
}
|
|
429
435
|
interface AIProviderProps {
|
|
430
436
|
children: React__default.ReactNode;
|
|
431
437
|
config?: AIConfig;
|
|
432
|
-
apiKey?: string;
|
|
433
438
|
}
|
|
434
439
|
declare const AIProvider: React__default.FC<AIProviderProps>;
|
|
435
440
|
declare const useAI: () => AIContextType;
|
package/dist/index.js
CHANGED
|
@@ -695,7 +695,6 @@ var init_translation_service = __esm({
|
|
|
695
695
|
"src/services/translation.service.ts"() {
|
|
696
696
|
"use strict";
|
|
697
697
|
translationService = {
|
|
698
|
-
// 1. Принимаем client первым аргументом
|
|
699
698
|
incrementVersion: async (client, namespace, langCodes) => {
|
|
700
699
|
try {
|
|
701
700
|
const { data } = await client.from("translation_versions").select("version, lang_code").eq("namespace", namespace);
|
|
@@ -716,36 +715,103 @@ var init_translation_service = __esm({
|
|
|
716
715
|
return null;
|
|
717
716
|
}
|
|
718
717
|
},
|
|
719
|
-
|
|
718
|
+
/**
|
|
719
|
+
* Универсальный метод перевода с поддержкой Gemini, OpenAI и автоматическим fallback
|
|
720
|
+
*/
|
|
721
|
+
translateSmart: async (client, aiGenerateFn, params, openAiApiKey) => {
|
|
720
722
|
const languagesToTranslate = params.targetLangs || (params.targetLang ? [params.targetLang] : []);
|
|
721
723
|
try {
|
|
722
724
|
const { data, error } = await client.functions.invoke("translate-smart", { body: params });
|
|
723
725
|
if (!error && data) return data;
|
|
724
726
|
} catch {
|
|
725
|
-
console.warn("Edge Function translate-smart \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430, \
|
|
727
|
+
console.warn("[translationService]: Edge Function translate-smart \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430, \u043F\u0435\u0440\u0435\u0445\u043E\u0434\u0438\u043C \u043A AIProvider...");
|
|
726
728
|
}
|
|
727
|
-
|
|
728
|
-
const prompt = `Translate the source text into language codes: ${JSON.stringify(languagesToTranslate)}.
|
|
729
|
+
const prompt = `Translate the source text into language codes: ${JSON.stringify(languagesToTranslate)}.
|
|
729
730
|
Source Text: "${params.text}"
|
|
730
731
|
${params.contextHint ? `Context Hint: "${params.contextHint}"` : ""}`;
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
732
|
+
const systemInstruction = 'You are a professional translator. Respond STRICTLY with a valid JSON object mapping language code to translated text. Example: {"en": "Hello", "uk": "\u041F\u0440\u0438\u0432\u0456\u0442"}';
|
|
733
|
+
if (aiGenerateFn) {
|
|
734
|
+
try {
|
|
735
|
+
const translations = await aiGenerateFn({
|
|
736
|
+
prompt,
|
|
737
|
+
systemInstruction,
|
|
738
|
+
jsonMode: true,
|
|
739
|
+
provider: params.provider,
|
|
740
|
+
modelName: params.modelName
|
|
741
|
+
});
|
|
742
|
+
if (translations) {
|
|
743
|
+
if (params.targetLang) {
|
|
744
|
+
return { translatedText: translations[params.targetLang] || params.text };
|
|
745
|
+
}
|
|
746
|
+
return { translations };
|
|
747
|
+
}
|
|
748
|
+
} catch (err) {
|
|
749
|
+
console.warn(`[translationService]: \u041E\u0448\u0438\u0431\u043A\u0430 \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u0438 \u0418\u0418 (${params.provider || "default"}), \u043F\u0440\u043E\u0431\u0443\u0435\u043C \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u044B\u0435 \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u044B...`, err);
|
|
750
|
+
}
|
|
751
|
+
if (params.provider === "gemini" || !params.provider) {
|
|
752
|
+
try {
|
|
753
|
+
console.warn("[translationService]: \u041F\u0440\u043E\u0431\u0443\u0435\u043C \u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u0441\u044F \u043D\u0430 OpenAI fallback...");
|
|
754
|
+
const translations = await aiGenerateFn({
|
|
755
|
+
prompt,
|
|
756
|
+
systemInstruction,
|
|
757
|
+
jsonMode: true,
|
|
758
|
+
provider: "openai"
|
|
759
|
+
});
|
|
760
|
+
if (translations) {
|
|
761
|
+
if (params.targetLang) {
|
|
762
|
+
return { translatedText: translations[params.targetLang] || params.text };
|
|
763
|
+
}
|
|
764
|
+
return { translations };
|
|
765
|
+
}
|
|
766
|
+
} catch (fallbackErr) {
|
|
767
|
+
console.warn("[translationService]: Fallback OpenAI \u0447\u0435\u0440\u0435\u0437 AIProvider \u043D\u0435 \u0443\u0434\u0430\u043B\u0441\u044F", fallbackErr);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
if (openAiApiKey) {
|
|
772
|
+
try {
|
|
773
|
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
774
|
+
method: "POST",
|
|
775
|
+
headers: {
|
|
776
|
+
"Content-Type": "application/json",
|
|
777
|
+
Authorization: `Bearer ${openAiApiKey}`
|
|
778
|
+
},
|
|
779
|
+
body: JSON.stringify({
|
|
780
|
+
model: params.modelName || "gpt-4o-mini",
|
|
781
|
+
response_format: { type: "json_object" },
|
|
782
|
+
messages: [
|
|
783
|
+
{ role: "system", content: systemInstruction },
|
|
784
|
+
{ role: "user", content: prompt }
|
|
785
|
+
],
|
|
786
|
+
temperature: 0.3
|
|
787
|
+
})
|
|
788
|
+
});
|
|
789
|
+
if (response.ok) {
|
|
790
|
+
const result = await response.json();
|
|
791
|
+
const content = result.choices?.[0]?.message?.content;
|
|
792
|
+
if (content) {
|
|
793
|
+
const translations = JSON.parse(content);
|
|
794
|
+
if (params.targetLang) {
|
|
795
|
+
return { translatedText: translations[params.targetLang] || params.text };
|
|
796
|
+
}
|
|
797
|
+
return { translations };
|
|
798
|
+
}
|
|
739
799
|
}
|
|
740
|
-
|
|
800
|
+
} catch (err) {
|
|
801
|
+
console.warn("[translationService]: Direct OpenAI API error, fallback to Google Translate", err);
|
|
741
802
|
}
|
|
742
803
|
}
|
|
743
804
|
if (params.targetLang) {
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
805
|
+
try {
|
|
806
|
+
const fallbackUrl = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=${params.targetLang}&dt=t&q=${encodeURIComponent(params.text)}`;
|
|
807
|
+
const res = await fetch(fallbackUrl);
|
|
808
|
+
if (res.ok) {
|
|
809
|
+
const data = await res.json();
|
|
810
|
+
const translatedText = data[0].map((x) => x[0]).join("");
|
|
811
|
+
return { translatedText };
|
|
812
|
+
}
|
|
813
|
+
} catch (err) {
|
|
814
|
+
console.error("[translationService]: Google Translate fallback failed:", err);
|
|
749
815
|
}
|
|
750
816
|
}
|
|
751
817
|
throw new Error("All translation strategies failed.");
|
|
@@ -761,36 +827,95 @@ var init_AIProvider = __esm({
|
|
|
761
827
|
"use strict";
|
|
762
828
|
import_react4 = require("react");
|
|
763
829
|
import_genai = require("@google/genai");
|
|
830
|
+
init_SupabaseProvider();
|
|
764
831
|
import_jsx_runtime4 = require("react/jsx-runtime");
|
|
765
832
|
AIContext = (0, import_react4.createContext)(null);
|
|
766
|
-
AIProvider = ({
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
833
|
+
AIProvider = ({ children, config: initialConfig = {} }) => {
|
|
834
|
+
const supabase = useSupabase();
|
|
835
|
+
const [dbConfig, setDbConfig] = (0, import_react4.useState)({});
|
|
836
|
+
const loadSettingsFromDb = (0, import_react4.useCallback)(async () => {
|
|
837
|
+
try {
|
|
838
|
+
const { data } = await supabase.from("app_settings").select("key, value").in("key", [
|
|
839
|
+
"ai_provider",
|
|
840
|
+
"gemini_api_key",
|
|
841
|
+
"gemini_model",
|
|
842
|
+
"openai_api_key",
|
|
843
|
+
"openai_model"
|
|
844
|
+
]);
|
|
845
|
+
if (!data) return;
|
|
846
|
+
const parseVal = (val) => {
|
|
847
|
+
if (typeof val === "string") return val;
|
|
848
|
+
return JSON.stringify(val).replace(/^"|"$/g, "");
|
|
849
|
+
};
|
|
850
|
+
let provider;
|
|
851
|
+
let geminiApiKey;
|
|
852
|
+
let geminiModel;
|
|
853
|
+
let openaiApiKey;
|
|
854
|
+
let openaiModel;
|
|
855
|
+
data.forEach((item) => {
|
|
856
|
+
const val = parseVal(item.value);
|
|
857
|
+
if (item.key === "ai_provider" && (val === "gemini" || val === "openai")) {
|
|
858
|
+
provider = val;
|
|
859
|
+
}
|
|
860
|
+
if (item.key === "gemini_api_key") geminiApiKey = val;
|
|
861
|
+
if (item.key === "gemini_model") geminiModel = val;
|
|
862
|
+
if (item.key === "openai_api_key") openaiApiKey = val;
|
|
863
|
+
if (item.key === "openai_model") openaiModel = val;
|
|
864
|
+
});
|
|
865
|
+
setDbConfig({
|
|
866
|
+
provider,
|
|
867
|
+
gemini: { apiKey: geminiApiKey, modelName: geminiModel },
|
|
868
|
+
openai: { apiKey: openaiApiKey, modelName: openaiModel }
|
|
869
|
+
});
|
|
870
|
+
} catch (err) {
|
|
871
|
+
console.warn("[AIProvider]: Failed to load AI settings from app_settings", err);
|
|
872
|
+
}
|
|
873
|
+
}, [supabase]);
|
|
874
|
+
(0, import_react4.useEffect)(() => {
|
|
875
|
+
loadSettingsFromDb();
|
|
876
|
+
}, [loadSettingsFromDb]);
|
|
877
|
+
const activeProvider = dbConfig.provider || initialConfig.provider || "gemini";
|
|
878
|
+
const geminiConfig = {
|
|
879
|
+
apiKey: dbConfig.gemini?.apiKey || initialConfig.gemini?.apiKey || "",
|
|
880
|
+
//import.meta.env.VITE_GEMINI_API_KEY,
|
|
881
|
+
modelName: dbConfig.gemini?.modelName || initialConfig.gemini?.modelName || "" || //import.meta.env.VITE_GEMINI_MODEL ||
|
|
882
|
+
"gemini-2.5-flash"
|
|
883
|
+
};
|
|
884
|
+
const openaiConfig = {
|
|
885
|
+
apiKey: dbConfig.openai?.apiKey || initialConfig.openai?.apiKey || "",
|
|
886
|
+
//import.meta.env.VITE_OPENAI_API_KEY,
|
|
887
|
+
modelName: dbConfig.openai?.modelName || initialConfig.openai?.modelName || "" || //import.meta.env.VITE_OPENAI_MODEL ||
|
|
888
|
+
"gpt-4o-mini"
|
|
889
|
+
};
|
|
774
890
|
const contextValue = (0, import_react4.useMemo)(() => {
|
|
775
891
|
return {
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
892
|
+
activeProvider,
|
|
893
|
+
config: {
|
|
894
|
+
provider: activeProvider,
|
|
895
|
+
gemini: geminiConfig,
|
|
896
|
+
openai: openaiConfig
|
|
897
|
+
},
|
|
898
|
+
reloadConfig: loadSettingsFromDb,
|
|
779
899
|
generate: async ({
|
|
780
900
|
prompt,
|
|
781
901
|
systemInstruction,
|
|
782
902
|
jsonMode = false,
|
|
783
|
-
temperature
|
|
903
|
+
temperature,
|
|
904
|
+
provider: overrideProvider,
|
|
905
|
+
modelName: overrideModelName
|
|
784
906
|
}) => {
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
907
|
+
const targetProvider = overrideProvider || activeProvider;
|
|
908
|
+
if (targetProvider === "gemini") {
|
|
909
|
+
const key = geminiConfig.apiKey;
|
|
910
|
+
const model = overrideModelName || geminiConfig.modelName || "gemini-2.5-flash";
|
|
911
|
+
if (!key) {
|
|
912
|
+
console.warn("[AIProvider]: API Key \u0434\u043B\u044F Gemini \u043D\u0435 \u0437\u0430\u0434\u0430\u043D.");
|
|
913
|
+
return null;
|
|
914
|
+
}
|
|
790
915
|
try {
|
|
791
|
-
const ai = new import_genai.GoogleGenAI({ apiKey });
|
|
916
|
+
const ai = new import_genai.GoogleGenAI({ apiKey: key });
|
|
792
917
|
const response = await ai.models.generateContent({
|
|
793
|
-
model
|
|
918
|
+
model,
|
|
794
919
|
contents: prompt,
|
|
795
920
|
config: {
|
|
796
921
|
systemInstruction,
|
|
@@ -809,7 +934,13 @@ var init_AIProvider = __esm({
|
|
|
809
934
|
return null;
|
|
810
935
|
}
|
|
811
936
|
}
|
|
812
|
-
if (
|
|
937
|
+
if (targetProvider === "openai") {
|
|
938
|
+
const key = openaiConfig.apiKey;
|
|
939
|
+
const model = overrideModelName || openaiConfig.modelName || "gpt-4o-mini";
|
|
940
|
+
if (!key) {
|
|
941
|
+
console.warn("[AIProvider]: API Key \u0434\u043B\u044F OpenAI \u043D\u0435 \u0437\u0430\u0434\u0430\u043D.");
|
|
942
|
+
return null;
|
|
943
|
+
}
|
|
813
944
|
try {
|
|
814
945
|
const messages = [];
|
|
815
946
|
if (systemInstruction) {
|
|
@@ -820,15 +951,19 @@ var init_AIProvider = __esm({
|
|
|
820
951
|
method: "POST",
|
|
821
952
|
headers: {
|
|
822
953
|
"Content-Type": "application/json",
|
|
823
|
-
Authorization: `Bearer ${
|
|
954
|
+
Authorization: `Bearer ${key}`
|
|
824
955
|
},
|
|
825
956
|
body: JSON.stringify({
|
|
826
|
-
model
|
|
957
|
+
model,
|
|
827
958
|
messages,
|
|
828
959
|
temperature,
|
|
829
960
|
...jsonMode ? { response_format: { type: "json_object" } } : {}
|
|
830
961
|
})
|
|
831
962
|
});
|
|
963
|
+
if (!res.ok) {
|
|
964
|
+
const errData = await res.json().catch(() => ({}));
|
|
965
|
+
throw new Error(`OpenAI API status ${res.status}: ${JSON.stringify(errData)}`);
|
|
966
|
+
}
|
|
832
967
|
const data = await res.json();
|
|
833
968
|
const content = data.choices?.[0]?.message?.content?.trim() || "";
|
|
834
969
|
if (jsonMode) {
|
|
@@ -843,7 +978,14 @@ var init_AIProvider = __esm({
|
|
|
843
978
|
return null;
|
|
844
979
|
}
|
|
845
980
|
};
|
|
846
|
-
}, [
|
|
981
|
+
}, [
|
|
982
|
+
activeProvider,
|
|
983
|
+
geminiConfig.apiKey,
|
|
984
|
+
geminiConfig.modelName,
|
|
985
|
+
openaiConfig.apiKey,
|
|
986
|
+
openaiConfig.modelName,
|
|
987
|
+
loadSettingsFromDb
|
|
988
|
+
]);
|
|
847
989
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AIContext.Provider, { value: contextValue, children });
|
|
848
990
|
};
|
|
849
991
|
useAI = () => {
|
|
@@ -857,7 +999,7 @@ var init_AIProvider = __esm({
|
|
|
857
999
|
});
|
|
858
1000
|
|
|
859
1001
|
// src/i18n/TranslationDialog.tsx
|
|
860
|
-
var import_react5, import_material, import_AutoFixHigh, import_Translate, import_Lightbulb, import_jsx_runtime5, TranslationDialog;
|
|
1002
|
+
var import_react5, import_material, import_AutoFixHigh, import_Translate, import_Lightbulb, import_SmartToy, import_jsx_runtime5, TranslationDialog;
|
|
861
1003
|
var init_TranslationDialog = __esm({
|
|
862
1004
|
"src/i18n/TranslationDialog.tsx"() {
|
|
863
1005
|
"use strict";
|
|
@@ -866,6 +1008,7 @@ var init_TranslationDialog = __esm({
|
|
|
866
1008
|
import_AutoFixHigh = __toESM(require("@mui/icons-material/AutoFixHigh"));
|
|
867
1009
|
import_Translate = __toESM(require("@mui/icons-material/Translate"));
|
|
868
1010
|
import_Lightbulb = __toESM(require("@mui/icons-material/Lightbulb"));
|
|
1011
|
+
import_SmartToy = __toESM(require("@mui/icons-material/SmartToy"));
|
|
869
1012
|
init_translation_service();
|
|
870
1013
|
init_SupabaseProvider();
|
|
871
1014
|
init_AIProvider();
|
|
@@ -878,10 +1021,11 @@ var init_TranslationDialog = __esm({
|
|
|
878
1021
|
onSave
|
|
879
1022
|
}) => {
|
|
880
1023
|
const supabase = useSupabase();
|
|
881
|
-
const { generate } = useAI();
|
|
1024
|
+
const { generate, activeProvider: defaultProvider } = useAI();
|
|
882
1025
|
const [languages, setLanguages] = (0, import_react5.useState)([]);
|
|
883
1026
|
const [values, setValues] = (0, import_react5.useState)({});
|
|
884
1027
|
const [contextHint, setContextHint] = (0, import_react5.useState)("");
|
|
1028
|
+
const [selectedProvider, setSelectedProvider] = (0, import_react5.useState)("auto");
|
|
885
1029
|
const [loading, setLoading] = (0, import_react5.useState)(false);
|
|
886
1030
|
const [saving, setSaving] = (0, import_react5.useState)(false);
|
|
887
1031
|
const [translatingCode, setTranslatingCode] = (0, import_react5.useState)(null);
|
|
@@ -918,6 +1062,7 @@ var init_TranslationDialog = __esm({
|
|
|
918
1062
|
};
|
|
919
1063
|
fetchData();
|
|
920
1064
|
}, [open, translationKey, namespace]);
|
|
1065
|
+
const effectiveProvider = selectedProvider === "auto" ? void 0 : selectedProvider;
|
|
921
1066
|
const handleAutoTranslate = async (e, targetLang) => {
|
|
922
1067
|
e.preventDefault();
|
|
923
1068
|
e.stopPropagation();
|
|
@@ -927,13 +1072,14 @@ var init_TranslationDialog = __esm({
|
|
|
927
1072
|
const res = await translationService.translateSmart(supabase, generate, {
|
|
928
1073
|
text: translationKey,
|
|
929
1074
|
targetLang,
|
|
930
|
-
contextHint
|
|
1075
|
+
contextHint,
|
|
1076
|
+
provider: effectiveProvider
|
|
931
1077
|
});
|
|
932
1078
|
if (res?.translatedText) {
|
|
933
1079
|
setValues((prev) => ({ ...prev, [targetLang]: res.translatedText }));
|
|
934
1080
|
}
|
|
935
1081
|
} catch (err) {
|
|
936
|
-
console.
|
|
1082
|
+
console.error(err);
|
|
937
1083
|
setError(`Failed to translate into ${targetLang}. ${err?.message || ""}`);
|
|
938
1084
|
} finally {
|
|
939
1085
|
setTranslatingCode(null);
|
|
@@ -950,7 +1096,8 @@ var init_TranslationDialog = __esm({
|
|
|
950
1096
|
const res = await translationService.translateSmart(supabase, generate, {
|
|
951
1097
|
text: translationKey,
|
|
952
1098
|
targetLangs,
|
|
953
|
-
contextHint
|
|
1099
|
+
contextHint,
|
|
1100
|
+
provider: effectiveProvider
|
|
954
1101
|
});
|
|
955
1102
|
if (res?.translations) {
|
|
956
1103
|
setValues((prev) => ({ ...prev, ...res.translations }));
|
|
@@ -993,36 +1140,76 @@ var init_TranslationDialog = __esm({
|
|
|
993
1140
|
onClick: (e) => e.stopPropagation(),
|
|
994
1141
|
onMouseDown: (e) => e.stopPropagation(),
|
|
995
1142
|
children: [
|
|
996
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1143
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1144
|
+
import_material.DialogTitle,
|
|
1145
|
+
{
|
|
1146
|
+
sx: { pb: 1, display: "flex", justifyContent: "space-between", alignItems: "flex-start" },
|
|
1147
|
+
children: [
|
|
1148
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material.Box, { children: [
|
|
1149
|
+
"Context Translation",
|
|
1150
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1151
|
+
import_material.Typography,
|
|
1152
|
+
{
|
|
1153
|
+
component: "div",
|
|
1154
|
+
variant: "subtitle2",
|
|
1155
|
+
color: "text.secondary",
|
|
1156
|
+
sx: { wordBreak: "break-all", mt: 0.5 },
|
|
1157
|
+
children: [
|
|
1158
|
+
"Original: ",
|
|
1159
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("strong", { children: [
|
|
1160
|
+
'"',
|
|
1161
|
+
translationKey,
|
|
1162
|
+
'"'
|
|
1163
|
+
] })
|
|
1164
|
+
]
|
|
1165
|
+
}
|
|
1166
|
+
)
|
|
1167
|
+
] }),
|
|
1168
|
+
!loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1169
|
+
import_material.Button,
|
|
1170
|
+
{
|
|
1171
|
+
type: "button",
|
|
1172
|
+
size: "small",
|
|
1173
|
+
variant: "outlined",
|
|
1174
|
+
color: "secondary",
|
|
1175
|
+
startIcon: isTranslatingAll ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material.CircularProgress, { size: 16, color: "inherit" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_Translate.default, { fontSize: "small" }),
|
|
1176
|
+
onClick: handleTranslateAll,
|
|
1177
|
+
disabled: isBusy,
|
|
1178
|
+
sx: { flexShrink: 0, ml: 2, whiteSpace: "nowrap" },
|
|
1179
|
+
children: isTranslatingAll ? "Translating..." : "Translate All"
|
|
1180
|
+
}
|
|
1181
|
+
)
|
|
1182
|
+
]
|
|
1183
|
+
}
|
|
1184
|
+
),
|
|
1023
1185
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material.DialogContent, { dividers: true, sx: { pt: 2 }, children: [
|
|
1024
1186
|
error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material.Alert, { severity: "error", onClose: () => setError(null), sx: { mb: 2 }, children: error }),
|
|
1025
1187
|
loading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material.Box, { sx: { display: "flex", justifyContent: "center", py: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material.CircularProgress, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material.Box, { sx: { display: "flex", flexDirection: "column", gap: 2.5 }, children: [
|
|
1188
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material.Box, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
1189
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material.Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
|
|
1190
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_SmartToy.default, { fontSize: "small", color: "action" }),
|
|
1191
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material.Typography, { variant: "caption", sx: { fontWeight: 600, color: "text.secondary" }, children: "AI Engine:" })
|
|
1192
|
+
] }),
|
|
1193
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1194
|
+
import_material.ToggleButtonGroup,
|
|
1195
|
+
{
|
|
1196
|
+
size: "small",
|
|
1197
|
+
value: selectedProvider,
|
|
1198
|
+
exclusive: true,
|
|
1199
|
+
onChange: (_, val) => val && setSelectedProvider(val),
|
|
1200
|
+
disabled: isBusy,
|
|
1201
|
+
children: [
|
|
1202
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material.ToggleButton, { value: "auto", sx: { px: 1.5, py: 0.2, fontSize: "0.75rem" }, children: [
|
|
1203
|
+
"Auto (",
|
|
1204
|
+
defaultProvider,
|
|
1205
|
+
")"
|
|
1206
|
+
] }),
|
|
1207
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material.ToggleButton, { value: "gemini", sx: { px: 1.5, py: 0.2, fontSize: "0.75rem" }, children: "Gemini" }),
|
|
1208
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material.ToggleButton, { value: "openai", sx: { px: 1.5, py: 0.2, fontSize: "0.75rem" }, children: "OpenAI" })
|
|
1209
|
+
]
|
|
1210
|
+
}
|
|
1211
|
+
)
|
|
1212
|
+
] }),
|
|
1026
1213
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material.Paper, { variant: "outlined", sx: { p: 2, bgcolor: "action.hover", borderRadius: 2 }, children: [
|
|
1027
1214
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material.Box, { sx: { display: "flex", alignItems: "center", gap: 1, mb: 1 }, children: [
|
|
1028
1215
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_Lightbulb.default, { color: "warning", fontSize: "small" }),
|
|
@@ -1071,7 +1258,7 @@ var init_TranslationDialog = __esm({
|
|
|
1071
1258
|
disabled: isBusy
|
|
1072
1259
|
}
|
|
1073
1260
|
),
|
|
1074
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material.Tooltip, { title:
|
|
1261
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material.Tooltip, { title: `Translate using ${selectedProvider === "auto" ? defaultProvider : selectedProvider}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1075
1262
|
import_material.IconButton,
|
|
1076
1263
|
{
|
|
1077
1264
|
type: "button",
|
|
@@ -1086,16 +1273,7 @@ var init_TranslationDialog = __esm({
|
|
|
1086
1273
|
] }),
|
|
1087
1274
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material.DialogActions, { sx: { px: 3, py: 2 }, children: [
|
|
1088
1275
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material.Button, { onClick: onClose, disabled: isBusy, color: "inherit", type: "button", children: "Cancel" }),
|
|
1089
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1090
|
-
import_material.Button,
|
|
1091
|
-
{
|
|
1092
|
-
onClick: handleSaveAll,
|
|
1093
|
-
variant: "contained",
|
|
1094
|
-
disabled: isBusy,
|
|
1095
|
-
type: "button",
|
|
1096
|
-
children: saving ? "Saving..." : "Save All"
|
|
1097
|
-
}
|
|
1098
|
-
)
|
|
1276
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material.Button, { onClick: handleSaveAll, variant: "contained", disabled: isBusy, type: "button", children: saving ? "Saving..." : "Save All" })
|
|
1099
1277
|
] })
|
|
1100
1278
|
]
|
|
1101
1279
|
}
|
|
@@ -4542,9 +4720,7 @@ var SwitchComponent = ({
|
|
|
4542
4720
|
}) => {
|
|
4543
4721
|
const currentLabel = label ?? (checked ? checkedLabel : uncheckedLabel);
|
|
4544
4722
|
const renderLabel = (node) => {
|
|
4545
|
-
console.log(node);
|
|
4546
4723
|
if (typeof node === "string") {
|
|
4547
|
-
console.log("string");
|
|
4548
4724
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TranslateText, { overrideNamespace, children: node });
|
|
4549
4725
|
}
|
|
4550
4726
|
return node;
|
package/dist/index.mjs
CHANGED
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
useTranslationEdit,
|
|
44
44
|
useTranslationNamespace,
|
|
45
45
|
useUserSettings
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-7WZQFX6U.mjs";
|
|
47
47
|
|
|
48
48
|
// src/UI/components/inputs/TextFieldComponent.tsx
|
|
49
49
|
import { useState } from "react";
|
|
@@ -741,7 +741,7 @@ var EmailInputComponent = ({
|
|
|
741
741
|
import { useState as useState5, useEffect as useEffect2, lazy, Suspense } from "react";
|
|
742
742
|
import { Avatar, Tooltip as Tooltip3, Typography as Typography2 } from "@mui/material";
|
|
743
743
|
import { Fragment as Fragment4, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
744
|
-
var LazyUserPopover = lazy(() => import("./UserPopoverComponent-
|
|
744
|
+
var LazyUserPopover = lazy(() => import("./UserPopoverComponent-Z7YPC3AV.mjs"));
|
|
745
745
|
var getInitials = (name) => {
|
|
746
746
|
if (!name) return "?";
|
|
747
747
|
const parts = name.trim().split(" ");
|
|
@@ -1810,9 +1810,7 @@ var SwitchComponent = ({
|
|
|
1810
1810
|
}) => {
|
|
1811
1811
|
const currentLabel = label ?? (checked ? checkedLabel : uncheckedLabel);
|
|
1812
1812
|
const renderLabel = (node) => {
|
|
1813
|
-
console.log(node);
|
|
1814
1813
|
if (typeof node === "string") {
|
|
1815
|
-
console.log("string");
|
|
1816
1814
|
return /* @__PURE__ */ jsx12(TranslateText, { overrideNamespace, children: node });
|
|
1817
1815
|
}
|
|
1818
1816
|
return node;
|