@iblai/iblai-js 2.3.15 → 2.4.0

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.
@@ -60579,6 +60579,14 @@ var analyticsAnalyticsAuditLogStats$3 = {
60579
60579
  colAction: "ACTION",
60580
60580
  colTime: "TIME"
60581
60581
  };
60582
+ var analyticsAnalyticsAgentPicker$3 = {
60583
+ analyticsScope: "Analytics scope",
60584
+ allAgents: "All Agents",
60585
+ agents: "Agents",
60586
+ searchAgents: "Search agents…",
60587
+ noAgentsFound: "No agents found",
60588
+ loading: "Loading…"
60589
+ };
60582
60590
  var analyticsAnalyticsCourseDetail$3 = {
60583
60591
  goBackAriaLabel: "Go back to courses list",
60584
60592
  activeEnrollments: "Active Enrollments",
@@ -66167,6 +66175,7 @@ var en = {
66167
66175
  agentSearchLabels: agentSearchLabels$3,
66168
66176
  analyticsAccessTimeHeatmap: analyticsAccessTimeHeatmap$3,
66169
66177
  analyticsAnalyticsAuditLogStats: analyticsAnalyticsAuditLogStats$3,
66178
+ analyticsAnalyticsAgentPicker: analyticsAnalyticsAgentPicker$3,
66170
66179
  analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail$3,
66171
66180
  analyticsAnalyticsCourses: analyticsAnalyticsCourses$3,
66172
66181
  analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats$3,
@@ -67043,6 +67052,14 @@ var analyticsAnalyticsAuditLogStats$2 = {
67043
67052
  colAction: "ACTION",
67044
67053
  colTime: "HEURE"
67045
67054
  };
67055
+ var analyticsAnalyticsAgentPicker$2 = {
67056
+ analyticsScope: "Portée des analyses",
67057
+ allAgents: "Tous les agents",
67058
+ agents: "Agents",
67059
+ searchAgents: "Rechercher des agents…",
67060
+ noAgentsFound: "Aucun agent trouvé",
67061
+ loading: "Chargement…"
67062
+ };
67046
67063
  var analyticsAnalyticsCourseDetail$2 = {
67047
67064
  goBackAriaLabel: "Retour à la liste des cours",
67048
67065
  activeEnrollments: "Inscriptions actives",
@@ -72631,6 +72648,7 @@ var fr = {
72631
72648
  agentSearchLabels: agentSearchLabels$2,
72632
72649
  analyticsAccessTimeHeatmap: analyticsAccessTimeHeatmap$2,
72633
72650
  analyticsAnalyticsAuditLogStats: analyticsAnalyticsAuditLogStats$2,
72651
+ analyticsAnalyticsAgentPicker: analyticsAnalyticsAgentPicker$2,
72634
72652
  analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail$2,
72635
72653
  analyticsAnalyticsCourses: analyticsAnalyticsCourses$2,
72636
72654
  analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats$2,
@@ -73507,6 +73525,14 @@ var analyticsAnalyticsAuditLogStats$1 = {
73507
73525
  colAction: "ACCIÓN",
73508
73526
  colTime: "HORA"
73509
73527
  };
73528
+ var analyticsAnalyticsAgentPicker$1 = {
73529
+ analyticsScope: "Alcance de analíticas",
73530
+ allAgents: "Todos los agentes",
73531
+ agents: "Agentes",
73532
+ searchAgents: "Buscar agentes…",
73533
+ noAgentsFound: "No se encontraron agentes",
73534
+ loading: "Cargando…"
73535
+ };
73510
73536
  var analyticsAnalyticsCourseDetail$1 = {
73511
73537
  goBackAriaLabel: "Volver a la lista de cursos",
73512
73538
  activeEnrollments: "Inscripciones activas",
@@ -79095,6 +79121,7 @@ var es = {
79095
79121
  agentSearchLabels: agentSearchLabels$1,
79096
79122
  analyticsAccessTimeHeatmap: analyticsAccessTimeHeatmap$1,
79097
79123
  analyticsAnalyticsAuditLogStats: analyticsAnalyticsAuditLogStats$1,
79124
+ analyticsAnalyticsAgentPicker: analyticsAnalyticsAgentPicker$1,
79098
79125
  analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail$1,
79099
79126
  analyticsAnalyticsCourses: analyticsAnalyticsCourses$1,
79100
79127
  analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats$1,
@@ -79971,6 +79998,14 @@ var analyticsAnalyticsAuditLogStats = {
79971
79998
  colAction: "操作",
79972
79999
  colTime: "时间"
79973
80000
  };
80001
+ var analyticsAnalyticsAgentPicker = {
80002
+ analyticsScope: "分析范围",
80003
+ allAgents: "所有智能体",
80004
+ agents: "智能体",
80005
+ searchAgents: "搜索智能体…",
80006
+ noAgentsFound: "未找到智能体",
80007
+ loading: "加载中…"
80008
+ };
79974
80009
  var analyticsAnalyticsCourseDetail = {
79975
80010
  goBackAriaLabel: "返回课程列表",
79976
80011
  activeEnrollments: "活跃注册",
@@ -85559,6 +85594,7 @@ var zh = {
85559
85594
  agentSearchLabels: agentSearchLabels,
85560
85595
  analyticsAccessTimeHeatmap: analyticsAccessTimeHeatmap,
85561
85596
  analyticsAnalyticsAuditLogStats: analyticsAnalyticsAuditLogStats,
85597
+ analyticsAnalyticsAgentPicker: analyticsAnalyticsAgentPicker,
85562
85598
  analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail,
85563
85599
  analyticsAnalyticsCourses: analyticsAnalyticsCourses,
85564
85600
  analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats,
@@ -148067,17 +148103,18 @@ function BlocksView({ platformKey, onBack, }) {
148067
148103
 
148068
148104
  const FILTER_ORDER = ['all', ...APPLICATION_STATUSES];
148069
148105
  const PAGE_SIZE$3 = 20;
148070
- const SEARCH_DEBOUNCE_MS$1 = 300;
148106
+ const SEARCH_DEBOUNCE_MS$2 = 300;
148071
148107
  /**
148072
148108
  * The public application URL on the auth SPA for one form of a platform
148073
- * (`<auth-url>/applications/<platform-key>/<form-id>?app=<spa>`), or null when
148074
- * the auth SPA URL cannot be resolved. `authSpaUrl` (prop) wins; otherwise the
148075
- * runtime-injected env (`window.__ENV__.NEXT_PUBLIC_AUTH_URL`) is used. With no
148076
- * `formId` the link resolves the platform's default form (404 when none). The
148077
- * `app` param carries the SPA the applicant is sent to after submitting;
148078
- * absent/unknown means the mentor SPA.
148079
- */
148080
- function buildApplicationLink(platformKey, formId, authSpaUrl, app) {
148109
+ * (`<auth-url>/applications/<platform-key>/<form-id>?redirect-to=<origin>`), or
148110
+ * null when the auth SPA URL cannot be resolved. `authSpaUrl` (prop) wins;
148111
+ * otherwise the runtime-injected env (`window.__ENV__.NEXT_PUBLIC_AUTH_URL`) is
148112
+ * used. With no `formId` the link resolves the platform's default form (404
148113
+ * when none). The `redirect-to` param carries the origin the applicant is sent
148114
+ * back to after submitting — by default the origin the link is copied from — and
148115
+ * is omitted when no origin can be read (no DOM).
148116
+ */
148117
+ function buildApplicationLink(platformKey, formId, authSpaUrl, redirectTo) {
148081
148118
  var _a, _b;
148082
148119
  const base = (_b = authSpaUrl !== null && authSpaUrl !== void 0 ? authSpaUrl : (typeof window !== 'undefined'
148083
148120
  ? (_a = window.__ENV__) === null || _a === void 0 ? void 0 : _a.NEXT_PUBLIC_AUTH_URL
@@ -148086,7 +148123,8 @@ function buildApplicationLink(platformKey, formId, authSpaUrl, app) {
148086
148123
  return null;
148087
148124
  const root = `${trimTrailingSlashes(base)}/applications/${encodeURIComponent(platformKey)}`;
148088
148125
  const path = formId != null ? `${root}/${encodeURIComponent(String(formId))}` : root;
148089
- return `${path}?app=${encodeURIComponent(app || 'mentor')}`;
148126
+ const target = (typeof window !== 'undefined' ? window.location.origin : undefined);
148127
+ return target ? `${path}?redirect-to=${encodeURIComponent(target)}` : path;
148090
148128
  }
148091
148129
  /**
148092
148130
  * Applications management. Entry view lists the platform's application forms
@@ -148094,7 +148132,7 @@ function buildApplicationLink(platformKey, formId, authSpaUrl, app) {
148094
148132
  * per-form (or all-form) submission pipelines, the submission workspace with
148095
148133
  * per-student decisions, the form/question editor, and the ban list.
148096
148134
  */
148097
- function ApplicationsTab({ platformKey, authSpaUrl, currentSpa, }) {
148135
+ function ApplicationsTab({ platformKey, authSpaUrl, }) {
148098
148136
  const [view, setView] = useState({ name: 'forms' });
148099
148137
  if (view.name === 'editor') {
148100
148138
  return (jsx(QuestionsEditor, { platformKey: platformKey, initialFormId: view.formId, startNew: view.startNew, onBack: () => setView({ name: 'forms' }) }));
@@ -148108,10 +148146,10 @@ function ApplicationsTab({ platformKey, authSpaUrl, currentSpa, }) {
148108
148146
  if (view.name === 'submissions') {
148109
148147
  return (jsx(SubmissionsPipeline, { platformKey: platformKey, form: view.form, onBack: () => setView({ name: 'forms' }), onOpen: (submissionId) => setView({ name: 'detail', submissionId, form: view.form }) }));
148110
148148
  }
148111
- return (jsx(FormsList, { platformKey: platformKey, authSpaUrl: authSpaUrl, currentSpa: currentSpa, onViewSubmissions: (form) => setView({ name: 'submissions', form }), onEditForm: (formId) => setView({ name: 'editor', formId, startNew: false }), onNewForm: () => setView({ name: 'editor', formId: null, startNew: true }), onViewBlocks: () => setView({ name: 'blocks' }) }));
148149
+ return (jsx(FormsList, { platformKey: platformKey, authSpaUrl: authSpaUrl, onViewSubmissions: (form) => setView({ name: 'submissions', form }), onEditForm: (formId) => setView({ name: 'editor', formId, startNew: false }), onNewForm: () => setView({ name: 'editor', formId: null, startNew: true }), onViewBlocks: () => setView({ name: 'blocks' }) }));
148112
148150
  }
148113
148151
  /** The entry view: every application form of the platform, with actions. */
148114
- function FormsList({ platformKey, authSpaUrl, currentSpa, onViewSubmissions, onEditForm, onNewForm, onViewBlocks, }) {
148152
+ function FormsList({ platformKey, authSpaUrl, onViewSubmissions, onEditForm, onNewForm, onViewBlocks, }) {
148115
148153
  const t = useT();
148116
148154
  /** The form id whose link was just copied (transient "Copied" feedback). */
148117
148155
  const [copiedFormId, setCopiedFormId] = useState(null);
@@ -148125,7 +148163,7 @@ function FormsList({ platformKey, authSpaUrl, currentSpa, onViewSubmissions, onE
148125
148163
  const counts = statsCounts(stats);
148126
148164
  const total = Object.values(counts).reduce((sum, n) => sum + n, 0);
148127
148165
  const handleCopyLink = async (form) => {
148128
- const link = buildApplicationLink(platformKey, form.id, authSpaUrl, currentSpa);
148166
+ const link = buildApplicationLink(platformKey, form.id, authSpaUrl);
148129
148167
  if (!link)
148130
148168
  return;
148131
148169
  try {
@@ -148145,7 +148183,7 @@ function FormsList({ platformKey, authSpaUrl, currentSpa, onViewSubmissions, onE
148145
148183
  ? 'bg-blue-50 text-blue-700 border-blue-200 dark:bg-blue-900/30 dark:text-blue-300 dark:border-blue-900'
148146
148184
  : 'bg-gray-100 text-gray-600 border-gray-200 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-600', children: t(form.enabled
148147
148185
  ? 'profileApplicationsTab.formEnabled'
148148
- : 'profileApplicationsTab.formDisabled') }) }), jsx("td", { className: "whitespace-nowrap px-6 py-4 text-right", children: jsxs("div", { className: "flex items-center justify-end gap-1", children: [buildApplicationLink(platformKey, form.id, authSpaUrl, currentSpa) && (jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsxs(Button$1, { variant: "ghost", className: copiedFormId === form.id
148186
+ : 'profileApplicationsTab.formDisabled') }) }), jsx("td", { className: "whitespace-nowrap px-6 py-4 text-right", children: jsxs("div", { className: "flex items-center justify-end gap-1", children: [buildApplicationLink(platformKey, form.id, authSpaUrl) && (jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsxs(Button$1, { variant: "ghost", className: copiedFormId === form.id
148149
148187
  ? 'h-8 w-8 p-0 text-blue-600 dark:text-blue-400'
148150
148188
  : 'h-8 w-8 p-0 text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-100', onClick: () => handleCopyLink(form), "aria-label": t('profileApplicationsTab.copyFormLink', {
148151
148189
  form: ((_b = form.schema) === null || _b === void 0 ? void 0 : _b.title) ||
@@ -148176,7 +148214,7 @@ function SubmissionsPipeline({ platformKey, form, onBack, onOpen, }) {
148176
148214
  const timer = setTimeout(() => {
148177
148215
  setDebouncedSearch(search.trim());
148178
148216
  setDebouncedCandidateFilter(candidateFilter.trim());
148179
- }, SEARCH_DEBOUNCE_MS$1);
148217
+ }, SEARCH_DEBOUNCE_MS$2);
148180
148218
  return () => clearTimeout(timer);
148181
148219
  }, [search, candidateFilter]);
148182
148220
  // New filters restart paging.
@@ -148256,7 +148294,7 @@ const TabDescription = ({ icon, title, children }) => {
148256
148294
  };
148257
148295
  const Admin = ({ tenant, onInviteClick, hasUserTabPermission = false, hasGroupsTabPermission = false, hasRolesTabPermission = false, hasPoliciesTabPermission = false, hasTeamsTabPermission = false, hasAlertsTabPermission = false, hasInviteUserPermission = false, hasCreateTeamPermission = false, onLoadGroupPermissions, rbacPermissions = {}, enableRbac = false, showGradebookTab = false, currentSpa, authSpaUrl, }) => {
148258
148296
  const t = useT();
148259
- return (jsx("div", { className: "border border-gray-200 rounded-lg p-6", children: jsxs(Tabs, { defaultValue: "users", "aria-label": t('profileAdmin.rbacManagementTabsAriaLabel'), children: [jsxs(TabsList, { "aria-label": t('profileAdmin.managementTabsAriaLabel'), className: "max-w-full overflow-x-auto justify-start px-1", children: [hasUserTabPermission && (jsx(TabsTrigger, { value: "users", children: t('profileAdmin.usersTab') })), hasGroupsTabPermission && (jsx(TabsTrigger, { value: "groups", children: t('profileAdmin.groupsTab') })), hasRolesTabPermission && (jsx(TabsTrigger, { value: "roles", children: t('profileAdmin.rolesTab') })), hasPoliciesTabPermission && (jsx(TabsTrigger, { value: "policies", children: t('profileAdmin.policiesTab') })), hasTeamsTabPermission && (jsx(TabsTrigger, { value: "teams", children: t('profileAdmin.teamsTab') })), hasAlertsTabPermission && (jsx(TabsTrigger, { value: "alerts", children: t('profileAdmin.alertsTab') })), jsx(TabsTrigger, { value: "applications", children: t('profileAdmin.applicationsTab') })] }), hasUserTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "users", children: [jsx(TabDescription, { icon: jsx(Users, { className: "w-5 h-5" }), title: t('profileAdmin.usersTab'), children: t('profileAdmin.usersDescription') }), jsx(UsersTab, { tenant: tenant, onInviteClick: onInviteClick, currentSpa: currentSpa, showGradebookTab: showGradebookTab })] })), hasGroupsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "groups", children: [jsx(TabDescription, { icon: jsx(UsersRound, { className: "w-5 h-5" }), title: t('profileAdmin.groupsTab'), children: t('profileAdmin.groupsDescription') }), jsx(GroupsTab, { tenant: tenant })] })), hasRolesTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "roles", children: [jsx(TabDescription, { icon: jsx(UserCog, { className: "w-5 h-5" }), title: t('profileAdmin.rolesTab'), children: t('profileAdmin.rolesDescription') }), jsx(RolesTab, { tenant: tenant })] })), hasPoliciesTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "policies", children: [jsx(TabDescription, { icon: jsx(ScrollText, { className: "w-5 h-5" }), title: t('profileAdmin.policiesTab'), children: t('profileAdmin.policiesDescription') }), jsx(PoliciesTab, { tenant: tenant })] })), hasTeamsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "teams", children: [jsx(TabDescription, { icon: jsx(Shield, { className: "w-5 h-5" }), title: t('profileAdmin.teamsTab'), children: t('profileAdmin.teamsDescription') }), jsx(GroupsTab, { tenant: tenant, isTeam: true, onInviteClick: onInviteClick, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac })] })), hasAlertsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "alerts", children: [jsx(TabDescription, { icon: jsx(BellRing, { className: "w-5 h-5" }), title: t('profileAdmin.alertsTab'), children: t('profileAdmin.alertsDescription') }), jsx(AlertsTab$1, { tenant: tenant })] })), jsxs(TabsContent, { className: "mt-4", value: "applications", children: [jsx(TabDescription, { icon: jsx(ClipboardList, { className: "w-5 h-5" }), title: t('profileAdmin.applicationsTab'), children: t('profileAdmin.applicationsTabDescription') }), jsx(ApplicationsTab, { platformKey: tenant, authSpaUrl: authSpaUrl, currentSpa: currentSpa })] })] }) }));
148297
+ return (jsx("div", { className: "border border-gray-200 rounded-lg p-6", children: jsxs(Tabs, { defaultValue: "users", "aria-label": t('profileAdmin.rbacManagementTabsAriaLabel'), children: [jsxs(TabsList, { "aria-label": t('profileAdmin.managementTabsAriaLabel'), className: "max-w-full overflow-x-auto justify-start px-1", children: [hasUserTabPermission && (jsx(TabsTrigger, { value: "users", children: t('profileAdmin.usersTab') })), hasGroupsTabPermission && (jsx(TabsTrigger, { value: "groups", children: t('profileAdmin.groupsTab') })), hasRolesTabPermission && (jsx(TabsTrigger, { value: "roles", children: t('profileAdmin.rolesTab') })), hasPoliciesTabPermission && (jsx(TabsTrigger, { value: "policies", children: t('profileAdmin.policiesTab') })), hasTeamsTabPermission && (jsx(TabsTrigger, { value: "teams", children: t('profileAdmin.teamsTab') })), hasAlertsTabPermission && (jsx(TabsTrigger, { value: "alerts", children: t('profileAdmin.alertsTab') })), jsx(TabsTrigger, { value: "applications", children: t('profileAdmin.applicationsTab') })] }), hasUserTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "users", children: [jsx(TabDescription, { icon: jsx(Users, { className: "w-5 h-5" }), title: t('profileAdmin.usersTab'), children: t('profileAdmin.usersDescription') }), jsx(UsersTab, { tenant: tenant, onInviteClick: onInviteClick, currentSpa: currentSpa, showGradebookTab: showGradebookTab })] })), hasGroupsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "groups", children: [jsx(TabDescription, { icon: jsx(UsersRound, { className: "w-5 h-5" }), title: t('profileAdmin.groupsTab'), children: t('profileAdmin.groupsDescription') }), jsx(GroupsTab, { tenant: tenant })] })), hasRolesTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "roles", children: [jsx(TabDescription, { icon: jsx(UserCog, { className: "w-5 h-5" }), title: t('profileAdmin.rolesTab'), children: t('profileAdmin.rolesDescription') }), jsx(RolesTab, { tenant: tenant })] })), hasPoliciesTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "policies", children: [jsx(TabDescription, { icon: jsx(ScrollText, { className: "w-5 h-5" }), title: t('profileAdmin.policiesTab'), children: t('profileAdmin.policiesDescription') }), jsx(PoliciesTab, { tenant: tenant })] })), hasTeamsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "teams", children: [jsx(TabDescription, { icon: jsx(Shield, { className: "w-5 h-5" }), title: t('profileAdmin.teamsTab'), children: t('profileAdmin.teamsDescription') }), jsx(GroupsTab, { tenant: tenant, isTeam: true, onInviteClick: onInviteClick, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac })] })), hasAlertsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "alerts", children: [jsx(TabDescription, { icon: jsx(BellRing, { className: "w-5 h-5" }), title: t('profileAdmin.alertsTab'), children: t('profileAdmin.alertsDescription') }), jsx(AlertsTab$1, { tenant: tenant })] })), jsxs(TabsContent, { className: "mt-4", value: "applications", children: [jsx(TabDescription, { icon: jsx(ClipboardList, { className: "w-5 h-5" }), title: t('profileAdmin.applicationsTab'), children: t('profileAdmin.applicationsTabDescription') }), jsx(ApplicationsTab, { platformKey: tenant, authSpaUrl: authSpaUrl })] })] }) }));
148260
148298
  };
