@serhii.olishevskyi/docs 1.2.13 → 1.2.15
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-LI5272PW.mjs → UserPopoverComponent-RAEPOSIE.mjs} +1 -1
- package/dist/{chunk-EW4DX6YG.mjs → chunk-4NEOJ5KZ.mjs} +123 -73
- package/dist/index.d.mts +2 -10
- package/dist/index.d.ts +2 -10
- package/dist/index.js +72 -21
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/UI/components/data.display/UserPopoverComponent.tsx
|
|
2
|
-
import { useEffect as
|
|
2
|
+
import { useEffect as useEffect10, useState as useState14 } from "react";
|
|
3
3
|
import {
|
|
4
4
|
Popover,
|
|
5
5
|
Box as Box4,
|
|
@@ -1070,7 +1070,7 @@ var useToast = () => {
|
|
|
1070
1070
|
};
|
|
1071
1071
|
|
|
1072
1072
|
// src/context/ConfirmationProvider.tsx
|
|
1073
|
-
import { createContext as createContext10, useContext as useContext10, useState as
|
|
1073
|
+
import { createContext as createContext10, useContext as useContext10, useState as useState10, useCallback as useCallback5 } from "react";
|
|
1074
1074
|
import {
|
|
1075
1075
|
Button as Button2,
|
|
1076
1076
|
Dialog as Dialog2,
|
|
@@ -1088,14 +1088,14 @@ import {
|
|
|
1088
1088
|
} from "@mui/icons-material";
|
|
1089
1089
|
|
|
1090
1090
|
// src/i18n/TranslateText.tsx
|
|
1091
|
-
import { useState as
|
|
1091
|
+
import { useState as useState9, useRef as useRef2, useEffect as useEffect7 } from "react";
|
|
1092
1092
|
import { useTranslation as useTranslation2 } from "react-i18next";
|
|
1093
1093
|
import { Box as Box2, Popper, Paper as Paper2, MenuList, MenuItem, ListItemIcon, ListItemText } from "@mui/material";
|
|
1094
1094
|
import TranslateIcon2 from "@mui/icons-material/Translate";
|
|
1095
1095
|
import LaunchIcon from "@mui/icons-material/Launch";
|
|
1096
1096
|
|
|
1097
1097
|
// src/i18n/TranslationDialog.tsx
|
|
1098
|
-
import { useEffect as
|
|
1098
|
+
import { useEffect as useEffect6, useState as useState8 } from "react";
|
|
1099
1099
|
import {
|
|
1100
1100
|
Dialog,
|
|
1101
1101
|
DialogTitle,
|
|
@@ -1244,24 +1244,66 @@ ${params.contextHint ? `Context Hint: "${params.contextHint}"` : ""}`;
|
|
|
1244
1244
|
};
|
|
1245
1245
|
|
|
1246
1246
|
// src/context/AIProvider.tsx
|
|
1247
|
-
import { createContext as createContext9, useContext as useContext9, useMemo as useMemo5 } from "react";
|
|
1247
|
+
import { createContext as createContext9, useContext as useContext9, useEffect as useEffect5, useMemo as useMemo5, useState as useState7, useCallback as useCallback4 } from "react";
|
|
1248
1248
|
import { GoogleGenAI } from "@google/genai";
|
|
1249
1249
|
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1250
1250
|
var AIContext = createContext9(null);
|
|
1251
|
-
var AIProvider = ({
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
})
|
|
1257
|
-
|
|
1251
|
+
var AIProvider = ({ children, config: initialConfig = {} }) => {
|
|
1252
|
+
const supabase = useSupabase();
|
|
1253
|
+
const [dbConfig, setDbConfig] = useState7({});
|
|
1254
|
+
const loadSettingsFromDb = useCallback4(async () => {
|
|
1255
|
+
try {
|
|
1256
|
+
const { data } = await supabase.from("app_settings").select("key, value").in("key", [
|
|
1257
|
+
"ai_provider",
|
|
1258
|
+
"gemini_api_key",
|
|
1259
|
+
"gemini_model",
|
|
1260
|
+
"openai_api_key",
|
|
1261
|
+
"openai_model"
|
|
1262
|
+
]);
|
|
1263
|
+
if (!data) return;
|
|
1264
|
+
const parseVal = (val) => {
|
|
1265
|
+
if (typeof val === "string") return val;
|
|
1266
|
+
return JSON.stringify(val).replace(/^"|"$/g, "");
|
|
1267
|
+
};
|
|
1268
|
+
let provider;
|
|
1269
|
+
let geminiApiKey;
|
|
1270
|
+
let geminiModel;
|
|
1271
|
+
let openaiApiKey;
|
|
1272
|
+
let openaiModel;
|
|
1273
|
+
data.forEach((item) => {
|
|
1274
|
+
const val = parseVal(item.value);
|
|
1275
|
+
if (item.key === "ai_provider" && (val === "gemini" || val === "openai")) {
|
|
1276
|
+
provider = val;
|
|
1277
|
+
}
|
|
1278
|
+
if (item.key === "gemini_api_key") geminiApiKey = val;
|
|
1279
|
+
if (item.key === "gemini_model") geminiModel = val;
|
|
1280
|
+
if (item.key === "openai_api_key") openaiApiKey = val;
|
|
1281
|
+
if (item.key === "openai_model") openaiModel = val;
|
|
1282
|
+
});
|
|
1283
|
+
setDbConfig({
|
|
1284
|
+
provider,
|
|
1285
|
+
gemini: { apiKey: geminiApiKey, modelName: geminiModel },
|
|
1286
|
+
openai: { apiKey: openaiApiKey, modelName: openaiModel }
|
|
1287
|
+
});
|
|
1288
|
+
} catch (err) {
|
|
1289
|
+
console.warn("[AIProvider]: Failed to load AI settings from app_settings", err);
|
|
1290
|
+
}
|
|
1291
|
+
}, [supabase]);
|
|
1292
|
+
useEffect5(() => {
|
|
1293
|
+
loadSettingsFromDb();
|
|
1294
|
+
}, [loadSettingsFromDb]);
|
|
1295
|
+
const activeProvider = dbConfig.provider || initialConfig.provider || "gemini";
|
|
1258
1296
|
const geminiConfig = {
|
|
1259
|
-
apiKey:
|
|
1260
|
-
|
|
1297
|
+
apiKey: dbConfig.gemini?.apiKey || initialConfig.gemini?.apiKey || "",
|
|
1298
|
+
//import.meta.env.VITE_GEMINI_API_KEY,
|
|
1299
|
+
modelName: dbConfig.gemini?.modelName || initialConfig.gemini?.modelName || "" || //import.meta.env.VITE_GEMINI_MODEL ||
|
|
1300
|
+
"gemini-2.5-flash"
|
|
1261
1301
|
};
|
|
1262
1302
|
const openaiConfig = {
|
|
1263
|
-
apiKey:
|
|
1264
|
-
|
|
1303
|
+
apiKey: dbConfig.openai?.apiKey || initialConfig.openai?.apiKey || "",
|
|
1304
|
+
//import.meta.env.VITE_OPENAI_API_KEY,
|
|
1305
|
+
modelName: dbConfig.openai?.modelName || initialConfig.openai?.modelName || "" || //import.meta.env.VITE_OPENAI_MODEL ||
|
|
1306
|
+
"gpt-4o-mini"
|
|
1265
1307
|
};
|
|
1266
1308
|
const contextValue = useMemo5(() => {
|
|
1267
1309
|
return {
|
|
@@ -1271,6 +1313,7 @@ var AIProvider = ({
|
|
|
1271
1313
|
gemini: geminiConfig,
|
|
1272
1314
|
openai: openaiConfig
|
|
1273
1315
|
},
|
|
1316
|
+
reloadConfig: loadSettingsFromDb,
|
|
1274
1317
|
generate: async ({
|
|
1275
1318
|
prompt,
|
|
1276
1319
|
systemInstruction,
|
|
@@ -1291,7 +1334,6 @@ var AIProvider = ({
|
|
|
1291
1334
|
const ai = new GoogleGenAI({ apiKey: key });
|
|
1292
1335
|
const response = await ai.models.generateContent({
|
|
1293
1336
|
model,
|
|
1294
|
-
// Теперь гарантированно string
|
|
1295
1337
|
contents: prompt,
|
|
1296
1338
|
config: {
|
|
1297
1339
|
systemInstruction,
|
|
@@ -1312,7 +1354,7 @@ var AIProvider = ({
|
|
|
1312
1354
|
}
|
|
1313
1355
|
if (targetProvider === "openai") {
|
|
1314
1356
|
const key = openaiConfig.apiKey;
|
|
1315
|
-
const model = overrideModelName || openaiConfig.modelName;
|
|
1357
|
+
const model = overrideModelName || openaiConfig.modelName || "gpt-4o-mini";
|
|
1316
1358
|
if (!key) {
|
|
1317
1359
|
console.warn("[AIProvider]: API Key \u0434\u043B\u044F OpenAI \u043D\u0435 \u0437\u0430\u0434\u0430\u043D.");
|
|
1318
1360
|
return null;
|
|
@@ -1359,7 +1401,8 @@ var AIProvider = ({
|
|
|
1359
1401
|
geminiConfig.apiKey,
|
|
1360
1402
|
geminiConfig.modelName,
|
|
1361
1403
|
openaiConfig.apiKey,
|
|
1362
|
-
openaiConfig.modelName
|
|
1404
|
+
openaiConfig.modelName,
|
|
1405
|
+
loadSettingsFromDb
|
|
1363
1406
|
]);
|
|
1364
1407
|
return /* @__PURE__ */ jsx9(AIContext.Provider, { value: contextValue, children });
|
|
1365
1408
|
};
|
|
@@ -1382,16 +1425,21 @@ var TranslationDialog = ({
|
|
|
1382
1425
|
}) => {
|
|
1383
1426
|
const supabase = useSupabase();
|
|
1384
1427
|
const { generate, activeProvider: defaultProvider } = useAI();
|
|
1385
|
-
const [languages, setLanguages] =
|
|
1386
|
-
const [values, setValues] =
|
|
1387
|
-
const [contextHint, setContextHint] =
|
|
1388
|
-
const [selectedProvider, setSelectedProvider] =
|
|
1389
|
-
const [loading, setLoading] =
|
|
1390
|
-
const [saving, setSaving] =
|
|
1391
|
-
const [translatingCode, setTranslatingCode] =
|
|
1392
|
-
const [isTranslatingAll, setIsTranslatingAll] =
|
|
1393
|
-
const [error, setError] =
|
|
1394
|
-
|
|
1428
|
+
const [languages, setLanguages] = useState8([]);
|
|
1429
|
+
const [values, setValues] = useState8({});
|
|
1430
|
+
const [contextHint, setContextHint] = useState8("");
|
|
1431
|
+
const [selectedProvider, setSelectedProvider] = useState8("auto");
|
|
1432
|
+
const [loading, setLoading] = useState8(false);
|
|
1433
|
+
const [saving, setSaving] = useState8(false);
|
|
1434
|
+
const [translatingCode, setTranslatingCode] = useState8(null);
|
|
1435
|
+
const [isTranslatingAll, setIsTranslatingAll] = useState8(false);
|
|
1436
|
+
const [error, setError] = useState8(null);
|
|
1437
|
+
useEffect6(() => {
|
|
1438
|
+
if (open) {
|
|
1439
|
+
setSelectedProvider(defaultProvider || "auto");
|
|
1440
|
+
}
|
|
1441
|
+
}, [open, defaultProvider]);
|
|
1442
|
+
useEffect6(() => {
|
|
1395
1443
|
if (!open) return;
|
|
1396
1444
|
const fetchData = async () => {
|
|
1397
1445
|
setLoading(true);
|
|
@@ -1421,7 +1469,7 @@ var TranslationDialog = ({
|
|
|
1421
1469
|
}
|
|
1422
1470
|
};
|
|
1423
1471
|
fetchData();
|
|
1424
|
-
}, [open, translationKey, namespace]);
|
|
1472
|
+
}, [open, translationKey, namespace, supabase]);
|
|
1425
1473
|
const effectiveProvider = selectedProvider === "auto" ? void 0 : selectedProvider;
|
|
1426
1474
|
const handleAutoTranslate = async (e, targetLang) => {
|
|
1427
1475
|
e.preventDefault();
|
|
@@ -1559,13 +1607,15 @@ var TranslationDialog = ({
|
|
|
1559
1607
|
onChange: (_, val) => val && setSelectedProvider(val),
|
|
1560
1608
|
disabled: isBusy,
|
|
1561
1609
|
children: [
|
|
1562
|
-
/* @__PURE__ */
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
")"
|
|
1610
|
+
/* @__PURE__ */ jsx10(ToggleButton, { value: "auto", sx: { px: 1.5, py: 0.2, fontSize: "0.75rem" }, children: "Auto" }),
|
|
1611
|
+
/* @__PURE__ */ jsxs3(ToggleButton, { value: "gemini", sx: { px: 1.5, py: 0.2, fontSize: "0.75rem" }, children: [
|
|
1612
|
+
"Gemini ",
|
|
1613
|
+
defaultProvider === "gemini" && "(Default)"
|
|
1566
1614
|
] }),
|
|
1567
|
-
/* @__PURE__ */
|
|
1568
|
-
|
|
1615
|
+
/* @__PURE__ */ jsxs3(ToggleButton, { value: "openai", sx: { px: 1.5, py: 0.2, fontSize: "0.75rem" }, children: [
|
|
1616
|
+
"OpenAI ",
|
|
1617
|
+
defaultProvider === "openai" && "(Default)"
|
|
1618
|
+
] })
|
|
1569
1619
|
]
|
|
1570
1620
|
}
|
|
1571
1621
|
)
|
|
@@ -1651,11 +1701,11 @@ var TranslateText = ({
|
|
|
1651
1701
|
const { t, i18n: i18n2 } = useTranslation2(namespace);
|
|
1652
1702
|
const { isTranslationMode, canEdit } = useTranslationEdit();
|
|
1653
1703
|
const supabase = useSupabase();
|
|
1654
|
-
const [anchorEl, setAnchorEl] =
|
|
1655
|
-
const [isDialogOpen, setIsDialogOpen] =
|
|
1704
|
+
const [anchorEl, setAnchorEl] = useState9(null);
|
|
1705
|
+
const [isDialogOpen, setIsDialogOpen] = useState9(false);
|
|
1656
1706
|
const timeoutRef = useRef2(null);
|
|
1657
1707
|
const translatedValue = t(children, values);
|
|
1658
|
-
|
|
1708
|
+
useEffect7(() => {
|
|
1659
1709
|
return () => {
|
|
1660
1710
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
1661
1711
|
};
|
|
@@ -1821,10 +1871,10 @@ var SEVERITY_ICONS = {
|
|
|
1821
1871
|
success: /* @__PURE__ */ jsx12(SuccessIcon, { color: "success", sx: { fontSize: 40 } })
|
|
1822
1872
|
};
|
|
1823
1873
|
var ConfirmationProvider = ({ overrideNamespace, children }) => {
|
|
1824
|
-
const [open, setOpen] =
|
|
1825
|
-
const [options, setOptions] =
|
|
1826
|
-
const [resolver, setResolver] =
|
|
1827
|
-
const confirm =
|
|
1874
|
+
const [open, setOpen] = useState10(false);
|
|
1875
|
+
const [options, setOptions] = useState10(null);
|
|
1876
|
+
const [resolver, setResolver] = useState10(null);
|
|
1877
|
+
const confirm = useCallback5((opts) => {
|
|
1828
1878
|
setOptions(opts);
|
|
1829
1879
|
setOpen(true);
|
|
1830
1880
|
return new Promise((resolve) => {
|
|
@@ -1899,7 +1949,7 @@ var useConfirmation = () => {
|
|
|
1899
1949
|
};
|
|
1900
1950
|
|
|
1901
1951
|
// src/context/AppSettingsProvider.tsx
|
|
1902
|
-
import { createContext as createContext11, useContext as useContext11, useEffect as
|
|
1952
|
+
import { createContext as createContext11, useContext as useContext11, useEffect as useEffect8, useState as useState11, useCallback as useCallback6 } from "react";
|
|
1903
1953
|
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1904
1954
|
var DEFAULT_SETTINGS = {
|
|
1905
1955
|
max_group_members: 100
|
|
@@ -1907,10 +1957,10 @@ var DEFAULT_SETTINGS = {
|
|
|
1907
1957
|
var AppSettingsContext = createContext11(void 0);
|
|
1908
1958
|
var AppSettingsProvider = ({ children }) => {
|
|
1909
1959
|
const supabase = useSupabase();
|
|
1910
|
-
const [settings, setSettings] =
|
|
1911
|
-
const [loading, setLoading] =
|
|
1912
|
-
const [error, setError] =
|
|
1913
|
-
const fetchSettings =
|
|
1960
|
+
const [settings, setSettings] = useState11(DEFAULT_SETTINGS);
|
|
1961
|
+
const [loading, setLoading] = useState11(true);
|
|
1962
|
+
const [error, setError] = useState11(null);
|
|
1963
|
+
const fetchSettings = useCallback6(async () => {
|
|
1914
1964
|
try {
|
|
1915
1965
|
setLoading(true);
|
|
1916
1966
|
setError(null);
|
|
@@ -1930,10 +1980,10 @@ var AppSettingsProvider = ({ children }) => {
|
|
|
1930
1980
|
setLoading(false);
|
|
1931
1981
|
}
|
|
1932
1982
|
}, []);
|
|
1933
|
-
|
|
1983
|
+
useEffect8(() => {
|
|
1934
1984
|
fetchSettings();
|
|
1935
1985
|
}, [fetchSettings]);
|
|
1936
|
-
const getSetting =
|
|
1986
|
+
const getSetting = useCallback6((key, defaultValue) => {
|
|
1937
1987
|
if (key in settings && settings[key] !== null && settings[key] !== void 0) {
|
|
1938
1988
|
return settings[key];
|
|
1939
1989
|
}
|
|
@@ -1962,7 +2012,7 @@ var useAppSettings = () => {
|
|
|
1962
2012
|
};
|
|
1963
2013
|
|
|
1964
2014
|
// src/context/UserSettingsProvider.tsx
|
|
1965
|
-
import { createContext as createContext12, useContext as useContext12, useEffect as
|
|
2015
|
+
import { createContext as createContext12, useContext as useContext12, useEffect as useEffect9, useState as useState12, useCallback as useCallback7 } from "react";
|
|
1966
2016
|
|
|
1967
2017
|
// src/types/user.types.ts
|
|
1968
2018
|
var defaultUserSettings = {
|
|
@@ -1979,14 +2029,14 @@ var UserSettingsProvider = ({ children }) => {
|
|
|
1979
2029
|
const supabase = useSupabase();
|
|
1980
2030
|
const { user, isAuthenticated, loading: isAuthLoading } = useAuth();
|
|
1981
2031
|
const userId = user?.id;
|
|
1982
|
-
const [settings, setSettings] =
|
|
2032
|
+
const [settings, setSettings] = useState12({
|
|
1983
2033
|
id: "",
|
|
1984
2034
|
...defaultUserSettings
|
|
1985
2035
|
});
|
|
1986
|
-
const [loading, setLoading] =
|
|
1987
|
-
const [error, setError] =
|
|
1988
|
-
const [activeChatUserId, setActiveChatUserId] =
|
|
1989
|
-
const fetchSettings =
|
|
2036
|
+
const [loading, setLoading] = useState12(true);
|
|
2037
|
+
const [error, setError] = useState12(null);
|
|
2038
|
+
const [activeChatUserId, setActiveChatUserId] = useState12(null);
|
|
2039
|
+
const fetchSettings = useCallback7(async () => {
|
|
1990
2040
|
if (isAuthLoading) return;
|
|
1991
2041
|
if (!isAuthenticated || !userId) {
|
|
1992
2042
|
setSettings({ id: "", ...defaultUserSettings });
|
|
@@ -2039,10 +2089,10 @@ var UserSettingsProvider = ({ children }) => {
|
|
|
2039
2089
|
setLoading(false);
|
|
2040
2090
|
}
|
|
2041
2091
|
}, [isAuthenticated, isAuthLoading, userId]);
|
|
2042
|
-
|
|
2092
|
+
useEffect9(() => {
|
|
2043
2093
|
fetchSettings();
|
|
2044
2094
|
}, [fetchSettings]);
|
|
2045
|
-
const toggleSidebar =
|
|
2095
|
+
const toggleSidebar = useCallback7(
|
|
2046
2096
|
async (open) => {
|
|
2047
2097
|
const isExplicitBoolean = typeof open === "boolean";
|
|
2048
2098
|
const nextState = isExplicitBoolean ? open : !settings.sidebar_open;
|
|
@@ -2058,7 +2108,7 @@ var UserSettingsProvider = ({ children }) => {
|
|
|
2058
2108
|
},
|
|
2059
2109
|
[settings.sidebar_open, userId]
|
|
2060
2110
|
);
|
|
2061
|
-
const toggleChat =
|
|
2111
|
+
const toggleChat = useCallback7(
|
|
2062
2112
|
async (open) => {
|
|
2063
2113
|
const isExplicitBoolean = typeof open === "boolean";
|
|
2064
2114
|
const nextState = isExplicitBoolean ? open : !settings.chat_open;
|
|
@@ -2074,7 +2124,7 @@ var UserSettingsProvider = ({ children }) => {
|
|
|
2074
2124
|
},
|
|
2075
2125
|
[settings.chat_open, userId]
|
|
2076
2126
|
);
|
|
2077
|
-
const openChatWithUser =
|
|
2127
|
+
const openChatWithUser = useCallback7(
|
|
2078
2128
|
async (targetUserId) => {
|
|
2079
2129
|
setActiveChatUserId(targetUserId);
|
|
2080
2130
|
if (!settings.chat_open) {
|
|
@@ -2083,7 +2133,7 @@ var UserSettingsProvider = ({ children }) => {
|
|
|
2083
2133
|
},
|
|
2084
2134
|
[settings.chat_open, toggleChat]
|
|
2085
2135
|
);
|
|
2086
|
-
const setLanguage =
|
|
2136
|
+
const setLanguage = useCallback7(
|
|
2087
2137
|
async (newLanguage) => {
|
|
2088
2138
|
const previousLanguage = settings.language;
|
|
2089
2139
|
setSettings((prev) => ({ ...prev, language: newLanguage }));
|
|
@@ -2098,7 +2148,7 @@ var UserSettingsProvider = ({ children }) => {
|
|
|
2098
2148
|
},
|
|
2099
2149
|
[settings.language, userId]
|
|
2100
2150
|
);
|
|
2101
|
-
const setThemeMode =
|
|
2151
|
+
const setThemeMode = useCallback7(
|
|
2102
2152
|
async (newMode) => {
|
|
2103
2153
|
const previousMode = settings.theme_mode;
|
|
2104
2154
|
setSettings((prev) => ({ ...prev, theme_mode: newMode }));
|
|
@@ -2273,7 +2323,7 @@ var UserRoleChipComponent = ({ overrideNamespace, role }) => {
|
|
|
2273
2323
|
};
|
|
2274
2324
|
|
|
2275
2325
|
// src/UI/components/buttons/CopyClipboardButtonComponent.tsx
|
|
2276
|
-
import { useState as
|
|
2326
|
+
import { useState as useState13 } from "react";
|
|
2277
2327
|
import { IconButton as IconButton3 } from "@mui/material";
|
|
2278
2328
|
import CheckIcon from "@mui/icons-material/Check";
|
|
2279
2329
|
import CopyIcon from "@mui/icons-material/ContentCopy";
|
|
@@ -2325,7 +2375,7 @@ var CopyClipboardButtonComponent = ({
|
|
|
2325
2375
|
sx,
|
|
2326
2376
|
...iconButtonProps
|
|
2327
2377
|
}) => {
|
|
2328
|
-
const [copied, setCopied] =
|
|
2378
|
+
const [copied, setCopied] = useState13(false);
|
|
2329
2379
|
const handleCopy = async (e) => {
|
|
2330
2380
|
e.stopPropagation();
|
|
2331
2381
|
if (!textToCopy) return;
|
|
@@ -2358,9 +2408,9 @@ var CopyClipboardButtonComponent = ({
|
|
|
2358
2408
|
// src/UI/components/data.display/UserPopoverComponent.tsx
|
|
2359
2409
|
import { Fragment as Fragment2, jsx as jsx20, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2360
2410
|
var useUserStatus = (supabase, userId, open) => {
|
|
2361
|
-
const [lastSeenAt, setLastSeenAt] =
|
|
2362
|
-
const [loading, setLoading] =
|
|
2363
|
-
|
|
2411
|
+
const [lastSeenAt, setLastSeenAt] = useState14(null);
|
|
2412
|
+
const [loading, setLoading] = useState14(true);
|
|
2413
|
+
useEffect10(() => {
|
|
2364
2414
|
if (!userId || !open) {
|
|
2365
2415
|
setLastSeenAt(null);
|
|
2366
2416
|
setLoading(false);
|
|
@@ -2409,13 +2459,13 @@ var UserPopoverComponent = ({
|
|
|
2409
2459
|
const { activeCompanyId, membership: currentMembership } = useAuth();
|
|
2410
2460
|
const { openChatWithUser } = useUserSettings();
|
|
2411
2461
|
const { formatDate, formatRelativeTime } = useLocalization();
|
|
2412
|
-
const [profileData, setProfileData] =
|
|
2413
|
-
const [membershipData, setMembershipData] =
|
|
2414
|
-
const [avatarUrl, setAvatarUrl] =
|
|
2415
|
-
const [coverUrl, setCoverUrl] =
|
|
2416
|
-
const [loading, setLoading] =
|
|
2462
|
+
const [profileData, setProfileData] = useState14(null);
|
|
2463
|
+
const [membershipData, setMembershipData] = useState14(null);
|
|
2464
|
+
const [avatarUrl, setAvatarUrl] = useState14(null);
|
|
2465
|
+
const [coverUrl, setCoverUrl] = useState14(null);
|
|
2466
|
+
const [loading, setLoading] = useState14(true);
|
|
2417
2467
|
const { lastSeenAt, isOnline } = useUserStatus(supabase, userId, open);
|
|
2418
|
-
|
|
2468
|
+
useEffect10(() => {
|
|
2419
2469
|
if (!open || !userId || !activeCompanyId) return;
|
|
2420
2470
|
let isMounted = true;
|
|
2421
2471
|
setLoading(true);
|
package/dist/index.d.mts
CHANGED
|
@@ -413,11 +413,8 @@ interface AIServiceConfig {
|
|
|
413
413
|
modelName?: string;
|
|
414
414
|
}
|
|
415
415
|
interface AIConfig {
|
|
416
|
-
/** Активный провайдер по умолчанию */
|
|
417
416
|
provider?: AIProviderType;
|
|
418
|
-
/** Конфигурация для Gemini */
|
|
419
417
|
gemini?: AIServiceConfig;
|
|
420
|
-
/** Конфигурация для OpenAI */
|
|
421
418
|
openai?: AIServiceConfig;
|
|
422
419
|
}
|
|
423
420
|
interface AIGenerateOptions {
|
|
@@ -425,24 +422,19 @@ interface AIGenerateOptions {
|
|
|
425
422
|
systemInstruction?: string;
|
|
426
423
|
jsonMode?: boolean;
|
|
427
424
|
temperature?: number;
|
|
428
|
-
/** Возможность переопределить провайдера для конкретного запроса */
|
|
429
425
|
provider?: AIProviderType;
|
|
430
|
-
/** Возможность переопределить модель для конкретного запроса */
|
|
431
426
|
modelName?: string;
|
|
432
427
|
}
|
|
433
428
|
interface AIContextType {
|
|
434
429
|
activeProvider: AIProviderType;
|
|
435
430
|
config: AIConfig;
|
|
436
|
-
/** Универсальный метод генерации (текст или JSON) */
|
|
437
431
|
generate: <T = string>(options: AIGenerateOptions) => Promise<T | null>;
|
|
432
|
+
/** Метод для перезагрузки настроек из базы данных */
|
|
433
|
+
reloadConfig: () => Promise<void>;
|
|
438
434
|
}
|
|
439
435
|
interface AIProviderProps {
|
|
440
436
|
children: React__default.ReactNode;
|
|
441
437
|
config?: AIConfig;
|
|
442
|
-
/** Устаревшая прямая передача ключа (для обратной совместимости) */
|
|
443
|
-
apiKey?: string;
|
|
444
|
-
/** Устаревший выбор провайдера (для обратной совместимости) */
|
|
445
|
-
provider?: AIProviderType;
|
|
446
438
|
}
|
|
447
439
|
declare const AIProvider: React__default.FC<AIProviderProps>;
|
|
448
440
|
declare const useAI: () => AIContextType;
|
package/dist/index.d.ts
CHANGED
|
@@ -413,11 +413,8 @@ interface AIServiceConfig {
|
|
|
413
413
|
modelName?: string;
|
|
414
414
|
}
|
|
415
415
|
interface AIConfig {
|
|
416
|
-
/** Активный провайдер по умолчанию */
|
|
417
416
|
provider?: AIProviderType;
|
|
418
|
-
/** Конфигурация для Gemini */
|
|
419
417
|
gemini?: AIServiceConfig;
|
|
420
|
-
/** Конфигурация для OpenAI */
|
|
421
418
|
openai?: AIServiceConfig;
|
|
422
419
|
}
|
|
423
420
|
interface AIGenerateOptions {
|
|
@@ -425,24 +422,19 @@ interface AIGenerateOptions {
|
|
|
425
422
|
systemInstruction?: string;
|
|
426
423
|
jsonMode?: boolean;
|
|
427
424
|
temperature?: number;
|
|
428
|
-
/** Возможность переопределить провайдера для конкретного запроса */
|
|
429
425
|
provider?: AIProviderType;
|
|
430
|
-
/** Возможность переопределить модель для конкретного запроса */
|
|
431
426
|
modelName?: string;
|
|
432
427
|
}
|
|
433
428
|
interface AIContextType {
|
|
434
429
|
activeProvider: AIProviderType;
|
|
435
430
|
config: AIConfig;
|
|
436
|
-
/** Универсальный метод генерации (текст или JSON) */
|
|
437
431
|
generate: <T = string>(options: AIGenerateOptions) => Promise<T | null>;
|
|
432
|
+
/** Метод для перезагрузки настроек из базы данных */
|
|
433
|
+
reloadConfig: () => Promise<void>;
|
|
438
434
|
}
|
|
439
435
|
interface AIProviderProps {
|
|
440
436
|
children: React__default.ReactNode;
|
|
441
437
|
config?: AIConfig;
|
|
442
|
-
/** Устаревшая прямая передача ключа (для обратной совместимости) */
|
|
443
|
-
apiKey?: string;
|
|
444
|
-
/** Устаревший выбор провайдера (для обратной совместимости) */
|
|
445
|
-
provider?: AIProviderType;
|
|
446
438
|
}
|
|
447
439
|
declare const AIProvider: React__default.FC<AIProviderProps>;
|
|
448
440
|
declare const useAI: () => AIContextType;
|
package/dist/index.js
CHANGED
|
@@ -827,22 +827,65 @@ var init_AIProvider = __esm({
|
|
|
827
827
|
"use strict";
|
|
828
828
|
import_react4 = require("react");
|
|
829
829
|
import_genai = require("@google/genai");
|
|
830
|
+
init_SupabaseProvider();
|
|
830
831
|
import_jsx_runtime4 = require("react/jsx-runtime");
|
|
831
832
|
AIContext = (0, import_react4.createContext)(null);
|
|
832
|
-
AIProvider = ({
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
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";
|
|
839
878
|
const geminiConfig = {
|
|
840
|
-
apiKey:
|
|
841
|
-
|
|
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"
|
|
842
883
|
};
|
|
843
884
|
const openaiConfig = {
|
|
844
|
-
apiKey:
|
|
845
|
-
|
|
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"
|
|
846
889
|
};
|
|
847
890
|
const contextValue = (0, import_react4.useMemo)(() => {
|
|
848
891
|
return {
|
|
@@ -852,6 +895,7 @@ var init_AIProvider = __esm({
|
|
|
852
895
|
gemini: geminiConfig,
|
|
853
896
|
openai: openaiConfig
|
|
854
897
|
},
|
|
898
|
+
reloadConfig: loadSettingsFromDb,
|
|
855
899
|
generate: async ({
|
|
856
900
|
prompt,
|
|
857
901
|
systemInstruction,
|
|
@@ -872,7 +916,6 @@ var init_AIProvider = __esm({
|
|
|
872
916
|
const ai = new import_genai.GoogleGenAI({ apiKey: key });
|
|
873
917
|
const response = await ai.models.generateContent({
|
|
874
918
|
model,
|
|
875
|
-
// Теперь гарантированно string
|
|
876
919
|
contents: prompt,
|
|
877
920
|
config: {
|
|
878
921
|
systemInstruction,
|
|
@@ -893,7 +936,7 @@ var init_AIProvider = __esm({
|
|
|
893
936
|
}
|
|
894
937
|
if (targetProvider === "openai") {
|
|
895
938
|
const key = openaiConfig.apiKey;
|
|
896
|
-
const model = overrideModelName || openaiConfig.modelName;
|
|
939
|
+
const model = overrideModelName || openaiConfig.modelName || "gpt-4o-mini";
|
|
897
940
|
if (!key) {
|
|
898
941
|
console.warn("[AIProvider]: API Key \u0434\u043B\u044F OpenAI \u043D\u0435 \u0437\u0430\u0434\u0430\u043D.");
|
|
899
942
|
return null;
|
|
@@ -940,7 +983,8 @@ var init_AIProvider = __esm({
|
|
|
940
983
|
geminiConfig.apiKey,
|
|
941
984
|
geminiConfig.modelName,
|
|
942
985
|
openaiConfig.apiKey,
|
|
943
|
-
openaiConfig.modelName
|
|
986
|
+
openaiConfig.modelName,
|
|
987
|
+
loadSettingsFromDb
|
|
944
988
|
]);
|
|
945
989
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AIContext.Provider, { value: contextValue, children });
|
|
946
990
|
};
|
|
@@ -987,6 +1031,11 @@ var init_TranslationDialog = __esm({
|
|
|
987
1031
|
const [translatingCode, setTranslatingCode] = (0, import_react5.useState)(null);
|
|
988
1032
|
const [isTranslatingAll, setIsTranslatingAll] = (0, import_react5.useState)(false);
|
|
989
1033
|
const [error, setError] = (0, import_react5.useState)(null);
|
|
1034
|
+
(0, import_react5.useEffect)(() => {
|
|
1035
|
+
if (open) {
|
|
1036
|
+
setSelectedProvider(defaultProvider || "auto");
|
|
1037
|
+
}
|
|
1038
|
+
}, [open, defaultProvider]);
|
|
990
1039
|
(0, import_react5.useEffect)(() => {
|
|
991
1040
|
if (!open) return;
|
|
992
1041
|
const fetchData = async () => {
|
|
@@ -1017,7 +1066,7 @@ var init_TranslationDialog = __esm({
|
|
|
1017
1066
|
}
|
|
1018
1067
|
};
|
|
1019
1068
|
fetchData();
|
|
1020
|
-
}, [open, translationKey, namespace]);
|
|
1069
|
+
}, [open, translationKey, namespace, supabase]);
|
|
1021
1070
|
const effectiveProvider = selectedProvider === "auto" ? void 0 : selectedProvider;
|
|
1022
1071
|
const handleAutoTranslate = async (e, targetLang) => {
|
|
1023
1072
|
e.preventDefault();
|
|
@@ -1155,13 +1204,15 @@ var init_TranslationDialog = __esm({
|
|
|
1155
1204
|
onChange: (_, val) => val && setSelectedProvider(val),
|
|
1156
1205
|
disabled: isBusy,
|
|
1157
1206
|
children: [
|
|
1158
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
")"
|
|
1207
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material.ToggleButton, { value: "auto", sx: { px: 1.5, py: 0.2, fontSize: "0.75rem" }, children: "Auto" }),
|
|
1208
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material.ToggleButton, { value: "gemini", sx: { px: 1.5, py: 0.2, fontSize: "0.75rem" }, children: [
|
|
1209
|
+
"Gemini ",
|
|
1210
|
+
defaultProvider === "gemini" && "(Default)"
|
|
1162
1211
|
] }),
|
|
1163
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1164
|
-
|
|
1212
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_material.ToggleButton, { value: "openai", sx: { px: 1.5, py: 0.2, fontSize: "0.75rem" }, children: [
|
|
1213
|
+
"OpenAI ",
|
|
1214
|
+
defaultProvider === "openai" && "(Default)"
|
|
1215
|
+
] })
|
|
1165
1216
|
]
|
|
1166
1217
|
}
|
|
1167
1218
|
)
|
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-4NEOJ5KZ.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-RAEPOSIE.mjs"));
|
|
745
745
|
var getInitials = (name) => {
|
|
746
746
|
if (!name) return "?";
|
|
747
747
|
const parts = name.trim().split(" ");
|