@iblai/iblai-js 2.9.1 → 2.9.3
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.
|
@@ -2260,7 +2260,6 @@ var analyticsAnalyticsTranscriptsStats$3 = {
|
|
|
2260
2260
|
avgCostPerConversation: "Average cost per conversation",
|
|
2261
2261
|
avgRating: "Average rating",
|
|
2262
2262
|
placeholderTopics: "Topics",
|
|
2263
|
-
placeholderUsers: "Users",
|
|
2264
2263
|
clearAll: "Clear All",
|
|
2265
2264
|
ariaTotalConversations: "Total transcripts conversations",
|
|
2266
2265
|
conversations: "conversations",
|
|
@@ -2345,6 +2344,7 @@ var analyticsStatCard$3 = {
|
|
|
2345
2344
|
var analyticsUserFilterSelect$3 = {
|
|
2346
2345
|
filterByUser: "Filter by user",
|
|
2347
2346
|
you: "You",
|
|
2347
|
+
allUsers: "All users",
|
|
2348
2348
|
searchPlaceholder: "Search users…",
|
|
2349
2349
|
noUsersFound: "No users found.",
|
|
2350
2350
|
loadingUsers: "Loading users…"
|
|
@@ -9281,7 +9281,6 @@ var analyticsAnalyticsTranscriptsStats$2 = {
|
|
|
9281
9281
|
avgCostPerConversation: "Coût moyen par conversation",
|
|
9282
9282
|
avgRating: "Note moyenne",
|
|
9283
9283
|
placeholderTopics: "Sujets",
|
|
9284
|
-
placeholderUsers: "Utilisateurs",
|
|
9285
9284
|
clearAll: "Tout effacer",
|
|
9286
9285
|
ariaTotalConversations: "Total des conversations transcrites",
|
|
9287
9286
|
conversations: "conversations",
|
|
@@ -9366,6 +9365,7 @@ var analyticsStatCard$2 = {
|
|
|
9366
9365
|
var analyticsUserFilterSelect$2 = {
|
|
9367
9366
|
filterByUser: "Filtrer par utilisateur",
|
|
9368
9367
|
you: "Vous",
|
|
9368
|
+
allUsers: "Tous les utilisateurs",
|
|
9369
9369
|
searchPlaceholder: "Rechercher des utilisateurs…",
|
|
9370
9370
|
noUsersFound: "Aucun utilisateur trouvé.",
|
|
9371
9371
|
loadingUsers: "Chargement des utilisateurs…"
|
|
@@ -16302,7 +16302,6 @@ var analyticsAnalyticsTranscriptsStats$1 = {
|
|
|
16302
16302
|
avgCostPerConversation: "Costo promedio por conversación",
|
|
16303
16303
|
avgRating: "Calificación promedio",
|
|
16304
16304
|
placeholderTopics: "Temas",
|
|
16305
|
-
placeholderUsers: "Usuarios",
|
|
16306
16305
|
clearAll: "Limpiar todo",
|
|
16307
16306
|
ariaTotalConversations: "Total de conversaciones transcritas",
|
|
16308
16307
|
conversations: "conversaciones",
|
|
@@ -16387,6 +16386,7 @@ var analyticsStatCard$1 = {
|
|
|
16387
16386
|
var analyticsUserFilterSelect$1 = {
|
|
16388
16387
|
filterByUser: "Filtrar por usuario",
|
|
16389
16388
|
you: "Tú",
|
|
16389
|
+
allUsers: "Todos los usuarios",
|
|
16390
16390
|
searchPlaceholder: "Buscar usuarios…",
|
|
16391
16391
|
noUsersFound: "No se encontraron usuarios.",
|
|
16392
16392
|
loadingUsers: "Cargando usuarios…"
|
|
@@ -23323,7 +23323,6 @@ var analyticsAnalyticsTranscriptsStats = {
|
|
|
23323
23323
|
avgCostPerConversation: "每次对话平均费用",
|
|
23324
23324
|
avgRating: "平均评分",
|
|
23325
23325
|
placeholderTopics: "主题",
|
|
23326
|
-
placeholderUsers: "用户",
|
|
23327
23326
|
clearAll: "清除全部",
|
|
23328
23327
|
ariaTotalConversations: "对话记录总数",
|
|
23329
23328
|
conversations: "次对话",
|
|
@@ -23408,6 +23407,7 @@ var analyticsStatCard = {
|
|
|
23408
23407
|
var analyticsUserFilterSelect = {
|
|
23409
23408
|
filterByUser: "按用户筛选",
|
|
23410
23409
|
you: "我",
|
|
23410
|
+
allUsers: "所有用户",
|
|
23411
23411
|
searchPlaceholder: "搜索用户…",
|
|
23412
23412
|
noUsersFound: "未找到用户。",
|
|
23413
23413
|
loadingUsers: "正在加载用户…"
|
|
@@ -228367,6 +228367,115 @@ const useTranscripts = ({ tenantKey, mentorId, usergroupIds, }) => {
|
|
|
228367
228367
|
};
|
|
228368
228368
|
};
|
|
228369
228369
|
|
|
228370
|
+
const USERS_PAGE_SIZE = 50;
|
|
228371
|
+
const SEARCH_DEBOUNCE_MS = 300;
|
|
228372
|
+
/** cmdk needs a non-empty value; the handler treats this one as "clear". */
|
|
228373
|
+
const SELF_VALUE = '__self__';
|
|
228374
|
+
/**
|
|
228375
|
+
* RBAC action a watcher must hold on a user for their memories to be listable —
|
|
228376
|
+
* the same one the memory endpoints check, so the dropdown can't offer a user
|
|
228377
|
+
* whose memories would then come back 403.
|
|
228378
|
+
*/
|
|
228379
|
+
const MEMORY_LIST_ACTION = 'Ibl.Mentor/Memory/list';
|
|
228380
|
+
function useDebouncedValue(value, delay) {
|
|
228381
|
+
const [debounced, setDebounced] = useState(value);
|
|
228382
|
+
useEffect(() => {
|
|
228383
|
+
const timer = setTimeout(() => setDebounced(value), delay);
|
|
228384
|
+
return () => clearTimeout(timer);
|
|
228385
|
+
}, [value, delay]);
|
|
228386
|
+
return debounced;
|
|
228387
|
+
}
|
|
228388
|
+
/**
|
|
228389
|
+
* Tenant user picker for the analytics filter rows — memory and transcripts.
|
|
228390
|
+
* Both endpoints behind it do the searching, so the dropdown only pages in the
|
|
228391
|
+
* first {@link USERS_PAGE_SIZE} matches for whatever is typed rather than
|
|
228392
|
+
* filtering client-side.
|
|
228393
|
+
*
|
|
228394
|
+
* Which endpoint serves the list depends on the caller:
|
|
228395
|
+
* - Admins get `GET /api/core/platform/users/` — every user on the tenant.
|
|
228396
|
+
* - Pure watchers get `GET /api/core/users/accessible/`, which the platform
|
|
228397
|
+
* endpoint would 403 for. It returns only the users they hold
|
|
228398
|
+
* {@link MEMORY_LIST_ACTION} on, i.e. the members of the groups they watch.
|
|
228399
|
+
*/
|
|
228400
|
+
function UserFilterSelect({ tenantKey, currentUsername, value, onChange, showSelfOption = true, className, }) {
|
|
228401
|
+
const t = useT();
|
|
228402
|
+
const [open, setOpen] = useState(false);
|
|
228403
|
+
const [search, setSearch] = useState('');
|
|
228404
|
+
const debouncedSearch = useDebouncedValue(search, SEARCH_DEBOUNCE_MS);
|
|
228405
|
+
const { currentTenant } = useCurrentTenant();
|
|
228406
|
+
const rbacPermissions = useSelector(selectRbacPermissions);
|
|
228407
|
+
const isWatcher = isPureWatcher(rbacPermissions, currentTenant);
|
|
228408
|
+
// Only fetched once the dropdown is open — the trigger shows the selected
|
|
228409
|
+
// username, which is the filter value itself, so nothing needs looking up
|
|
228410
|
+
// first.
|
|
228411
|
+
const { data, isFetching: isFetchingPlatformUsers } = usePlatformUsersQuery({
|
|
228412
|
+
platform_key: tenantKey,
|
|
228413
|
+
platform_org: tenantKey,
|
|
228414
|
+
page: 1,
|
|
228415
|
+
page_size: USERS_PAGE_SIZE,
|
|
228416
|
+
query: debouncedSearch,
|
|
228417
|
+
return_policies: 'false',
|
|
228418
|
+
}, { skip: !open || !tenantKey || isWatcher });
|
|
228419
|
+
// The accessible endpoint scopes itself to the caller's platform from their
|
|
228420
|
+
// token, so it takes no tenant param. It also filters per field instead of
|
|
228421
|
+
// with one search param, hence the "@" routing the term to `email` and
|
|
228422
|
+
// anything else to `username`.
|
|
228423
|
+
const { data: accessibleUsers, isFetching: isFetchingAccessibleUsers } = useGetAccessibleUsersQuery({
|
|
228424
|
+
required_action: MEMORY_LIST_ACTION,
|
|
228425
|
+
page: 1,
|
|
228426
|
+
page_size: USERS_PAGE_SIZE,
|
|
228427
|
+
sort: 'name',
|
|
228428
|
+
...(debouncedSearch.includes('@')
|
|
228429
|
+
? { email: debouncedSearch }
|
|
228430
|
+
: { username: debouncedSearch }),
|
|
228431
|
+
}, { skip: !open || !isWatcher });
|
|
228432
|
+
const isFetching = isWatcher ? isFetchingAccessibleUsers : isFetchingPlatformUsers;
|
|
228433
|
+
const users = useMemo(() => {
|
|
228434
|
+
var _a, _b;
|
|
228435
|
+
let list;
|
|
228436
|
+
if (isWatcher) {
|
|
228437
|
+
list = ((_a = accessibleUsers === null || accessibleUsers === void 0 ? void 0 : accessibleUsers.results) !== null && _a !== void 0 ? _a : []).map((user) => ({
|
|
228438
|
+
key: String(user.id),
|
|
228439
|
+
username: user.username,
|
|
228440
|
+
name: user.name,
|
|
228441
|
+
email: user.email,
|
|
228442
|
+
}));
|
|
228443
|
+
}
|
|
228444
|
+
else {
|
|
228445
|
+
// `results` is a bare array unless policies were requested, in which case
|
|
228446
|
+
// the users sit under `results.data`.
|
|
228447
|
+
const results = data === null || data === void 0 ? void 0 : data.results;
|
|
228448
|
+
const platformUsers = Array.isArray(results)
|
|
228449
|
+
? results
|
|
228450
|
+
: ((_b = results === null || results === void 0 ? void 0 : results.data) !== null && _b !== void 0 ? _b : []);
|
|
228451
|
+
list = platformUsers.map((user) => {
|
|
228452
|
+
var _a;
|
|
228453
|
+
return ({
|
|
228454
|
+
key: String((_a = user.user_id) !== null && _a !== void 0 ? _a : user.username),
|
|
228455
|
+
username: user.username,
|
|
228456
|
+
name: user.name,
|
|
228457
|
+
email: user.email,
|
|
228458
|
+
});
|
|
228459
|
+
});
|
|
228460
|
+
}
|
|
228461
|
+
return list.filter(
|
|
228462
|
+
// Usernames are the filter values, so a user without one is unselectable,
|
|
228463
|
+
// and the caller is dropped only when the "You" entry already stands for
|
|
228464
|
+
// them at the top of the list.
|
|
228465
|
+
(user) => !!user.username && !(showSelfOption && user.username === currentUsername));
|
|
228466
|
+
}, [isWatcher, accessibleUsers, data, currentUsername, showSelfOption]);
|
|
228467
|
+
const handleSelect = (username) => {
|
|
228468
|
+
onChange(username);
|
|
228469
|
+
setOpen(false);
|
|
228470
|
+
};
|
|
228471
|
+
return (jsxs(Popover, { open: open, onOpenChange: setOpen, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", role: "combobox", "aria-expanded": open, "aria-label": t('analyticsUserFilterSelect.filterByUser'), className: cn('h-9 w-full justify-between bg-white font-normal', className), children: [jsx("span", { className: "truncate", children: value ||
|
|
228472
|
+
t(showSelfOption
|
|
228473
|
+
? 'analyticsUserFilterSelect.you'
|
|
228474
|
+
: 'analyticsUserFilterSelect.allUsers') }), jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), jsx(PopoverContent, { "data-iblai-dialog-interaction-layer": true, className: "z-[60] w-[280px] p-0", align: "start", children: jsxs(Command, { shouldFilter: false, children: [jsx(CommandInput, { value: search, onValueChange: setSearch, placeholder: t('analyticsUserFilterSelect.searchPlaceholder') }), jsxs(CommandList, { children: [jsxs(CommandGroup, { children: [showSelfOption && (jsxs(CommandItem, { value: SELF_VALUE, onSelect: () => handleSelect(''), children: [jsx(Check, { className: cn('mr-2 h-4 w-4', value ? 'opacity-0' : 'opacity-100') }), t('analyticsUserFilterSelect.you')] })), users.map((user) => (jsxs(CommandItem, {
|
|
228475
|
+
// cmdk keys items by value; the search itself is server-side.
|
|
228476
|
+
value: user.username, onSelect: () => handleSelect(user.username), children: [jsx(Check, { className: cn('mr-2 h-4 w-4', value === user.username ? 'opacity-100' : 'opacity-0') }), jsxs("div", { className: "flex min-w-0 flex-col", children: [jsx("span", { className: "truncate font-medium", children: user.name || user.username }), jsx("span", { className: "truncate text-xs text-gray-500", children: user.email || user.username })] })] }, user.key)))] }), isFetching && (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-500", children: t('analyticsUserFilterSelect.loadingUsers') })), !isFetching && users.length === 0 && (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-500", children: t('analyticsUserFilterSelect.noUsersFound') }))] })] }) })] }));
|
|
228477
|
+
}
|
|
228478
|
+
|
|
228370
228479
|
// Utility function to format relative time
|
|
228371
228480
|
const formatRelativeTime = (dateString, t) => {
|
|
228372
228481
|
const date = new Date(dateString);
|
|
@@ -228405,8 +228514,14 @@ const getMessageContent = (content) => {
|
|
|
228405
228514
|
}
|
|
228406
228515
|
return '';
|
|
228407
228516
|
};
|
|
228517
|
+
/**
|
|
228518
|
+
* Label for whoever a transcript belongs to. The analytics payload carries an
|
|
228519
|
+
* email only on newer deployments, so it wins where present and the display
|
|
228520
|
+
* name / username stand in behind it.
|
|
228521
|
+
*/
|
|
228522
|
+
const identifyUser = (...candidates) => candidates.find((candidate) => !!candidate) || '-';
|
|
228408
228523
|
function AnalyticsTranscriptsStats({ tenantKey, mentorId, selectedMentorId, usergroupIds, }) {
|
|
228409
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
228524
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
228410
228525
|
const t = useT();
|
|
228411
228526
|
const currentMentorId = useScopedMentorId(selectedMentorId, mentorId);
|
|
228412
228527
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
@@ -228515,18 +228630,18 @@ function AnalyticsTranscriptsStats({ tenantKey, mentorId, selectedMentorId, user
|
|
|
228515
228630
|
};
|
|
228516
228631
|
// Transcript Detail Component (reusable for both desktop and mobile)
|
|
228517
228632
|
const TranscriptDetail = ({ className = '' }) => {
|
|
228518
|
-
var _a, _b, _c, _d, _e, _f;
|
|
228633
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
228519
228634
|
return (jsx("div", { className: cn('h-full flex flex-col', className), children: !selectedTranscript ? (jsx("div", { className: "flex items-center justify-center h-full text-gray-400", children: jsxs("div", { className: "text-center", children: [jsx(ArrowLeft, { className: "h-6 w-6 mx-auto mb-2" }), jsx("p", { children: t('analyticsAnalyticsTranscriptsStats.selectConversation') })] }) })) : isLoadingTranscriptsMessagesDetailsData ? (
|
|
228520
228635
|
/* Loading state */
|
|
228521
228636
|
jsx("div", { className: "flex items-center justify-center h-full text-gray-400", children: jsxs("div", { className: "text-center", children: [jsx("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mx-auto mb-3", "aria-hidden": "true" }), jsx("p", { children: t('analyticsAnalyticsTranscriptsStats.loadingTranscript') })] }) })) : isErrorTranscriptsMessagesDetailsData || !transcriptsMessagesDetailsData ? (
|
|
228522
228637
|
/* Error or no data state */
|
|
228523
228638
|
jsx("div", { className: "flex items-center justify-center h-full text-gray-400", children: jsxs("div", { className: "text-center", children: [jsx(X$1, { className: "h-6 w-6 mx-auto mb-2 text-red-400" }), jsx("p", { children: t('analyticsAnalyticsTranscriptsStats.noTranscriptDetails') }), jsx("p", { className: "text-sm mt-1", children: t('analyticsAnalyticsTranscriptsStats.unableToLoadTranscript') })] }) })) : (
|
|
228524
228639
|
/* Data loaded successfully */
|
|
228525
|
-
jsxs(Fragment$1, { children: [jsxs("div", { className: "mb-4 flex-shrink-0", children: [jsx("h2", { className: "text-lg font-semibold mb-2", children: t('analyticsAnalyticsTranscriptsStats.conversationTranscript') }), jsxs("div", { className: "text-sm text-gray-500", children: [jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelFullName'), ' ', ((_a = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _a === void 0 ? void 0 : _a.
|
|
228640
|
+
jsxs(Fragment$1, { children: [jsxs("div", { className: "mb-4 flex-shrink-0", children: [jsx("h2", { className: "text-lg font-semibold mb-2", children: t('analyticsAnalyticsTranscriptsStats.conversationTranscript') }), jsxs("div", { className: "text-sm text-gray-500", children: [jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelFullName'), ' ', identifyUser((_a = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _a === void 0 ? void 0 : _a.email, (_b = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _b === void 0 ? void 0 : _b.name)] }), jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelUsername'), ' ', identifyUser((_c = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _c === void 0 ? void 0 : _c.email, (_d = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _d === void 0 ? void 0 : _d.username)] }), jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelAgent'), ' ', ((_e = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _e === void 0 ? void 0 : _e.mentor) || '-'] }), jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelModel'), ' ', ((_f = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _f === void 0 ? void 0 : _f.model) || '-'] })] })] }), jsx("div", { className: "flex-1 overflow-y-auto space-y-4 min-h-0", children: ((_g = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.messages) === null || _g === void 0 ? void 0 : _g.length) > 0 ? ((_h = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.messages) === null || _h === void 0 ? void 0 : _h.map((message, index) => (jsxs(React__default.Fragment, { children: [(message === null || message === void 0 ? void 0 : message.human) && (jsxs("div", { className: `p-3 rounded-lg bg-blue-100 ml-4`, children: [jsx("div", { className: "flex justify-between items-start mb-1", children: jsx("span", { className: "font-medium text-sm", children: t('analyticsAnalyticsTranscriptsStats.roleUser') }) }), jsx("p", { className: "text-sm", children: getMessageContent(message.human) })] }, `${index}-human`)), (message === null || message === void 0 ? void 0 : message.ai) && (jsxs("div", { className: `p-3 rounded-lg bg-white mr-4`, children: [jsx("div", { className: "flex justify-between items-start mb-1", children: jsx("span", { className: "font-medium text-sm", children: t('analyticsAnalyticsTranscriptsStats.roleAgent') }) }), jsx(Markdown, { children: getMessageContent(message.ai) })] }, `${index}-ai`))] }, index)))) : (jsx("div", { className: "text-center text-gray-500 py-8", children: jsx("p", { children: t('analyticsAnalyticsTranscriptsStats.noMessages') }) })) })] })) }));
|
|
228526
228641
|
};
|
|
228527
228642
|
return (jsxs("div", { className: "space-y-8", children: [jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-6", children: [jsx(StatCard, { title: t('analyticsAnalyticsTranscriptsStats.avgMessagesPerConversation'), value: ((_a = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_messages_per_conversation) === null || _a === void 0 ? void 0 : _a.value) || 0, percentage: ((_b = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_messages_per_conversation) === null || _b === void 0 ? void 0 : _b.percentage_change) ||
|
|
228528
228643
|
undefined, loading: isLoadingTranscriptsConversationHeadlineData, description: t('analyticsAnalyticsTranscriptsStats.avgMessagesPerConversationDescription') }), jsx(StatCard, { title: t('analyticsAnalyticsTranscriptsStats.avgCostPerConversation'), value: Number(((_c = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_cost_per_conversation) === null || _c === void 0 ? void 0 : _c.value) || 0).toFixed(2), percentage: ((_d = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_cost_per_conversation) === null || _d === void 0 ? void 0 : _d.percentage_change) ||
|
|
228529
|
-
undefined, showDollarSign: true, loading: isLoadingTranscriptsConversationHeadlineData, description: t('analyticsAnalyticsTranscriptsStats.avgCostPerConversationDescription') }), jsx(StatCard, { title: t('analyticsAnalyticsTranscriptsStats.avgRating'), value: ((_e = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_rating) === null || _e === void 0 ? void 0 : _e.value) || 0, percentage: ((_f = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_rating) === null || _f === void 0 ? void 0 : _f.percentage_change) || undefined, loading: isLoadingTranscriptsConversationHeadlineData, description: t('analyticsAnalyticsTranscriptsStats.avgRatingDescription') })] }), jsxs("div", { className: "flex h-[calc(100vh-120px)]", children: [jsxs("div", { className: "w-full md:w-2/3 md:pr-6 overflow-y-auto md:border-r border-gray-200 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: [jsx("div", { className: "mb-6", children: jsxs("div", { className: "flex gap-2 mb-4 items-center", children: [jsxs("div", { className: "relative", children: [jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" }), jsx(Input, { placeholder: t('analyticsAnalyticsTranscriptsStats.placeholderTopics'), value: filters.topicSearch, onChange: (e) => setFilters({ ...filters, topicSearch: e.target.value }), className: "pl-10 w-[200px]" })] }),
|
|
228644
|
+
undefined, showDollarSign: true, loading: isLoadingTranscriptsConversationHeadlineData, description: t('analyticsAnalyticsTranscriptsStats.avgCostPerConversationDescription') }), jsx(StatCard, { title: t('analyticsAnalyticsTranscriptsStats.avgRating'), value: ((_e = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_rating) === null || _e === void 0 ? void 0 : _e.value) || 0, percentage: ((_f = transcriptsConversationHeadlineData === null || transcriptsConversationHeadlineData === void 0 ? void 0 : transcriptsConversationHeadlineData.avg_rating) === null || _f === void 0 ? void 0 : _f.percentage_change) || undefined, loading: isLoadingTranscriptsConversationHeadlineData, description: t('analyticsAnalyticsTranscriptsStats.avgRatingDescription') })] }), jsxs("div", { className: "flex h-[calc(100vh-120px)]", children: [jsxs("div", { className: "w-full md:w-2/3 md:pr-6 overflow-y-auto md:border-r border-gray-200 [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: [jsx("div", { className: "mb-6", children: jsxs("div", { className: "flex gap-2 mb-4 items-center", children: [jsxs("div", { className: "relative", children: [jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" }), jsx(Input, { placeholder: t('analyticsAnalyticsTranscriptsStats.placeholderTopics'), value: filters.topicSearch, onChange: (e) => setFilters({ ...filters, topicSearch: e.target.value }), className: "pl-10 w-[200px]" })] }), jsx("div", { className: "w-[200px]", children: jsx(UserFilterSelect, { tenantKey: tenantKey, value: filters.userSearch, onChange: (username) => setFilters({ ...filters, userSearch: username }), showSelfOption: false, className: "bg-transparent" }) }), isFetchingTranscriptsMessagesData && (filters.userSearch || filters.topicSearch) ? (jsx("div", { className: "animate-spin rounded-full h-5 w-5 border-b-2 border-blue-500 ml-2", "aria-hidden": "true" })) : (jsx(Button$1, { variant: "outline", onClick: handleClearFilters, className: "whitespace-nowrap", children: t('analyticsAnalyticsTranscriptsStats.clearAll') }))] }) }), jsxs("div", { className: "bg-gray-50 p-4 rounded-lg mb-6", children: [jsxs("div", { className: "flex flex-wrap gap-x-8 gap-y-2 text-sm text-gray-600", children: [jsxs("div", { "aria-label": t('analyticsAnalyticsTranscriptsStats.ariaTotalConversations'), children: [transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.summary.total_conversations, ' ', t('analyticsAnalyticsTranscriptsStats.conversations')] }), jsx("div", { children: "\u2022" }), jsxs("div", { children: [transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.summary.user_queries, ' ', t('analyticsAnalyticsTranscriptsStats.userQueries')] }), jsx("div", { children: "\u2022" }), jsxs("div", { children: [transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.summary.assistant_responses, ' ', t('analyticsAnalyticsTranscriptsStats.assistantResponses')] })] }), jsx("div", { className: "flex flex-wrap gap-x-8 gap-y-2 text-sm text-gray-600 mt-2", children: jsxs("div", { children: [transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.summary.average_sentiment_score, ' ', t('analyticsAnalyticsTranscriptsStats.averageSentimentScore')] }) })] }), jsx("div", { className: "flex flex-col gap-4", children: isLoadingTranscriptsMessagesData ? (
|
|
228530
228645
|
// Loading state
|
|
228531
228646
|
jsx("div", { className: "space-y-4", children: Array.from({ length: 3 }).map((_, index) => (jsxs(Card, { className: "p-4 animate-pulse", children: [jsx("div", { className: "mb-3", children: jsx("div", { className: "h-4 bg-gray-200 rounded w-3/4" }) }), jsxs("div", { className: "flex flex-wrap gap-2 mb-3", children: [jsx("div", { className: "h-6 bg-gray-200 rounded w-16" }), jsx("div", { className: "h-6 bg-gray-200 rounded w-20" })] }), jsxs("div", { className: "flex flex-wrap gap-x-6 gap-y-2 mb-2", children: [jsx("div", { className: "h-4 bg-gray-200 rounded w-24" }), jsx("div", { className: "h-4 bg-gray-200 rounded w-20" })] }), jsxs("div", { className: "flex flex-wrap gap-x-6 gap-y-2", children: [jsx("div", { className: "h-4 bg-gray-200 rounded w-20" }), jsx("div", { className: "h-4 bg-gray-200 rounded w-24" })] })] }, index))) })) : (transcriptsMessagesData === null || transcriptsMessagesData === void 0 ? void 0 : transcriptsMessagesData.results) && transcriptsMessagesData.results.length > 0 ? (
|
|
228532
228647
|
// Results
|
|
@@ -228543,7 +228658,7 @@ function AnalyticsTranscriptsStats({ tenantKey, mentorId, selectedMentorId, user
|
|
|
228543
228658
|
? t('analyticsAnalyticsTranscriptsStats.sentimentNegative')
|
|
228544
228659
|
: transcript.sentiment === 'positive'
|
|
228545
228660
|
? t('analyticsAnalyticsTranscriptsStats.sentimentPositive')
|
|
228546
|
-
: t('analyticsAnalyticsTranscriptsStats.sentimentNeutral'), ' ', t('analyticsAnalyticsTranscriptsStats.userSentiment')] })] }) }), jsxs("div", { className: "flex flex-wrap gap-x-6 gap-y-2 text-xs text-gray-500 mb-2", children: [jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelUser'), ' ', (transcript === null || transcript === void 0 ? void 0 : transcript.
|
|
228661
|
+
: t('analyticsAnalyticsTranscriptsStats.sentimentNeutral'), ' ', t('analyticsAnalyticsTranscriptsStats.userSentiment')] })] }) }), jsxs("div", { className: "flex flex-wrap gap-x-6 gap-y-2 text-xs text-gray-500 mb-2", children: [jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelUser'), ' ', identifyUser(transcript === null || transcript === void 0 ? void 0 : transcript.email, transcript === null || transcript === void 0 ? void 0 : transcript.name, transcript === null || transcript === void 0 ? void 0 : transcript.username)] }), jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelAgent'), ' ', (transcript === null || transcript === void 0 ? void 0 : transcript.mentor) || '-'] })] }), jsxs("div", { className: "flex flex-wrap gap-x-6 gap-y-2 text-xs text-gray-500 mb-2", children: [jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelModelCard'), ' ', (transcript === null || transcript === void 0 ? void 0 : transcript.model) || '-'] }), jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelUserId'), ' ', identifyUser(transcript === null || transcript === void 0 ? void 0 : transcript.email, transcript === null || transcript === void 0 ? void 0 : transcript.username)] })] }), jsxs("div", { className: "flex flex-wrap gap-x-6 gap-y-2 text-xs text-gray-500", children: [jsxs("div", { children: [transcript.message_count, " ", t('analyticsAnalyticsTranscriptsStats.messages')] }), jsx("div", { children: "\u2022" }), jsxs("div", { children: ["$", Number((transcript === null || transcript === void 0 ? void 0 : transcript.cost) || 0).toFixed(2), ' ', t('analyticsAnalyticsTranscriptsStats.estimatedCost')] }), (transcript === null || transcript === void 0 ? void 0 : transcript.created_at) && (jsxs(Fragment$1, { children: [jsx("div", { children: "\u2022" }), jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.created'), ' ', formatRelativeTime(transcript.created_at, t)] })] }))] })] }, transcript.session));
|
|
228547
228662
|
})) : (
|
|
228548
228663
|
// Empty state
|
|
228549
228664
|
jsx("div", { className: "text-center py-12", children: jsx("p", { className: "text-gray-500", children: filters.topicSearch || filters.userSearch || filters.rating
|
|
@@ -228579,7 +228694,7 @@ function AnalyticsTranscriptsStats({ tenantKey, mentorId, selectedMentorId, user
|
|
|
228579
228694
|
/* Error or no data state */
|
|
228580
228695
|
jsx("div", { className: "flex items-center justify-center h-full text-gray-400", children: jsxs("div", { className: "text-center", children: [jsx(X$1, { className: "h-6 w-6 mx-auto mb-2 text-red-400" }), jsx("p", { children: t('analyticsAnalyticsTranscriptsStats.noTranscriptDetails') }), jsx("p", { className: "text-sm mt-1", children: t('analyticsAnalyticsTranscriptsStats.unableToLoadTranscript') })] }) })) : (
|
|
228581
228696
|
/* Data loaded successfully */
|
|
228582
|
-
jsxs("div", { className: "space-y-4", children: [jsx("div", { className: "mb-4", children: jsxs("div", { className: "text-sm text-gray-500 space-y-1", children: [jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelFullName'), ' ', ((_g = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _g === void 0 ? void 0 : _g.
|
|
228697
|
+
jsxs("div", { className: "space-y-4", children: [jsx("div", { className: "mb-4", children: jsxs("div", { className: "text-sm text-gray-500 space-y-1", children: [jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelFullName'), ' ', identifyUser((_g = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _g === void 0 ? void 0 : _g.email, (_h = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _h === void 0 ? void 0 : _h.name)] }), jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelUsername'), ' ', identifyUser((_j = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _j === void 0 ? void 0 : _j.email, (_k = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _k === void 0 ? void 0 : _k.username)] }), jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelAgent'), ' ', ((_l = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _l === void 0 ? void 0 : _l.mentor) || '-'] }), jsxs("div", { children: [t('analyticsAnalyticsTranscriptsStats.labelModel'), ' ', ((_m = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.summary) === null || _m === void 0 ? void 0 : _m.model) || '-'] })] }) }), jsx("div", { className: "space-y-4 pb-4", children: ((_o = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.messages) === null || _o === void 0 ? void 0 : _o.length) > 0 ? ((_p = transcriptsMessagesDetailsData === null || transcriptsMessagesDetailsData === void 0 ? void 0 : transcriptsMessagesDetailsData.messages) === null || _p === void 0 ? void 0 : _p.map((message, index) => (jsxs(React__default.Fragment, { children: [(message === null || message === void 0 ? void 0 : message.human) && (jsxs("div", { className: "p-3 rounded-lg bg-blue-100 ml-4", children: [jsx("div", { className: "flex justify-between items-start mb-1", children: jsx("span", { className: "font-medium text-sm", children: t('analyticsAnalyticsTranscriptsStats.roleUser') }) }), jsx("p", { className: "text-sm", children: getMessageContent(message.human) })] })), (message === null || message === void 0 ? void 0 : message.ai) && (jsxs("div", { className: "p-3 rounded-lg bg-white mr-4 border", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx("div", { className: "flex justify-between items-start mb-1", children: jsx("span", { className: "font-medium text-sm", children: t('analyticsAnalyticsTranscriptsStats.roleAgent') }) }), jsx(Markdown, { children: getMessageContent(message.ai) })] }))] }, index)))) : (jsx("div", { className: "text-center text-gray-500 py-8", children: jsx("p", { children: t('analyticsAnalyticsTranscriptsStats.noMessages') }) })) })] })) })] }) }))] }));
|
|
228583
228698
|
}
|
|
228584
228699
|
|
|
228585
228700
|
const phaseConfig = {
|
|
@@ -231210,111 +231325,6 @@ function MentorSelectionGrid({ selectedMentorIds, onMentorSelect, searchQuery, o
|
|
|
231210
231325
|
})) }), jsx(IblPagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: handlePageChange, disabled: isMentorsFetching || isMentorsLoading })] })] }));
|
|
231211
231326
|
}
|
|
231212
231327
|
|
|
231213
|
-
const USERS_PAGE_SIZE = 50;
|
|
231214
|
-
const SEARCH_DEBOUNCE_MS = 300;
|
|
231215
|
-
/** cmdk needs a non-empty value; the handler treats this one as "clear". */
|
|
231216
|
-
const SELF_VALUE = '__self__';
|
|
231217
|
-
/**
|
|
231218
|
-
* RBAC action a watcher must hold on a user for their memories to be listable —
|
|
231219
|
-
* the same one the memory endpoints check, so the dropdown can't offer a user
|
|
231220
|
-
* whose memories would then come back 403.
|
|
231221
|
-
*/
|
|
231222
|
-
const MEMORY_LIST_ACTION = 'Ibl.Mentor/Memory/list';
|
|
231223
|
-
function useDebouncedValue(value, delay) {
|
|
231224
|
-
const [debounced, setDebounced] = useState(value);
|
|
231225
|
-
useEffect(() => {
|
|
231226
|
-
const timer = setTimeout(() => setDebounced(value), delay);
|
|
231227
|
-
return () => clearTimeout(timer);
|
|
231228
|
-
}, [value, delay]);
|
|
231229
|
-
return debounced;
|
|
231230
|
-
}
|
|
231231
|
-
/**
|
|
231232
|
-
* Tenant user picker for the analytics memory filters. Both endpoints behind it
|
|
231233
|
-
* do the searching, so the dropdown only pages in the first
|
|
231234
|
-
* {@link USERS_PAGE_SIZE} matches for whatever is typed rather than filtering
|
|
231235
|
-
* client-side.
|
|
231236
|
-
*
|
|
231237
|
-
* Which endpoint serves the list depends on the caller:
|
|
231238
|
-
* - Admins get `GET /api/core/platform/users/` — every user on the tenant.
|
|
231239
|
-
* - Pure watchers get `GET /api/core/users/accessible/`, which the platform
|
|
231240
|
-
* endpoint would 403 for. It returns only the users they hold
|
|
231241
|
-
* {@link MEMORY_LIST_ACTION} on, i.e. the members of the groups they watch.
|
|
231242
|
-
*/
|
|
231243
|
-
function UserFilterSelect({ tenantKey, currentUsername, value, onChange, }) {
|
|
231244
|
-
const t = useT();
|
|
231245
|
-
const [open, setOpen] = useState(false);
|
|
231246
|
-
const [search, setSearch] = useState('');
|
|
231247
|
-
const debouncedSearch = useDebouncedValue(search, SEARCH_DEBOUNCE_MS);
|
|
231248
|
-
const { currentTenant } = useCurrentTenant();
|
|
231249
|
-
const rbacPermissions = useSelector(selectRbacPermissions);
|
|
231250
|
-
const isWatcher = isPureWatcher(rbacPermissions, currentTenant);
|
|
231251
|
-
// Only fetched once the dropdown is open — the trigger shows the selected
|
|
231252
|
-
// username, which is the filter value itself, so nothing needs looking up
|
|
231253
|
-
// first.
|
|
231254
|
-
const { data, isFetching: isFetchingPlatformUsers } = usePlatformUsersQuery({
|
|
231255
|
-
platform_key: tenantKey,
|
|
231256
|
-
platform_org: tenantKey,
|
|
231257
|
-
page: 1,
|
|
231258
|
-
page_size: USERS_PAGE_SIZE,
|
|
231259
|
-
query: debouncedSearch,
|
|
231260
|
-
return_policies: 'false',
|
|
231261
|
-
}, { skip: !open || !tenantKey || isWatcher });
|
|
231262
|
-
// The accessible endpoint scopes itself to the caller's platform from their
|
|
231263
|
-
// token, so it takes no tenant param. It also filters per field instead of
|
|
231264
|
-
// with one search param, hence the "@" routing the term to `email` and
|
|
231265
|
-
// anything else to `username`.
|
|
231266
|
-
const { data: accessibleUsers, isFetching: isFetchingAccessibleUsers } = useGetAccessibleUsersQuery({
|
|
231267
|
-
required_action: MEMORY_LIST_ACTION,
|
|
231268
|
-
page: 1,
|
|
231269
|
-
page_size: USERS_PAGE_SIZE,
|
|
231270
|
-
sort: 'name',
|
|
231271
|
-
...(debouncedSearch.includes('@')
|
|
231272
|
-
? { email: debouncedSearch }
|
|
231273
|
-
: { username: debouncedSearch }),
|
|
231274
|
-
}, { skip: !open || !isWatcher });
|
|
231275
|
-
const isFetching = isWatcher ? isFetchingAccessibleUsers : isFetchingPlatformUsers;
|
|
231276
|
-
const users = useMemo(() => {
|
|
231277
|
-
var _a, _b;
|
|
231278
|
-
let list;
|
|
231279
|
-
if (isWatcher) {
|
|
231280
|
-
list = ((_a = accessibleUsers === null || accessibleUsers === void 0 ? void 0 : accessibleUsers.results) !== null && _a !== void 0 ? _a : []).map((user) => ({
|
|
231281
|
-
key: String(user.id),
|
|
231282
|
-
username: user.username,
|
|
231283
|
-
name: user.name,
|
|
231284
|
-
email: user.email,
|
|
231285
|
-
}));
|
|
231286
|
-
}
|
|
231287
|
-
else {
|
|
231288
|
-
// `results` is a bare array unless policies were requested, in which case
|
|
231289
|
-
// the users sit under `results.data`.
|
|
231290
|
-
const results = data === null || data === void 0 ? void 0 : data.results;
|
|
231291
|
-
const platformUsers = Array.isArray(results)
|
|
231292
|
-
? results
|
|
231293
|
-
: ((_b = results === null || results === void 0 ? void 0 : results.data) !== null && _b !== void 0 ? _b : []);
|
|
231294
|
-
list = platformUsers.map((user) => {
|
|
231295
|
-
var _a;
|
|
231296
|
-
return ({
|
|
231297
|
-
key: String((_a = user.user_id) !== null && _a !== void 0 ? _a : user.username),
|
|
231298
|
-
username: user.username,
|
|
231299
|
-
name: user.name,
|
|
231300
|
-
email: user.email,
|
|
231301
|
-
});
|
|
231302
|
-
});
|
|
231303
|
-
}
|
|
231304
|
-
return list.filter(
|
|
231305
|
-
// Usernames are the filter values, so a user without one is unselectable,
|
|
231306
|
-
// and the caller already has their own entry at the top of the list.
|
|
231307
|
-
(user) => !!user.username && user.username !== currentUsername);
|
|
231308
|
-
}, [isWatcher, accessibleUsers, data, currentUsername]);
|
|
231309
|
-
const handleSelect = (username) => {
|
|
231310
|
-
onChange(username);
|
|
231311
|
-
setOpen(false);
|
|
231312
|
-
};
|
|
231313
|
-
return (jsxs(Popover, { open: open, onOpenChange: setOpen, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", role: "combobox", "aria-expanded": open, "aria-label": t('analyticsUserFilterSelect.filterByUser'), className: "h-9 w-full justify-between bg-white font-normal", children: [jsx("span", { className: "truncate", children: value || t('analyticsUserFilterSelect.you') }), jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), jsx(PopoverContent, { "data-iblai-dialog-interaction-layer": true, className: "z-[60] w-[280px] p-0", align: "start", children: jsxs(Command, { shouldFilter: false, children: [jsx(CommandInput, { value: search, onValueChange: setSearch, placeholder: t('analyticsUserFilterSelect.searchPlaceholder') }), jsxs(CommandList, { children: [jsxs(CommandGroup, { children: [jsxs(CommandItem, { value: SELF_VALUE, onSelect: () => handleSelect(''), children: [jsx(Check, { className: cn('mr-2 h-4 w-4', value ? 'opacity-0' : 'opacity-100') }), t('analyticsUserFilterSelect.you')] }), users.map((user) => (jsxs(CommandItem, {
|
|
231314
|
-
// cmdk keys items by value; the search itself is server-side.
|
|
231315
|
-
value: user.username, onSelect: () => handleSelect(user.username), children: [jsx(Check, { className: cn('mr-2 h-4 w-4', value === user.username ? 'opacity-100' : 'opacity-0') }), jsxs("div", { className: "flex min-w-0 flex-col", children: [jsx("span", { className: "truncate font-medium", children: user.name || user.username }), jsx("span", { className: "truncate text-xs text-gray-500", children: user.email || user.username })] })] }, user.key)))] }), isFetching && (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-500", children: t('analyticsUserFilterSelect.loadingUsers') })), !isFetching && users.length === 0 && (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-500", children: t('analyticsUserFilterSelect.noUsersFound') }))] })] }) })] }));
|
|
231316
|
-
}
|
|
231317
|
-
|
|
231318
231328
|
/**
|
|
231319
231329
|
* The global and cross-mentor endpoints both cap `page_size` at 25 server-side,
|
|
231320
231330
|
* so we ask for a size every scope can honor rather than paginating
|
|
@@ -97047,7 +97047,6 @@ var analyticsAnalyticsTranscriptsStats$3 = {
|
|
|
97047
97047
|
avgCostPerConversation: "Average cost per conversation",
|
|
97048
97048
|
avgRating: "Average rating",
|
|
97049
97049
|
placeholderTopics: "Topics",
|
|
97050
|
-
placeholderUsers: "Users",
|
|
97051
97050
|
clearAll: "Clear All",
|
|
97052
97051
|
ariaTotalConversations: "Total transcripts conversations",
|
|
97053
97052
|
conversations: "conversations",
|
|
@@ -97132,6 +97131,7 @@ var analyticsStatCard$3 = {
|
|
|
97132
97131
|
var analyticsUserFilterSelect$3 = {
|
|
97133
97132
|
filterByUser: "Filter by user",
|
|
97134
97133
|
you: "You",
|
|
97134
|
+
allUsers: "All users",
|
|
97135
97135
|
searchPlaceholder: "Search users…",
|
|
97136
97136
|
noUsersFound: "No users found.",
|
|
97137
97137
|
loadingUsers: "Loading users…"
|
|
@@ -104068,7 +104068,6 @@ var analyticsAnalyticsTranscriptsStats$2 = {
|
|
|
104068
104068
|
avgCostPerConversation: "Coût moyen par conversation",
|
|
104069
104069
|
avgRating: "Note moyenne",
|
|
104070
104070
|
placeholderTopics: "Sujets",
|
|
104071
|
-
placeholderUsers: "Utilisateurs",
|
|
104072
104071
|
clearAll: "Tout effacer",
|
|
104073
104072
|
ariaTotalConversations: "Total des conversations transcrites",
|
|
104074
104073
|
conversations: "conversations",
|
|
@@ -104153,6 +104152,7 @@ var analyticsStatCard$2 = {
|
|
|
104153
104152
|
var analyticsUserFilterSelect$2 = {
|
|
104154
104153
|
filterByUser: "Filtrer par utilisateur",
|
|
104155
104154
|
you: "Vous",
|
|
104155
|
+
allUsers: "Tous les utilisateurs",
|
|
104156
104156
|
searchPlaceholder: "Rechercher des utilisateurs…",
|
|
104157
104157
|
noUsersFound: "Aucun utilisateur trouvé.",
|
|
104158
104158
|
loadingUsers: "Chargement des utilisateurs…"
|
|
@@ -111089,7 +111089,6 @@ var analyticsAnalyticsTranscriptsStats$1 = {
|
|
|
111089
111089
|
avgCostPerConversation: "Costo promedio por conversación",
|
|
111090
111090
|
avgRating: "Calificación promedio",
|
|
111091
111091
|
placeholderTopics: "Temas",
|
|
111092
|
-
placeholderUsers: "Usuarios",
|
|
111093
111092
|
clearAll: "Limpiar todo",
|
|
111094
111093
|
ariaTotalConversations: "Total de conversaciones transcritas",
|
|
111095
111094
|
conversations: "conversaciones",
|
|
@@ -111174,6 +111173,7 @@ var analyticsStatCard$1 = {
|
|
|
111174
111173
|
var analyticsUserFilterSelect$1 = {
|
|
111175
111174
|
filterByUser: "Filtrar por usuario",
|
|
111176
111175
|
you: "Tú",
|
|
111176
|
+
allUsers: "Todos los usuarios",
|
|
111177
111177
|
searchPlaceholder: "Buscar usuarios…",
|
|
111178
111178
|
noUsersFound: "No se encontraron usuarios.",
|
|
111179
111179
|
loadingUsers: "Cargando usuarios…"
|
|
@@ -118110,7 +118110,6 @@ var analyticsAnalyticsTranscriptsStats = {
|
|
|
118110
118110
|
avgCostPerConversation: "每次对话平均费用",
|
|
118111
118111
|
avgRating: "平均评分",
|
|
118112
118112
|
placeholderTopics: "主题",
|
|
118113
|
-
placeholderUsers: "用户",
|
|
118114
118113
|
clearAll: "清除全部",
|
|
118115
118114
|
ariaTotalConversations: "对话记录总数",
|
|
118116
118115
|
conversations: "次对话",
|
|
@@ -118195,6 +118194,7 @@ var analyticsStatCard = {
|
|
|
118195
118194
|
var analyticsUserFilterSelect = {
|
|
118196
118195
|
filterByUser: "按用户筛选",
|
|
118197
118196
|
you: "我",
|
|
118197
|
+
allUsers: "所有用户",
|
|
118198
118198
|
searchPlaceholder: "搜索用户…",
|
|
118199
118199
|
noUsersFound: "未找到用户。",
|
|
118200
118200
|
loadingUsers: "正在加载用户…"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iblai/iblai-js",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.3",
|
|
4
4
|
"description": "Unified JavaScript SDK for IBL.ai — re-exports data-layer, web-containers, and web-utils under a single package",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
"axios": "1.13.6",
|
|
77
77
|
"dotenv": "16.6.1",
|
|
78
78
|
"winston": "3.19.0",
|
|
79
|
-
"@iblai/
|
|
80
|
-
"@iblai/
|
|
81
|
-
"@iblai/
|
|
79
|
+
"@iblai/data-layer": "1.13.2",
|
|
80
|
+
"@iblai/mcp": "1.12.7",
|
|
81
|
+
"@iblai/web-containers": "1.19.9",
|
|
82
82
|
"@iblai/web-utils": "2.4.0"
|
|
83
83
|
},
|
|
84
84
|
"peerDependencies": {
|