148261
148299
 
148262
148300
  function DeleteApiModal({ isOpen, onClose, apiKey, tenantKey }) {
@@ -152913,7 +152951,7 @@ function SearchableMultiSelect({ items, selectedItems, onSelectionChange, search
152913
152951
  }) }))] }));
152914
152952
  }
152915
152953
 
152916
- function useDebouncedValue$4(value, delay) {
152954
+ function useDebouncedValue$5(value, delay) {
152917
152955
  const [debouncedValue, setDebouncedValue] = React__default.useState(value);
152918
152956
  React__default.useEffect(() => {
152919
152957
  const timer = window.setTimeout(() => setDebouncedValue(value), delay);
@@ -152958,8 +152996,8 @@ function TokenPolicyFields({ tenantKey, mode, onModeChange, policies, onPolicies
152958
152996
  const t = useT();
152959
152997
  const [policySearch, setPolicySearch] = React__default.useState('');
152960
152998
  const [groupSearch, setGroupSearch] = React__default.useState('');
152961
- const debouncedPolicySearch = useDebouncedValue$4(policySearch, RBAC_SEARCH_DEBOUNCE_MS);
152962
- const debouncedGroupSearch = useDebouncedValue$4(groupSearch, RBAC_SEARCH_DEBOUNCE_MS);
152999
+ const debouncedPolicySearch = useDebouncedValue$5(policySearch, RBAC_SEARCH_DEBOUNCE_MS);
153000
+ const debouncedGroupSearch = useDebouncedValue$5(groupSearch, RBAC_SEARCH_DEBOUNCE_MS);
152963
153001
  const canWriteMode = canWriteField(fieldPermissions, 'mode');
152964
153002
  const canWritePolicies = canWriteField(fieldPermissions, 'policies_to_add') ||
152965
153003
  canWriteField(fieldPermissions, 'policies_to_remove');
@@ -185840,7 +185878,7 @@ function PolicyConfigDialog({ open, onOpenChange, config, onSave, }) {
185840
185878
  return (jsx(Dialog, { open: open, onOpenChange: handleOpenChange, children: jsxs(DialogContent, { className: "sm:max-w-md", "aria-describedby": "policy-config-description", children: [jsxs(DialogHeader, { children: [jsx(DialogTitle, { children: t('componentsPolicyConfigDialog.title') }), jsx(DialogDescription, { id: "policy-config-description", children: t('componentsPolicyConfigDialog.description') })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { children: [jsx(Label$2, { htmlFor: "policy-config-role-name", className: "text-sm font-medium text-gray-700", children: t('componentsPolicyConfigDialog.roleName') }), jsx(Input, { id: "policy-config-role-name", value: (_a = draft === null || draft === void 0 ? void 0 : draft.role_name) !== null && _a !== void 0 ? _a : '', disabled: true, className: "bg-gray-50" })] }), jsxs("div", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { id: "policy-config-enabled", checked: (_b = draft === null || draft === void 0 ? void 0 : draft.enabled) !== null && _b !== void 0 ? _b : true, onCheckedChange: (checked) => updateDraft({ enabled: checked === true }) }), jsx(Label$2, { htmlFor: "policy-config-enabled", className: "text-sm font-medium text-gray-700 cursor-pointer", children: t('componentsPolicyConfigDialog.enabled') })] }), jsxs("div", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { id: "policy-config-notify-assignment", checked: (_c = draft === null || draft === void 0 ? void 0 : draft.notify_on_assignment) !== null && _c !== void 0 ? _c : true, onCheckedChange: (checked) => updateDraft({ notify_on_assignment: checked === true }) }), jsx(Label$2, { htmlFor: "policy-config-notify-assignment", className: "text-sm font-medium text-gray-700 cursor-pointer", children: t('componentsPolicyConfigDialog.notifyOnAssignment') })] }), jsxs("div", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { id: "policy-config-notify-removal", checked: (_d = draft === null || draft === void 0 ? void 0 : draft.notify_on_removal) !== null && _d !== void 0 ? _d : true, onCheckedChange: (checked) => updateDraft({ notify_on_removal: checked === true }) }), jsx(Label$2, { htmlFor: "policy-config-notify-removal", className: "text-sm font-medium text-gray-700 cursor-pointer", children: t('componentsPolicyConfigDialog.notifyOnRemoval') })] }), jsxs("div", { className: "space-y-2", children: [jsx(Label$2, { htmlFor: "policy-config-subject", className: "text-sm font-medium text-gray-700", children: t('componentsPolicyConfigDialog.subject') }), jsx(Textarea, { id: "policy-config-subject", value: (_e = draft === null || draft === void 0 ? void 0 : draft.subject) !== null && _e !== void 0 ? _e : '', onChange: (event) => updateDraft({ subject: event.target.value }), placeholder: t('componentsPolicyConfigDialog.subjectPlaceholder'), rows: 3 }), jsx("p", { className: "text-xs text-gray-500", children: t('componentsPolicyConfigDialog.subjectHint') })] })] }), jsxs(DialogFooter, { className: "pt-2", children: [jsx(Button$1, { variant: "outline", onClick: () => onOpenChange(false), children: t('componentsPolicyConfigDialog.cancel') }), jsx(Button$1, { className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", onClick: handleSave, disabled: !config, children: t('componentsPolicyConfigDialog.saveConfiguration') })] })] }) }));
185841
185879
  }
185842
185880
 
185843
- function useDebouncedValue$3(value, delay) {
185881
+ function useDebouncedValue$4(value, delay) {
185844
185882
  const [debouncedValue, setDebouncedValue] = useState(value);
185845
185883
  useEffect(() => {
185846
185884
  const timer = window.setTimeout(() => setDebouncedValue(value), delay);
@@ -185869,7 +185907,7 @@ function ProactiveSettingsSection({ platformKey, username, isSaving, userLocalTi
185869
185907
  const [isPromptDialogOpen, setIsPromptDialogOpen] = useState(false);
185870
185908
  const customIntervalErrorId = 'proactive-custom-interval-error';
185871
185909
  const executionTimeErrorId = 'proactive-execution-time-error';
185872
- const debouncedMentorSearch = useDebouncedValue$3(mentorSearch, 300);
185910
+ const debouncedMentorSearch = useDebouncedValue$4(mentorSearch, 300);
185873
185911
  const showUseLocalTimezone = periodicTimezone !== userLocalTimezone;
185874
185912
  const shouldFetchMentors = Boolean(platformKey) && Boolean(username);
185875
185913
  const { data: mentorsResponse, isLoading: isMentorsLoading } = useGetMentorsQuery({
@@ -185966,7 +186004,7 @@ function ProactiveSettingsSection({ platformKey, username, isSaving, userLocalTi
185966
186004
  }) })] })] }), jsxs("div", { className: "space-y-2", children: [jsx(Label$2, { htmlFor: "periodic-execution-time", className: "text-sm font-medium text-gray-700", children: t('componentsProactiveSettingsSection.executionTimeLabel') }), jsx(Input, { id: "periodic-execution-time", type: "time", value: periodicExecutionTime, onChange: (event) => onExecutionTimeChange(event.target.value), disabled: isSaving, "aria-invalid": isExecutionTimeMissing, "aria-describedby": isExecutionTimeMissing ? executionTimeErrorId : undefined }), renderTimezoneNotice(t('componentsProactiveSettingsSection.chooseWhenNotice'))] })] })), periodicFrequency !== 'CUSTOM' && (jsxs("div", { className: "space-y-2", children: [jsx(Label$2, { htmlFor: "periodic-execution-time", className: "text-sm font-medium text-gray-700", children: t('componentsProactiveSettingsSection.executionTimeLabel') }), jsx(Input, { id: "periodic-execution-time", type: "time", value: periodicExecutionTime, onChange: (event) => onExecutionTimeChange(event.target.value), disabled: isSaving }), renderTimezoneNotice(t('componentsProactiveSettingsSection.optionalChooseWhenNotice'))] })), isProactiveInvalid && (jsxs("div", { className: "space-y-1", "aria-live": "polite", children: [isCustomIntervalMissing && (jsx("p", { id: customIntervalErrorId, className: "text-sm text-red-600", role: "alert", children: t('componentsProactiveSettingsSection.customIntervalError') })), isExecutionTimeMissing && (jsx("p", { id: executionTimeErrorId, className: "text-sm text-red-600", role: "alert", children: t('componentsProactiveSettingsSection.executionTimeError') }))] })), jsxs("div", { className: "space-y-2", children: [jsx(Label$2, { className: "text-sm font-medium text-gray-700", htmlFor: "periodic-mentors", children: t('componentsProactiveSettingsSection.periodicAgentsLabel') }), jsx(SearchableMultiSelect, { items: mentorOptions, selectedItems: selectedMentors, onSelectionChange: handleMentorSelectionChange, searchQuery: mentorSearch, onSearchChange: setMentorSearch, isLoading: isMentorsLoading, placeholder: t('componentsProactiveSettingsSection.searchAgentsPlaceholder'), getItemValue: (mentor) => mentor.unique_id, getItemLabel: (mentor) => mentor.name ? `${mentor.name} (${mentor.unique_id})` : mentor.unique_id, onSelectedItemAction: handleEditMentorPrompt, selectedItemActionIcon: jsx(SquarePen, { className: "h-3 w-3", "aria-hidden": "true" }), selectedItemActionAriaLabel: t('componentsProactiveSettingsSection.editAgentPromptAriaLabel'), inputId: "periodic-mentors", ariaDescribedBy: "periodic-mentors-help", className: "max-w-full" }), jsx("p", { id: "periodic-mentors-help", className: "text-xs text-gray-500", children: t('componentsProactiveSettingsSection.periodicAgentsHelp') })] })] }), jsx(MentorPromptDialog, { open: isPromptDialogOpen, onOpenChange: setIsPromptDialogOpen, mentor: activePromptMentor, initialPrompt: activePromptMentor ? ((_b = mentorPrompts[activePromptMentor.id]) !== null && _b !== void 0 ? _b : '') : '', onSave: handlePromptSave })] }));
185967
186005
  }
185968
186006
 
185969
- function useDebouncedValue$2(value, delay) {
186007
+ function useDebouncedValue$3(value, delay) {
185970
186008
  const [debouncedValue, setDebouncedValue] = useState(value);
185971
186009
  useEffect(() => {
185972
186010
  const timer = window.setTimeout(() => setDebouncedValue(value), delay);
@@ -185998,7 +186036,7 @@ function PolicyAssignmentSection({ platformKey, isSaving, notifyOnAssignment, on
185998
186036
  const [isPolicyConfigDialogOpen, setIsPolicyConfigDialogOpen] = useState(false);
185999
186037
  // Track the last initialized data to detect when new data arrives
186000
186038
  const lastInitializedRef = useRef('');
186001
- const debouncedPolicySearch = useDebouncedValue$2(policySearch, 300);
186039
+ const debouncedPolicySearch = useDebouncedValue$3(policySearch, 300);
186002
186040
  const shouldFetchPolicies = Boolean(platformKey);
186003
186041
  const { data: policiesResponse, isLoading: isPoliciesLoading } = useGetRbacPoliciesQuery({ platformKey }, { skip: !shouldFetchPolicies });
186004
186042
  const policyOptions = useMemo(() => {
@@ -186093,7 +186131,7 @@ function PolicyAssignmentSection({ platformKey, isSaving, notifyOnAssignment, on
186093
186131
  return (jsxs(Fragment$1, { children: [jsxs("div", { className: "space-y-4 border-t border-gray-200 pt-4", children: [jsxs("div", { className: "space-y-1", children: [jsx("h3", { className: "text-sm font-semibold text-gray-900", children: t('componentsPolicyAssignmentSection.sectionTitle') }), jsx("p", { className: "text-xs text-gray-500", children: t('componentsPolicyAssignmentSection.sectionDescription') })] }), jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [jsxs("div", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { id: "policy-notify-assignment", checked: notifyOnAssignment, onCheckedChange: (checked) => onNotifyOnAssignmentChange(checked === true), disabled: isSaving }), jsx(Label$2, { htmlFor: "policy-notify-assignment", className: "text-sm font-medium text-gray-700 cursor-pointer", children: t('componentsPolicyAssignmentSection.notifyOnAssignment') })] }), jsxs("div", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { id: "policy-notify-removal", checked: notifyOnRemoval, onCheckedChange: (checked) => onNotifyOnRemovalChange(checked === true), disabled: isSaving }), jsx(Label$2, { htmlFor: "policy-notify-removal", className: "text-sm font-medium text-gray-700 cursor-pointer", children: t('componentsPolicyAssignmentSection.notifyOnRemoval') })] })] }), jsxs("div", { className: "space-y-2", children: [jsx(Label$2, { className: "text-sm font-medium text-gray-700", htmlFor: "enabled-policies", children: t('componentsPolicyAssignmentSection.enabledPoliciesLabel') }), jsx(SearchableMultiSelect, { items: policyOptions, selectedItems: selectedPolicies, onSelectionChange: handlePolicySelectionChange, searchQuery: policySearch, onSearchChange: setPolicySearch, isLoading: isPoliciesLoading, placeholder: t('componentsPolicyAssignmentSection.searchPlaceholder'), getItemValue: (policy) => String(policy.id), getItemLabel: (policy) => { var _a; return (((_a = policy.role) === null || _a === void 0 ? void 0 : _a.name) ? `${policy.name}` : policy.name); }, onSelectedItemAction: handleEditPolicyConfig, selectedItemActionIcon: jsx(SquarePen, { className: "h-3 w-3", "aria-hidden": "true" }), selectedItemActionAriaLabel: t('componentsPolicyAssignmentSection.editPolicyAriaLabel'), inputId: "enabled-policies", ariaDescribedBy: "enabled-policies-help", className: "max-w-full" }), jsx("p", { id: "enabled-policies-help", className: "text-xs text-gray-500", children: t('componentsPolicyAssignmentSection.enabledPoliciesHelp') })] })] }), jsx(PolicyConfigDialog, { open: isPolicyConfigDialogOpen, onOpenChange: setIsPolicyConfigDialogOpen, config: activePolicyConfig, onSave: handlePolicyConfigSave })] }));
186094
186132
  }
186095
186133
 
186096
- function useDebouncedValue$1(value, delay) {
186134
+ function useDebouncedValue$2(value, delay) {
186097
186135
  const [debouncedValue, setDebouncedValue] = useState(value);
186098
186136
  useEffect(() => {
186099
186137
  const timer = window.setTimeout(() => setDebouncedValue(value), delay);
@@ -186162,9 +186200,9 @@ function HumanSupportSection({ platformKey, isSaving, recipientMode, onRecipient
186162
186200
  // Track the last initialized data to detect when new data arrives
186163
186201
  const lastInitializedRef = useRef('');
186164
186202
  // Debounced search values
186165
- const debouncedUserSearch = useDebouncedValue$1(userSearch, 300);
186166
- const debouncedGroupSearch = useDebouncedValue$1(groupSearch, 300);
186167
- const debouncedPolicySearch = useDebouncedValue$1(policySearch, 300);
186203
+ const debouncedUserSearch = useDebouncedValue$2(userSearch, 300);
186204
+ const debouncedGroupSearch = useDebouncedValue$2(groupSearch, 300);
186205
+ const debouncedPolicySearch = useDebouncedValue$2(policySearch, 300);
186168
186206
  const shouldFetch = Boolean(platformKey);
186169
186207
  // Fetch users
186170
186208
  const { data: usersResponse, isLoading: isUsersLoading } = usePlatformUsersQuery({
@@ -187802,10 +187840,41 @@ const formatDateToShortFormat$2 = (dateString, isToday = false) => {
187802
187840
  return date.toLocaleDateString([], { month: 'short', day: 'numeric', timeZone: 'UTC' });
187803
187841
  };
187804
187842
 
187843
+ const AnalyticsScopeContext = createContext({ scopedMentor: null });
187844
+ const AnalyticsScopeProvider = AnalyticsScopeContext.Provider;
187845
+ /** Read the analytics agent scope. `scopedMentor` is `null` outside a provider. */
187846
+ function useAnalyticsScope() {
187847
+ return useContext(AnalyticsScopeContext);
187848
+ }
187849
+ /**
187850
+ * The agent a container should report on, in precedence order:
187851
+ *
187852
+ * 1. `selectedMentorId` — an agent the host explicitly switched to.
187853
+ * 2. `mentorId` — the agent in the route, on a per-agent analytics page.
187854
+ * 3. The picker's scope, which only exists on tenant-wide pages.
187855
+ *
187856
+ * The picker comes last so it can never override a host that already knows
187857
+ * which agent the page is about; on those pages `AnalyticsLayout` doesn't
187858
+ * render the picker at all. An empty string is the tenant-wide mode every
187859
+ * analytics hook already understands.
187860
+ */
187861
+ function useScopedMentorId(selectedMentorId, mentorId) {
187862
+ const { scopedMentor } = useAnalyticsScope();
187863
+ return selectedMentorId || mentorId || (scopedMentor === null || scopedMentor === void 0 ? void 0 : scopedMentor.uniqueId) || '';
187864
+ }
187865
+ /**
187866
+ * The database id matching {@link useScopedMentorId}, for the endpoints that
187867
+ * key off the primary key instead of `unique_id`.
187868
+ */
187869
+ function useScopedMentorDbId(selectedMentorDbId) {
187870
+ const { scopedMentor } = useAnalyticsScope();
187871
+ return selectedMentorDbId || (scopedMentor === null || scopedMentor === void 0 ? void 0 : scopedMentor.dbId) || undefined;
187872
+ }
187873
+
187805
187874
  function AnalyticsOverview({ tenantKey, mentorId, selectedMentorId, usergroupIds, }) {
187806
187875
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
187807
187876
  const t = useT();
187808
- const currentMentorId = selectedMentorId || mentorId;
187877
+ const currentMentorId = useScopedMentorId(selectedMentorId, mentorId);
187809
187878
  const { messageStat, topicStat, conversationStat, sessionStats, isLoadingAllStats, isLoadingUsersStats, isLoadingSessionStats, isLoadingTopicsDetailsStats, isLoadingActiveUsersStats, setSessionStatsDateFilter, usersStats, sessionStatsDateFilter, topicsDetailsStats, setTopicsDetailsStatsDateFilter, topicsDetailsStatsDateFilter, activeUsersStats, setUsersStatsDateFilter, usersStatsDateFilter, } = useOverview({ tenantKey, mentorId: currentMentorId, usergroupIds });
187810
187879
  return (jsxs("div", { className: "space-y-8", children: [jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6", children: [jsx(StatCard, { loading: isLoadingAllStats, title: t('analyticsAnalyticsOverview.messages'), value: messageStat.stat, percentage: messageStat.percentage, description: t('analyticsAnalyticsOverview.messagesDescription') }), jsx(StatCard, { loading: isLoadingUsersStats, title: t('analyticsAnalyticsOverview.activeUsers'), value: (usersStats === null || usersStats === void 0 ? void 0 : usersStats.count) || 0, percentage: (usersStats === null || usersStats === void 0 ? void 0 : usersStats.percentage_change) || 0, description: t('analyticsAnalyticsOverview.activeUsersDescription') }), jsx(StatCard, { loading: isLoadingAllStats, title: t('analyticsAnalyticsOverview.topics'), value: topicStat.stat, percentage: topicStat.percentage, description: t('analyticsAnalyticsOverview.topicsDescription') }), jsx(StatCard, { loading: isLoadingAllStats, title: t('analyticsAnalyticsOverview.conversations'), value: conversationStat.stat, percentage: conversationStat.percentage, description: t('analyticsAnalyticsOverview.conversationsDescription') })] }), jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-5", children: [jsx(ChartCardWrapper, { title: t('analyticsAnalyticsOverview.sessions'), label: t('analyticsAnalyticsOverview.sessions'), setOutsideFilters: setSessionStatsDateFilter, filters: sessionStatsDateFilter, description: t('analyticsAnalyticsOverview.sessionsChartDescription'), children: isLoadingSessionStats ? (jsx(ChartLoading, {})) : ((_a = sessionStats === null || sessionStats === void 0 ? void 0 : sessionStats.points) === null || _a === void 0 ? void 0 : _a.length) && ((_b = sessionStats === null || sessionStats === void 0 ? void 0 : sessionStats.points) === null || _b === void 0 ? void 0 : _b.length) > 0 ? (jsxs(LineChart, { data: ((_c = sessionStats === null || sessionStats === void 0 ? void 0 : sessionStats.points) === null || _c === void 0 ? void 0 : _c.map((point) => ({
187811
187880
  date: formatDateToShortFormat$2(point.date, sessionStatsDateFilter.activeFilter === 'today'),
@@ -187842,6 +187911,157 @@ function AnalyticsOverview({ tenantKey, mentorId, selectedMentorId, usergroupIds
187842
187911
  }, cursor: { fill: 'rgba(0, 0, 0, 0.05)' }, wrapperStyle: { outline: 'none' } }), jsx(Bar, { dataKey: "value", fill: "#38A1E5", radius: [4, 4, 0, 0] })] })) : (jsx(EmptyStats, {})) }) })] }));
187843
187912
  }
187844
187913
 
187914
+ /**
187915
+ * Core agent search hook — thin wrapper around `useGetAiSearchMentorsQuery`.
187916
+ *
187917
+ * This is the low-level building block. For a higher-level hook that manages
187918
+ * search state, debounce, and pagination controls, use
187919
+ * `useAgentSearchWithPagination`.
187920
+ */
187921
+ function useAgentSearch({ tenantKey, query, limit = 6, offset, starred, featured, category, subjects, llm, types, includeMainPublicMentors, orderDirection, skip = false, }) {
187922
+ var _a, _b, _c;
187923
+ const { data, isLoading, isFetching, refetch } = useGetAiSearchMentorsQuery({
187924
+ platform_key: tenantKey,
187925
+ query: query || undefined,
187926
+ limit,
187927
+ ...(offset !== undefined && { offset }),
187928
+ ...(starred !== undefined && { starred }),
187929
+ ...(featured !== undefined && { featured }),
187930
+ ...(category && { category }),
187931
+ ...(subjects && { subjects }),
187932
+ ...(llm && { llm }),
187933
+ ...(types && { types }),
187934
+ ...(includeMainPublicMentors !== undefined && {
187935
+ include_main_public_mentors: includeMainPublicMentors,
187936
+ }),
187937
+ ...(orderDirection && { order_direction: orderDirection }),
187938
+ }, { skip: skip || !tenantKey });
187939
+ return {
187940
+ agents: ((_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : []),
187941
+ facets: data === null || data === void 0 ? void 0 : data.facets,
187942
+ hasMore: !!(data === null || data === void 0 ? void 0 : data.next),
187943
+ totalCount: (_b = data === null || data === void 0 ? void 0 : data.count) !== null && _b !== void 0 ? _b : 0,
187944
+ totalPages: (_c = data === null || data === void 0 ? void 0 : data.total_pages) !== null && _c !== void 0 ? _c : 0,
187945
+ isLoading,
187946
+ isFetching,
187947
+ refetch,
187948
+ };
187949
+ }
187950
+
187951
+ function c(e,u,c){var i=this,a=useRef(null),o=useRef(0),f=useRef(null),l=useRef([]),v=useRef(),m=useRef(),d=useRef(e),g=useRef(true);d.current=e;var p="undefined"!=typeof window,w=!u&&0!==u&&p;if("function"!=typeof e)throw new TypeError("Expected a function");u=+u||0;var s=!!(c=c||{}).leading,x=!("trailing"in c)||!!c.trailing,h="maxWait"in c,y="debounceOnServer"in c&&!!c.debounceOnServer,F=h?Math.max(+c.maxWait||0,u):null;useEffect(function(){return g.current=true,function(){g.current=false;}},[]);var A=useMemo(function(){var r=function(r){var n=l.current,t=v.current;return l.current=v.current=null,o.current=r,m.current=d.current.apply(t,n)},n=function(r,n){w&&cancelAnimationFrame(f.current),f.current=w?requestAnimationFrame(r):setTimeout(r,n);},t=function(r){if(!g.current)return false;var n=r-a.current;return !a.current||n>=u||n<0||h&&r-o.current>=F},e=function(n){return f.current=null,x&&l.current?r(n):(l.current=v.current=null,m.current)},c=function r(){var c=Date.now();if(t(c))return e(c);if(g.current){var i=u-(c-a.current),f=h?Math.min(i,F-(c-o.current)):i;n(r,f);}},A=function(){if(p||y){var e=Date.now(),d=t(e);if(l.current=[].slice.call(arguments),v.current=i,a.current=e,d){if(!f.current&&g.current)return o.current=a.current,n(c,u),s?r(a.current):m.current;if(h)return n(c,u),r(a.current)}return f.current||n(c,u),m.current}};return A.cancel=function(){f.current&&(w?cancelAnimationFrame(f.current):clearTimeout(f.current)),o.current=0,l.current=a.current=v.current=f.current=null;},A.isPending=function(){return !!f.current},A.flush=function(){return f.current?e(Date.now()):m.current},A},[s,h,u,F,x,w,p,y]);return A}function i(r,n){return r===n}function a(n,t,a){var o=i,f=useRef(n),l=useState({})[1],v=c(useCallback(function(r){f.current=r,l({});},[l]),t,a),m=useRef(n);return o(m.current,n)||(v(n),m.current=n),[f.current,v]}
187952
+
187953
+ /**
187954
+ * Higher-level agent search hook that manages search state, debounce, and
187955
+ * pagination controls on top of `useAgentSearch`.
187956
+ *
187957
+ * Use this for simple list/table views (MyMentorsModal, SettingsModal).
187958
+ * For the full explore page with sections, use `useAgentSearch` directly.
187959
+ */
187960
+ function useAgentSearchWithPagination({ itemsPerPage = 6, paginationMode = 'paginated', debounceMs = 500, ...queryConfig }) {
187961
+ const [searchQuery, setSearchQuery] = React__default.useState('');
187962
+ const [debouncedQuery] = a(searchQuery, debounceMs);
187963
+ const [currentPage, setCurrentPage] = React__default.useState(1);
187964
+ const [infiniteLimit, setInfiniteLimit] = React__default.useState(itemsPerPage);
187965
+ // Reset pagination when search changes
187966
+ React__default.useEffect(() => {
187967
+ setCurrentPage(1);
187968
+ setInfiniteLimit(itemsPerPage);
187969
+ }, [debouncedQuery, itemsPerPage]);
187970
+ const isPaginated = paginationMode === 'paginated';
187971
+ const result = useAgentSearch({
187972
+ ...queryConfig,
187973
+ query: debouncedQuery,
187974
+ limit: isPaginated ? itemsPerPage : infiniteLimit,
187975
+ offset: isPaginated ? (currentPage - 1) * itemsPerPage : undefined,
187976
+ });
187977
+ const totalPages = Math.ceil(result.totalCount / itemsPerPage);
187978
+ const handlePageChange = React__default.useCallback((page) => {
187979
+ setCurrentPage(page);
187980
+ }, []);
187981
+ const loadMore = React__default.useCallback(() => {
187982
+ setInfiniteLimit((prev) => prev + itemsPerPage);
187983
+ }, [itemsPerPage]);
187984
+ return {
187985
+ ...result,
187986
+ searchQuery,
187987
+ setSearchQuery,
187988
+ debouncedQuery,
187989
+ currentPage,
187990
+ totalPages,
187991
+ handlePageChange,
187992
+ loadMore,
187993
+ };
187994
+ }
187995
+
187996
+ const AGENTS_PAGE_SIZE = 20;
187997
+ const SEARCH_DEBOUNCE_MS$1 = 300;
187998
+ /** cmdk needs a non-empty value; the handler treats this one as "clear". */
187999
+ const ALL_AGENTS_VALUE = '__all_agents__';
188000
+ function useDebouncedValue$1(value, delay) {
188001
+ const [debounced, setDebounced] = useState(value);
188002
+ useEffect(() => {
188003
+ const timer = setTimeout(() => setDebounced(value), delay);
188004
+ return () => clearTimeout(timer);
188005
+ }, [value, delay]);
188006
+ return debounced;
188007
+ }
188008
+ /**
188009
+ * Scope selector for tenant-wide analytics: either the whole platform, or a
188010
+ * single agent found by typing. Tenant-wide analytics has no agent in the
188011
+ * route, so this is the only way to drill into one without changing pages.
188012
+ *
188013
+ * The list is served by the agent-search endpoint and is not filtered again
188014
+ * client-side — searching is how you reach anything past the first
188015
+ * {@link AGENTS_PAGE_SIZE} results.
188016
+ */
188017
+ function AnalyticsAgentPicker({ tenantKey, value, onChange, className, }) {
188018
+ const t = useT();
188019
+ const [open, setOpen] = useState(false);
188020
+ const [search, setSearch] = useState('');
188021
+ const debouncedSearch = useDebouncedValue$1(search, SEARCH_DEBOUNCE_MS$1);
188022
+ // Skipped until the popover opens, so merely landing on an analytics page
188023
+ // doesn't fire an agent search nobody asked for.
188024
+ const { agents, isFetching } = useAgentSearch({
188025
+ tenantKey,
188026
+ query: debouncedSearch,
188027
+ limit: AGENTS_PAGE_SIZE,
188028
+ skip: !open,
188029
+ });
188030
+ const results = useMemo(
188031
+ // `unique_id` is what the analytics endpoints filter on. A result without
188032
+ // one would produce a selection that silently reports on everything.
188033
+ () => agents.filter((agent) => !!agent.unique_id), [agents]);
188034
+ const handleSelect = (mentor) => {
188035
+ onChange(mentor);
188036
+ setOpen(false);
188037
+ // Re-opening starts from the unfiltered list rather than a stale query.
188038
+ setSearch('');
188039
+ };
188040
+ return (jsxs(Popover, { open: open, onOpenChange: setOpen, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1
188041
+ // Ghost rather than outline: the picker sits in the tab strip's own
188042
+ // background, so it carries no chrome of its own until hovered.
188043
+ , {
188044
+ // Ghost rather than outline: the picker sits in the tab strip's own
188045
+ // background, so it carries no chrome of its own until hovered.
188046
+ variant: "ghost", role: "combobox", "aria-expanded": open, "aria-label": t('analyticsAnalyticsAgentPicker.analyticsScope'), className: cn(
188047
+ // Capped so a long agent name ellipsizes instead of pushing the tab
188048
+ // strip along; the label below is what actually truncates.
188049
+ 'h-9 max-w-[220px] justify-between bg-transparent pl-2 font-normal', className), children: [jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [value ? (jsxs(Avatar, { className: "h-5 w-5 shrink-0", children: [jsx(AvatarImage, { src: value.profileImage, alt: "" }), jsx(AvatarFallback, { className: "text-[10px]", children: value.name.charAt(0).toUpperCase() })] })) : (jsx(Globe, { className: "h-4 w-4 shrink-0 opacity-70", "aria-hidden": "true" })), jsx("span", { className: "min-w-0 truncate", children: value ? value.name : t('analyticsAnalyticsAgentPicker.allAgents') })] }), jsx(ChevronDown, { className: "h-4 w-4 shrink-0 opacity-50", "aria-hidden": "true" })] }) }), 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('analyticsAnalyticsAgentPicker.searchAgents') }), jsxs(CommandList, { children: [jsx(CommandGroup, { children: jsxs(CommandItem, { value: ALL_AGENTS_VALUE, onSelect: () => handleSelect(null), children: [jsx(Check, { className: cn('mr-2 h-4 w-4', value ? 'opacity-0' : 'opacity-100') }), jsx(Globe, { className: "mr-2 h-4 w-4 opacity-70", "aria-hidden": "true" }), t('analyticsAnalyticsAgentPicker.allAgents')] }) }), results.length > 0 && (jsx(CommandGroup, { heading: t('analyticsAnalyticsAgentPicker.agents'), children: results.map((agent) => {
188050
+ var _a;
188051
+ const uniqueId = agent.unique_id;
188052
+ return (jsxs(CommandItem, {
188053
+ // cmdk keys items by value; the search itself is server-side.
188054
+ value: uniqueId, onSelect: () => handleSelect({
188055
+ uniqueId,
188056
+ // Search returns the DB id as a number, but every
188057
+ // consumer downstream types it as a string.
188058
+ dbId: String(agent.id),
188059
+ name: agent.name,
188060
+ profileImage: agent.profile_image,
188061
+ }), children: [jsx(Check, { className: cn('mr-2 h-4 w-4', (value === null || value === void 0 ? void 0 : value.uniqueId) === uniqueId ? 'opacity-100' : 'opacity-0') }), jsxs(Avatar, { className: "mr-2 h-5 w-5 shrink-0", children: [jsx(AvatarImage, { src: agent.profile_image, alt: "" }), jsx(AvatarFallback, { className: "text-[10px]", children: (_a = agent.name) === null || _a === void 0 ? void 0 : _a.charAt(0).toUpperCase() })] }), jsx("span", { className: "truncate", children: agent.name })] }, uniqueId));
188062
+ }) })), isFetching && results.length === 0 && (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-500", children: t('analyticsAnalyticsAgentPicker.loading') })), !isFetching && results.length === 0 && (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-500", children: t('analyticsAnalyticsAgentPicker.noAgentsFound') }))] })] }) })] }));
188063
+ }
188064
+
187845
188065
  const defaultTabs = [
187846
188066
  {
187847
188067
  label: 'Overview',
@@ -187885,9 +188105,29 @@ const defaultTabs = [
187885
188105
  },*/
187886
188106
  ];
187887
188107
  const className = 'inline-flex items-center justify-center whitespace-nowrap rounded-[5px] px-2 sm:px-2.5 pt-1 pb-0.5 sm:text-sm text-gray-500 ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-blue-600 data-[state=active]:font-semibold text-sm font-medium data-[state=active]:bg-[#f5f7fb] data-[state=active]:shadow-none cursor-pointer';
187888
- function AnalyticsLayout({ children, currentPath, basePath, onTabChange, tabs = defaultTabs, activeTabClassName = '', beforeDataReports, excludeTabs = [], }) {
188108
+ function AnalyticsLayout({ children, currentPath, basePath, onTabChange, tabs = defaultTabs, activeTabClassName = '', beforeDataReports, excludeTabs = [], showPicker = false, tenantKey, scopedMentor, onScopedMentorChange, }) {
188109
+ var _a, _b;
187889
188110
  const { currentTenant } = useCurrentTenant();
187890
188111
  const rbacPermissions = useSelector(selectRbacPermissions);
188112
+ // Deliberately its own state rather than whatever the host already tracks as
188113
+ // "the agent in context": reusing that would silently scope every chart to
188114
+ // the last agent the user chatted with, with nothing on screen saying why.
188115
+ // The trade-off is that it resets on reload — a host that needs it shareable
188116
+ // controls the value instead.
188117
+ const [internalScopedMentor, setInternalScopedMentor] = useState(null);
188118
+ const isScopeControlled = onScopedMentorChange !== undefined;
188119
+ const activeScopedMentor = (_a = (isScopeControlled ? scopedMentor : internalScopedMentor)) !== null && _a !== void 0 ? _a : null;
188120
+ const handleScopedMentorChange = useCallback((mentor) => {
188121
+ if (isScopeControlled) {
188122
+ onScopedMentorChange === null || onScopedMentorChange === void 0 ? void 0 : onScopedMentorChange(mentor);
188123
+ return;
188124
+ }
188125
+ setInternalScopedMentor(mentor);
188126
+ }, [isScopeControlled, onScopedMentorChange]);
188127
+ const scopeValue = useMemo(
188128
+ // Only a rendered picker may scope the page — otherwise a host that stops
188129
+ // showing it would leave a stale agent filtering every chart.
188130
+ () => ({ scopedMentor: showPicker ? activeScopedMentor : null }), [showPicker, activeScopedMentor]);
187891
188131
  // Only a pure watcher narrows the tab strip — everyone else keeps whatever
187892
188132
  // the caller passed, custom tabs included.
187893
188133
  const isRestricted = isPureWatcher(rbacPermissions, currentTenant);
@@ -187957,12 +188197,12 @@ function AnalyticsLayout({ children, currentPath, basePath, onTabChange, tabs =
187957
188197
  return;
187958
188198
  onTabChange(tabValue);
187959
188199
  };
187960
- return (jsxs("div", { className: "flex flex-col flex-1 min-h-0 h-full overflow-hidden overscroll-none bg-[#f5f7fb]", children: [jsx("div", { className: "p-6 pb-0 pt-4 xs:pt-0", children: jsx("div", { className: "flex items-center justify-between mb-4 xs:mb-2", children: jsxs("div", { className: "flex items-center justify-between w-full overflow-x-auto", children: [jsx(Tabs, { className: "bg-[#f5f7fb]", value: activeTab, children: jsx(TabsList, { className: "bg-[#f5f7fb]", children: tabs
187961
- .filter((tab) => !excludeTabs.includes(tab.value) && canAccessTab(tab.value))
187962
- .map((tab) => {
187963
- const isActive = activeTab === tab.value;
187964
- return (jsx(TabsTrigger, { value: tab.value, className: cn(className, isActive && activeTabClassName), onClick: () => handleTabClick(tab.value), children: tab.label }, tab.value));
187965
- }) }) }), jsxs("div", { className: "flex items-center gap-4", children: [beforeDataReports, canAccessTab('reports') && (jsx(Tabs, { className: "bg-[#f5f7fb]", value: activeTab, children: jsx(TabsList, { className: "bg-[#f5f7fb]", children: jsx(TabsTrigger, { value: "reports", className: cn(className, activeTab === 'reports' && activeTabClassName), onClick: () => handleTabClick('reports'), children: "Data Reports" }) }) }))] })] }) }) }), jsx("div", { className: "flex-1 overflow-auto overscroll-contain scrollbar-none px-6 pb-6 pt-0", children: isActiveTabAllowed ? children : null })] }));
188200
+ return (jsx(AnalyticsScopeProvider, { value: scopeValue, children: jsxs("div", { className: "flex flex-col flex-1 min-h-0 h-full overflow-hidden overscroll-none bg-[#f5f7fb]", children: [jsx("div", { className: "p-6 pb-0 pt-4 xs:pt-0", children: jsx("div", { className: "flex items-center justify-between mb-4 xs:mb-2", children: jsxs("div", { className: "flex items-center justify-between w-full overflow-x-auto", children: [jsxs("div", { className: "flex items-center gap-3", children: [showPicker && (jsx("div", { className: "shrink-0", children: jsx(AnalyticsAgentPicker, { tenantKey: (_b = tenantKey !== null && tenantKey !== void 0 ? tenantKey : currentTenant === null || currentTenant === void 0 ? void 0 : currentTenant.key) !== null && _b !== void 0 ? _b : '', value: activeScopedMentor, onChange: handleScopedMentorChange }) })), jsx(Tabs, { className: "bg-[#f5f7fb]", value: activeTab, children: jsx(TabsList, { className: "bg-[#f5f7fb]", children: tabs
188201
+ .filter((tab) => !excludeTabs.includes(tab.value) && canAccessTab(tab.value))
188202
+ .map((tab) => {
188203
+ const isActive = activeTab === tab.value;
188204
+ return (jsx(TabsTrigger, { value: tab.value, className: cn(className, isActive && activeTabClassName), onClick: () => handleTabClick(tab.value), children: tab.label }, tab.value));
188205
+ }) }) })] }), jsxs("div", { className: "flex items-center gap-4", children: [beforeDataReports, canAccessTab('reports') && (jsx(Tabs, { className: "bg-[#f5f7fb]", value: activeTab, children: jsx(TabsList, { className: "bg-[#f5f7fb]", children: jsx(TabsTrigger, { value: "reports", className: cn(className, activeTab === 'reports' && activeTabClassName), onClick: () => handleTabClick('reports'), children: "Data Reports" }) }) }))] })] }) }) }), jsx("div", { className: "flex-1 overflow-auto overscroll-contain scrollbar-none px-6 pb-6 pt-0", children: isActiveTabAllowed ? children : null })] }) }));
187966
188206
  }
187967
188207
 
187968
188208
  const accessTimeData = [
@@ -188184,7 +188424,7 @@ const formatRelativeTime$1 = (dateString, t) => {
188184
188424
  function AnalyticsUsersStats({ tenantKey, mentorId, selectedMentorId, usergroupIds, }) {
188185
188425
  var _a, _b, _c, _d, _e, _f, _g, _h;
188186
188426
  const t = useT();
188187
- const currentMentorId = selectedMentorId || mentorId;
188427
+ const currentMentorId = useScopedMentorId(selectedMentorId, mentorId);
188188
188428
  const { registeredUsers, isLoadingRegisteredUsers, activeUsers, isLoadingActiveUsers, setActiveUsersStatsDateFilter, activeUsersStatsDateFilter, accessTimeHeatmap, isLoadingAccessTimeHeatmap, setAccessTimeHeatmapDateFilter, accessTimeHeatmapDateFilter, userDetailsStats, isLoadingUserDetailsStats, setUserDetailsStatsDateFilter, userDetailsStatsDateFilter, setUserDetailsStatsPage, userDetailsStatsSearch, handleSearchInputChange, currentlyActiveUsers, isLoadingCurrentlyActiveUsers, activeUsers30D, isLoadingActiveUsers30D, } = useUsers({ tenantKey, mentorId: currentMentorId, usergroupIds });
188189
188429
  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('analyticsAnalyticsUsersStats.usersLoggedInNow'), value: (currentlyActiveUsers === null || currentlyActiveUsers === void 0 ? void 0 : currentlyActiveUsers.count) || 0, loading: isLoadingCurrentlyActiveUsers, description: t('analyticsAnalyticsUsersStats.usersLoggedInNowDescription') }), jsx(StatCard, { title: t('analyticsAnalyticsUsersStats.usersLoggedInPast30Days'), value: (activeUsers30D === null || activeUsers30D === void 0 ? void 0 : activeUsers30D.count) || 0, loading: isLoadingActiveUsers30D, description: t('analyticsAnalyticsUsersStats.usersLoggedInPast30DaysDescription') }), jsx(StatCard, { title: t('analyticsAnalyticsUsersStats.totalRegisteredUsers'), value: (registeredUsers === null || registeredUsers === void 0 ? void 0 : registeredUsers.count) || 0, loading: isLoadingRegisteredUsers, description: t('analyticsAnalyticsUsersStats.totalRegisteredUsersDescription') })] }), jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-5", children: [jsx(ChartCardWrapper, { title: t('analyticsAnalyticsUsersStats.activeUsersTitle'), label: t('analyticsAnalyticsUsersStats.activeUsersLabel'), filters: activeUsersStatsDateFilter, setOutsideFilters: setActiveUsersStatsDateFilter, description: t('analyticsAnalyticsUsersStats.activeUsersChartDescription'), children: isLoadingActiveUsers ? (jsx(ChartLoading, {})) : ((_a = activeUsers === null || activeUsers === void 0 ? void 0 : activeUsers.points) === null || _a === void 0 ? void 0 : _a.length) && ((_b = activeUsers === null || activeUsers === void 0 ? void 0 : activeUsers.points) === null || _b === void 0 ? void 0 : _b.length) > 0 ? (jsxs(BarChart, { data: (_c = activeUsers === null || activeUsers === void 0 ? void 0 : activeUsers.points) === null || _c === void 0 ? void 0 : _c.map((point) => ({
188190
188430
  date: formatDateToShortFormat$2(point.date, activeUsersStatsDateFilter.activeFilter === 'today'),
@@ -188290,7 +188530,7 @@ const useTopics = ({ tenantKey, mentorId, usergroupIds, }) => {
188290
188530
  function AnalyticsTopicsStats({ tenantKey, mentorId, selectedMentorId, usergroupIds, }) {
188291
188531
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
188292
188532
  const t = useT();
188293
- const currentMentorId = selectedMentorId || mentorId;
188533
+ const currentMentorId = useScopedMentorId(selectedMentorId, mentorId);
188294
188534
  const { topicsStats, isLoadingTopicsStats, conversationsStats, isLoadingConversationsStats, conversationsStatsDateFilter, setConversationsStatsDateFilter, averageRatingStats, averageRatingDateFilter, setAverageRatingDateFilter, topicsDetailsStats, isLoadingTopicsDetailsStats, topicsDetailsDateFilter, setTopicsDetailsDateFilter, } = useTopics({ tenantKey, mentorId: currentMentorId, usergroupIds });
188295
188535
  const averageRatingDisplayed = ((_a = averageRatingStats === null || averageRatingStats === void 0 ? void 0 : averageRatingStats.points) === null || _a === void 0 ? void 0 : _a.length) && ((_b = averageRatingStats === null || averageRatingStats === void 0 ? void 0 : averageRatingStats.points) === null || _b === void 0 ? void 0 : _b.length) > 0;
188296
188536
  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('analyticsAnalyticsTopicsStats.topics'), value: ((_c = topicsStats === null || topicsStats === void 0 ? void 0 : topicsStats.topics) === null || _c === void 0 ? void 0 : _c.this_month) || 0, loading: isLoadingTopicsStats, percentage: ((_d = topicsStats === null || topicsStats === void 0 ? void 0 : topicsStats.topics) === null || _d === void 0 ? void 0 : _d.percentage_change) || 0, description: t('analyticsAnalyticsTopicsStats.topicsDescription') }), jsx(StatCard, { title: t('analyticsAnalyticsTopicsStats.conversations'), value: ((_e = topicsStats === null || topicsStats === void 0 ? void 0 : topicsStats.conversations) === null || _e === void 0 ? void 0 : _e.this_month) || 0, loading: isLoadingTopicsStats, percentage: ((_f = topicsStats === null || topicsStats === void 0 ? void 0 : topicsStats.conversations) === null || _f === void 0 ? void 0 : _f.percentage_change) || 0, description: t('analyticsAnalyticsTopicsStats.conversationsDescription') }), jsx(StatCard, { title: t('analyticsAnalyticsTopicsStats.messages'), value: ((_g = topicsStats === null || topicsStats === void 0 ? void 0 : topicsStats.messages) === null || _g === void 0 ? void 0 : _g.this_month) || 0, loading: isLoadingTopicsStats, percentage: ((_h = topicsStats === null || topicsStats === void 0 ? void 0 : topicsStats.messages) === null || _h === void 0 ? void 0 : _h.percentage_change) || 0, description: t('analyticsAnalyticsTopicsStats.messagesDescription') })] }), jsxs("div", { className: cn('grid grid-cols-1 lg:grid-cols-2 gap-5', !averageRatingDisplayed ? 'lg:grid-cols-1' : ''), children: [jsx(ChartCardWrapper, { title: t('analyticsAnalyticsTopicsStats.conversations'), label: t('analyticsAnalyticsTopicsStats.conversations'), filters: conversationsStatsDateFilter, setOutsideFilters: setConversationsStatsDateFilter, description: t('analyticsAnalyticsTopicsStats.conversationsChartDescription'), children: isLoadingConversationsStats ? (jsx(ChartLoading, {})) : ((_j = conversationsStats === null || conversationsStats === void 0 ? void 0 : conversationsStats.points) === null || _j === void 0 ? void 0 : _j.length) && ((_k = conversationsStats === null || conversationsStats === void 0 ? void 0 : conversationsStats.points) === null || _k === void 0 ? void 0 : _k.length) > 0 ? (jsxs(LineChart, { data: (_l = conversationsStats === null || conversationsStats === void 0 ? void 0 : conversationsStats.points) === null || _l === void 0 ? void 0 : _l.map((point) => ({
@@ -188506,7 +188746,7 @@ const useFinancial = ({ tenantKey, mentorId, usergroupIds, }) => {
188506
188746
  function AnalyticsFinancialStats({ tenantKey, mentorId, selectedMentorId, usergroupIds, }) {
188507
188747
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
188508
188748
  const t = useT();
188509
- const currentMentorId = selectedMentorId || mentorId;
188749
+ const currentMentorId = useScopedMentorId(selectedMentorId, mentorId);
188510
188750
  const { weeklyCostData, isLoadingWeeklyCostData, monthlyCostData, isLoadingMonthlyCostData, totalCostData, isLoadingTotalCostData, detailedCostPerDayData, isLoadingDetailedCostPerDayData, detailedCostPerDayFilters, setDetailedCostPerDayFilters, detailedCostPerProviderData, isLoadingDetailedCostPerProviderData, detailedCostPerProviderFilters, setDetailedCostPerProviderFilters, detailedCostPerUserData, isLoadingDetailedCostPerUserData, detailedCostPerUserFilters, setDetailedCostPerUserFilters, costPerUserPage, setCostPerUserPage, costPerUserLimit, providerColors, detailedLLMCostData, isLoadingDetailedLLMCostData, detailedLLMCostFilters, setDetailedLLMCostFilters, } = useFinancial({ tenantKey, mentorId: currentMentorId, usergroupIds });
188511
188751
  // Pagination handlers
188512
188752
  const handleFirstPage = () => {
@@ -223205,7 +223445,7 @@ const getMessageContent = (content) => {
223205
223445
  function AnalyticsTranscriptsStats({ tenantKey, mentorId, selectedMentorId, usergroupIds, }) {
223206
223446
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
223207
223447
  const t = useT();
223208
- const currentMentorId = selectedMentorId || mentorId;
223448
+ const currentMentorId = useScopedMentorId(selectedMentorId, mentorId);
223209
223449
  const [isModalOpen, setIsModalOpen] = useState(false);
223210
223450
  const searchParams = useSearchParams();
223211
223451
  const router = useRouter();
@@ -223818,6 +224058,8 @@ function AnalyticsReports({ tenantKey, selectedMentorId, disabledReports = [], u
223818
224058
  const t = useT();
223819
224059
  const { currentTenant } = useCurrentTenant();
223820
224060
  const rbacPermissions = useSelector(selectRbacPermissions);
224061
+ const scopedMentorId = useScopedMentorId(selectedMentorId);
224062
+ const scopedMentorDbId = useScopedMentorDbId(selectedMentorDbId);
223821
224063
  const { metadata } = useTenantMetadata({ org: tenantKey });
223822
224064
  //we using metadata to get the combined recommendation reports
223823
224065
  //"combined_recommendation_reports": "Recommendation History Report,Course Grade Report,User Group Member List Report",
@@ -223829,9 +224071,11 @@ function AnalyticsReports({ tenantKey, selectedMentorId, disabledReports = [], u
223829
224071
  }, [metadata === null || metadata === void 0 ? void 0 : metadata.combined_recommendation_reports, metadata === null || metadata === void 0 ? void 0 : metadata.enable_combined_recommendation_report]);
223830
224072
  const { reports, isLoading, initializeReportDownload, activeReportName, isGenerating } = useReports({
223831
224073
  tenantKey,
223832
- selectedMentorId,
224074
+ // Reports keys off both ids: `unique_id` for the agent's public settings,
224075
+ // and the database id for the `mentor_id` filter on the report list.
224076
+ selectedMentorId: scopedMentorId,
223833
224077
  usergroupIds,
223834
- selectedMentorDbId,
224078
+ selectedMentorDbId: scopedMentorDbId,
223835
224079
  });
223836
224080
  const [fetchReportBlob] = useLazyGetDownloadReportFromURLQuery();
223837
224081
  const fetchAuthenticatedContent = useCallback(async (url) => {
@@ -224577,7 +224821,7 @@ function AnalyticsCourses({ tenantKey, mentorId, selectedMentorId, basePath = ''
224577
224821
  var _a, _b, _c, _d;
224578
224822
  const t = useT();
224579
224823
  const router = useRouter();
224580
- const currentMentorId = selectedMentorId || mentorId;
224824
+ const currentMentorId = useScopedMentorId(selectedMentorId, mentorId);
224581
224825
  const { courseStats, isLoading, enrollmentStats, enrollmentStatsDateFilter, setEnrollmentStatsDateFilter, coursesList, setCoursesListPage, coursesListSearch, handleSearchInputChange, coursesPagination, } = useCourses({ tenantKey, mentorId: currentMentorId });
224582
224826
  const handleCourseClick = (courseId) => {
224583
224827
  router.push(`${basePath}/courses/${courseId}`);
@@ -224629,7 +224873,7 @@ function AnalyticsCourses({ tenantKey, mentorId, selectedMentorId, basePath = ''
224629
224873
  function AnalyticsCourseDetail({ tenantKey, mentorId, selectedMentorId, courseId, courseName, showCourseTitle = true, onBack, }) {
224630
224874
  var _a, _b;
224631
224875
  const t = useT();
224632
- const currentMentorId = selectedMentorId || mentorId;
224876
+ const currentMentorId = useScopedMentorId(selectedMentorId, mentorId);
224633
224877
  const { courseDetailStats, isLoading, courseEnrollments, courseEnrollmentsSearch, handleCourseEnrollmentsSearchInputChange, setCourseEnrollmentsPage, courseEnrollmentsPagination, courseInfo, } = useCourses({
224634
224878
  tenantKey,
224635
224879
  mentorId: currentMentorId,
@@ -224936,7 +225180,7 @@ function AnalyticsPrograms({ tenantKey, mentorId, selectedMentorId, basePath = '
224936
225180
  var _a, _b, _c, _d;
224937
225181
  const t = useT();
224938
225182
  const router = useRouter();
224939
- const currentMentorId = selectedMentorId || mentorId;
225183
+ const currentMentorId = useScopedMentorId(selectedMentorId, mentorId);
224940
225184
  const { programStats, isLoading, enrollmentStats, enrollmentStatsDateFilter, setEnrollmentStatsDateFilter, programsList, setProgramsListPage, programsListSearch, handleSearchInputChange, programsPagination, } = usePrograms({ tenantKey, mentorId: currentMentorId });
224941
225185
  const handleProgramClick = (programId) => {
224942
225186
  router.push(`${basePath}/programs/${programId}`);
@@ -224988,7 +225232,7 @@ function AnalyticsPrograms({ tenantKey, mentorId, selectedMentorId, basePath = '
224988
225232
  function AnalyticsProgramDetail({ tenantKey, mentorId, selectedMentorId, programId, programName, onBack, }) {
224989
225233
  var _a, _b;
224990
225234
  const t = useT();
224991
- const currentMentorId = selectedMentorId || mentorId;
225235
+ const currentMentorId = useScopedMentorId(selectedMentorId, mentorId);
224992
225236
  const { programDetailStats, isLoading, programEnrollments, programEnrollmentsSearch, handleProgramEnrollmentsSearchInputChange, setProgramEnrollmentsPage, programEnrollmentsPagination, programInfo, } = usePrograms({
224993
225237
  tenantKey,
224994
225238
  mentorId: currentMentorId,
@@ -225928,7 +226172,7 @@ function summarizeChanges(entry) {
225928
226172
  function AgentAuditLogView({ tenantKey, mentorId, userId, selectedMentorId, }) {
225929
226173
  var _a;
225930
226174
  const t = useT();
225931
- const currentMentorId = selectedMentorId || mentorId;
226175
+ const currentMentorId = useScopedMentorId(selectedMentorId, mentorId);
225932
226176
  const [actorOpen, setActorOpen] = useState(false);
225933
226177
  const { data, isLoading, error, page, setPage, totalPages, actionFilter, setActionFilter, actorFilter, setActorFilter, dateRange, setDateRange, } = useAuditLog({
225934
226178
  tenantKey,
@@ -225982,88 +226226,6 @@ function AnalyticsAuditLogStats({ tenantKey, mentorId, userId, selectedMentorId,
225982
226226
  : t('analyticsAnalyticsAuditLogStats.scopePlatformHint') })] })), activeScope === 'platform' ? (jsx(AnalyticsPlatformAuditLog, { platformKey: tenantKey, timezone: timezone })) : (jsx(AgentAuditLogView, { tenantKey: tenantKey, mentorId: mentorId, userId: userId, selectedMentorId: selectedMentorId }))] }));
225983
226227
  }
225984
226228
 
225985
- /**
225986
- * Core agent search hook — thin wrapper around `useGetAiSearchMentorsQuery`.
225987
- *
225988
- * This is the low-level building block. For a higher-level hook that manages
225989
- * search state, debounce, and pagination controls, use
225990
- * `useAgentSearchWithPagination`.
225991
- */
225992
- function useAgentSearch({ tenantKey, query, limit = 6, offset, starred, featured, category, subjects, llm, types, includeMainPublicMentors, orderDirection, skip = false, }) {
225993
- var _a, _b, _c;
225994
- const { data, isLoading, isFetching, refetch } = useGetAiSearchMentorsQuery({
225995
- platform_key: tenantKey,
225996
- query: query || undefined,
225997
- limit,
225998
- ...(offset !== undefined && { offset }),
225999
- ...(starred !== undefined && { starred }),
226000
- ...(featured !== undefined && { featured }),
226001
- ...(category && { category }),
226002
- ...(subjects && { subjects }),
226003
- ...(llm && { llm }),
226004
- ...(types && { types }),
226005
- ...(includeMainPublicMentors !== undefined && {
226006
- include_main_public_mentors: includeMainPublicMentors,
226007
- }),
226008
- ...(orderDirection && { order_direction: orderDirection }),
226009
- }, { skip: skip || !tenantKey });
226010
- return {
226011
- agents: ((_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : []),
226012
- facets: data === null || data === void 0 ? void 0 : data.facets,
226013
- hasMore: !!(data === null || data === void 0 ? void 0 : data.next),
226014
- totalCount: (_b = data === null || data === void 0 ? void 0 : data.count) !== null && _b !== void 0 ? _b : 0,
226015
- totalPages: (_c = data === null || data === void 0 ? void 0 : data.total_pages) !== null && _c !== void 0 ? _c : 0,
226016
- isLoading,
226017
- isFetching,
226018
- refetch,
226019
- };
226020
- }
226021
-
226022
- function c(e,u,c){var i=this,a=useRef(null),o=useRef(0),f=useRef(null),l=useRef([]),v=useRef(),m=useRef(),d=useRef(e),g=useRef(true);d.current=e;var p="undefined"!=typeof window,w=!u&&0!==u&&p;if("function"!=typeof e)throw new TypeError("Expected a function");u=+u||0;var s=!!(c=c||{}).leading,x=!("trailing"in c)||!!c.trailing,h="maxWait"in c,y="debounceOnServer"in c&&!!c.debounceOnServer,F=h?Math.max(+c.maxWait||0,u):null;useEffect(function(){return g.current=true,function(){g.current=false;}},[]);var A=useMemo(function(){var r=function(r){var n=l.current,t=v.current;return l.current=v.current=null,o.current=r,m.current=d.current.apply(t,n)},n=function(r,n){w&&cancelAnimationFrame(f.current),f.current=w?requestAnimationFrame(r):setTimeout(r,n);},t=function(r){if(!g.current)return false;var n=r-a.current;return !a.current||n>=u||n<0||h&&r-o.current>=F},e=function(n){return f.current=null,x&&l.current?r(n):(l.current=v.current=null,m.current)},c=function r(){var c=Date.now();if(t(c))return e(c);if(g.current){var i=u-(c-a.current),f=h?Math.min(i,F-(c-o.current)):i;n(r,f);}},A=function(){if(p||y){var e=Date.now(),d=t(e);if(l.current=[].slice.call(arguments),v.current=i,a.current=e,d){if(!f.current&&g.current)return o.current=a.current,n(c,u),s?r(a.current):m.current;if(h)return n(c,u),r(a.current)}return f.current||n(c,u),m.current}};return A.cancel=function(){f.current&&(w?cancelAnimationFrame(f.current):clearTimeout(f.current)),o.current=0,l.current=a.current=v.current=f.current=null;},A.isPending=function(){return !!f.current},A.flush=function(){return f.current?e(Date.now()):m.current},A},[s,h,u,F,x,w,p,y]);return A}function i(r,n){return r===n}function a(n,t,a){var o=i,f=useRef(n),l=useState({})[1],v=c(useCallback(function(r){f.current=r,l({});},[l]),t,a),m=useRef(n);return o(m.current,n)||(v(n),m.current=n),[f.current,v]}
226023
-
226024
- /**
226025
- * Higher-level agent search hook that manages search state, debounce, and
226026
- * pagination controls on top of `useAgentSearch`.
226027
- *
226028
- * Use this for simple list/table views (MyMentorsModal, SettingsModal).
226029
- * For the full explore page with sections, use `useAgentSearch` directly.
226030
- */
226031
- function useAgentSearchWithPagination({ itemsPerPage = 6, paginationMode = 'paginated', debounceMs = 500, ...queryConfig }) {
226032
- const [searchQuery, setSearchQuery] = React__default.useState('');
226033
- const [debouncedQuery] = a(searchQuery, debounceMs);
226034
- const [currentPage, setCurrentPage] = React__default.useState(1);
226035
- const [infiniteLimit, setInfiniteLimit] = React__default.useState(itemsPerPage);
226036
- // Reset pagination when search changes
226037
- React__default.useEffect(() => {
226038
- setCurrentPage(1);
226039
- setInfiniteLimit(itemsPerPage);
226040
- }, [debouncedQuery, itemsPerPage]);
226041
- const isPaginated = paginationMode === 'paginated';
226042
- const result = useAgentSearch({
226043
- ...queryConfig,
226044
- query: debouncedQuery,
226045
- limit: isPaginated ? itemsPerPage : infiniteLimit,
226046
- offset: isPaginated ? (currentPage - 1) * itemsPerPage : undefined,
226047
- });
226048
- const totalPages = Math.ceil(result.totalCount / itemsPerPage);
226049
- const handlePageChange = React__default.useCallback((page) => {
226050
- setCurrentPage(page);
226051
- }, []);
226052
- const loadMore = React__default.useCallback(() => {
226053
- setInfiniteLimit((prev) => prev + itemsPerPage);
226054
- }, [itemsPerPage]);
226055
- return {
226056
- ...result,
226057
- searchQuery,
226058
- setSearchQuery,
226059
- debouncedQuery,
226060
- currentPage,
226061
- totalPages,
226062
- handlePageChange,
226063
- loadMore,
226064
- };
226065
- }
226066
-
226067
226229
  function MentorSelectionGrid({ selectedMentorIds, onMentorSelect, searchQuery, onSearchChange, tenantKey, itemsPerPage = 8, showSearch = true, minHeight = '400px', }) {
226068
226230
  const t = useT();
226069
226231
  const { agents: mentors, isLoading: isMentorsLoading, isFetching: isMentorsFetching, currentPage, totalPages, setSearchQuery: setMentorSearch, handlePageChange, } = useAgentSearchWithPagination({ tenantKey, itemsPerPage });
@@ -226462,6 +226624,7 @@ function AgentSearchDialog({ tenantKey, open, onClose, selectedMentorId, onSelec
226462
226624
  */
226463
226625
  function AnalyticsMemoryStats({ tenantKey, mentorId, userId, selectedMentorId, myMemory = false, }) {
226464
226626
  const t = useT();
226627
+ const scopedMentorId = useScopedMentorId(selectedMentorId, mentorId);
226465
226628
  const [selectedMemory, setSelectedMemory] = useState(null);
226466
226629
  const [agentSearchOpen, setAgentSearchOpen] = useState(false);
226467
226630
  // The content search is committed on Enter/blur rather than per-keystroke so
@@ -226470,7 +226633,10 @@ function AnalyticsMemoryStats({ tenantKey, mentorId, userId, selectedMentorId, m
226470
226633
  const { scope, setScope, availableScopes, searchedMentor, selectSearchedMentor, rows, aggregates, categories, isLoading, error, isForbidden, page, setPage, totalPages, learnerFilter, setLearnerFilter, categoryFilter, setCategoryFilter, setContentFilter, dateRange, setDateRange, } = useMemory({
226471
226634
  tenantKey,
226472
226635
  userId,
226473
- mentorId: selectedMentorId || mentorId,
226636
+ // The agent scope picker feeds the same slot the route agent would, so the
226637
+ // tab's own agent search still overrides it (`searchedMentor || mentorId`)
226638
+ // rather than the two controls fighting over the scope.
226639
+ mentorId: scopedMentorId,
226474
226640
  myMemory,
226475
226641
  });
226476
226642
  const scopeLabels = {
@@ -237303,5 +237469,5 @@ var trainOrDeleteModal = /*#__PURE__*/Object.freeze({
237303
237469
  TrainOrDeleteModal: TrainOrDeleteModal
237304
237470
  });
237305
237471
 
237306
- export { ACCESS_COURSE_LABEL, ALL_CATEGORIES, AccessTimeHeatmap, AccessiblePaginate, AddMentorToProjectModal, AddSkillDialog, Admin, AdvancedTab, AgentConfigPrompts, AgentSkills, AlertsTab, AnalyticsAuditLogStats, AnalyticsCourseDetail, AnalyticsCourses, AnalyticsFinancialStats, AnalyticsLayout, AnalyticsMemoryStats, AnalyticsMonetizationStats, AnalyticsOverview, AnalyticsPlatformAuditLog, AnalyticsProgramDetail, AnalyticsPrograms, AnalyticsReportDownload, AnalyticsReports, AnalyticsSettingsProvider, AnalyticsTopicsStats, AnalyticsTranscriptsStats, AnalyticsUsersStats, AppleRestrictionModal, ApplyWizard, AuditLogChangesView, AuditLogJsonView, BUY_NOW_LABEL, BillingTab, CATALOGS, CREATE_AGENT_LABELS, CUA_DRIVER_REPO_URL, CUA_DRIVER_TAURI_COMMANDS, CUA_DRIVER_TAURI_EVENTS, CardInfoIcon, CategorizedDropdownMenu, ChartCardWrapper, ChartFiltersProvider, ChartLoading, ChatContext, ChatPrivacyToggle, ChatProvider, CompanyDialog, ConnectorManagementDialog, CopyButtonIcon, CourseAccessGuard, CourseCardSkeleton, CourseContentLoading, CourseOutline, CourseOutlineContext, CourseOutlineDrawer, CreateAgentForm, CreateAgentModal, CreateProjectModal, CreateWorkflowModal, CredentialBox, CredentialMiniBoxSkeleton, CredentialsList, CreditBalance, CustomDateRangePicker, CustomTooltip, DEFAULT_COWORK_REQUIRED_SIZE_GB, DEFAULT_LOCALE, DefaultEmptyBox, DeleteProjectModal, DeleteWorkflowModal, DiscoverContentCard, DiscoverFacetsFilter, DiscoverFilterDrawer, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, ENROLL_NOW_COURSE_STARTING_SOON_LABEL, ENROLL_NOW_LABEL, EditAlertDialog, EducationBox, EducationDialog, EducationTab, EdxIframeContext, EmptyStats, ExperienceBox, ExperienceDialog, ExperienceTab, FacetFilterContext, Footer, GradebookTab, GroupsFilterDropdown, INVITATION_ONLY_LABEL, InstitutionDialog, IntegrationsTab, InviteUserContent, InviteUserDialog, InvitedUsersDialog, LOCAL_MODELS, Loader, LocalLLMTab, LocalModelsContent, LoginButton, MACOS_PERMISSIONS_COMMANDS, MEMORY_PAGE_SIZE, Markdown, MinimumMentorAlert, MonetizationTab, NotificationDisplay, NotificationDropdown, ONBOARDING_SECTORS, OnboardingShell, OnboardingWizard, PLATFORM_AUDIT_DEEP_PAGING_THRESHOLD, PLATFORM_AUDIT_PAGE_SIZE, PaywallModal, PlacementExam, PlacementExamsDropdown, PlatformAuditLogDetailSheet, PlatformNavbar, PlatformNavbarSearch, Profile, ProfileTimeChart, ProgressDots, ProjectActionButtons, ProjectFilesModal, ProjectInstructionsModal, ProjectLandingPage, ProjectMentorsList, ProjectsPage, REQUEST_ACCESS_COURSE_STARTING_SOON_LABEL, REQUEST_ACCESS_LABEL, RenameProjectModal, ResumeBox, ResumeTab, RichTextEditor, SUPPORTED_LOCALES, SandboxConfig, SearchableMultiSelect, SendNotificationDialog, SignupButton, SkeletonActivityStatBox, SkeletonAddSkillsLoading, SkeletonCreatePathwaySearchList, SkeletonDiscoverFilterBox, SkeletonEducationBox, SkeletonMultiplier, SkeletonPathwayBox, SkeletonProfileInfoCard, SkeletonSkillBox, SkillBox, SkillDetailModal, SkillLeaderboardChart, SkillsBox, SkillsList, SlashSkillPicker, Spinner, StatCard, StepHeader, TAURI_COMMANDS, TAURI_EVENTS, TenantSwitcher, TimeFilter, TimeTrackingProvider, TimedExam, ToolDialogs, TopBanner, UpgradePackageModal, UserAvatar, Version, WebContainersI18nProvider, WorkflowSidebar, addBookmarksTab, availablePlacementExams, findLastResumeBlock, findSequentialParent, flattenVerticalBlocks, formatAuditTimestamp, formatTimeZoneLabel, getCatalog, getFirstAvailableUnit, getLocalLLMModel, getLocalLLMToolSupport, getNextUnitIframe, getOrg, getParentBlockById, getParentsInfosFromSublessonId, getPreviousUnitIframe, getRandomCourseImage, getSectorById, getTenant, getUnitToIframe, getUserId, getUserName, humanizeAuditToken, inBrowserPrint, inIframe, initialCuaDriverInstallState, initialModelDownloadState, isCoworkEnabled, isLocalLLMEnabled, isPlatformNavbarCreditBalanceVisible, isSlashCommandToken, isTauriApp, isValidLocale, isValidTimeZone, components as markdownComponents, modelSupportsCowork, onboardingPrimaryButtonClass, onboardingSecondaryButtonClass, resolveAuditTimeZone, resolveCreateAgentLabels, sanitizeCss, setCoworkEnabled, setLocalLLMEnabled, setLocalLLMModel, setLocalLLMToolSupport, smallestCoworkModel, useAnalyticsSettings, useAuditLog, useCatalogSearch, useChartFilters, useChatPrivacy, useChatState, useCourseDetail, useCourseMetadata, useCourses, useCuaDriver, useDiscover, useEdxIframe, useFinancial, useIframeMessageHandler, useLocalStorage, useMemory, useModelDownload, useMonetization, useOverview, usePlatformAuditLabels, usePlatformAuditLog, useProfileActivityStats, useProfileCredentials, useProfilePathways, useProfilePrograms, useProfileSkills, useProfileTimeSpent, usePrograms, useReports, useSlashSkillPicker, useSlashSkills, useT, useTauri, useTimeTracking, useTopics, useTranscripts, useUserCourses, useUserMetadata, useUsers, useWebContainersI18n, useWebContainersLocale };
237472
+ export { ACCESS_COURSE_LABEL, ALL_CATEGORIES, AccessTimeHeatmap, AccessiblePaginate, AddMentorToProjectModal, AddSkillDialog, Admin, AdvancedTab, AgentConfigPrompts, AgentSkills, AlertsTab, AnalyticsAgentPicker, AnalyticsAuditLogStats, AnalyticsCourseDetail, AnalyticsCourses, AnalyticsFinancialStats, AnalyticsLayout, AnalyticsMemoryStats, AnalyticsMonetizationStats, AnalyticsOverview, AnalyticsPlatformAuditLog, AnalyticsProgramDetail, AnalyticsPrograms, AnalyticsReportDownload, AnalyticsReports, AnalyticsScopeProvider, AnalyticsSettingsProvider, AnalyticsTopicsStats, AnalyticsTranscriptsStats, AnalyticsUsersStats, AppleRestrictionModal, ApplyWizard, AuditLogChangesView, AuditLogJsonView, BUY_NOW_LABEL, BillingTab, CATALOGS, CREATE_AGENT_LABELS, CUA_DRIVER_REPO_URL, CUA_DRIVER_TAURI_COMMANDS, CUA_DRIVER_TAURI_EVENTS, CardInfoIcon, CategorizedDropdownMenu, ChartCardWrapper, ChartFiltersProvider, ChartLoading, ChatContext, ChatPrivacyToggle, ChatProvider, CompanyDialog, ConnectorManagementDialog, CopyButtonIcon, CourseAccessGuard, CourseCardSkeleton, CourseContentLoading, CourseOutline, CourseOutlineContext, CourseOutlineDrawer, CreateAgentForm, CreateAgentModal, CreateProjectModal, CreateWorkflowModal, CredentialBox, CredentialMiniBoxSkeleton, CredentialsList, CreditBalance, CustomDateRangePicker, CustomTooltip, DEFAULT_COWORK_REQUIRED_SIZE_GB, DEFAULT_LOCALE, DefaultEmptyBox, DeleteProjectModal, DeleteWorkflowModal, DiscoverContentCard, DiscoverFacetsFilter, DiscoverFilterDrawer, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, ENROLL_NOW_COURSE_STARTING_SOON_LABEL, ENROLL_NOW_LABEL, EditAlertDialog, EducationBox, EducationDialog, EducationTab, EdxIframeContext, EmptyStats, ExperienceBox, ExperienceDialog, ExperienceTab, FacetFilterContext, Footer, GradebookTab, GroupsFilterDropdown, INVITATION_ONLY_LABEL, InstitutionDialog, IntegrationsTab, InviteUserContent, InviteUserDialog, InvitedUsersDialog, LOCAL_MODELS, Loader, LocalLLMTab, LocalModelsContent, LoginButton, MACOS_PERMISSIONS_COMMANDS, MEMORY_PAGE_SIZE, Markdown, MinimumMentorAlert, MonetizationTab, NotificationDisplay, NotificationDropdown, ONBOARDING_SECTORS, OnboardingShell, OnboardingWizard, PLATFORM_AUDIT_DEEP_PAGING_THRESHOLD, PLATFORM_AUDIT_PAGE_SIZE, PaywallModal, PlacementExam, PlacementExamsDropdown, PlatformAuditLogDetailSheet, PlatformNavbar, PlatformNavbarSearch, Profile, ProfileTimeChart, ProgressDots, ProjectActionButtons, ProjectFilesModal, ProjectInstructionsModal, ProjectLandingPage, ProjectMentorsList, ProjectsPage, REQUEST_ACCESS_COURSE_STARTING_SOON_LABEL, REQUEST_ACCESS_LABEL, RenameProjectModal, ResumeBox, ResumeTab, RichTextEditor, SUPPORTED_LOCALES, SandboxConfig, SearchableMultiSelect, SendNotificationDialog, SignupButton, SkeletonActivityStatBox, SkeletonAddSkillsLoading, SkeletonCreatePathwaySearchList, SkeletonDiscoverFilterBox, SkeletonEducationBox, SkeletonMultiplier, SkeletonPathwayBox, SkeletonProfileInfoCard, SkeletonSkillBox, SkillBox, SkillDetailModal, SkillLeaderboardChart, SkillsBox, SkillsList, SlashSkillPicker, Spinner, StatCard, StepHeader, TAURI_COMMANDS, TAURI_EVENTS, TenantSwitcher, TimeFilter, TimeTrackingProvider, TimedExam, ToolDialogs, TopBanner, UpgradePackageModal, UserAvatar, Version, WebContainersI18nProvider, WorkflowSidebar, addBookmarksTab, availablePlacementExams, findLastResumeBlock, findSequentialParent, flattenVerticalBlocks, formatAuditTimestamp, formatTimeZoneLabel, getCatalog, getFirstAvailableUnit, getLocalLLMModel, getLocalLLMToolSupport, getNextUnitIframe, getOrg, getParentBlockById, getParentsInfosFromSublessonId, getPreviousUnitIframe, getRandomCourseImage, getSectorById, getTenant, getUnitToIframe, getUserId, getUserName, humanizeAuditToken, inBrowserPrint, inIframe, initialCuaDriverInstallState, initialModelDownloadState, isCoworkEnabled, isLocalLLMEnabled, isPlatformNavbarCreditBalanceVisible, isSlashCommandToken, isTauriApp, isValidLocale, isValidTimeZone, components as markdownComponents, modelSupportsCowork, onboardingPrimaryButtonClass, onboardingSecondaryButtonClass, resolveAuditTimeZone, resolveCreateAgentLabels, sanitizeCss, setCoworkEnabled, setLocalLLMEnabled, setLocalLLMModel, setLocalLLMToolSupport, smallestCoworkModel, useAnalyticsScope, useAnalyticsSettings, useAuditLog, useCatalogSearch, useChartFilters, useChatPrivacy, useChatState, useCourseDetail, useCourseMetadata, useCourses, useCuaDriver, useDiscover, useEdxIframe, useFinancial, useIframeMessageHandler, useLocalStorage, useMemory, useModelDownload, useMonetization, useOverview, usePlatformAuditLabels, usePlatformAuditLog, useProfileActivityStats, useProfileCredentials, useProfilePathways, useProfilePrograms, useProfileSkills, useProfileTimeSpent, usePrograms, useReports, useScopedMentorDbId, useScopedMentorId, useSlashSkillPicker, useSlashSkills, useT, useTauri, useTimeTracking, useTopics, useTranscripts, useUserCourses, useUserMetadata, useUsers, useWebContainersI18n, useWebContainersLocale };
237307
237473
  //# sourceMappingURL=index.esm.js.map