@iblai/iblai-js 2.3.5 → 2.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data-layer/playwright/grader-tab-helpers.d.ts +41 -7
- package/dist/data-layer/playwright/index.d.ts +1 -1
- package/dist/playwright/index.cjs +111 -11
- package/dist/playwright/index.cjs.map +1 -1
- package/dist/playwright/index.d.ts +42 -8
- package/dist/playwright/index.esm.js +108 -12
- package/dist/playwright/index.esm.js.map +1 -1
- package/dist/playwright/playwright/grader-tab-helpers.d.ts +41 -7
- package/dist/playwright/playwright/index.d.ts +1 -1
- package/dist/security/playwright/grader-tab-helpers.d.ts +41 -7
- package/dist/security/playwright/index.d.ts +1 -1
- package/dist/web-containers/playwright/grader-tab-helpers.d.ts +41 -7
- package/dist/web-containers/playwright/index.d.ts +1 -1
- package/dist/web-containers/source/index.esm.js +1303 -303
- package/dist/web-containers/source/next/index.esm.js +1213 -326
- package/dist/web-utils/playwright/grader-tab-helpers.d.ts +41 -7
- package/dist/web-utils/playwright/index.d.ts +1 -1
- package/package.json +5 -5
|
@@ -2,8 +2,8 @@ import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import React__default, { useState, useEffect, forwardRef, createElement as createElement$3, useLayoutEffect, createContext, useContext, useMemo, useReducer, useRef, useImperativeHandle, useCallback, isValidElement, Children, PureComponent, cloneElement, Component as Component$1, useId as useId$2, useDebugValue, lazy, Suspense } from 'react';
|
|
4
4
|
import * as dataLayer from '@iblai/data-layer';
|
|
5
|
-
import { useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useGetLearnerDetailsQuery, useGetUserEnrolledCoursesQuery, useGetUserEnrolledProgramsQuery, useGetUserCatalogPathwaysQuery, useGetUsersAsAssertionsQuery, useGetUserEarnedSkillsQuery, useGetUserReportedSkillsQuery, useGetUserDesiredSkillsQuery, useCreateGlobalMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacActionsDefinitionQuery, useGetRbacResourceDiscoveryQuery, useGetRbacResourceListQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useGetWatchedGroupsQuery, useCreateWatchedGroupMutation, useUpdateWatchedGroupMutation, useDeleteWatchedGroupMutation, useAddWatchedUserMutation, useRemoveWatchedUserMutation, useAddWatcherMutation, useUpdateWatcherMutation, useDeleteWatcherMutation, useGetWatchedUsersQuery, useGetWatchersQuery, WATCHER_NOTIFICATION_EVENTS, WATCHER_NOTIFICATION_EVENT_LABELS, useGetApplicationFormsQuery, useGetApplicationFormDetailQuery, useCreateApplicationFormMutation, useUpdateApplicationFormMutation, useGetApplicationAdminDetailQuery, useInviteApplicationCandidateMutation, useLazyGetApplicationAttachmentFileQuery, useCreateApplicationWaiverMutation, useDeleteApplicationWaiverMutation, useSubmitApplicationOverrideMutation, useUpdateApplicationPlacementMutation, useDeleteApplicationCourseAssignmentMutation, useCreateApplicationNoteMutation, useUpdateApplicationNoteMutation, useDeleteApplicationNoteMutation, useTransitionApplicationMutation, useLinkApplicationCandidateMutation, useCreateApplicationPlacementsMutation, useGetCustomMentorsQuery, useCreateApplicationCourseAssignmentsMutation, useGetApplicationBlocksQuery, useDeleteApplicationBlockMutation, useGetApplicationsPipelineStatsQuery, useGetApplicationsPipelineQuery, useDeleteApiKeyMutation, useGetApiKeyQuery, useGetApiKeyFieldPermissionsQuery, useUpdateApiKeyMutation, useGetApiKeysQuery, unwrapApiTokenList, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, useGetCustomDomainsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useUpdateTenantMetadataMutation, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useGetMemsearchConfigQuery, useUpdateMemsearchConfigMutation, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useGetAiSearchMentorsQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetAgentSkillResourcesQuery, useCreateAgentSkillResourceMutation, useUpdateAgentSkillResourceMutation, useUploadAgentSkillResourceAssetMutation, useDeleteAgentSkillResourceMutation, useGetAgentSkillsQuery, useGetMentorSkillAssignmentsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, resolveEffectiveAgentSkills, filterSlashSkills, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useGetVectorDocumentsQuery, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useDeleteMentorMemoryMutation, useUpdateMentorMemoryMutation, useCreateMentorMemoryMutation, useLazyGetConnectedServiceAuthUrlQuery, useStarMentorMutation, useUnstarMentorMutation, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorSettingsQuery, useEditMentorMutation, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, LOGO_ENDPOINTS, useCreateEvalDatasetMutation, useAddEvalDatasetItemsMutation, useUploadEvalDatasetCsvMutation, useDeleteEvalDatasetItemMutation, useListEvalDatasetItemsQuery, evalTotalPages, useListEvalDatasetsQuery, useGetUserProjectsQuery, useCreateSessionIdMutation, useGetMentorCategoriesQuery, useGetTenantChatPrivacyConfigQuery as useGetTenantChatPrivacyConfigQuery$1, useGetCallConfigurationsQuery, useCreateCallConfigurationMutation, useUpdateCallConfigurationMutation, chatPrivacyApiSlice, useDeleteMentorMutation, useForkMentorMutation, useGetToolsQuery, useLazyGetMCPServersQuery, useOauthFindMutation, useLazyStartOAuthFlowQuery, useCreateMCPServerMutation, usePartialUpdateMCPServerMutation, useCreateMCPServerConnectionMutation, usePatchMCPServerConnectionMutation, useGetConnectedServicesQuery, useGetMCPServersQuery, useGetMCPServerConnectionsQuery, useUpdateMCPServerMutation, useDeleteMCPServerMutation, useEditMentorJsonMutation, useDisconnectServiceMutation, useGetPromptCategoriesQuery, PRIVACY_ACTIONS, PRIVACY_ENTITY_TYPES, useGetVoicesQuery, useGetVoiceQuery, isBaseAgentMentor, useGetMentorGraderConfigurationQuery, useListGraderCriteriaQuery, useCreateMentorGraderConfigurationMutation, useUpdateMentorGraderConfigurationMutation, useCreateGraderCriterionMutation, useUpdateGraderCriterionMutation, useDeleteGraderCriterionMutation, useGetMentorPublicSettingsQuery, useGetChatHistoryFilterQuery, useGetChatHistoryQuery, useGetMentorSummariesQuery, useGetConversationMemoriesQuery, useGetSupportTicketsQuery, useGetSupportTicketMessagesQuery, useCreateSupportTicketMessageMutation, usePatchSupportTicketMutation, useCloseSupportTicketMutation, useCreateLtiMentorMutation, useUpdateLtiMentorMutation, useGetLtiMentorsQuery, useCreateLtiKeyMutation, useUpdateLtiKeyMutation, useDeleteLtiKeyMutation, useGetLtiKeysQuery, useCreateLtiToolMutation, useUpdateLtiToolMutation, useGetLtiToolsQuery, useGetPlatformInfoQuery, useCreatePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useCreateRedirectTokenMutation, useGetShareableLinkQuery, useCreateShareableLinkMutation, useUpdateShareableLinkMutation, useCreateDisclaimerMutation, useUpdateDisclaimerMutation, useGetDisclaimersQuery, useUpdateRbacMentorAccessMutation, useGetRbacMentorAccessListQuery, useStartEvalRunMutation, useEvaluateEvalRunMutation, useGetEvalRunQuery, useDeleteEvalScoreMutation, useListEvalRunJudgesQuery, useCreateEvalScoreMutation, useDeleteEvalRunMutation, useExportEvalRunMutation, useListEvalRunsQuery, useLazyGetEvalRunQuery, evaluationsApiSlice, EVALUATIONS_TAGS, useGetPersonnalizedMentorsQuery, useCreateCallCredentialsMutation, useGetGuidedPromptsQuery, useUpdateChatSessionSharedMutation, useUpdateMessageFeedbackMutation, useLazyGetPromptsSearchQuery, useLazyGetGuidedPromptsQuery, useGetPublicMentorsQuery, useGetPeriodicAgentsQuery, useGetPeriodicAgentLogsListQuery, useCreatePeriodicAgentMutation, useDeletePeriodicAgentMutation, useDeletePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useUpdateArtifactMutation, useLazyGetArtifactVersionQuery, useLazyListArtifactVersionsQuery, useSetCurrentVersionMutation, useListArtifactVersionsQuery, useLazyGetArtifactQuery, useLazyListArtifactsQuery, useEditSessionMutation } from '@iblai/data-layer';
|
|
6
|
-
import { getInitials, useTenantMetadata, WithPermissions, canWriteField, useStripeUpgrade, openExternalUrl, CHAT_AREA_SIZE, isAlphaNumeric32, checkRbacPermission, selectNumberOfActiveChatMessages, useUsername, selectStreaming, isLoggedIn, TOOLS, hasRemoteAiConfig, isSafariBrowser, useShowAttachment, useShowVoiceCall, useShowVoiceRecorder, useMentorSettings, selectShowingSharedChat,
|
|
5
|
+
import { useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useGetLearnerDetailsQuery, useGetUserEnrolledCoursesQuery, useGetUserEnrolledProgramsQuery, useGetUserCatalogPathwaysQuery, useGetUsersAsAssertionsQuery, useGetUserEarnedSkillsQuery, useGetUserReportedSkillsQuery, useGetUserDesiredSkillsQuery, useCreateGlobalMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useGetAllMentorMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, useGetAccessibleUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacActionsDefinitionQuery, useGetRbacResourceDiscoveryQuery, useGetRbacResourceListQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useGetWatchedGroupsQuery, useCreateWatchedGroupMutation, useUpdateWatchedGroupMutation, useDeleteWatchedGroupMutation, useAddWatchedUserMutation, useRemoveWatchedUserMutation, useAddWatcherMutation, useUpdateWatcherMutation, useDeleteWatcherMutation, useGetWatchedUsersQuery, useGetWatchersQuery, WATCHER_NOTIFICATION_EVENTS, WATCHER_NOTIFICATION_EVENT_LABELS, useGetApplicationFormsQuery, useGetApplicationFormDetailQuery, useCreateApplicationFormMutation, useUpdateApplicationFormMutation, useGetApplicationAdminDetailQuery, useInviteApplicationCandidateMutation, useLazyGetApplicationAttachmentFileQuery, useCreateApplicationWaiverMutation, useDeleteApplicationWaiverMutation, useSubmitApplicationOverrideMutation, useUpdateApplicationPlacementMutation, useDeleteApplicationCourseAssignmentMutation, useCreateApplicationNoteMutation, useUpdateApplicationNoteMutation, useDeleteApplicationNoteMutation, useTransitionApplicationMutation, useLinkApplicationCandidateMutation, useCreateApplicationPlacementsMutation, useGetCustomMentorsQuery, useCreateApplicationCourseAssignmentsMutation, useGetApplicationBlocksQuery, useDeleteApplicationBlockMutation, useGetApplicationsPipelineStatsQuery, useGetApplicationsPipelineQuery, useDeleteApiKeyMutation, useGetApiKeyQuery, useGetApiKeyFieldPermissionsQuery, useUpdateApiKeyMutation, useGetApiKeysQuery, unwrapApiTokenList, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, useGetCustomDomainsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useUpdateTenantMetadataMutation, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useGetMemsearchConfigQuery, useUpdateMemsearchConfigMutation, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useGetAiSearchMentorsQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useStarMentorMutation, useUnstarMentorMutation, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetAgentSkillResourcesQuery, useCreateAgentSkillResourceMutation, useUpdateAgentSkillResourceMutation, useUploadAgentSkillResourceAssetMutation, useDeleteAgentSkillResourceMutation, useGetAgentSkillsQuery, useGetMentorSkillAssignmentsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, resolveEffectiveAgentSkills, filterSlashSkills, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useGetVectorDocumentsQuery, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useDeleteMentorMemoryMutation, useUpdateMentorMemoryMutation, useCreateMentorMemoryMutation, useLazyGetConnectedServiceAuthUrlQuery, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorSettingsQuery, useEditMentorMutation, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, LOGO_ENDPOINTS, useCreateEvalDatasetMutation, useAddEvalDatasetItemsMutation, useUploadEvalDatasetCsvMutation, useDeleteEvalDatasetItemMutation, useListEvalDatasetItemsQuery, evalTotalPages, useListEvalDatasetsQuery, useGetUserProjectsQuery, useCreateSessionIdMutation, useGetMentorCategoriesQuery, useGetTenantChatPrivacyConfigQuery as useGetTenantChatPrivacyConfigQuery$1, useGetCallConfigurationsQuery, useCreateCallConfigurationMutation, useUpdateCallConfigurationMutation, chatPrivacyApiSlice, useDeleteMentorMutation, useForkMentorMutation, useGetToolsQuery, useLazyGetMCPServersQuery, useOauthFindMutation, useLazyStartOAuthFlowQuery, useCreateMCPServerMutation, usePartialUpdateMCPServerMutation, useCreateMCPServerConnectionMutation, usePatchMCPServerConnectionMutation, useGetConnectedServicesQuery, useGetMCPServersQuery, useGetMCPServerConnectionsQuery, useUpdateMCPServerMutation, useDeleteMCPServerMutation, useEditMentorJsonMutation, useDisconnectServiceMutation, useGetPromptCategoriesQuery, PRIVACY_ACTIONS, PRIVACY_ENTITY_TYPES, useGetVoicesQuery, useGetVoiceQuery, isBaseAgentMentor, useGetGradeResultQuery, useOverrideGradeResultMutation, useGetChatHistoryFilterQuery, useListGradeResultsQuery, useGetMentorGraderConfigurationQuery, useListGraderCriteriaQuery, useCreateMentorGraderConfigurationMutation, useUpdateMentorGraderConfigurationMutation, useCreateGraderCriterionMutation, useUpdateGraderCriterionMutation, useDeleteGraderCriterionMutation, useGetMentorPublicSettingsQuery, useGetChatHistoryQuery, useGetMentorSummariesQuery, useGetConversationMemoriesQuery, useGetSupportTicketsQuery, useGetSupportTicketMessagesQuery, useCreateSupportTicketMessageMutation, usePatchSupportTicketMutation, useCloseSupportTicketMutation, useCreateLtiMentorMutation, useUpdateLtiMentorMutation, useGetLtiMentorsQuery, useCreateLtiKeyMutation, useUpdateLtiKeyMutation, useDeleteLtiKeyMutation, useGetLtiKeysQuery, useCreateLtiToolMutation, useUpdateLtiToolMutation, useGetLtiToolsQuery, useGetPlatformInfoQuery, useCreatePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useCreateRedirectTokenMutation, useGetShareableLinkQuery, useCreateShareableLinkMutation, useUpdateShareableLinkMutation, useCreateDisclaimerMutation, useUpdateDisclaimerMutation, useGetDisclaimersQuery, useUpdateRbacMentorAccessMutation, useGetRbacMentorAccessListQuery, useStartEvalRunMutation, useEvaluateEvalRunMutation, useGetEvalRunQuery, useDeleteEvalScoreMutation, useListEvalRunJudgesQuery, useCreateEvalScoreMutation, useDeleteEvalRunMutation, useExportEvalRunMutation, useListEvalRunsQuery, useLazyGetEvalRunQuery, evaluationsApiSlice, EVALUATIONS_TAGS, useGetPersonnalizedMentorsQuery, useCreateCallCredentialsMutation, useGetGuidedPromptsQuery, useUpdateChatSessionSharedMutation, useUpdateMessageFeedbackMutation, useLazyGetPromptsSearchQuery, useLazyGetGuidedPromptsQuery, useGetPublicMentorsQuery, useGetPeriodicAgentsQuery, useGetPeriodicAgentLogsListQuery, useCreatePeriodicAgentMutation, useDeletePeriodicAgentMutation, useDeletePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useUpdateArtifactMutation, useLazyGetArtifactVersionQuery, useLazyListArtifactVersionsQuery, useSetCurrentVersionMutation, useListArtifactVersionsQuery, useLazyGetArtifactQuery, useLazyListArtifactsQuery, useEditSessionMutation } from '@iblai/data-layer';
|
|
6
|
+
import { getInitials, useTenantMetadata, useCurrentTenant, selectRbacPermissions, isPureWatcher, WithPermissions, canWriteField, useStripeUpgrade, openExternalUrl, CHAT_AREA_SIZE, isAlphaNumeric32, checkRbacPermission, selectNumberOfActiveChatMessages, useUsername, selectStreaming, isLoggedIn, TOOLS, hasRemoteAiConfig, isSafariBrowser, useShowAttachment, useShowVoiceCall, useShowVoiceRecorder, useMentorSettings, selectShowingSharedChat, useShowFreeTrialDialog, useEmbedMode, chatInputSliceSelectors, useResponsive, useAccessingPublicRoute, useVisitingTenant, useModelFileUploadCapabilities, useChatFileUpload, useVoiceChat, selectAttachedFiles, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, removeFile, chatInputSliceActions, chatActions, WithFormPermissions, useTenantContext, TimeTracker, advancedTabsProperties, defaultSessionIds, pickWritableFields, ANONYMOUS_USERNAME as ANONYMOUS_USERNAME$3, redirectToAuthSpaJoinTenant, selectActiveTab, useAxdToken, useWelcomeMessage, markdownToPlainText, useCachedSessionId, use402ErrorCheck, selectTokenEnabled, selectToken, useServiceWorker, useUserAgreement, useAdvancedChat, sendMessageToParentWebsite, useMentorTools, useFileDragDrop, eventBus, RemoteEvents, selectEnableChatActionsPopup, advancedTabs, isInIframe, getAuthSpaJoinUrl, addMessage, clearFiles, MENTOR_VISIBILITY } from '@iblai/web-utils';
|
|
7
7
|
import { useDispatch, useSelector } from 'react-redux';
|
|
8
8
|
import { toast } from 'sonner';
|
|
9
9
|
import { useSearchParams, useParams, useRouter, usePathname } from 'next/navigation';
|
|
@@ -97537,6 +97537,37 @@ var analyticsAnalyticsFinancialStats$3 = {
|
|
|
97537
97537
|
goToLastPage: "Go to last page",
|
|
97538
97538
|
paginationShowing: "Showing {from} to {to} of {total} results"
|
|
97539
97539
|
};
|
|
97540
|
+
var analyticsAnalyticsMemoryStats$3 = {
|
|
97541
|
+
noPermission: "You do not have permission to view user memories.",
|
|
97542
|
+
scopeLabel: "Memory scope",
|
|
97543
|
+
scopeMentor: "This Agent",
|
|
97544
|
+
scopeAllMentors: "All Agents",
|
|
97545
|
+
scopeGlobal: "Global",
|
|
97546
|
+
searchAgents: "Search Agents…",
|
|
97547
|
+
searchAgentsTitle: "Search Agents",
|
|
97548
|
+
clearAgentSearch: "Clear Agent Search",
|
|
97549
|
+
contentPlaceholder: "Search memory content",
|
|
97550
|
+
pickDateRange: "Pick a Date Range",
|
|
97551
|
+
allCategories: "All Categories",
|
|
97552
|
+
byCategory: "Memories by Category",
|
|
97553
|
+
categoryCount: "{count} ({percent}%)",
|
|
97554
|
+
loadError: "An error occurred while loading memories.",
|
|
97555
|
+
noMemories: "No memories have been captured yet.",
|
|
97556
|
+
detailTitle: "Memory Detail",
|
|
97557
|
+
detailUser: "User",
|
|
97558
|
+
detailAgent: "Agent",
|
|
97559
|
+
detailCategory: "Category",
|
|
97560
|
+
detailSource: "Source",
|
|
97561
|
+
detailCaptured: "Captured",
|
|
97562
|
+
detailSession: "Session",
|
|
97563
|
+
sourceAuto: "Auto-captured",
|
|
97564
|
+
sourceManual: "Added manually",
|
|
97565
|
+
colUser: "USER",
|
|
97566
|
+
colMemory: "MEMORY",
|
|
97567
|
+
colAgent: "AGENT",
|
|
97568
|
+
colCategory: "CATEGORY",
|
|
97569
|
+
colCaptured: "CAPTURED"
|
|
97570
|
+
};
|
|
97540
97571
|
var analyticsAnalyticsMonetizationStats$3 = {
|
|
97541
97572
|
totalRevenue: "Total Revenue",
|
|
97542
97573
|
totalSales: "Total Sales",
|
|
@@ -97782,6 +97813,13 @@ var analyticsStatCard$3 = {
|
|
|
97782
97813
|
ariaLabel: "{title} mini card",
|
|
97783
97814
|
ariaLabelValue: "{title} mini card value"
|
|
97784
97815
|
};
|
|
97816
|
+
var analyticsUserFilterSelect$3 = {
|
|
97817
|
+
filterByUser: "Filter by user",
|
|
97818
|
+
you: "You",
|
|
97819
|
+
searchPlaceholder: "Search users…",
|
|
97820
|
+
noUsersFound: "No users found.",
|
|
97821
|
+
loadingUsers: "Loading users…"
|
|
97822
|
+
};
|
|
97785
97823
|
var apiTabApiKeyModal$3 = {
|
|
97786
97824
|
title: "API Key",
|
|
97787
97825
|
dialogDescription: "Copy and paste the API key.",
|
|
@@ -99485,12 +99523,14 @@ var memoryMemoryTab$3 = {
|
|
|
99485
99523
|
useMemoryLabelDesc: "When enabled, the AI will use what it knows about you to personalize responses.",
|
|
99486
99524
|
useMemoryAriaLabel: "Use memory in responses {state}",
|
|
99487
99525
|
sectionMyMemories: "My Memories",
|
|
99526
|
+
sectionMyMemoriesPreview: "Memories",
|
|
99488
99527
|
addMemoryButton: "Add Memory",
|
|
99489
99528
|
autoGeneratedMemoryAriaLabel: "Auto-generated memory",
|
|
99490
99529
|
manuallyAddedMemoryAriaLabel: "Manually added memory",
|
|
99491
99530
|
autoBadge: "auto",
|
|
99492
99531
|
deleteMemoryAriaLabel: "Delete memory: {excerpt}",
|
|
99493
99532
|
noMemoriesYet: "No memories yet. The AI will start remembering information from your conversations, or you can add memories manually.",
|
|
99533
|
+
noMemoriesYetPreview: "No memories yet. The AI has not recorded any information from this user's conversations.",
|
|
99494
99534
|
stateEnabled: "enabled",
|
|
99495
99535
|
stateDisabled: "disabled"
|
|
99496
99536
|
};
|
|
@@ -101696,6 +101736,10 @@ var analyticsTabLabels$3 = {
|
|
|
101696
101736
|
label: "Transcripts",
|
|
101697
101737
|
description: "Read full conversation transcripts message by message."
|
|
101698
101738
|
},
|
|
101739
|
+
memory: {
|
|
101740
|
+
label: "Memory",
|
|
101741
|
+
description: "What this agent remembers about each user it talks to."
|
|
101742
|
+
},
|
|
101699
101743
|
financial: {
|
|
101700
101744
|
label: "Costs",
|
|
101701
101745
|
description: "Track token usage and what this agent is costing you."
|
|
@@ -102688,11 +102732,12 @@ var graderTabLabels$3 = {
|
|
|
102688
102732
|
offHint: "Turn it on to write grading instructions and build your rubric. Anything you set up here is kept safe if you later turn it off."
|
|
102689
102733
|
},
|
|
102690
102734
|
subTabs: {
|
|
102691
|
-
setup: "Grading
|
|
102692
|
-
rubric: "Rubric"
|
|
102735
|
+
setup: "Grading Setup",
|
|
102736
|
+
rubric: "Rubric",
|
|
102737
|
+
results: "Results"
|
|
102693
102738
|
},
|
|
102694
102739
|
denied: {
|
|
102695
|
-
title: "No
|
|
102740
|
+
title: "No Access to Grading Settings",
|
|
102696
102741
|
description: "You don't have permission to view this agent's grading setup. Ask an administrator for access."
|
|
102697
102742
|
},
|
|
102698
102743
|
warnings: {
|
|
@@ -102700,12 +102745,12 @@ var graderTabLabels$3 = {
|
|
|
102700
102745
|
noCriteria: "Grading is on but the rubric is empty — the agent will fail when asked to grade. Add at least one criterion in the Rubric tab."
|
|
102701
102746
|
},
|
|
102702
102747
|
config: {
|
|
102703
|
-
sectionTitle: "Grading
|
|
102748
|
+
sectionTitle: "Grading Setup",
|
|
102704
102749
|
gradingMode: {
|
|
102705
|
-
label: "What
|
|
102750
|
+
label: "What Gets Graded",
|
|
102706
102751
|
options: {
|
|
102707
|
-
submission: "A
|
|
102708
|
-
conversation: "The
|
|
102752
|
+
submission: "A Submission",
|
|
102753
|
+
conversation: "The Conversation"
|
|
102709
102754
|
},
|
|
102710
102755
|
help: {
|
|
102711
102756
|
submission: "The agent grades a piece of work the person hands in, like an essay or answer.",
|
|
@@ -102713,16 +102758,16 @@ var graderTabLabels$3 = {
|
|
|
102713
102758
|
}
|
|
102714
102759
|
},
|
|
102715
102760
|
feedbackMode: {
|
|
102716
|
-
label: "Feedback
|
|
102761
|
+
label: "Feedback Shared with the Person",
|
|
102717
102762
|
options: {
|
|
102718
|
-
overall: "Overall
|
|
102719
|
-
perCriteria: "Feedback per
|
|
102720
|
-
both: "Overall + per
|
|
102763
|
+
overall: "Overall Feedback Only",
|
|
102764
|
+
perCriteria: "Feedback per Criterion",
|
|
102765
|
+
both: "Overall + per Criterion"
|
|
102721
102766
|
},
|
|
102722
102767
|
help: "The overall score is always calculated — this only controls how much detail is shared back."
|
|
102723
102768
|
},
|
|
102724
102769
|
instructions: {
|
|
102725
|
-
label: "Grading
|
|
102770
|
+
label: "Grading Instructions",
|
|
102726
102771
|
placeholder: "Describe what's being graded and anything the grader should know beyond the rubric. E.g. 'You are grading a 500-word persuasive essay on climate policy written by a high-school student. Be encouraging but honest.'",
|
|
102727
102772
|
help: "Required. This is the context the agent uses every time it grades."
|
|
102728
102773
|
},
|
|
@@ -102734,7 +102779,7 @@ var graderTabLabels$3 = {
|
|
|
102734
102779
|
description: "Each row is one thing the agent looks for and how many points it is worth. The overall score is points earned out of the total.",
|
|
102735
102780
|
needsConfigHint: "Save your grading setup first, then add rubric criteria here.",
|
|
102736
102781
|
emptyState: "No criteria yet. Add your first one — for example \"Clarity\", 10 points.",
|
|
102737
|
-
addButton: "Add
|
|
102782
|
+
addButton: "Add Criterion",
|
|
102738
102783
|
columns: {
|
|
102739
102784
|
name: "Name",
|
|
102740
102785
|
criteria: "Criteria",
|
|
@@ -102743,12 +102788,12 @@ var graderTabLabels$3 = {
|
|
|
102743
102788
|
actionsAria: "Actions for {name}",
|
|
102744
102789
|
edit: "Edit",
|
|
102745
102790
|
"delete": "Delete",
|
|
102746
|
-
totalPoints: "Total
|
|
102791
|
+
totalPoints: "Total Possible Points: {total}",
|
|
102747
102792
|
scoreHint: "Overall score = points earned ÷ {total}.",
|
|
102748
102793
|
lastCriterionHint: "A rubric needs at least one criterion — add another before removing this one.",
|
|
102749
102794
|
modal: {
|
|
102750
|
-
addTitle: "Add
|
|
102751
|
-
editTitle: "Edit
|
|
102795
|
+
addTitle: "Add Criterion",
|
|
102796
|
+
editTitle: "Edit Criterion",
|
|
102752
102797
|
name: {
|
|
102753
102798
|
label: "Name",
|
|
102754
102799
|
placeholder: "e.g. Clarity",
|
|
@@ -102769,7 +102814,7 @@ var graderTabLabels$3 = {
|
|
|
102769
102814
|
cancel: "Cancel"
|
|
102770
102815
|
},
|
|
102771
102816
|
deleteModal: {
|
|
102772
|
-
title: "Delete
|
|
102817
|
+
title: "Delete Criterion",
|
|
102773
102818
|
confirmationPrefix: "Are you sure you want to remove",
|
|
102774
102819
|
confirmationSuffix: " from the rubric?",
|
|
102775
102820
|
cancel: "Cancel",
|
|
@@ -102787,6 +102832,59 @@ var graderTabLabels$3 = {
|
|
|
102787
102832
|
criterionUpdated: "Criterion updated",
|
|
102788
102833
|
criterionDeleted: "Criterion deleted",
|
|
102789
102834
|
criterionError: "Couldn't update the rubric"
|
|
102835
|
+
},
|
|
102836
|
+
results: {
|
|
102837
|
+
sectionTitle: "Grade Results",
|
|
102838
|
+
description: "Every grade this agent has issued. Override a score to correct it — the change is pushed back to the LMS the grade came from.",
|
|
102839
|
+
filters: {
|
|
102840
|
+
searchUser: "Search for User",
|
|
102841
|
+
searchUsersPlaceholder: "Search users...",
|
|
102842
|
+
noUsersFound: "No users found.",
|
|
102843
|
+
allUsers: "All Users",
|
|
102844
|
+
statusLabel: "Score Status",
|
|
102845
|
+
allStatuses: "All Statuses",
|
|
102846
|
+
dateRangeLabel: "Pick a Date Range"
|
|
102847
|
+
},
|
|
102848
|
+
statusValues: {
|
|
102849
|
+
pending: "Pending",
|
|
102850
|
+
published: "Published",
|
|
102851
|
+
failed: "Failed"
|
|
102852
|
+
},
|
|
102853
|
+
columns: {
|
|
102854
|
+
learner: "Learner",
|
|
102855
|
+
score: "Score",
|
|
102856
|
+
status: "Status",
|
|
102857
|
+
override: "Override",
|
|
102858
|
+
gradedAt: "Graded"
|
|
102859
|
+
},
|
|
102860
|
+
emptyState: "No grades yet. They will appear here once the agent starts grading.",
|
|
102861
|
+
emptyFiltered: "No grades match the current filters.",
|
|
102862
|
+
overriddenBadge: "Overridden",
|
|
102863
|
+
overrideModal: {
|
|
102864
|
+
title: "Override Grade",
|
|
102865
|
+
learnerLabel: "Learner",
|
|
102866
|
+
aiScoreLabel: "AI Score",
|
|
102867
|
+
currentOverrideLabel: "Current Override",
|
|
102868
|
+
noOverride: "None",
|
|
102869
|
+
pointsLabel: "Override Points",
|
|
102870
|
+
pointsHelp: "Between 0 and {total}. The score pushed to the LMS becomes points ÷ {total}.",
|
|
102871
|
+
pointsRange: "Points must be between 0 and {total}",
|
|
102872
|
+
feedbackLabel: "Override Feedback",
|
|
102873
|
+
feedbackPlaceholder: "Explain the change for the learner (optional).",
|
|
102874
|
+
clearHelp: "Clearing the override restores the AI score and pushes it back to the LMS.",
|
|
102875
|
+
save: "Save",
|
|
102876
|
+
saving: "Saving…",
|
|
102877
|
+
clear: "Clear",
|
|
102878
|
+
clearing: "Clearing…",
|
|
102879
|
+
cancel: "Cancel"
|
|
102880
|
+
},
|
|
102881
|
+
toasts: {
|
|
102882
|
+
overrideSaved: "Override saved and pushed to the LMS",
|
|
102883
|
+
overrideCleared: "Override cleared — the AI score was restored",
|
|
102884
|
+
overrideError: "Couldn't save the override"
|
|
102885
|
+
},
|
|
102886
|
+
overrideButton: "Override",
|
|
102887
|
+
overrideButtonAria: "Override grade for {email}"
|
|
102790
102888
|
}
|
|
102791
102889
|
};
|
|
102792
102890
|
var en = {
|
|
@@ -102815,6 +102913,7 @@ var en = {
|
|
|
102815
102913
|
analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail$3,
|
|
102816
102914
|
analyticsAnalyticsCourses: analyticsAnalyticsCourses$3,
|
|
102817
102915
|
analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats$3,
|
|
102916
|
+
analyticsAnalyticsMemoryStats: analyticsAnalyticsMemoryStats$3,
|
|
102818
102917
|
analyticsAnalyticsMonetizationStats: analyticsAnalyticsMonetizationStats$3,
|
|
102819
102918
|
analyticsAnalyticsOverview: analyticsAnalyticsOverview$3,
|
|
102820
102919
|
analyticsAnalyticsProgramDetail: analyticsAnalyticsProgramDetail$3,
|
|
@@ -102825,6 +102924,7 @@ var en = {
|
|
|
102825
102924
|
analyticsAnalyticsUsersStats: analyticsAnalyticsUsersStats$3,
|
|
102826
102925
|
analyticsGroupsFilterDropdown: analyticsGroupsFilterDropdown$3,
|
|
102827
102926
|
analyticsStatCard: analyticsStatCard$3,
|
|
102927
|
+
analyticsUserFilterSelect: analyticsUserFilterSelect$3,
|
|
102828
102928
|
apiTabApiKeyModal: apiTabApiKeyModal$3,
|
|
102829
102929
|
apiTabCreateApiModal2: apiTabCreateApiModal2$3,
|
|
102830
102930
|
apiTabDeleteApiModal2: apiTabDeleteApiModal2$3,
|
|
@@ -103757,6 +103857,37 @@ var analyticsAnalyticsFinancialStats$2 = {
|
|
|
103757
103857
|
goToLastPage: "Aller à la dernière page",
|
|
103758
103858
|
paginationShowing: "Affichage de {from} à {to} sur {total} résultats"
|
|
103759
103859
|
};
|
|
103860
|
+
var analyticsAnalyticsMemoryStats$2 = {
|
|
103861
|
+
noPermission: "Vous n'avez pas l'autorisation de consulter les mémoires des utilisateurs.",
|
|
103862
|
+
scopeLabel: "Portée de la mémoire",
|
|
103863
|
+
scopeMentor: "Cet agent",
|
|
103864
|
+
scopeAllMentors: "Tous les agents",
|
|
103865
|
+
scopeGlobal: "Global",
|
|
103866
|
+
searchAgents: "Rechercher des agents…",
|
|
103867
|
+
searchAgentsTitle: "Rechercher des agents",
|
|
103868
|
+
clearAgentSearch: "Effacer la recherche d'agent",
|
|
103869
|
+
contentPlaceholder: "Rechercher dans le contenu des mémoires",
|
|
103870
|
+
pickDateRange: "Choisir une plage de dates",
|
|
103871
|
+
allCategories: "Toutes les catégories",
|
|
103872
|
+
byCategory: "Mémoires par catégorie",
|
|
103873
|
+
categoryCount: "{count} ({percent}%)",
|
|
103874
|
+
loadError: "Une erreur s'est produite lors du chargement des mémoires.",
|
|
103875
|
+
noMemories: "Aucune mémoire n'a encore été capturée.",
|
|
103876
|
+
detailTitle: "Détail de la mémoire",
|
|
103877
|
+
detailUser: "Utilisateur",
|
|
103878
|
+
detailAgent: "Agent",
|
|
103879
|
+
detailCategory: "Catégorie",
|
|
103880
|
+
detailSource: "Source",
|
|
103881
|
+
detailCaptured: "Capturée",
|
|
103882
|
+
detailSession: "Session",
|
|
103883
|
+
sourceAuto: "Capturée automatiquement",
|
|
103884
|
+
sourceManual: "Ajoutée manuellement",
|
|
103885
|
+
colUser: "UTILISATEUR",
|
|
103886
|
+
colMemory: "MÉMOIRE",
|
|
103887
|
+
colAgent: "AGENT",
|
|
103888
|
+
colCategory: "CATÉGORIE",
|
|
103889
|
+
colCaptured: "CAPTURÉE"
|
|
103890
|
+
};
|
|
103760
103891
|
var analyticsAnalyticsMonetizationStats$2 = {
|
|
103761
103892
|
totalRevenue: "Revenu total",
|
|
103762
103893
|
totalSales: "Ventes totales",
|
|
@@ -104002,6 +104133,13 @@ var analyticsStatCard$2 = {
|
|
|
104002
104133
|
ariaLabel: "mini carte {title}",
|
|
104003
104134
|
ariaLabelValue: "valeur de la mini carte {title}"
|
|
104004
104135
|
};
|
|
104136
|
+
var analyticsUserFilterSelect$2 = {
|
|
104137
|
+
filterByUser: "Filtrer par utilisateur",
|
|
104138
|
+
you: "Vous",
|
|
104139
|
+
searchPlaceholder: "Rechercher des utilisateurs…",
|
|
104140
|
+
noUsersFound: "Aucun utilisateur trouvé.",
|
|
104141
|
+
loadingUsers: "Chargement des utilisateurs…"
|
|
104142
|
+
};
|
|
104005
104143
|
var apiTabApiKeyModal$2 = {
|
|
104006
104144
|
title: "Clé API",
|
|
104007
104145
|
dialogDescription: "Copiez et collez la clé API.",
|
|
@@ -104329,7 +104467,8 @@ var graderTabLabels$2 = {
|
|
|
104329
104467
|
},
|
|
104330
104468
|
subTabs: {
|
|
104331
104469
|
setup: "Configuration de la notation",
|
|
104332
|
-
rubric: "Grille d'évaluation"
|
|
104470
|
+
rubric: "Grille d'évaluation",
|
|
104471
|
+
results: "Résultats"
|
|
104333
104472
|
},
|
|
104334
104473
|
denied: {
|
|
104335
104474
|
title: "Pas d'accès aux paramètres de notation",
|
|
@@ -104417,6 +104556,59 @@ var graderTabLabels$2 = {
|
|
|
104417
104556
|
deleting: "Suppression…"
|
|
104418
104557
|
}
|
|
104419
104558
|
},
|
|
104559
|
+
results: {
|
|
104560
|
+
sectionTitle: "Résultats de notation",
|
|
104561
|
+
description: "Toutes les notes émises par cet agent. Remplacez une note pour la corriger — la modification est renvoyée au LMS d'où provient la note.",
|
|
104562
|
+
filters: {
|
|
104563
|
+
searchUser: "Rechercher un utilisateur",
|
|
104564
|
+
searchUsersPlaceholder: "Rechercher des utilisateurs...",
|
|
104565
|
+
noUsersFound: "Aucun utilisateur trouvé.",
|
|
104566
|
+
allUsers: "Tous les utilisateurs",
|
|
104567
|
+
statusLabel: "Statut de la note",
|
|
104568
|
+
allStatuses: "Tous les statuts",
|
|
104569
|
+
dateRangeLabel: "Choisir une plage de dates"
|
|
104570
|
+
},
|
|
104571
|
+
statusValues: {
|
|
104572
|
+
pending: "En attente",
|
|
104573
|
+
published: "Publié",
|
|
104574
|
+
failed: "Échoué"
|
|
104575
|
+
},
|
|
104576
|
+
columns: {
|
|
104577
|
+
learner: "Apprenant",
|
|
104578
|
+
score: "Note",
|
|
104579
|
+
status: "Statut",
|
|
104580
|
+
override: "Remplacement",
|
|
104581
|
+
gradedAt: "Noté"
|
|
104582
|
+
},
|
|
104583
|
+
emptyState: "Aucune note pour l'instant. Elles apparaîtront ici dès que l'agent commencera à noter.",
|
|
104584
|
+
emptyFiltered: "Aucune note ne correspond aux filtres actuels.",
|
|
104585
|
+
overriddenBadge: "Remplacée",
|
|
104586
|
+
overrideModal: {
|
|
104587
|
+
title: "Remplacer la note",
|
|
104588
|
+
learnerLabel: "Apprenant",
|
|
104589
|
+
aiScoreLabel: "Note de l'IA",
|
|
104590
|
+
currentOverrideLabel: "Remplacement actuel",
|
|
104591
|
+
noOverride: "Aucun",
|
|
104592
|
+
pointsLabel: "Points de remplacement",
|
|
104593
|
+
pointsHelp: "Entre 0 et {total}. La note envoyée au LMS devient points ÷ {total}.",
|
|
104594
|
+
pointsRange: "Les points doivent être compris entre 0 et {total}",
|
|
104595
|
+
feedbackLabel: "Retour sur le remplacement",
|
|
104596
|
+
feedbackPlaceholder: "Expliquez le changement à l'apprenant (facultatif).",
|
|
104597
|
+
clearHelp: "Supprimer le remplacement restaure la note de l'IA et la renvoie au LMS.",
|
|
104598
|
+
save: "Enregistrer",
|
|
104599
|
+
saving: "Enregistrement…",
|
|
104600
|
+
clear: "Supprimer",
|
|
104601
|
+
clearing: "Suppression…",
|
|
104602
|
+
cancel: "Annuler"
|
|
104603
|
+
},
|
|
104604
|
+
toasts: {
|
|
104605
|
+
overrideSaved: "Remplacement enregistré et envoyé au LMS",
|
|
104606
|
+
overrideCleared: "Remplacement supprimé — la note de l'IA a été restaurée",
|
|
104607
|
+
overrideError: "Impossible d'enregistrer le remplacement"
|
|
104608
|
+
},
|
|
104609
|
+
overrideButton: "Remplacer",
|
|
104610
|
+
overrideButtonAria: "Remplacer la note de {email}"
|
|
104611
|
+
},
|
|
104420
104612
|
toasts: {
|
|
104421
104613
|
toggleOn: "Notation activée",
|
|
104422
104614
|
toggleOff: "Notation désactivée — votre grille est conservée pour la prochaine fois",
|
|
@@ -105817,12 +106009,14 @@ var memoryMemoryTab$2 = {
|
|
|
105817
106009
|
useMemoryLabelDesc: "Lorsque cette option est activée, l'IA utilisera ce qu'elle sait de vous pour personnaliser ses réponses.",
|
|
105818
106010
|
useMemoryAriaLabel: "Utilisation de la mémoire dans les réponses {state}",
|
|
105819
106011
|
sectionMyMemories: "Mes souvenirs",
|
|
106012
|
+
sectionMyMemoriesPreview: "Souvenirs",
|
|
105820
106013
|
addMemoryButton: "Ajouter un souvenir",
|
|
105821
106014
|
autoGeneratedMemoryAriaLabel: "Souvenir généré automatiquement",
|
|
105822
106015
|
manuallyAddedMemoryAriaLabel: "Souvenir ajouté manuellement",
|
|
105823
106016
|
autoBadge: "auto",
|
|
105824
106017
|
deleteMemoryAriaLabel: "Supprimer le souvenir : {excerpt}",
|
|
105825
106018
|
noMemoriesYet: "Aucun souvenir pour l'instant. L'IA commencera à mémoriser des informations de vos conversations, ou vous pouvez ajouter des souvenirs manuellement.",
|
|
106019
|
+
noMemoriesYetPreview: "Aucun souvenir pour l'instant. L'IA n'a enregistré aucune information des conversations de cet utilisateur.",
|
|
105826
106020
|
stateEnabled: "activée",
|
|
105827
106021
|
stateDisabled: "désactivée"
|
|
105828
106022
|
};
|
|
@@ -108028,6 +108222,10 @@ var analyticsTabLabels$2 = {
|
|
|
108028
108222
|
label: "Transcriptions",
|
|
108029
108223
|
description: "Lisez les transcriptions complètes des conversations, message par message."
|
|
108030
108224
|
},
|
|
108225
|
+
memory: {
|
|
108226
|
+
label: "Mémoire",
|
|
108227
|
+
description: "Ce que cet agent retient de chaque utilisateur avec qui il échange."
|
|
108228
|
+
},
|
|
108031
108229
|
financial: {
|
|
108032
108230
|
label: "Coûts",
|
|
108033
108231
|
description: "Suivez l'utilisation des jetons et ce que cet agent vous coûte."
|
|
@@ -109035,6 +109233,7 @@ var fr = {
|
|
|
109035
109233
|
analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail$2,
|
|
109036
109234
|
analyticsAnalyticsCourses: analyticsAnalyticsCourses$2,
|
|
109037
109235
|
analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats$2,
|
|
109236
|
+
analyticsAnalyticsMemoryStats: analyticsAnalyticsMemoryStats$2,
|
|
109038
109237
|
analyticsAnalyticsMonetizationStats: analyticsAnalyticsMonetizationStats$2,
|
|
109039
109238
|
analyticsAnalyticsOverview: analyticsAnalyticsOverview$2,
|
|
109040
109239
|
analyticsAnalyticsProgramDetail: analyticsAnalyticsProgramDetail$2,
|
|
@@ -109045,6 +109244,7 @@ var fr = {
|
|
|
109045
109244
|
analyticsAnalyticsUsersStats: analyticsAnalyticsUsersStats$2,
|
|
109046
109245
|
analyticsGroupsFilterDropdown: analyticsGroupsFilterDropdown$2,
|
|
109047
109246
|
analyticsStatCard: analyticsStatCard$2,
|
|
109247
|
+
analyticsUserFilterSelect: analyticsUserFilterSelect$2,
|
|
109048
109248
|
apiTabApiKeyModal: apiTabApiKeyModal$2,
|
|
109049
109249
|
apiTabCreateApiModal2: apiTabCreateApiModal2$2,
|
|
109050
109250
|
apiTabDeleteApiModal2: apiTabDeleteApiModal2$2,
|
|
@@ -109977,6 +110177,37 @@ var analyticsAnalyticsFinancialStats$1 = {
|
|
|
109977
110177
|
goToLastPage: "Ir a la última página",
|
|
109978
110178
|
paginationShowing: "Mostrando {from} a {to} de {total} resultados"
|
|
109979
110179
|
};
|
|
110180
|
+
var analyticsAnalyticsMemoryStats$1 = {
|
|
110181
|
+
noPermission: "No tienes permiso para ver los recuerdos de los usuarios.",
|
|
110182
|
+
scopeLabel: "Alcance de la memoria",
|
|
110183
|
+
scopeMentor: "Este agente",
|
|
110184
|
+
scopeAllMentors: "Todos los agentes",
|
|
110185
|
+
scopeGlobal: "Global",
|
|
110186
|
+
searchAgents: "Buscar agentes…",
|
|
110187
|
+
searchAgentsTitle: "Buscar agentes",
|
|
110188
|
+
clearAgentSearch: "Borrar la búsqueda de agentes",
|
|
110189
|
+
contentPlaceholder: "Buscar en el contenido de los recuerdos",
|
|
110190
|
+
pickDateRange: "Elige un rango de fechas",
|
|
110191
|
+
allCategories: "Todas las categorías",
|
|
110192
|
+
byCategory: "Recuerdos por categoría",
|
|
110193
|
+
categoryCount: "{count} ({percent}%)",
|
|
110194
|
+
loadError: "Se produjo un error al cargar los recuerdos.",
|
|
110195
|
+
noMemories: "Todavía no se ha capturado ningún recuerdo.",
|
|
110196
|
+
detailTitle: "Detalle del recuerdo",
|
|
110197
|
+
detailUser: "Usuario",
|
|
110198
|
+
detailAgent: "Agente",
|
|
110199
|
+
detailCategory: "Categoría",
|
|
110200
|
+
detailSource: "Origen",
|
|
110201
|
+
detailCaptured: "Capturado",
|
|
110202
|
+
detailSession: "Sesión",
|
|
110203
|
+
sourceAuto: "Capturado automáticamente",
|
|
110204
|
+
sourceManual: "Añadido manualmente",
|
|
110205
|
+
colUser: "USUARIO",
|
|
110206
|
+
colMemory: "RECUERDO",
|
|
110207
|
+
colAgent: "AGENTE",
|
|
110208
|
+
colCategory: "CATEGORÍA",
|
|
110209
|
+
colCaptured: "CAPTURADO"
|
|
110210
|
+
};
|
|
109980
110211
|
var analyticsAnalyticsMonetizationStats$1 = {
|
|
109981
110212
|
totalRevenue: "Ingresos totales",
|
|
109982
110213
|
totalSales: "Ventas totales",
|
|
@@ -110222,6 +110453,13 @@ var analyticsStatCard$1 = {
|
|
|
110222
110453
|
ariaLabel: "mini tarjeta {title}",
|
|
110223
110454
|
ariaLabelValue: "valor de la mini tarjeta {title}"
|
|
110224
110455
|
};
|
|
110456
|
+
var analyticsUserFilterSelect$1 = {
|
|
110457
|
+
filterByUser: "Filtrar por usuario",
|
|
110458
|
+
you: "Tú",
|
|
110459
|
+
searchPlaceholder: "Buscar usuarios…",
|
|
110460
|
+
noUsersFound: "No se encontraron usuarios.",
|
|
110461
|
+
loadingUsers: "Cargando usuarios…"
|
|
110462
|
+
};
|
|
110225
110463
|
var apiTabApiKeyModal$1 = {
|
|
110226
110464
|
title: "Clave API",
|
|
110227
110465
|
dialogDescription: "Copie y pegue la clave API.",
|
|
@@ -110549,7 +110787,8 @@ var graderTabLabels$1 = {
|
|
|
110549
110787
|
},
|
|
110550
110788
|
subTabs: {
|
|
110551
110789
|
setup: "Configuración de calificación",
|
|
110552
|
-
rubric: "Rúbrica"
|
|
110790
|
+
rubric: "Rúbrica",
|
|
110791
|
+
results: "Resultados"
|
|
110553
110792
|
},
|
|
110554
110793
|
denied: {
|
|
110555
110794
|
title: "Sin acceso a la configuración de calificación",
|
|
@@ -110637,6 +110876,59 @@ var graderTabLabels$1 = {
|
|
|
110637
110876
|
deleting: "Eliminando…"
|
|
110638
110877
|
}
|
|
110639
110878
|
},
|
|
110879
|
+
results: {
|
|
110880
|
+
sectionTitle: "Resultados de calificación",
|
|
110881
|
+
description: "Todas las calificaciones que este agente ha emitido. Anula una puntuación para corregirla — el cambio se envía de vuelta al LMS del que proviene la calificación.",
|
|
110882
|
+
filters: {
|
|
110883
|
+
searchUser: "Buscar usuario",
|
|
110884
|
+
searchUsersPlaceholder: "Buscar usuarios...",
|
|
110885
|
+
noUsersFound: "No se encontraron usuarios.",
|
|
110886
|
+
allUsers: "Todos los usuarios",
|
|
110887
|
+
statusLabel: "Estado de la puntuación",
|
|
110888
|
+
allStatuses: "Todos los estados",
|
|
110889
|
+
dateRangeLabel: "Selecciona un rango de fechas"
|
|
110890
|
+
},
|
|
110891
|
+
statusValues: {
|
|
110892
|
+
pending: "Pendiente",
|
|
110893
|
+
published: "Publicado",
|
|
110894
|
+
failed: "Fallido"
|
|
110895
|
+
},
|
|
110896
|
+
columns: {
|
|
110897
|
+
learner: "Estudiante",
|
|
110898
|
+
score: "Puntuación",
|
|
110899
|
+
status: "Estado",
|
|
110900
|
+
override: "Anulación",
|
|
110901
|
+
gradedAt: "Calificado"
|
|
110902
|
+
},
|
|
110903
|
+
emptyState: "Aún no hay calificaciones. Aparecerán aquí cuando el agente comience a calificar.",
|
|
110904
|
+
emptyFiltered: "Ninguna calificación coincide con los filtros actuales.",
|
|
110905
|
+
overriddenBadge: "Anulada",
|
|
110906
|
+
overrideModal: {
|
|
110907
|
+
title: "Anular calificación",
|
|
110908
|
+
learnerLabel: "Estudiante",
|
|
110909
|
+
aiScoreLabel: "Puntuación de la IA",
|
|
110910
|
+
currentOverrideLabel: "Anulación actual",
|
|
110911
|
+
noOverride: "Ninguna",
|
|
110912
|
+
pointsLabel: "Puntos de anulación",
|
|
110913
|
+
pointsHelp: "Entre 0 y {total}. La puntuación enviada al LMS es puntos ÷ {total}.",
|
|
110914
|
+
pointsRange: "Los puntos deben estar entre 0 y {total}",
|
|
110915
|
+
feedbackLabel: "Retroalimentación de la anulación",
|
|
110916
|
+
feedbackPlaceholder: "Explica el cambio al estudiante (opcional).",
|
|
110917
|
+
clearHelp: "Quitar la anulación restaura la puntuación de la IA y la envía de vuelta al LMS.",
|
|
110918
|
+
save: "Guardar",
|
|
110919
|
+
saving: "Guardando…",
|
|
110920
|
+
clear: "Quitar",
|
|
110921
|
+
clearing: "Quitando…",
|
|
110922
|
+
cancel: "Cancelar"
|
|
110923
|
+
},
|
|
110924
|
+
toasts: {
|
|
110925
|
+
overrideSaved: "Anulación guardada y enviada al LMS",
|
|
110926
|
+
overrideCleared: "Anulación quitada — se restauró la puntuación de la IA",
|
|
110927
|
+
overrideError: "No se pudo guardar la anulación"
|
|
110928
|
+
},
|
|
110929
|
+
overrideButton: "Anular",
|
|
110930
|
+
overrideButtonAria: "Anular la calificación de {email}"
|
|
110931
|
+
},
|
|
110640
110932
|
toasts: {
|
|
110641
110933
|
toggleOn: "Calificación activada",
|
|
110642
110934
|
toggleOff: "Calificación desactivada — tu rúbrica se conserva para la próxima vez",
|
|
@@ -112037,12 +112329,14 @@ var memoryMemoryTab$1 = {
|
|
|
112037
112329
|
useMemoryLabelDesc: "Cuando está habilitado, la IA usará lo que sabe sobre usted para personalizar las respuestas.",
|
|
112038
112330
|
useMemoryAriaLabel: "Uso de memoria en las respuestas {state}",
|
|
112039
112331
|
sectionMyMemories: "Mis memorias",
|
|
112332
|
+
sectionMyMemoriesPreview: "Memorias",
|
|
112040
112333
|
addMemoryButton: "Añadir memoria",
|
|
112041
112334
|
autoGeneratedMemoryAriaLabel: "Memoria generada automáticamente",
|
|
112042
112335
|
manuallyAddedMemoryAriaLabel: "Memoria añadida manualmente",
|
|
112043
112336
|
autoBadge: "auto",
|
|
112044
112337
|
deleteMemoryAriaLabel: "Eliminar memoria: {excerpt}",
|
|
112045
112338
|
noMemoriesYet: "Aún no hay memorias. La IA comenzará a recordar información de sus conversaciones, o puede añadir memorias manualmente.",
|
|
112339
|
+
noMemoriesYetPreview: "Aún no hay memorias. La IA no ha registrado información de las conversaciones de este usuario.",
|
|
112046
112340
|
stateEnabled: "habilitada",
|
|
112047
112341
|
stateDisabled: "deshabilitada"
|
|
112048
112342
|
};
|
|
@@ -114248,6 +114542,10 @@ var analyticsTabLabels$1 = {
|
|
|
114248
114542
|
label: "Transcripciones",
|
|
114249
114543
|
description: "Lee las transcripciones completas de las conversaciones, mensaje a mensaje."
|
|
114250
114544
|
},
|
|
114545
|
+
memory: {
|
|
114546
|
+
label: "Memoria",
|
|
114547
|
+
description: "Lo que este agente recuerda de cada usuario con el que habla."
|
|
114548
|
+
},
|
|
114251
114549
|
financial: {
|
|
114252
114550
|
label: "Costos",
|
|
114253
114551
|
description: "Controla el uso de tokens y lo que te cuesta este agente."
|
|
@@ -115255,6 +115553,7 @@ var es = {
|
|
|
115255
115553
|
analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail$1,
|
|
115256
115554
|
analyticsAnalyticsCourses: analyticsAnalyticsCourses$1,
|
|
115257
115555
|
analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats$1,
|
|
115556
|
+
analyticsAnalyticsMemoryStats: analyticsAnalyticsMemoryStats$1,
|
|
115258
115557
|
analyticsAnalyticsMonetizationStats: analyticsAnalyticsMonetizationStats$1,
|
|
115259
115558
|
analyticsAnalyticsOverview: analyticsAnalyticsOverview$1,
|
|
115260
115559
|
analyticsAnalyticsProgramDetail: analyticsAnalyticsProgramDetail$1,
|
|
@@ -115265,6 +115564,7 @@ var es = {
|
|
|
115265
115564
|
analyticsAnalyticsUsersStats: analyticsAnalyticsUsersStats$1,
|
|
115266
115565
|
analyticsGroupsFilterDropdown: analyticsGroupsFilterDropdown$1,
|
|
115267
115566
|
analyticsStatCard: analyticsStatCard$1,
|
|
115567
|
+
analyticsUserFilterSelect: analyticsUserFilterSelect$1,
|
|
115268
115568
|
apiTabApiKeyModal: apiTabApiKeyModal$1,
|
|
115269
115569
|
apiTabCreateApiModal2: apiTabCreateApiModal2$1,
|
|
115270
115570
|
apiTabDeleteApiModal2: apiTabDeleteApiModal2$1,
|
|
@@ -116197,6 +116497,37 @@ var analyticsAnalyticsFinancialStats = {
|
|
|
116197
116497
|
goToLastPage: "转到最后一页",
|
|
116198
116498
|
paginationShowing: "显示第 {from} 至 {to} 条,共 {total} 条结果"
|
|
116199
116499
|
};
|
|
116500
|
+
var analyticsAnalyticsMemoryStats = {
|
|
116501
|
+
noPermission: "您没有查看用户记忆的权限。",
|
|
116502
|
+
scopeLabel: "记忆范围",
|
|
116503
|
+
scopeMentor: "当前智能体",
|
|
116504
|
+
scopeAllMentors: "所有智能体",
|
|
116505
|
+
scopeGlobal: "全局",
|
|
116506
|
+
searchAgents: "搜索智能体…",
|
|
116507
|
+
searchAgentsTitle: "搜索智能体",
|
|
116508
|
+
clearAgentSearch: "清除智能体搜索",
|
|
116509
|
+
contentPlaceholder: "搜索记忆内容",
|
|
116510
|
+
pickDateRange: "选择日期范围",
|
|
116511
|
+
allCategories: "所有类别",
|
|
116512
|
+
byCategory: "按类别统计记忆",
|
|
116513
|
+
categoryCount: "{count} ({percent}%)",
|
|
116514
|
+
loadError: "加载记忆时发生错误。",
|
|
116515
|
+
noMemories: "尚未捕获任何记忆。",
|
|
116516
|
+
detailTitle: "记忆详情",
|
|
116517
|
+
detailUser: "用户",
|
|
116518
|
+
detailAgent: "智能体",
|
|
116519
|
+
detailCategory: "类别",
|
|
116520
|
+
detailSource: "来源",
|
|
116521
|
+
detailCaptured: "捕获时间",
|
|
116522
|
+
detailSession: "会话",
|
|
116523
|
+
sourceAuto: "自动捕获",
|
|
116524
|
+
sourceManual: "手动添加",
|
|
116525
|
+
colUser: "用户",
|
|
116526
|
+
colMemory: "记忆",
|
|
116527
|
+
colAgent: "智能体",
|
|
116528
|
+
colCategory: "类别",
|
|
116529
|
+
colCaptured: "捕获时间"
|
|
116530
|
+
};
|
|
116200
116531
|
var analyticsAnalyticsMonetizationStats = {
|
|
116201
116532
|
totalRevenue: "总收入",
|
|
116202
116533
|
totalSales: "总销售额",
|
|
@@ -116442,6 +116773,13 @@ var analyticsStatCard = {
|
|
|
116442
116773
|
ariaLabel: "{title} 迷你卡片",
|
|
116443
116774
|
ariaLabelValue: "{title} 迷你卡片值"
|
|
116444
116775
|
};
|
|
116776
|
+
var analyticsUserFilterSelect = {
|
|
116777
|
+
filterByUser: "按用户筛选",
|
|
116778
|
+
you: "我",
|
|
116779
|
+
searchPlaceholder: "搜索用户…",
|
|
116780
|
+
noUsersFound: "未找到用户。",
|
|
116781
|
+
loadingUsers: "正在加载用户…"
|
|
116782
|
+
};
|
|
116445
116783
|
var apiTabApiKeyModal = {
|
|
116446
116784
|
title: "API 密钥",
|
|
116447
116785
|
dialogDescription: "复制并粘贴 API 密钥。",
|
|
@@ -116769,7 +117107,8 @@ var graderTabLabels = {
|
|
|
116769
117107
|
},
|
|
116770
117108
|
subTabs: {
|
|
116771
117109
|
setup: "评分设置",
|
|
116772
|
-
rubric: "评分标准"
|
|
117110
|
+
rubric: "评分标准",
|
|
117111
|
+
results: "结果"
|
|
116773
117112
|
},
|
|
116774
117113
|
denied: {
|
|
116775
117114
|
title: "无权访问评分设置",
|
|
@@ -116857,6 +117196,59 @@ var graderTabLabels = {
|
|
|
116857
117196
|
deleting: "删除中…"
|
|
116858
117197
|
}
|
|
116859
117198
|
},
|
|
117199
|
+
results: {
|
|
117200
|
+
sectionTitle: "评分结果",
|
|
117201
|
+
description: "此智能体发出的所有评分。覆盖分数即可更正 — 更改会推送回评分来源的 LMS。",
|
|
117202
|
+
filters: {
|
|
117203
|
+
searchUser: "搜索用户",
|
|
117204
|
+
searchUsersPlaceholder: "搜索用户...",
|
|
117205
|
+
noUsersFound: "未找到用户。",
|
|
117206
|
+
allUsers: "所有用户",
|
|
117207
|
+
statusLabel: "分数状态",
|
|
117208
|
+
allStatuses: "全部状态",
|
|
117209
|
+
dateRangeLabel: "选择日期范围"
|
|
117210
|
+
},
|
|
117211
|
+
statusValues: {
|
|
117212
|
+
pending: "待处理",
|
|
117213
|
+
published: "已发布",
|
|
117214
|
+
failed: "失败"
|
|
117215
|
+
},
|
|
117216
|
+
columns: {
|
|
117217
|
+
learner: "学员",
|
|
117218
|
+
score: "分数",
|
|
117219
|
+
status: "状态",
|
|
117220
|
+
override: "覆盖",
|
|
117221
|
+
gradedAt: "评分时间"
|
|
117222
|
+
},
|
|
117223
|
+
emptyState: "还没有评分。智能体开始评分后将显示在这里。",
|
|
117224
|
+
emptyFiltered: "没有符合当前筛选条件的评分。",
|
|
117225
|
+
overriddenBadge: "已覆盖",
|
|
117226
|
+
overrideModal: {
|
|
117227
|
+
title: "覆盖评分",
|
|
117228
|
+
learnerLabel: "学员",
|
|
117229
|
+
aiScoreLabel: "AI 分数",
|
|
117230
|
+
currentOverrideLabel: "当前覆盖",
|
|
117231
|
+
noOverride: "无",
|
|
117232
|
+
pointsLabel: "覆盖分数",
|
|
117233
|
+
pointsHelp: "介于 0 和 {total} 之间。推送到 LMS 的分数为 分数 ÷ {total}。",
|
|
117234
|
+
pointsRange: "分数必须介于 0 和 {total} 之间",
|
|
117235
|
+
feedbackLabel: "覆盖反馈",
|
|
117236
|
+
feedbackPlaceholder: "向学员说明此更改(可选)。",
|
|
117237
|
+
clearHelp: "清除覆盖会恢复 AI 分数并推送回 LMS。",
|
|
117238
|
+
save: "保存",
|
|
117239
|
+
saving: "保存中…",
|
|
117240
|
+
clear: "清除",
|
|
117241
|
+
clearing: "清除中…",
|
|
117242
|
+
cancel: "取消"
|
|
117243
|
+
},
|
|
117244
|
+
toasts: {
|
|
117245
|
+
overrideSaved: "覆盖已保存并推送到 LMS",
|
|
117246
|
+
overrideCleared: "覆盖已清除 — AI 分数已恢复",
|
|
117247
|
+
overrideError: "无法保存覆盖"
|
|
117248
|
+
},
|
|
117249
|
+
overrideButton: "覆盖",
|
|
117250
|
+
overrideButtonAria: "覆盖 {email} 的评分"
|
|
117251
|
+
},
|
|
116860
117252
|
toasts: {
|
|
116861
117253
|
toggleOn: "评分已开启",
|
|
116862
117254
|
toggleOff: "评分已关闭 — 您的评分标准已保留,下次可继续使用",
|
|
@@ -118257,12 +118649,14 @@ var memoryMemoryTab = {
|
|
|
118257
118649
|
useMemoryLabelDesc: "启用后,AI 将利用它对您的了解来个性化回复。",
|
|
118258
118650
|
useMemoryAriaLabel: "在回复中使用记忆{state}",
|
|
118259
118651
|
sectionMyMemories: "我的记忆",
|
|
118652
|
+
sectionMyMemoriesPreview: "记忆",
|
|
118260
118653
|
addMemoryButton: "添加记忆",
|
|
118261
118654
|
autoGeneratedMemoryAriaLabel: "自动生成的记忆",
|
|
118262
118655
|
manuallyAddedMemoryAriaLabel: "手动添加的记忆",
|
|
118263
118656
|
autoBadge: "自动",
|
|
118264
118657
|
deleteMemoryAriaLabel: "删除记忆:{excerpt}",
|
|
118265
118658
|
noMemoriesYet: "暂无记忆。AI 将开始记住您对话中的信息,或者您也可以手动添加记忆。",
|
|
118659
|
+
noMemoriesYetPreview: "暂无记忆。AI 尚未记录该用户对话中的任何信息。",
|
|
118266
118660
|
stateEnabled: "已启用",
|
|
118267
118661
|
stateDisabled: "已禁用"
|
|
118268
118662
|
};
|
|
@@ -120468,6 +120862,10 @@ var analyticsTabLabels = {
|
|
|
120468
120862
|
label: "对话记录",
|
|
120469
120863
|
description: "逐条阅读完整的对话记录。"
|
|
120470
120864
|
},
|
|
120865
|
+
memory: {
|
|
120866
|
+
label: "记忆",
|
|
120867
|
+
description: "该智能体记住的与其对话的每位用户的相关信息。"
|
|
120868
|
+
},
|
|
120471
120869
|
financial: {
|
|
120472
120870
|
label: "费用",
|
|
120473
120871
|
description: "跟踪令牌用量以及该智能体的花费。"
|
|
@@ -121475,6 +121873,7 @@ var zh = {
|
|
|
121475
121873
|
analyticsAnalyticsCourseDetail: analyticsAnalyticsCourseDetail,
|
|
121476
121874
|
analyticsAnalyticsCourses: analyticsAnalyticsCourses,
|
|
121477
121875
|
analyticsAnalyticsFinancialStats: analyticsAnalyticsFinancialStats,
|
|
121876
|
+
analyticsAnalyticsMemoryStats: analyticsAnalyticsMemoryStats,
|
|
121478
121877
|
analyticsAnalyticsMonetizationStats: analyticsAnalyticsMonetizationStats,
|
|
121479
121878
|
analyticsAnalyticsOverview: analyticsAnalyticsOverview,
|
|
121480
121879
|
analyticsAnalyticsProgramDetail: analyticsAnalyticsProgramDetail,
|
|
@@ -121485,6 +121884,7 @@ var zh = {
|
|
|
121485
121884
|
analyticsAnalyticsUsersStats: analyticsAnalyticsUsersStats,
|
|
121486
121885
|
analyticsGroupsFilterDropdown: analyticsGroupsFilterDropdown,
|
|
121487
121886
|
analyticsStatCard: analyticsStatCard,
|
|
121887
|
+
analyticsUserFilterSelect: analyticsUserFilterSelect,
|
|
121488
121888
|
apiTabApiKeyModal: apiTabApiKeyModal,
|
|
121489
121889
|
apiTabCreateApiModal2: apiTabCreateApiModal2,
|
|
121490
121890
|
apiTabDeleteApiModal2: apiTabDeleteApiModal2,
|
|
@@ -124462,11 +124862,10 @@ const getUserName$1 = () => {
|
|
|
124462
124862
|
};
|
|
124463
124863
|
|
|
124464
124864
|
/**
|
|
124465
|
-
*
|
|
124466
|
-
*
|
|
124467
|
-
* localStorage after mount to stay SSR-safe.
|
|
124865
|
+
* The signed-in user's username, or an empty string before it is known. Read
|
|
124866
|
+
* from localStorage after mount to stay SSR-safe.
|
|
124468
124867
|
*/
|
|
124469
|
-
function
|
|
124868
|
+
function useCurrentUsername() {
|
|
124470
124869
|
const [currentUsername, setCurrentUsername] = useState('');
|
|
124471
124870
|
useEffect(() => {
|
|
124472
124871
|
try {
|
|
@@ -124476,6 +124875,14 @@ function useIsProfilePreview(username) {
|
|
|
124476
124875
|
setCurrentUsername('');
|
|
124477
124876
|
}
|
|
124478
124877
|
}, []);
|
|
124878
|
+
return currentUsername;
|
|
124879
|
+
}
|
|
124880
|
+
/**
|
|
124881
|
+
* True when the logged-in user is viewing someone else's profile (preview
|
|
124882
|
+
* mode), so editing affordances can be hidden.
|
|
124883
|
+
*/
|
|
124884
|
+
function useIsProfilePreview(username) {
|
|
124885
|
+
const currentUsername = useCurrentUsername();
|
|
124479
124886
|
return !!currentUsername && currentUsername !== username;
|
|
124480
124887
|
}
|
|
124481
124888
|
|
|
@@ -175623,7 +176030,7 @@ function DetailRow({ label, children }) {
|
|
|
175623
176030
|
return (jsxs("div", { className: "flex items-center justify-between gap-4 py-2", children: [jsx("span", { className: "text-sm text-gray-500", children: label }), jsx("span", { className: "text-sm font-medium text-gray-900 text-right", children: children })] }));
|
|
175624
176031
|
}
|
|
175625
176032
|
|
|
175626
|
-
const PAGE_SIZE$
|
|
176033
|
+
const PAGE_SIZE$b = 8;
|
|
175627
176034
|
const CONTENT_TYPES = [
|
|
175628
176035
|
{ value: 'courses', labelKey: 'gradebookGradebookTab.typeCourses', icon: GraduationCap },
|
|
175629
176036
|
{ value: 'programs', labelKey: 'gradebookGradebookTab.typePrograms', icon: Layers },
|
|
@@ -175654,14 +176061,14 @@ function useGradebookData(type, org, username, page, search) {
|
|
|
175654
176061
|
username,
|
|
175655
176062
|
query: {
|
|
175656
176063
|
page,
|
|
175657
|
-
page_size: PAGE_SIZE$
|
|
176064
|
+
page_size: PAGE_SIZE$b,
|
|
175658
176065
|
platform_key: org,
|
|
175659
176066
|
...(trimmed ? { search: trimmed } : {}),
|
|
175660
176067
|
},
|
|
175661
176068
|
}, { skip: type !== 'courses', refetchOnMountOrArgChange: true });
|
|
175662
176069
|
const programsQ = useGetUserEnrolledProgramsQuery([{ username, platformKey: org }], { skip: type !== 'programs' });
|
|
175663
176070
|
const pathwaysQ = useGetUserCatalogPathwaysQuery({ username, platform_key: org }, { skip: type !== 'pathways' });
|
|
175664
|
-
const credentialsQ = useGetUsersAsAssertionsQuery({ platformKey: org, userId: username, page, pageSize: PAGE_SIZE$
|
|
176071
|
+
const credentialsQ = useGetUsersAsAssertionsQuery({ platformKey: org, userId: username, page, pageSize: PAGE_SIZE$b }, { skip: type !== 'credentials', refetchOnMountOrArgChange: true });
|
|
175665
176072
|
const earnedQ = useGetUserEarnedSkillsQuery([{ org, userId: username }], { skip: type !== 'skills' });
|
|
175666
176073
|
const reportedQ = useGetUserReportedSkillsQuery([{ username }], { skip: type !== 'skills' });
|
|
175667
176074
|
const desiredQ = useGetUserDesiredSkillsQuery([{ username }], { skip: type !== 'skills' });
|
|
@@ -175671,12 +176078,12 @@ function useGradebookData(type, org, username, page, search) {
|
|
|
175671
176078
|
const filtered = trimmed
|
|
175672
176079
|
? rows.filter((row) => row.name.toLowerCase().includes(trimmed.toLowerCase()))
|
|
175673
176080
|
: rows;
|
|
175674
|
-
const start = (page - 1) * PAGE_SIZE$
|
|
176081
|
+
const start = (page - 1) * PAGE_SIZE$b;
|
|
175675
176082
|
return {
|
|
175676
|
-
rows: filtered.slice(start, start + PAGE_SIZE$
|
|
176083
|
+
rows: filtered.slice(start, start + PAGE_SIZE$b),
|
|
175677
176084
|
total: filtered.length,
|
|
175678
176085
|
hasPrev: page > 1,
|
|
175679
|
-
hasNext: start + PAGE_SIZE$
|
|
176086
|
+
hasNext: start + PAGE_SIZE$b < filtered.length,
|
|
175680
176087
|
};
|
|
175681
176088
|
};
|
|
175682
176089
|
switch (type) {
|
|
@@ -175733,7 +176140,7 @@ function useGradebookData(type, org, username, page, search) {
|
|
|
175733
176140
|
rows,
|
|
175734
176141
|
total,
|
|
175735
176142
|
hasPrev: page > 1,
|
|
175736
|
-
hasNext: page * PAGE_SIZE$
|
|
176143
|
+
hasNext: page * PAGE_SIZE$b < total,
|
|
175737
176144
|
isLoading: credentialsQ.isLoading,
|
|
175738
176145
|
isFetching: credentialsQ.isFetching,
|
|
175739
176146
|
isError: credentialsQ.isError,
|
|
@@ -175972,29 +176379,58 @@ const IblPagination = ({ currentPage, totalPages, onPageChange, disabled = false
|
|
|
175972
176379
|
|
|
175973
176380
|
const MEMORIES_PAGE_SIZE = 25;
|
|
175974
176381
|
function MemoryTab({ org, username }) {
|
|
175975
|
-
var _a, _b
|
|
176382
|
+
var _a, _b;
|
|
175976
176383
|
const t = useT();
|
|
175977
176384
|
const [isAddDialogOpen, setIsAddDialogOpen] = useState(false);
|
|
175978
176385
|
const [deletingId, setDeletingId] = useState(null);
|
|
175979
176386
|
const [currentPage, setCurrentPage] = useState(1);
|
|
176387
|
+
// Viewing someone else's profile, which lists both of that user's memory
|
|
176388
|
+
// collections — global and per-agent — instead of just your own global feed.
|
|
176389
|
+
const isPreview = useIsProfilePreview(username);
|
|
176390
|
+
const currentUsername = useCurrentUsername();
|
|
175980
176391
|
// Platform memsearch status (available to students and admins)
|
|
175981
176392
|
const { data: memsearchStatus, isLoading: isLoadingConfig, isError: isConfigError, } = useGetMemsearchStatusQuery({
|
|
175982
176393
|
org,
|
|
175983
176394
|
userId: username,
|
|
175984
|
-
});
|
|
176395
|
+
}, { skip: isPreview });
|
|
175985
176396
|
// User memory settings
|
|
175986
176397
|
const { data: settings, isLoading: isLoadingSettings } = useGetUserMemorySettingsQuery({
|
|
175987
176398
|
org,
|
|
175988
176399
|
userId: username,
|
|
175989
|
-
});
|
|
176400
|
+
}, { skip: isPreview });
|
|
175990
176401
|
const [updateSettings, { isLoading: isUpdatingSettings }] = useUpdateUserMemorySettingsMutation();
|
|
175991
|
-
|
|
175992
|
-
|
|
176402
|
+
const memoriesParams = { page: currentPage, page_size: MEMORIES_PAGE_SIZE };
|
|
176403
|
+
// Global memories. On your own profile this is the plain call — your username
|
|
176404
|
+
// in the path. Previewing someone else addresses it the way the analytics
|
|
176405
|
+
// memory tab does: the caller in the `{user_id}` path segment, and the user
|
|
176406
|
+
// being looked at in the `user_id` param.
|
|
176407
|
+
const { data: globalMemoriesData, isLoading: isLoadingGlobalMemories } = useGetGlobalMemoriesQuery(isPreview
|
|
176408
|
+
? { org, userId: currentUsername, params: { ...memoriesParams, user_id: username } }
|
|
176409
|
+
: { org, userId: username, params: memoriesParams }, { skip: isPreview && !currentUsername });
|
|
176410
|
+
// Agent memories across every mentor, addressed the same way. Only fetched in
|
|
176411
|
+
// preview, where the tab shows both of the profile owner's collections.
|
|
176412
|
+
const { data: mentorMemoriesData, isLoading: isLoadingMentorMemories } = useGetAllMentorMemoriesQuery({
|
|
175993
176413
|
org,
|
|
175994
|
-
userId:
|
|
175995
|
-
params: {
|
|
175996
|
-
});
|
|
175997
|
-
const
|
|
176414
|
+
userId: currentUsername,
|
|
176415
|
+
params: { ...memoriesParams, user_id: username },
|
|
176416
|
+
}, { skip: !isPreview || !currentUsername });
|
|
176417
|
+
const memories = useMemo(() => {
|
|
176418
|
+
var _a, _b;
|
|
176419
|
+
const globalMemories = (_a = globalMemoriesData === null || globalMemoriesData === void 0 ? void 0 : globalMemoriesData.results) !== null && _a !== void 0 ? _a : [];
|
|
176420
|
+
if (!isPreview)
|
|
176421
|
+
return globalMemories;
|
|
176422
|
+
// Both collections are newest-first on their own; interleave them so the
|
|
176423
|
+
// combined list still reads chronologically.
|
|
176424
|
+
return [...((_b = mentorMemoriesData === null || mentorMemoriesData === void 0 ? void 0 : mentorMemoriesData.results) !== null && _b !== void 0 ? _b : []), ...globalMemories].sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
176425
|
+
}, [isPreview, globalMemoriesData, mentorMemoriesData]);
|
|
176426
|
+
const isLoadingMemories = isLoadingGlobalMemories || (isPreview && isLoadingMentorMemories);
|
|
176427
|
+
// The two collections page independently at the same size, so a page shows
|
|
176428
|
+
// that page of each and the pager spans whichever collection is longer.
|
|
176429
|
+
const totalPages = useMemo(() => {
|
|
176430
|
+
const pageCount = (count) => (count ? Math.ceil(count / MEMORIES_PAGE_SIZE) : 0);
|
|
176431
|
+
const globalPages = pageCount(globalMemoriesData === null || globalMemoriesData === void 0 ? void 0 : globalMemoriesData.count);
|
|
176432
|
+
return isPreview ? Math.max(globalPages, pageCount(mentorMemoriesData === null || mentorMemoriesData === void 0 ? void 0 : mentorMemoriesData.count)) : globalPages;
|
|
176433
|
+
}, [isPreview, globalMemoriesData, mentorMemoriesData]);
|
|
175998
176434
|
const [deleteMemory] = useDeleteGlobalMemoryMutation();
|
|
175999
176435
|
const handleToggleSetting = async (key, checked) => {
|
|
176000
176436
|
try {
|
|
@@ -176033,7 +176469,7 @@ function MemoryTab({ org, username }) {
|
|
|
176033
176469
|
if (!isConfigError && memsearchStatus && !memsearchStatus.enable_memsearch) {
|
|
176034
176470
|
return (jsx("div", { className: "max-w-2xl", children: jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children: t('memoryMemoryTab.memoryFeatureDisabled') }) }) }));
|
|
176035
176471
|
}
|
|
176036
|
-
return (jsxs("div", { className: "space-y-8", children: [jsxs("div", { className: "space-y-4", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children: t('memoryMemoryTab.sectionMemoryPersonalization') }), jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex-1 mr-4", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: t('memoryMemoryTab.autoCaptureLabelTitle') }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: t('memoryMemoryTab.autoCaptureLabelDesc') })] }), jsx(Switch, { checked: (_a = settings === null || settings === void 0 ? void 0 : settings.auto_capture_enabled) !== null && _a !== void 0 ? _a : false, onCheckedChange: (checked) => handleToggleSetting('auto_capture_enabled', checked), disabled: isUpdatingSettings, "aria-label": t('memoryMemoryTab.autoCaptureAriaLabel', {
|
|
176472
|
+
return (jsxs("div", { className: "space-y-8", children: [!isPreview && (jsxs("div", { className: "space-y-4", children: [!isPreview && (jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children: t('memoryMemoryTab.sectionMemoryPersonalization') })), jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex-1 mr-4", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: t('memoryMemoryTab.autoCaptureLabelTitle') }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: t('memoryMemoryTab.autoCaptureLabelDesc') })] }), jsx(Switch, { checked: (_a = settings === null || settings === void 0 ? void 0 : settings.auto_capture_enabled) !== null && _a !== void 0 ? _a : false, onCheckedChange: (checked) => handleToggleSetting('auto_capture_enabled', checked), disabled: isUpdatingSettings, "aria-label": t('memoryMemoryTab.autoCaptureAriaLabel', {
|
|
176037
176473
|
state: (settings === null || settings === void 0 ? void 0 : settings.auto_capture_enabled)
|
|
176038
176474
|
? t('memoryMemoryTab.stateEnabled')
|
|
176039
176475
|
: t('memoryMemoryTab.stateDisabled'),
|
|
@@ -176041,9 +176477,13 @@ function MemoryTab({ org, username }) {
|
|
|
176041
176477
|
state: (settings === null || settings === void 0 ? void 0 : settings.use_memory_in_responses)
|
|
176042
176478
|
? t('memoryMemoryTab.stateEnabled')
|
|
176043
176479
|
: t('memoryMemoryTab.stateDisabled'),
|
|
176044
|
-
}), className: "cursor-pointer data-[state=checked]:bg-blue-500 flex-shrink-0" })] })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children:
|
|
176480
|
+
}), className: "cursor-pointer data-[state=checked]:bg-blue-500 flex-shrink-0" })] })] })), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children: isPreview
|
|
176481
|
+
? t('memoryMemoryTab.sectionMyMemoriesPreview')
|
|
176482
|
+
: t('memoryMemoryTab.sectionMyMemories') }), !isPreview && (jsxs(Button$1, { variant: "outline", size: "sm", onClick: () => setIsAddDialogOpen(true), className: "text-xs", children: [jsx(Plus, { className: "h-3 w-3 mr-1" }), t('memoryMemoryTab.addMemoryButton')] }))] }), isLoadingMemories ? (jsx("div", { className: "space-y-3", children: [1, 2, 3].map((i) => (jsx(Skeleton, { className: "h-16 w-full rounded-lg" }, i))) })) : memories.length ? (jsx("div", { className: "space-y-3", children: memories.map((memory) => (jsxs("div", { className: "group flex items-start gap-3 rounded-lg border px-4 py-3", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx("div", { className: "flex-shrink-0 mt-0.5", children: memory.is_auto_generated ? (jsx(Bot, { className: "h-4 w-4 text-blue-500", "aria-label": t('memoryMemoryTab.autoGeneratedMemoryAriaLabel') })) : (jsx(User, { className: "h-4 w-4 text-gray-400", "aria-label": t('memoryMemoryTab.manuallyAddedMemoryAriaLabel') })) }), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("p", { className: "text-sm text-gray-800 dark:text-gray-200", children: memory.content }), jsxs("p", { className: "text-xs text-gray-400 mt-1", children: [new Date(memory.created_at).toLocaleDateString(), memory.is_auto_generated && (jsx("span", { className: "ml-2 inline-flex items-center rounded-full bg-blue-50 px-1.5 py-0.5 text-[10px] font-medium text-blue-600", children: t('memoryMemoryTab.autoBadge') }))] })] }), !isPreview && (jsx("button", { type: "button", onClick: () => handleDeleteMemory(memory.id), disabled: deletingId === memory.id, className: "flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded hover:bg-gray-100 text-gray-400 hover:text-gray-600 focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-gray-300", "aria-label": t('memoryMemoryTab.deleteMemoryAriaLabel', {
|
|
176045
176483
|
excerpt: memory.content.substring(0, 30),
|
|
176046
|
-
}), children: deletingId === memory.id ? (jsx("div", { className: "w-4 h-4 border-2 border-gray-500 border-t-transparent rounded-full animate-spin" })) : (jsx(Trash2, { className: "h-4 w-4" })) })] }, memory.id))) })) : (jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children:
|
|
176484
|
+
}), children: deletingId === memory.id ? (jsx("div", { className: "w-4 h-4 border-2 border-gray-500 border-t-transparent rounded-full animate-spin" })) : (jsx(Trash2, { className: "h-4 w-4" })) }))] }, `${'mentor_id' in memory ? memory.mentor_id : 'global'}-${memory.id}`))) })) : (jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children: isPreview
|
|
176485
|
+
? t('memoryMemoryTab.noMemoriesYetPreview')
|
|
176486
|
+
: t('memoryMemoryTab.noMemoriesYet') }) })), totalPages > 1 && (jsx(IblPagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: setCurrentPage, disabled: isLoadingMemories }))] }), jsx(AddMemoryDialog, { open: isAddDialogOpen, onOpenChange: setIsAddDialogOpen, org: org, username: username })] }));
|
|
176047
176487
|
}
|
|
176048
176488
|
|
|
176049
176489
|
var _a$1;
|
|
@@ -178184,7 +178624,9 @@ const PopoverContent = React.forwardRef(({ className, align = 'center', sideOffs
|
|
|
178184
178624
|
});
|
|
178185
178625
|
PopoverContent.displayName = Content2$2.displayName;
|
|
178186
178626
|
|
|
178627
|
+
const PAGE_SIZE$a = 10;
|
|
178187
178628
|
function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false, }) {
|
|
178629
|
+
var _a, _b;
|
|
178188
178630
|
const t = useT();
|
|
178189
178631
|
const dispatch = useDispatch();
|
|
178190
178632
|
const [page, setPage] = useState(1);
|
|
@@ -178196,14 +178638,35 @@ function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false,
|
|
|
178196
178638
|
const [updatingUserIds, setUpdatingUserIds] = useState(new Set());
|
|
178197
178639
|
const [openPolicyPopover, setOpenPolicyPopover] = useState(null);
|
|
178198
178640
|
const [selectedUser, setSelectedUser] = useState(null);
|
|
178199
|
-
const {
|
|
178641
|
+
const { currentTenant } = useCurrentTenant();
|
|
178642
|
+
const rbacPermissions = useSelector(selectRbacPermissions);
|
|
178643
|
+
// A pure watcher administers nothing: the platform users endpoint 403s for
|
|
178644
|
+
// them, so they get the RBAC-scoped list of users they may read instead —
|
|
178645
|
+
// name and email only, with no invite, role, policy or status controls.
|
|
178646
|
+
const isWatcher = isPureWatcher(rbacPermissions, currentTenant);
|
|
178647
|
+
const { data: users, refetch: refetchPlatformUsers, isLoading: isLoadingPlatformUsers, } = usePlatformUsersQuery({
|
|
178200
178648
|
page,
|
|
178201
|
-
page_size:
|
|
178649
|
+
page_size: PAGE_SIZE$a,
|
|
178202
178650
|
platform_key: tenant,
|
|
178203
178651
|
platform_org: tenant,
|
|
178204
178652
|
query: debouncedSearchQuery,
|
|
178205
178653
|
return_policies: 'true',
|
|
178206
|
-
});
|
|
178654
|
+
}, { skip: isWatcher });
|
|
178655
|
+
// The accessible endpoint scopes itself to the caller's platform from their
|
|
178656
|
+
// token, so it takes no tenant param. It also filters per field instead of
|
|
178657
|
+
// with one search param, hence the "@" routing the term to `email` and
|
|
178658
|
+
// anything else to `username`.
|
|
178659
|
+
const { data: accessibleUsers, isLoading: isLoadingAccessibleUsers } = useGetAccessibleUsersQuery({
|
|
178660
|
+
// TODO to use required_action: 'Ibl.Core/Users/read',
|
|
178661
|
+
required_action: 'Ibl.Mentor/Memory/list',
|
|
178662
|
+
page,
|
|
178663
|
+
page_size: PAGE_SIZE$a,
|
|
178664
|
+
sort: 'name',
|
|
178665
|
+
...(debouncedSearchQuery.includes('@')
|
|
178666
|
+
? { email: debouncedSearchQuery }
|
|
178667
|
+
: { username: debouncedSearchQuery }),
|
|
178668
|
+
}, { skip: !isWatcher });
|
|
178669
|
+
const isLoading = isWatcher ? isLoadingAccessibleUsers : isLoadingPlatformUsers;
|
|
178207
178670
|
useEffect(() => {
|
|
178208
178671
|
const handler = setTimeout(() => {
|
|
178209
178672
|
if (searchQuery.length > 2) {
|
|
@@ -178220,7 +178683,10 @@ function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false,
|
|
|
178220
178683
|
}, [searchQuery]);
|
|
178221
178684
|
const handlePageChange = async (newPage) => {
|
|
178222
178685
|
setPage(newPage);
|
|
178223
|
-
|
|
178686
|
+
// The watcher list is served by the other (skipped) query — changing `page`
|
|
178687
|
+
// is enough to refetch it.
|
|
178688
|
+
if (!isWatcher)
|
|
178689
|
+
await refetchPlatformUsers();
|
|
178224
178690
|
};
|
|
178225
178691
|
const handleUserRoleChange = async (user) => {
|
|
178226
178692
|
const userId = user === null || user === void 0 ? void 0 : user.user_id;
|
|
@@ -178338,8 +178804,6 @@ function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false,
|
|
|
178338
178804
|
});
|
|
178339
178805
|
}
|
|
178340
178806
|
};
|
|
178341
|
-
// Calculate total pages
|
|
178342
|
-
const totalPages = users ? Math.ceil(users.count / 10) : 0; // Assuming 10 users per page
|
|
178343
178807
|
// Extract allowed policies and user data
|
|
178344
178808
|
const isResultsWithPolicies = (users === null || users === void 0 ? void 0 : users.results) ? isPoliciesResponse(users.results) : false;
|
|
178345
178809
|
const allowedPolicies = isResultsWithPolicies
|
|
@@ -178348,31 +178812,55 @@ function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false,
|
|
|
178348
178812
|
const userData = isResultsWithPolicies
|
|
178349
178813
|
? (users === null || users === void 0 ? void 0 : users.results).data
|
|
178350
178814
|
: [];
|
|
178351
|
-
|
|
178352
|
-
|
|
178353
|
-
|
|
178354
|
-
|
|
178815
|
+
const rows = isWatcher
|
|
178816
|
+
? ((_a = accessibleUsers === null || accessibleUsers === void 0 ? void 0 : accessibleUsers.results) !== null && _a !== void 0 ? _a : []).map((user) => ({
|
|
178817
|
+
key: user.id,
|
|
178818
|
+
name: user.name,
|
|
178819
|
+
email: user.email,
|
|
178820
|
+
username: user.username,
|
|
178821
|
+
isAdmin: false,
|
|
178822
|
+
}))
|
|
178823
|
+
: userData.map((user) => ({
|
|
178824
|
+
key: user.user_id,
|
|
178825
|
+
name: user.name,
|
|
178826
|
+
email: user.email,
|
|
178827
|
+
username: user.username,
|
|
178828
|
+
isAdmin: user.is_admin,
|
|
178829
|
+
managed: user,
|
|
178830
|
+
}));
|
|
178831
|
+
const totalCount = (_b = (isWatcher ? accessibleUsers === null || accessibleUsers === void 0 ? void 0 : accessibleUsers.count : users === null || users === void 0 ? void 0 : users.count)) !== null && _b !== void 0 ? _b : 0;
|
|
178832
|
+
const totalPages = Math.ceil(totalCount / PAGE_SIZE$a);
|
|
178833
|
+
return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex justify-between items-center gap-1", children: [jsxs("div", { className: "relative mb-6 max-w-sm", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { type: "text", value: searchQuery, onChange: (event) => setQuerySearch(event.target.value), placeholder: t('tabsUserstab.searchPlaceholder'), className: "pl-10 pr-10 focus:ring-blue-500 focus:border-blue-500 h-[35px]", "aria-label": t('tabsUserstab.searchAriaLabel') }), searchQuery.length > 0 && (searchQuery !== debouncedSearchQuery || isLoading) && (jsx(LoaderCircle, { "data-testid": "search-spinner", className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400 animate-spin", "aria-hidden": "true" }))] }), !isWatcher && (jsx("div", { className: "mb-6", children: jsx(Button$1, { className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", onClick: onInviteClick, children: t('tabsUserstab.inviteButton') }) }))] }), isLoading ? (jsx("div", { className: "flex justify-center items-center h-64", children: jsx(Spinner, {}) })) : (jsxs(Fragment$1, { children: [jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: `px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 ${isWatcher ? 'w-[40%]' : 'w-[16%]'}`, children: t('tabsUserstab.columnName') }), jsx("th", { className: `px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 ${isWatcher ? 'w-[60%]' : 'w-[25%]'}`, children: t('tabsUserstab.columnEmail') }), !isWatcher && (jsxs(Fragment$1, { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[16%]", children: t('tabsUserstab.columnRole') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[25%]", children: t('tabsUserstab.columnPolicies') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[18%]", children: t('tabsUserstab.columnStatus') })] }))] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [rows.map((row) => {
|
|
178834
|
+
// Only set on the admin path — see {@link UserRow}.
|
|
178835
|
+
const user = row.managed;
|
|
178836
|
+
return (jsxs("tr", { onClick: () => setSelectedUser(row), className: "cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors", children: [jsx("td", { "aria-label": 'user-management-name-column', className: "px-6 py-4 text-gray-900 dark:text-gray-100 text-sm whitespace-nowrap overflow-hidden text-ellipsis max-w-0", children: jsx("button", { type: "button", onClick: (e) => {
|
|
178837
|
+
e.stopPropagation();
|
|
178838
|
+
setSelectedUser(row);
|
|
178839
|
+
}, className: "block max-w-full truncate text-left hover:text-blue-600 hover:underline focus:outline-none focus:text-blue-600", "aria-label": t('tabsUserstab.viewProfileAriaLabel', { name: row.name }), children: row.name }) }), jsx("td", { "aria-label": 'user-management-email-column', className: "px-6 py-4 text-gray-600 dark:text-gray-300 text-sm max-w-0", children: jsx("div", { className: "truncate", children: row.email }) }), user && (jsxs(Fragment$1, { children: [jsx("td", { className: "px-6 py-4", onClick: (e) => e.stopPropagation(), children: jsxs(Select$1, { value: user.is_admin ? 'admin' : 'student', onValueChange: () => handleUserRoleChange(user), children: [jsx(SelectTrigger, { className: "w-full text-sm", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { className: "text-sm", children: [jsx(SelectItem, { value: "admin", children: t('tabsUserstab.roleAdmin') }), jsx(SelectItem, { value: "student", children: t('tabsUserstab.roleUser') })] })] }) }), jsx("td", { className: "px-6 py-4", onClick: (e) => e.stopPropagation(), children: jsxs(Popover, { modal: true, open: openPolicyPopover === user.user_id, onOpenChange: (open) => setOpenPolicyPopover(open ? user.user_id : null), children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", role: "combobox", "aria-expanded": openPolicyPopover === user.user_id, "aria-label": t('tabsUserstab.selectPoliciesAriaLabel', {
|
|
178840
|
+
name: user.name,
|
|
178841
|
+
}), className: "w-full justify-between text-sm h-9 font-normal", disabled: updatingUserIds.has(user === null || user === void 0 ? void 0 : user.user_id), children: [jsx("span", { className: "truncate", children: user.is_admin
|
|
178842
|
+
? t('tabsUserstab.allPoliciesSelected', {
|
|
178843
|
+
count: allowedPolicies.length,
|
|
178844
|
+
})
|
|
178845
|
+
: user.policies && user.policies.length > 0
|
|
178846
|
+
? t('tabsUserstab.nPoliciesSelected', {
|
|
178847
|
+
count: user.policies.length,
|
|
178848
|
+
})
|
|
178849
|
+
: t('tabsUserstab.noPolicies') }), openPolicyPopover === user.user_id ? (jsx(ChevronUp, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })) : (jsx(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" }))] }) }), jsx(PopoverContent, { className: "w-64 p-3", align: "start", children: jsxs("div", { className: "space-y-2", children: [jsx("div", { className: "text-sm font-medium mb-2", children: t('tabsUserstab.selectPoliciesHeading') }), allowedPolicies.map((policy) => {
|
|
178850
|
+
var _a;
|
|
178851
|
+
return (jsxs("div", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { id: `${user.user_id}-${policy}`, checked: user.is_admin || ((_a = user.policies) === null || _a === void 0 ? void 0 : _a.includes(policy)), onCheckedChange: (checked) => handlePolicyChange(user, policy, checked), disabled: user.is_admin || updatingUserIds.has(user === null || user === void 0 ? void 0 : user.user_id), "aria-label": t('tabsUserstab.togglePolicyAriaLabel', {
|
|
178852
|
+
policy,
|
|
178853
|
+
name: user.name,
|
|
178854
|
+
}) }), jsx("label", { htmlFor: `${user.user_id}-${policy}`, className: `text-sm font-normal ${user.is_admin ? 'cursor-default' : 'cursor-pointer'}`, children: policy })] }, policy));
|
|
178855
|
+
})] }) })] }) }), jsx("td", { className: "px-6 py-4", onClick: (e) => e.stopPropagation(), children: jsx(Switch, { checked: user.active, onCheckedChange: (checked) => handleUserStatusChange(user, checked), disabled: updatingUserIds.has(user === null || user === void 0 ? void 0 : user.user_id), "aria-label": t('tabsUserstab.toggleStatusAriaLabel', {
|
|
178355
178856
|
name: user.name,
|
|
178356
|
-
}), className: "
|
|
178357
|
-
|
|
178358
|
-
count: allowedPolicies.length,
|
|
178359
|
-
})
|
|
178360
|
-
: user.policies && user.policies.length > 0
|
|
178361
|
-
? t('tabsUserstab.nPoliciesSelected', {
|
|
178362
|
-
count: user.policies.length,
|
|
178363
|
-
})
|
|
178364
|
-
: t('tabsUserstab.noPolicies') }), openPolicyPopover === user.user_id ? (jsx(ChevronUp, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })) : (jsx(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" }))] }) }), jsx(PopoverContent, { className: "w-64 p-3", align: "start", children: jsxs("div", { className: "space-y-2", children: [jsx("div", { className: "text-sm font-medium mb-2", children: t('tabsUserstab.selectPoliciesHeading') }), allowedPolicies.map((policy) => {
|
|
178365
|
-
var _a;
|
|
178366
|
-
return (jsxs("div", { className: "flex items-center space-x-2", children: [jsx(Checkbox, { id: `${user.user_id}-${policy}`, checked: user.is_admin || ((_a = user.policies) === null || _a === void 0 ? void 0 : _a.includes(policy)), onCheckedChange: (checked) => handlePolicyChange(user, policy, checked), disabled: user.is_admin || updatingUserIds.has(user === null || user === void 0 ? void 0 : user.user_id), "aria-label": t('tabsUserstab.togglePolicyAriaLabel', {
|
|
178367
|
-
policy,
|
|
178368
|
-
name: user.name,
|
|
178369
|
-
}) }), jsx("label", { htmlFor: `${user.user_id}-${policy}`, className: `text-sm font-normal ${user.is_admin ? 'cursor-default' : 'cursor-pointer'}`, children: policy })] }, policy));
|
|
178370
|
-
})] }) })] }) }), jsx("td", { className: "px-6 py-4", onClick: (e) => e.stopPropagation(), children: jsx(Switch, { checked: user.active, onCheckedChange: (checked) => handleUserStatusChange(user, checked), disabled: updatingUserIds.has(user === null || user === void 0 ? void 0 : user.user_id), "aria-label": t('tabsUserstab.toggleStatusAriaLabel', { name: user.name }), className: "cursor-pointer data-[state=checked]:bg-blue-500 disabled:cursor-not-allowed disabled:opacity-50" }) })] }, index))), (!userData || userData.length === 0) && (jsx("tr", { children: jsx("td", { colSpan: 5, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: t('tabsUserstab.noUsersFound') }) }))] })] }) }), jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (_page) => handlePageChange(_page), totalCount: users === null || users === void 0 ? void 0 : users.count, itemsPerPage: 10, itemLabel: "users" })] })), selectedUser && (jsx(Dialog, { open: !!selectedUser, onOpenChange: (open) => {
|
|
178857
|
+
}), className: "cursor-pointer data-[state=checked]:bg-blue-500 disabled:cursor-not-allowed disabled:opacity-50" }) })] }))] }, row.key));
|
|
178858
|
+
}), rows.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: isWatcher ? 2 : 5, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: t('tabsUserstab.noUsersFound') }) }))] })] }) }), jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (_page) => handlePageChange(_page), totalCount: totalCount, itemsPerPage: PAGE_SIZE$a, itemLabel: "users" })] })), selectedUser && (jsx(Dialog, { open: !!selectedUser, onOpenChange: (open) => {
|
|
178371
178859
|
if (!open)
|
|
178372
178860
|
setSelectedUser(null);
|
|
178373
|
-
}, children: jsxs(DialogContent, { autoFocus: false, className: "max-w-7xl w-[85vw] p-0 gap-0 overflow-hidden bg-white profile-component-dialog", style: { height: '85vh', display: 'flex', flexDirection: 'column' }, children: [jsx(DialogTitle, { className: "sr-only", children: t('tabsUserstab.profileDialogTitle') }), jsx(DialogDescription, { className: "sr-only", children: t('tabsUserstab.profileDialogDescription') }), jsx(Profile, { tenant: tenant, tenants: [], username: selectedUser.username, isAdmin: selectedUser.
|
|
178861
|
+
}, children: jsxs(DialogContent, { autoFocus: false, className: "max-w-7xl w-[85vw] p-0 gap-0 overflow-hidden bg-white profile-component-dialog", style: { height: '85vh', display: 'flex', flexDirection: 'column' }, children: [jsx(DialogTitle, { className: "sr-only", children: t('tabsUserstab.profileDialogTitle') }), jsx(DialogDescription, { className: "sr-only", children: t('tabsUserstab.profileDialogDescription') }), jsx(Profile, { tenant: tenant, tenants: [], username: selectedUser.username, isAdmin: selectedUser.isAdmin, currentSPA: currentSpa, onClose: () => setSelectedUser(null), customization: {
|
|
178374
178862
|
showGradebookTab: showGradebookTab,
|
|
178375
|
-
} })] }) }))] }));
|
|
178863
|
+
}, enableMemoryTab: true })] }) }))] }));
|
|
178376
178864
|
}
|
|
178377
178865
|
|
|
178378
178866
|
// Permission options for teams access
|
|
@@ -179587,7 +180075,7 @@ function PoliciesTab({ tenant }) {
|
|
|
179587
180075
|
: t('tabsPoliciestab.createPolicy')] }) }) }), editing && (policyDetails === null || policyDetails === void 0 ? void 0 : policyDetails.is_internal) && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsPoliciestab.cannotEditInternal') }) }))] }) })] })] }) }), jsx(ResourcePickerModal, { open: isResourcePickerOpen, onOpenChange: setIsResourcePickerOpen, tenant: tenant, onSelect: addPickedResource })] }));
|
|
179588
180076
|
}
|
|
179589
180077
|
|
|
179590
|
-
const PAGE_SIZE$
|
|
180078
|
+
const PAGE_SIZE$9 = 10;
|
|
179591
180079
|
function normalizeEvents(events) {
|
|
179592
180080
|
if (!events)
|
|
179593
180081
|
return [];
|
|
@@ -179636,8 +180124,8 @@ function AlertsTab({ tenant }) {
|
|
|
179636
180124
|
const { data: watchedGroupsData, isLoading, isError, refetch, } = useGetWatchedGroupsQuery({
|
|
179637
180125
|
params: {
|
|
179638
180126
|
platform_key: tenant,
|
|
179639
|
-
limit: PAGE_SIZE$
|
|
179640
|
-
offset: (page - 1) * PAGE_SIZE$
|
|
180127
|
+
limit: PAGE_SIZE$9,
|
|
180128
|
+
offset: (page - 1) * PAGE_SIZE$9,
|
|
179641
180129
|
},
|
|
179642
180130
|
});
|
|
179643
180131
|
const groups = useMemo(() => {
|
|
@@ -179650,7 +180138,7 @@ function AlertsTab({ tenant }) {
|
|
|
179650
180138
|
return results;
|
|
179651
180139
|
}, [watchedGroupsData, debouncedSearchQuery]);
|
|
179652
180140
|
const totalPages = watchedGroupsData
|
|
179653
|
-
? Math.max(1, Math.ceil(watchedGroupsData.count / PAGE_SIZE$
|
|
180141
|
+
? Math.max(1, Math.ceil(watchedGroupsData.count / PAGE_SIZE$9))
|
|
179654
180142
|
: 0;
|
|
179655
180143
|
const handlePageChange = async (newPage) => {
|
|
179656
180144
|
setPage(newPage);
|
|
@@ -179959,7 +180447,7 @@ function AlertsTab({ tenant }) {
|
|
|
179959
180447
|
setDeletingGroupId(null);
|
|
179960
180448
|
}
|
|
179961
180449
|
}
|
|
179962
|
-
return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex mb-6 gap-2 flex-row items-center justify-between", children: [jsxs("div", { className: "relative max-w-sm w-full sm:w-auto", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: t('tabsAlertstab.searchAlertsPlaceholder'), "aria-label": t('tabsAlertstab.searchAlertsAriaLabel'), className: "pl-10 pr-10 focus:ring-blue-500 focus:border-blue-500 h-[35px]" }), isLoading && (jsx(LoaderCircle, { "data-testid": "search-spinner", className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400 animate-spin", "aria-hidden": "true" }))] }), jsx("div", { className: "flex gap-2", children: jsx(Button$1, { onClick: openNew, "aria-label": t('tabsAlertstab.newAlertAriaLabel'), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", children: t('tabsAlertstab.newAlert') }) })] }), isLoading && (jsx("div", { className: "flex justify-center items-center h-64", children: jsx("div", { className: "py-8 text-center text-sm text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.loading') }) })), isError && (jsx("div", { className: "py-8 text-center text-sm text-red-500", children: t('tabsAlertstab.failedToLoadAlerts') })), !isLoading && !isError && (jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.columnName') }), jsx("th", { className: "px-6 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[120px]" })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [groups.map((g) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 text-gray-900 dark:text-gray-100 text-sm", children: g.name }), jsx("td", { className: "px-6 py-4", children: jsxs("div", { className: "flex gap-2 justify-end", children: [jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => openEdit(g), disabled: deletingGroupId === g.id, "aria-label": t('tabsAlertstab.editAlertAriaLabel', { name: g.name }), children: jsx(Pencil, { className: "h-4 w-4", "aria-hidden": "true" }) }), jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => onDelete(g), className: "text-red-600 hover:text-red-700", disabled: deletingGroupId === g.id, "aria-label": t('tabsAlertstab.deleteAlertAriaLabel', { name: g.name }), children: deletingGroupId === g.id ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" })) : (jsx(Trash2, { className: "h-4 w-4", "aria-hidden": "true" })) })] }) })] }, g.id))), groups.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 2, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.noAlertsFound') }) }))] })] }) })), !isLoading && !isError && (jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (newPage) => handlePageChange(newPage), totalCount: watchedGroupsData === null || watchedGroupsData === void 0 ? void 0 : watchedGroupsData.count, itemsPerPage: PAGE_SIZE$
|
|
180450
|
+
return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex mb-6 gap-2 flex-row items-center justify-between", children: [jsxs("div", { className: "relative max-w-sm w-full sm:w-auto", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: t('tabsAlertstab.searchAlertsPlaceholder'), "aria-label": t('tabsAlertstab.searchAlertsAriaLabel'), className: "pl-10 pr-10 focus:ring-blue-500 focus:border-blue-500 h-[35px]" }), isLoading && (jsx(LoaderCircle, { "data-testid": "search-spinner", className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400 animate-spin", "aria-hidden": "true" }))] }), jsx("div", { className: "flex gap-2", children: jsx(Button$1, { onClick: openNew, "aria-label": t('tabsAlertstab.newAlertAriaLabel'), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", children: t('tabsAlertstab.newAlert') }) })] }), isLoading && (jsx("div", { className: "flex justify-center items-center h-64", children: jsx("div", { className: "py-8 text-center text-sm text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.loading') }) })), isError && (jsx("div", { className: "py-8 text-center text-sm text-red-500", children: t('tabsAlertstab.failedToLoadAlerts') })), !isLoading && !isError && (jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.columnName') }), jsx("th", { className: "px-6 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[120px]" })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [groups.map((g) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 text-gray-900 dark:text-gray-100 text-sm", children: g.name }), jsx("td", { className: "px-6 py-4", children: jsxs("div", { className: "flex gap-2 justify-end", children: [jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => openEdit(g), disabled: deletingGroupId === g.id, "aria-label": t('tabsAlertstab.editAlertAriaLabel', { name: g.name }), children: jsx(Pencil, { className: "h-4 w-4", "aria-hidden": "true" }) }), jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => onDelete(g), className: "text-red-600 hover:text-red-700", disabled: deletingGroupId === g.id, "aria-label": t('tabsAlertstab.deleteAlertAriaLabel', { name: g.name }), children: deletingGroupId === g.id ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" })) : (jsx(Trash2, { className: "h-4 w-4", "aria-hidden": "true" })) })] }) })] }, g.id))), groups.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 2, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.noAlertsFound') }) }))] })] }) })), !isLoading && !isError && (jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (newPage) => handlePageChange(newPage), totalCount: watchedGroupsData === null || watchedGroupsData === void 0 ? void 0 : watchedGroupsData.count, itemsPerPage: PAGE_SIZE$9, itemLabel: "alerts" })), jsx(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: jsxs(DialogContent, { "aria-describedby": undefined, className: "max-w-2xl max-h-[90vh] overflow-y-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { children: editingGroup ? t('tabsAlertstab.editAlert') : t('tabsAlertstab.newAlert') }) }), jsxs("div", { className: "space-y-5", children: [jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { htmlFor: "wg-name", children: t('tabsAlertstab.nameLabel') }), jsx(Input, { id: "wg-name", value: name, onChange: (e) => setName(e.target.value), placeholder: t('tabsAlertstab.enterAlertNamePlaceholder'), required: true })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { children: t('tabsAlertstab.watchedUsersLabel') }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.watchedUsersDescription') }), watchedUsers.length > 0 ? (jsx("div", { className: "space-y-2 max-h-48 overflow-y-auto border border-gray-200 dark:border-gray-700 rounded-md p-2", children: watchedUsers.map((user) => (jsxs("div", { className: "flex items-center justify-between bg-gray-50 dark:bg-gray-800 p-2 rounded-md", children: [jsxs("div", { className: "flex flex-col", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: user.name || user.username }), user.email && (jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: user.email }))] }), jsx(Button$1, { type: "button", variant: "ghost", size: "sm", onClick: () => removeWatchedUserDraft(user.id), className: "h-8 w-8 p-0 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20", "aria-label": t('tabsAlertstab.removeWatchedUserAriaLabel', {
|
|
179963
180451
|
username: user.username,
|
|
179964
180452
|
}), children: jsx(X$2, { className: "h-4 w-4" }) })] }, user.id))) })) : (jsx("div", { className: "text-sm text-gray-500 dark:text-gray-400 p-4 text-center border border-dashed border-gray-300 dark:border-gray-600 rounded-md", children: t('tabsAlertstab.noWatchedUsersAdded') })), jsxs("div", { className: "relative", children: [jsx(Input, { value: watchedUserSearch, onChange: (e) => {
|
|
179965
180453
|
setWatchedUserSearch(e.target.value);
|
|
@@ -181279,7 +181767,7 @@ function BlocksView({ platformKey, onBack, }) {
|
|
|
181279
181767
|
}
|
|
181280
181768
|
|
|
181281
181769
|
const FILTER_ORDER = ['all', ...APPLICATION_STATUSES];
|
|
181282
|
-
const PAGE_SIZE$
|
|
181770
|
+
const PAGE_SIZE$8 = 20;
|
|
181283
181771
|
const SEARCH_DEBOUNCE_MS = 300;
|
|
181284
181772
|
/**
|
|
181285
181773
|
* The public application URL on the auth SPA for one form of a platform
|
|
@@ -181412,7 +181900,7 @@ function SubmissionsPipeline({ platformKey, form, onBack, onOpen, }) {
|
|
|
181412
181900
|
...(sort !== '-created' ? { sort } : {}),
|
|
181413
181901
|
...candidateParams,
|
|
181414
181902
|
page,
|
|
181415
|
-
page_size: PAGE_SIZE$
|
|
181903
|
+
page_size: PAGE_SIZE$8,
|
|
181416
181904
|
}, {
|
|
181417
181905
|
refetchOnMountOrArgChange: true,
|
|
181418
181906
|
});
|
|
@@ -181421,7 +181909,7 @@ function SubmissionsPipeline({ platformKey, form, onBack, onOpen, }) {
|
|
|
181421
181909
|
: [];
|
|
181422
181910
|
const rows = form ? allRows.filter((row) => row.form_id === form.id) : allRows;
|
|
181423
181911
|
const count = typeof (pipeline === null || pipeline === void 0 ? void 0 : pipeline.count) === 'number' ? pipeline.count : allRows.length;
|
|
181424
|
-
const totalPages = Math.max(1, Math.ceil(count / PAGE_SIZE$
|
|
181912
|
+
const totalPages = Math.max(1, Math.ceil(count / PAGE_SIZE$8));
|
|
181425
181913
|
const counts = statsCounts(stats);
|
|
181426
181914
|
const countFor = (key) => {
|
|
181427
181915
|
if (!stats)
|
|
@@ -181459,7 +181947,7 @@ function SubmissionsPipeline({ platformKey, form, onBack, onOpen, }) {
|
|
|
181459
181947
|
}) }) }), jsx("td", { className: "whitespace-nowrap px-6 py-4 text-sm text-gray-600 dark:text-gray-300", children: formatDate(row) }), jsx("td", { className: "px-6 py-4", children: jsx(Badge, { variant: "outline", className: approvalTone(row.status), children: STATUS_LABEL_KEYS[row.status]
|
|
181460
181948
|
? t(STATUS_LABEL_KEYS[row.status])
|
|
181461
181949
|
: row.status }) })] }, row.id));
|
|
181462
|
-
})) })] }) }), jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (newPage) => setPage(newPage), totalCount: count, itemsPerPage: PAGE_SIZE$
|
|
181950
|
+
})) })] }) }), jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (newPage) => setPage(newPage), totalCount: count, itemsPerPage: PAGE_SIZE$8, itemLabel: "applications" })] }))] }));
|
|
181463
181951
|
}
|
|
181464
181952
|
|
|
181465
181953
|
const TabDescription = ({ icon, title, children }) => {
|
|
@@ -186451,6 +186939,64 @@ function CreateApiModal$1({ isOpen, onClose, tenantKey, username }) {
|
|
|
186451
186939
|
: t('apiTabLabels.createModal.submit') })) }) })] })] }) }), apiKey && jsx(ApiKeyModal$1, { isOpen: true, onClose: () => setApiKey(null), apiKey: apiKey })] }));
|
|
186452
186940
|
}
|
|
186453
186941
|
|
|
186942
|
+
/**
|
|
186943
|
+
* Returns the canonical logo path and display name for an LLM provider.
|
|
186944
|
+
* `logo` is a static-root path (e.g. `/llm-amazon-provider.png`); the package
|
|
186945
|
+
* ships the canonical assets under `@iblai/web-containers/public/` — copy them
|
|
186946
|
+
* into your app's static-root (`public/` for Next.js) so the paths resolve.
|
|
186947
|
+
*/
|
|
186948
|
+
function getLLMProviderDetails(llmProvider, llmName) {
|
|
186949
|
+
switch (llmProvider) {
|
|
186950
|
+
case 'groq':
|
|
186951
|
+
return { logo: '/llm-groq-provider.png', name: 'Groq' };
|
|
186952
|
+
case 'azure_openai':
|
|
186953
|
+
return { logo: '/llm-microsoft-provider.png', name: 'Microsoft' };
|
|
186954
|
+
case 'openai':
|
|
186955
|
+
if (llmName)
|
|
186956
|
+
return { logo: '/llm-openai-provider.jpg', name: 'OpenAI' };
|
|
186957
|
+
return { logo: '/llm-openai-provider-2.svg', name: 'OpenAI' };
|
|
186958
|
+
case 'mistral':
|
|
186959
|
+
return { logo: '/llm-mistral-provider.jpeg', name: 'Mistral' };
|
|
186960
|
+
case 'google':
|
|
186961
|
+
if (llmName)
|
|
186962
|
+
return { logo: '/llm-gemini-provider.png', name: 'Google' };
|
|
186963
|
+
return { logo: '/llm-google-provider.svg', name: 'Google' };
|
|
186964
|
+
case 'llama':
|
|
186965
|
+
return { logo: '/llm-llama-provider.jpeg', name: 'Meta' };
|
|
186966
|
+
case 'perplexity':
|
|
186967
|
+
return { logo: '/llm-perplexity-provider.webp', name: 'Perplexity' };
|
|
186968
|
+
case 'deepseek':
|
|
186969
|
+
return { logo: '/llm-deepseek-provider.png', name: 'DeepSeek' };
|
|
186970
|
+
case 'xai':
|
|
186971
|
+
return { logo: '/llm-xai-provider.jpg', name: 'xAI' };
|
|
186972
|
+
case 'IBLChatAnthropic':
|
|
186973
|
+
case 'anthropic':
|
|
186974
|
+
return { logo: '/llm-claude-provider.png', name: 'Anthropic' };
|
|
186975
|
+
case 'IBLChatNvidia':
|
|
186976
|
+
case 'nvidia':
|
|
186977
|
+
return { logo: '/llm-nvidia-provider.webp', name: 'NVIDIA' };
|
|
186978
|
+
case 'bedrock':
|
|
186979
|
+
case 'amazon-bedrock':
|
|
186980
|
+
case 'amazon_bedrock':
|
|
186981
|
+
case 'IBLChatBedrock':
|
|
186982
|
+
return { logo: '/llm-amazon-provider.png', name: 'Amazon' };
|
|
186983
|
+
// ibl.ai's own hosted provider. The backend key is `iblai` (NameEnum.IBLAI);
|
|
186984
|
+
// the other cases cover the `IBLChat<Vendor>` house spelling and the
|
|
186985
|
+
// dotted/dashed/underscored brand forms seen in labels and older payloads.
|
|
186986
|
+
case 'iblai':
|
|
186987
|
+
case 'IBLAI':
|
|
186988
|
+
case 'ibl.ai':
|
|
186989
|
+
case 'ibl_ai':
|
|
186990
|
+
case 'ibl-ai':
|
|
186991
|
+
case 'ibl':
|
|
186992
|
+
case 'IBLChatIBL':
|
|
186993
|
+
case 'IBLChatIBLAI':
|
|
186994
|
+
return { logo: '/llm-iblai-provider.png', name: 'ibl.ai' };
|
|
186995
|
+
default:
|
|
186996
|
+
return { logo: '/llm-generic-provider.png', name: llmProvider };
|
|
186997
|
+
}
|
|
186998
|
+
}
|
|
186999
|
+
|
|
186454
187000
|
// Dynamic schema based on selected provider
|
|
186455
187001
|
const createDynamicSchema$1 = (schemaFields) => {
|
|
186456
187002
|
const schemaObj = {
|
|
@@ -186679,10 +187225,14 @@ function CreateLLMModal({ isOpen, onClose, tenantKey, onSuccess }) {
|
|
|
186679
187225
|
}
|
|
186680
187226
|
}, children: [jsx(SelectTrigger, { children: jsx(SelectValue, { placeholder: t('llmsTabCreateLlmModal.selectProviderPlaceholder') }) }), jsx(SelectContent, { children: availableProviders.map((provider) => {
|
|
186681
187227
|
var _a, _b;
|
|
186682
|
-
|
|
187228
|
+
// Prefer the logo the API ships; fall back to the
|
|
187229
|
+
// bundled provider artwork so known providers (ibl.ai
|
|
187230
|
+
// included) never degrade to a generic key emoji.
|
|
187231
|
+
const providerLogo = ((_a = provider === null || provider === void 0 ? void 0 : provider.service_info) === null || _a === void 0 ? void 0 : _a.logo) ||
|
|
187232
|
+
getLLMProviderDetails(provider.name).logo;
|
|
186683
187233
|
const providerName = ((_b = provider === null || provider === void 0 ? void 0 : provider.service_info) === null || _b === void 0 ? void 0 : _b.display_name) ||
|
|
186684
187234
|
provider.name;
|
|
186685
|
-
return (jsx(SelectItem, { value: provider.name, children: jsxs("div", { className: "flex items-center gap-2", children: [
|
|
187235
|
+
return (jsx(SelectItem, { value: provider.name, children: jsxs("div", { className: "flex items-center gap-2", children: [jsx("img", { src: providerLogo, alt: provider.name, className: "w-4 h-4 rounded-sm object-contain" }), providerName || provider.name] }) }, provider.name));
|
|
186686
187236
|
}) })] }), shouldShowError && (jsx("p", { className: "text-red-500 text-xs", children: (_b = field.state.meta.errors[0]) === null || _b === void 0 ? void 0 : _b.message }))] }));
|
|
186687
187237
|
} })), isCredentialsSchemaLoading && (jsxs("div", { className: "flex items-center justify-center py-4", children: [jsx(LoaderCircle, { className: "h-4 w-4 animate-spin mr-2" }), jsx("span", { className: "text-sm text-gray-600", children: t('llmsTabCreateLlmModal.loadingProviderConfigurations') })] })), showProviderForm && !isCredentialsSchemaLoading && !isAzureOpenAI && (jsx(Fragment$1, { children: schemaFields.map((fieldName) => (jsx(form.Field, { name: fieldName, children: (field) => {
|
|
186688
187238
|
var _a, _b;
|
|
@@ -186771,17 +187321,22 @@ function IntegrationLLMsTab({ tenantKey }) {
|
|
|
186771
187321
|
return (jsxs("div", { className: "space-y-4", children: [jsx(InfoBanner, { icon: jsx(Bot, { className: "w-5 h-5" }), children: t('llmsTabIntegrationLlmsTab.infoBannerText') }), jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm min-w-[600px]", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: t('llmsTabIntegrationLlmsTab.colName') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: t('llmsTabIntegrationLlmsTab.colKey') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[50px]" })] }) }), jsx("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: isMaskedCredentialsLoading ? (jsx("tr", { children: jsx("td", { colSpan: 3, className: "px-6 py-8 text-center text-sm text-gray-500", children: t('llmsTabIntegrationLlmsTab.loading') }) })) : maskedCredentials.length === 0 ? (jsx("tr", { children: jsx("td", { colSpan: 3, className: "px-6 py-8 text-center text-sm text-gray-500", children: t('llmsTabIntegrationLlmsTab.noLlmKeysFound') }) })) : (maskedCredentials.map((cred, idx) => {
|
|
186772
187322
|
var _a, _b, _c;
|
|
186773
187323
|
const provider = ((_a = cred.service_info) === null || _a === void 0 ? void 0 : _a.display_name) || cred.name;
|
|
186774
|
-
//
|
|
187324
|
+
// Prefer the logo the API ships; fall back to the bundled
|
|
187325
|
+
// provider artwork so known providers (ibl.ai included) never
|
|
187326
|
+
// degrade to a generic key emoji.
|
|
186775
187327
|
let logoUrl;
|
|
186776
187328
|
let logoAlt;
|
|
186777
187329
|
if ((_b = cred.service_info) === null || _b === void 0 ? void 0 : _b.logo) {
|
|
186778
187330
|
logoUrl = cred.service_info.logo;
|
|
186779
187331
|
logoAlt = cred.service_info.display_name || cred.service_info.name;
|
|
186780
187332
|
}
|
|
187333
|
+
else {
|
|
187334
|
+
logoUrl = getLLMProviderDetails(cred.name).logo;
|
|
187335
|
+
}
|
|
186781
187336
|
const isAzure = isAzureOpenAI(cred);
|
|
186782
187337
|
const azureModels = isAzure ? getAzureModels(cred) : [];
|
|
186783
187338
|
const isExpanded = expandedRows.has(cred.name);
|
|
186784
|
-
return (jsxs(React__default.Fragment, { children: [jsxs("tr", { children: [jsx("td", { className: "px-6 py-4", children: jsxs("div", { className: "flex items-center gap-2", children: [
|
|
187339
|
+
return (jsxs(React__default.Fragment, { children: [jsxs("tr", { children: [jsx("td", { className: "px-6 py-4", children: jsxs("div", { className: "flex items-center gap-2", children: [jsx("img", { src: logoUrl, alt: logoAlt || provider || cred.name, className: "w-6 h-6 rounded-sm object-contain" }), jsx("span", { className: "font-normal text-gray-900 dark:text-gray-100", children: provider || cred.name }), isAzure && azureModels.length > 0 && (jsx("button", { type: "button", onClick: () => toggleRowExpansion(cred.name), className: "p-0.5 hover:bg-gray-100 rounded", children: isExpanded ? (jsx(ChevronUp, { className: "h-4 w-4 text-gray-500" })) : (jsx(ChevronDown, { className: "h-4 w-4 text-gray-500" })) }))] }) }), jsx("td", { className: "px-6 py-4 font-mono text-sm text-gray-900 dark:text-gray-100", children: isAzure ? (jsx("span", { className: "text-xs text-gray-500", children: t('llmsTabIntegrationLlmsTab.azureModelCount', {
|
|
186785
187340
|
count: azureModels.length,
|
|
186786
187341
|
}) })) : (String((_c = cred === null || cred === void 0 ? void 0 : cred.value) === null || _c === void 0 ? void 0 : _c.key).slice(0, 15) || '') }), jsx("td", { className: "px-6 py-4", children: jsx(Button$1, { variant: "ghost", size: "sm", className: "cursor-pointer mr-2", disabled: isDeletingIntegration || isDeletingCredential, onClick: () => handleDeleteCredential(cred.name, cred.platform, false), children: jsx(Trash, { className: "h-4 w-4" }) }) })] }), isAzure &&
|
|
186787
187342
|
isExpanded &&
|
|
@@ -189547,7 +190102,7 @@ function ItemSearchDropdown({ platformKey, onSelect, }) {
|
|
|
189547
190102
|
}, children: [jsx("div", { className: "flex-1 min-w-0", children: jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100 block truncate", children: item.name }) }), jsx(Badge, { variant: "secondary", className: "text-xs shrink-0 capitalize", children: displayItemType(item.itemType) })] }, `${item.itemType}-${item.id}`)))) : isFetching ? (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-400", children: t('monetizationItemSearchDropdown.searching') })) : (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-400", children: t('monetizationItemSearchDropdown.noItemsFound') })) }))] }));
|
|
189548
190103
|
}
|
|
189549
190104
|
|
|
189550
|
-
const PAGE_SIZE$
|
|
190105
|
+
const PAGE_SIZE$7 = 8;
|
|
189551
190106
|
function PaywalledItemsList({ platformKey, onSelectItem, onAddCustomItem, }) {
|
|
189552
190107
|
const t = useT();
|
|
189553
190108
|
const [page, setPage] = useState(1);
|
|
@@ -189555,7 +190110,7 @@ function PaywalledItemsList({ platformKey, onSelectItem, onAddCustomItem, }) {
|
|
|
189555
190110
|
const { data: paywalls, isLoading } = useListPaywallsQuery({
|
|
189556
190111
|
platform_key: platformKey,
|
|
189557
190112
|
page,
|
|
189558
|
-
page_size: PAGE_SIZE$
|
|
190113
|
+
page_size: PAGE_SIZE$7,
|
|
189559
190114
|
...(statusFilter !== 'all' && { is_enabled: statusFilter === 'active' }),
|
|
189560
190115
|
}, { refetchOnMountOrArgChange: true });
|
|
189561
190116
|
return (jsxs("div", { className: "space-y-4", children: [jsx(Card, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", children: [jsx("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 mb-3", children: t('monetizationPaywalledItemsList.configureItemForSale') }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(ItemSearchDropdown, { platformKey: platformKey, onSelect: (itemType, uniqueId, name) => onSelectItem(itemType, uniqueId, name) }), jsx(Button$1, { variant: "outline", size: "icon", onClick: onAddCustomItem, className: "shrink-0 cursor-pointer", title: t('monetizationPaywalledItemsList.addCustomItemTitle'), children: jsx(Plus, { className: "h-4 w-4" }) })] })] }) }), jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-medium text-gray-500", children: t('monetizationPaywalledItemsList.configuredItems') }), jsxs(Select$1, { value: statusFilter, onValueChange: (v) => {
|
|
@@ -189578,7 +190133,7 @@ function PaywalledItemsList({ platformKey, onSelectItem, onAddCustomItem, }) {
|
|
|
189578
190133
|
: 'bg-gray-100 text-gray-500 border-gray-200 hover:bg-gray-100', children: pw.is_enabled
|
|
189579
190134
|
? t('monetizationPaywalledItemsList.statusActive')
|
|
189580
190135
|
: t('monetizationPaywalledItemsList.statusDisabled') })] }) }, `${pw.item_type}-${pw.item_id}`));
|
|
189581
|
-
}), jsx(AdvancedPagination, { variant: "footer", className: "mt-2 rounded-lg border", currentPage: page, totalPages: Math.ceil(paywalls.count / PAGE_SIZE$
|
|
190136
|
+
}), jsx(AdvancedPagination, { variant: "footer", className: "mt-2 rounded-lg border", currentPage: page, totalPages: Math.ceil(paywalls.count / PAGE_SIZE$7), onPageChange: setPage, totalCount: paywalls.count, itemsPerPage: PAGE_SIZE$7, itemLabel: "items" })] })) : (jsx("p", { className: "text-sm text-gray-400 text-center py-6", children: statusFilter !== 'all'
|
|
189582
190137
|
? t('monetizationPaywalledItemsList.noFilteredItemsFound', { status: statusFilter })
|
|
189583
190138
|
: t('monetizationPaywalledItemsList.noItemsConfigured') }))] })] }));
|
|
189584
190139
|
}
|
|
@@ -251993,6 +252548,147 @@ function Markdown({ children, className }) {
|
|
|
251993
252548
|
const AnalyticsSettingsContext = createContext({});
|
|
251994
252549
|
AnalyticsSettingsContext.Provider;
|
|
251995
252550
|
|
|
252551
|
+
/**
|
|
252552
|
+
* Core agent search hook — thin wrapper around `useGetAiSearchMentorsQuery`.
|
|
252553
|
+
*
|
|
252554
|
+
* This is the low-level building block. For a higher-level hook that manages
|
|
252555
|
+
* search state, debounce, and pagination controls, use
|
|
252556
|
+
* `useAgentSearchWithPagination`.
|
|
252557
|
+
*/
|
|
252558
|
+
function useAgentSearch({ tenantKey, query, limit = 6, offset, starred, featured, category, subjects, llm, types, includeMainPublicMentors, orderDirection, skip = false, }) {
|
|
252559
|
+
var _a, _b, _c;
|
|
252560
|
+
const { data, isLoading, isFetching, refetch } = useGetAiSearchMentorsQuery({
|
|
252561
|
+
platform_key: tenantKey,
|
|
252562
|
+
query: query || undefined,
|
|
252563
|
+
limit,
|
|
252564
|
+
...(offset !== undefined && { offset }),
|
|
252565
|
+
...(starred !== undefined && { starred }),
|
|
252566
|
+
...(featured !== undefined && { featured }),
|
|
252567
|
+
...(category && { category }),
|
|
252568
|
+
...(subjects && { subjects }),
|
|
252569
|
+
...(llm && { llm }),
|
|
252570
|
+
...(types && { types }),
|
|
252571
|
+
...(includeMainPublicMentors !== undefined && {
|
|
252572
|
+
include_main_public_mentors: includeMainPublicMentors,
|
|
252573
|
+
}),
|
|
252574
|
+
...(orderDirection && { order_direction: orderDirection }),
|
|
252575
|
+
}, { skip: skip || !tenantKey });
|
|
252576
|
+
return {
|
|
252577
|
+
agents: ((_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : []),
|
|
252578
|
+
facets: data === null || data === void 0 ? void 0 : data.facets,
|
|
252579
|
+
hasMore: !!(data === null || data === void 0 ? void 0 : data.next),
|
|
252580
|
+
totalCount: (_b = data === null || data === void 0 ? void 0 : data.count) !== null && _b !== void 0 ? _b : 0,
|
|
252581
|
+
totalPages: (_c = data === null || data === void 0 ? void 0 : data.total_pages) !== null && _c !== void 0 ? _c : 0,
|
|
252582
|
+
isLoading,
|
|
252583
|
+
isFetching,
|
|
252584
|
+
refetch,
|
|
252585
|
+
};
|
|
252586
|
+
}
|
|
252587
|
+
|
|
252588
|
+
function c$3(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$8(r,n){return r===n}function a$3(n,t,a){var o=i$8,f=useRef(n),l=useState({})[1],v=c$3(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]}
|
|
252589
|
+
|
|
252590
|
+
/**
|
|
252591
|
+
* Higher-level agent search hook that manages search state, debounce, and
|
|
252592
|
+
* pagination controls on top of `useAgentSearch`.
|
|
252593
|
+
*
|
|
252594
|
+
* Use this for simple list/table views (MyMentorsModal, SettingsModal).
|
|
252595
|
+
* For the full explore page with sections, use `useAgentSearch` directly.
|
|
252596
|
+
*/
|
|
252597
|
+
function useAgentSearchWithPagination({ itemsPerPage = 6, paginationMode = 'paginated', debounceMs = 500, ...queryConfig }) {
|
|
252598
|
+
const [searchQuery, setSearchQuery] = React__default.useState('');
|
|
252599
|
+
const [debouncedQuery] = a$3(searchQuery, debounceMs);
|
|
252600
|
+
const [currentPage, setCurrentPage] = React__default.useState(1);
|
|
252601
|
+
const [infiniteLimit, setInfiniteLimit] = React__default.useState(itemsPerPage);
|
|
252602
|
+
// Reset pagination when search changes
|
|
252603
|
+
React__default.useEffect(() => {
|
|
252604
|
+
setCurrentPage(1);
|
|
252605
|
+
setInfiniteLimit(itemsPerPage);
|
|
252606
|
+
}, [debouncedQuery, itemsPerPage]);
|
|
252607
|
+
const isPaginated = paginationMode === 'paginated';
|
|
252608
|
+
const result = useAgentSearch({
|
|
252609
|
+
...queryConfig,
|
|
252610
|
+
query: debouncedQuery,
|
|
252611
|
+
limit: isPaginated ? itemsPerPage : infiniteLimit,
|
|
252612
|
+
offset: isPaginated ? (currentPage - 1) * itemsPerPage : undefined,
|
|
252613
|
+
});
|
|
252614
|
+
const totalPages = Math.ceil(result.totalCount / itemsPerPage);
|
|
252615
|
+
const handlePageChange = React__default.useCallback((page) => {
|
|
252616
|
+
setCurrentPage(page);
|
|
252617
|
+
}, []);
|
|
252618
|
+
const loadMore = React__default.useCallback(() => {
|
|
252619
|
+
setInfiniteLimit((prev) => prev + itemsPerPage);
|
|
252620
|
+
}, [itemsPerPage]);
|
|
252621
|
+
return {
|
|
252622
|
+
...result,
|
|
252623
|
+
searchQuery,
|
|
252624
|
+
setSearchQuery,
|
|
252625
|
+
debouncedQuery,
|
|
252626
|
+
currentPage,
|
|
252627
|
+
totalPages,
|
|
252628
|
+
handlePageChange,
|
|
252629
|
+
loadMore,
|
|
252630
|
+
};
|
|
252631
|
+
}
|
|
252632
|
+
|
|
252633
|
+
/**
|
|
252634
|
+
* Hook for starring / un-starring agents.
|
|
252635
|
+
*
|
|
252636
|
+
* Extracted so the star logic can be shared by any component that renders
|
|
252637
|
+
* agent cards with a favorite toggle.
|
|
252638
|
+
*/
|
|
252639
|
+
function useAgentStar({ tenantKey, username, onUnauthenticatedAction, }) {
|
|
252640
|
+
const [starAgent] = useStarMentorMutation();
|
|
252641
|
+
const [unstarAgent] = useUnstarMentorMutation();
|
|
252642
|
+
const [togglingAgentId, setTogglingAgentId] = React__default.useState(null);
|
|
252643
|
+
const toggleFavorite = React__default.useCallback(async (agent, event) => {
|
|
252644
|
+
event.stopPropagation();
|
|
252645
|
+
if (!username) {
|
|
252646
|
+
onUnauthenticatedAction === null || onUnauthenticatedAction === void 0 ? void 0 : onUnauthenticatedAction();
|
|
252647
|
+
return;
|
|
252648
|
+
}
|
|
252649
|
+
if (!tenantKey)
|
|
252650
|
+
return;
|
|
252651
|
+
setTogglingAgentId(String(agent.id));
|
|
252652
|
+
try {
|
|
252653
|
+
const mutation = agent.starred ? unstarAgent : starAgent;
|
|
252654
|
+
await mutation({
|
|
252655
|
+
org: tenantKey,
|
|
252656
|
+
// @ts-expect-error userId param type mismatch in data-layer
|
|
252657
|
+
userId: username,
|
|
252658
|
+
mentor: agent.unique_id || '',
|
|
252659
|
+
}).unwrap();
|
|
252660
|
+
}
|
|
252661
|
+
catch (error) {
|
|
252662
|
+
console.error('Error toggling favorite:', error);
|
|
252663
|
+
}
|
|
252664
|
+
finally {
|
|
252665
|
+
setTogglingAgentId(null);
|
|
252666
|
+
}
|
|
252667
|
+
}, [username, tenantKey, starAgent, unstarAgent, onUnauthenticatedAction]);
|
|
252668
|
+
return { toggleFavorite, togglingAgentId };
|
|
252669
|
+
}
|
|
252670
|
+
|
|
252671
|
+
function MentorSelectionGrid({ selectedMentorIds, onMentorSelect, searchQuery, onSearchChange, tenantKey, itemsPerPage = 8, showSearch = true, minHeight = '400px', }) {
|
|
252672
|
+
const t = useT();
|
|
252673
|
+
const { agents: mentors, isLoading: isMentorsLoading, isFetching: isMentorsFetching, currentPage, totalPages, setSearchQuery: setMentorSearch, handlePageChange, } = useAgentSearchWithPagination({ tenantKey, itemsPerPage });
|
|
252674
|
+
// Update search query with debounce effect handled by the hook
|
|
252675
|
+
React__default.useEffect(() => {
|
|
252676
|
+
setMentorSearch(searchQuery);
|
|
252677
|
+
}, [searchQuery]);
|
|
252678
|
+
const isMentorSelected = (mentorId) => {
|
|
252679
|
+
return selectedMentorIds.includes(mentorId);
|
|
252680
|
+
};
|
|
252681
|
+
return (jsxs("div", { className: "space-y-4", children: [showSearch && (jsxs("div", { className: "relative", children: [isMentorsFetching ? (jsx(Spinner, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 transform text-gray-400" })) : (jsx(Search, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 transform text-gray-400" })), jsx(Input, { placeholder: t('mentorsMentorSelectionGrid.searchAgentsPlaceholder'), value: searchQuery, onChange: (e) => onSearchChange(e.target.value), className: "h-10 border-gray-200 pl-10 focus:border-blue-500 focus:ring-0" })] })), jsxs("div", { className: "space-y-4", children: [jsx("div", { className: "grid max-h-96 auto-rows-min grid-cols-1 items-start gap-3 overflow-y-auto rounded-lg border border-gray-200 p-4 md:max-h-none md:grid-cols-2", style: { minHeight }, children: isMentorsLoading ? (jsx("div", { className: "col-span-full py-8 text-center text-gray-500", children: t('mentorsMentorSelectionGrid.loadingAgents') })) : mentors.length === 0 ? (jsx("div", { className: "col-span-full py-8 text-center text-gray-500", children: t('mentorsMentorSelectionGrid.noAgentsFound') })) : (mentors.map((mentor) => {
|
|
252682
|
+
const isSelected = isMentorSelected(mentor.unique_id || '');
|
|
252683
|
+
const isAlreadyAdded = selectedMentorIds.includes(mentor.unique_id || '');
|
|
252684
|
+
return (jsxs("button", { onClick: () => onMentorSelect(mentor), className: `flex cursor-pointer items-center gap-3 rounded-lg border-2 p-3 transition-all ${isSelected
|
|
252685
|
+
? 'border-blue-500 bg-blue-50'
|
|
252686
|
+
: isAlreadyAdded
|
|
252687
|
+
? 'bg-blue-25 border-blue-300'
|
|
252688
|
+
: 'border-gray-200 hover:border-gray-300 hover:bg-gray-50'}`, children: [jsxs(Avatar, { className: "h-12 w-12 flex-shrink-0", children: [jsx(AvatarImage, { src: mentor.profile_image || '/placeholder.svg', alt: mentor.name }), jsx(AvatarFallback, { children: mentor.name.substring(0, 2) })] }), jsxs("div", { className: "flex min-w-0 flex-1 flex-col justify-start text-left", children: [jsx("h4", { className: "truncate text-sm font-medium text-gray-900", children: mentor.name }), jsx("p", { className: "line-clamp-2 text-xs text-gray-600", children: mentor.description })] }), isSelected && (jsx("div", { className: "flex-shrink-0", children: jsx("div", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-blue-600", children: jsx(Check, { className: "h-4 w-4 text-white" }) }) })), isAlreadyAdded && !isSelected && (jsx("div", { className: "flex-shrink-0", children: jsx("div", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-blue-400", children: jsx(Check, { className: "h-4 w-4 text-white" }) }) }))] }, mentor.unique_id));
|
|
252689
|
+
})) }), jsx(IblPagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: handlePageChange, disabled: isMentorsFetching || isMentorsLoading })] })] }));
|
|
252690
|
+
}
|
|
252691
|
+
|
|
251996
252692
|
const SkeletonMultiplier = ({ Skeleton, multiplier }) => {
|
|
251997
252693
|
return (jsx(Fragment$1, { children: Array.from({ length: multiplier }).map((_, index) => (jsx(Skeleton, {}, index))) }));
|
|
251998
252694
|
};
|
|
@@ -253141,52 +253837,6 @@ var reactPaginate = {exports: {}};
|
|
|
253141
253837
|
|
|
253142
253838
|
} (reactPaginate));
|
|
253143
253839
|
|
|
253144
|
-
/**
|
|
253145
|
-
* Returns the canonical logo path and display name for an LLM provider.
|
|
253146
|
-
* `logo` is a static-root path (e.g. `/llm-amazon-provider.png`); the package
|
|
253147
|
-
* ships the canonical assets under `@iblai/web-containers/public/` — copy them
|
|
253148
|
-
* into your app's static-root (`public/` for Next.js) so the paths resolve.
|
|
253149
|
-
*/
|
|
253150
|
-
function getLLMProviderDetails(llmProvider, llmName) {
|
|
253151
|
-
switch (llmProvider) {
|
|
253152
|
-
case 'groq':
|
|
253153
|
-
return { logo: '/llm-groq-provider.png', name: 'Groq' };
|
|
253154
|
-
case 'azure_openai':
|
|
253155
|
-
return { logo: '/llm-microsoft-provider.png', name: 'Microsoft' };
|
|
253156
|
-
case 'openai':
|
|
253157
|
-
if (llmName)
|
|
253158
|
-
return { logo: '/llm-openai-provider.jpg', name: 'OpenAI' };
|
|
253159
|
-
return { logo: '/llm-openai-provider-2.svg', name: 'OpenAI' };
|
|
253160
|
-
case 'mistral':
|
|
253161
|
-
return { logo: '/llm-mistral-provider.jpeg', name: 'Mistral' };
|
|
253162
|
-
case 'google':
|
|
253163
|
-
if (llmName)
|
|
253164
|
-
return { logo: '/llm-gemini-provider.png', name: 'Google' };
|
|
253165
|
-
return { logo: '/llm-google-provider.svg', name: 'Google' };
|
|
253166
|
-
case 'llama':
|
|
253167
|
-
return { logo: '/llm-llama-provider.jpeg', name: 'Meta' };
|
|
253168
|
-
case 'perplexity':
|
|
253169
|
-
return { logo: '/llm-perplexity-provider.webp', name: 'Perplexity' };
|
|
253170
|
-
case 'deepseek':
|
|
253171
|
-
return { logo: '/llm-deepseek-provider.png', name: 'DeepSeek' };
|
|
253172
|
-
case 'xai':
|
|
253173
|
-
return { logo: '/llm-xai-provider.jpg', name: 'xAI' };
|
|
253174
|
-
case 'IBLChatAnthropic':
|
|
253175
|
-
case 'anthropic':
|
|
253176
|
-
return { logo: '/llm-claude-provider.png', name: 'Anthropic' };
|
|
253177
|
-
case 'IBLChatNvidia':
|
|
253178
|
-
case 'nvidia':
|
|
253179
|
-
return { logo: '/llm-nvidia-provider.webp', name: 'NVIDIA' };
|
|
253180
|
-
case 'bedrock':
|
|
253181
|
-
case 'amazon-bedrock':
|
|
253182
|
-
case 'amazon_bedrock':
|
|
253183
|
-
case 'IBLChatBedrock':
|
|
253184
|
-
return { logo: '/llm-amazon-provider.png', name: 'Amazon' };
|
|
253185
|
-
default:
|
|
253186
|
-
return { logo: '/llm-generic-provider.png', name: llmProvider };
|
|
253187
|
-
}
|
|
253188
|
-
}
|
|
253189
|
-
|
|
253190
253840
|
function OverlayModal({ open, onClose, title, description, className, children, }) {
|
|
253191
253841
|
const t = useT();
|
|
253192
253842
|
const [mounted, setMounted] = useState(false);
|
|
@@ -253724,8 +254374,6 @@ function useSlashSkillPicker({ inputValue, setInputValue, skills, isLoading = fa
|
|
|
253724
254374
|
};
|
|
253725
254375
|
}
|
|
253726
254376
|
|
|
253727
|
-
function c$3(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$8(r,n){return r===n}function a$3(n,t,a){var o=i$8,f=useRef(n),l=useState({})[1],v=c$3(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]}
|
|
253728
|
-
|
|
253729
254377
|
lazy(() => Promise.resolve().then(function () { return createProjectModal; }).then((mod) => ({
|
|
253730
254378
|
default: mod.CreateProjectModal,
|
|
253731
254379
|
})));
|
|
@@ -254561,7 +255209,7 @@ function RetrievedDocumentsButton({ sessionId }) {
|
|
|
254561
255209
|
return (jsxs(Fragment$1, { children: [jsxs(Button$1, { variant: "outline", size: "sm", className: "flex items-center gap-2 border-gray-200 bg-white text-gray-700 hover:bg-gray-50", onClick: () => setIsOpen(true), children: [jsx(FileText, { className: "h-4 w-4 text-blue-600" }), jsx("span", { children: t('retrievedDocumentsButton.title') })] }), jsx(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: jsxs(DialogContent, { className: "flex max-h-[80vh] flex-col gap-0 p-0 sm:max-w-[425px] md:max-w-[600px]", children: [jsx(DialogHeader, { className: "border-b px-4 py-2", children: jsxs(DialogTitle, { className: "flex items-center gap-2 text-base font-medium text-[#646464]", children: [jsx(FileText, { className: "h-5 w-5 text-blue-600" }), t('retrievedDocumentsButton.title')] }) }), jsx("div", { className: "flex-1 overflow-hidden", children: jsx(DocumentSidebar, { isModal: true, sessionId: sessionId }) })] }) })] }));
|
|
254562
255210
|
}
|
|
254563
255211
|
|
|
254564
|
-
const PAGE_SIZE$
|
|
255212
|
+
const PAGE_SIZE$6 = 10;
|
|
254565
255213
|
const MemoryMenu = ({ onClose, mentorId, tenantKey, username }) => {
|
|
254566
255214
|
const t = useT();
|
|
254567
255215
|
const [page, setPage] = useState(1);
|
|
@@ -254579,7 +255227,7 @@ const MemoryMenu = ({ onClose, mentorId, tenantKey, username }) => {
|
|
|
254579
255227
|
mentorId,
|
|
254580
255228
|
params: {
|
|
254581
255229
|
page,
|
|
254582
|
-
page_size: PAGE_SIZE$
|
|
255230
|
+
page_size: PAGE_SIZE$6,
|
|
254583
255231
|
my_memory: true,
|
|
254584
255232
|
},
|
|
254585
255233
|
}, {
|
|
@@ -256129,145 +256777,6 @@ var minimumMentorAlert = /*#__PURE__*/Object.freeze({
|
|
|
256129
256777
|
MinimumMentorAlert: MinimumMentorAlert
|
|
256130
256778
|
});
|
|
256131
256779
|
|
|
256132
|
-
/**
|
|
256133
|
-
* Core agent search hook — thin wrapper around `useGetAiSearchMentorsQuery`.
|
|
256134
|
-
*
|
|
256135
|
-
* This is the low-level building block. For a higher-level hook that manages
|
|
256136
|
-
* search state, debounce, and pagination controls, use
|
|
256137
|
-
* `useAgentSearchWithPagination`.
|
|
256138
|
-
*/
|
|
256139
|
-
function useAgentSearch({ tenantKey, query, limit = 6, offset, starred, featured, category, subjects, llm, types, includeMainPublicMentors, orderDirection, skip = false, }) {
|
|
256140
|
-
var _a, _b, _c;
|
|
256141
|
-
const { data, isLoading, isFetching, refetch } = useGetAiSearchMentorsQuery({
|
|
256142
|
-
platform_key: tenantKey,
|
|
256143
|
-
query: query || undefined,
|
|
256144
|
-
limit,
|
|
256145
|
-
...(offset !== undefined && { offset }),
|
|
256146
|
-
...(starred !== undefined && { starred }),
|
|
256147
|
-
...(featured !== undefined && { featured }),
|
|
256148
|
-
...(category && { category }),
|
|
256149
|
-
...(subjects && { subjects }),
|
|
256150
|
-
...(llm && { llm }),
|
|
256151
|
-
...(types && { types }),
|
|
256152
|
-
...(includeMainPublicMentors !== undefined && {
|
|
256153
|
-
include_main_public_mentors: includeMainPublicMentors,
|
|
256154
|
-
}),
|
|
256155
|
-
...(orderDirection && { order_direction: orderDirection }),
|
|
256156
|
-
}, { skip: skip || !tenantKey });
|
|
256157
|
-
return {
|
|
256158
|
-
agents: ((_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : []),
|
|
256159
|
-
facets: data === null || data === void 0 ? void 0 : data.facets,
|
|
256160
|
-
hasMore: !!(data === null || data === void 0 ? void 0 : data.next),
|
|
256161
|
-
totalCount: (_b = data === null || data === void 0 ? void 0 : data.count) !== null && _b !== void 0 ? _b : 0,
|
|
256162
|
-
totalPages: (_c = data === null || data === void 0 ? void 0 : data.total_pages) !== null && _c !== void 0 ? _c : 0,
|
|
256163
|
-
isLoading,
|
|
256164
|
-
isFetching,
|
|
256165
|
-
refetch,
|
|
256166
|
-
};
|
|
256167
|
-
}
|
|
256168
|
-
|
|
256169
|
-
/**
|
|
256170
|
-
* Higher-level agent search hook that manages search state, debounce, and
|
|
256171
|
-
* pagination controls on top of `useAgentSearch`.
|
|
256172
|
-
*
|
|
256173
|
-
* Use this for simple list/table views (MyMentorsModal, SettingsModal).
|
|
256174
|
-
* For the full explore page with sections, use `useAgentSearch` directly.
|
|
256175
|
-
*/
|
|
256176
|
-
function useAgentSearchWithPagination({ itemsPerPage = 6, paginationMode = 'paginated', debounceMs = 500, ...queryConfig }) {
|
|
256177
|
-
const [searchQuery, setSearchQuery] = React__default.useState('');
|
|
256178
|
-
const [debouncedQuery] = a$3(searchQuery, debounceMs);
|
|
256179
|
-
const [currentPage, setCurrentPage] = React__default.useState(1);
|
|
256180
|
-
const [infiniteLimit, setInfiniteLimit] = React__default.useState(itemsPerPage);
|
|
256181
|
-
// Reset pagination when search changes
|
|
256182
|
-
React__default.useEffect(() => {
|
|
256183
|
-
setCurrentPage(1);
|
|
256184
|
-
setInfiniteLimit(itemsPerPage);
|
|
256185
|
-
}, [debouncedQuery, itemsPerPage]);
|
|
256186
|
-
const isPaginated = paginationMode === 'paginated';
|
|
256187
|
-
const result = useAgentSearch({
|
|
256188
|
-
...queryConfig,
|
|
256189
|
-
query: debouncedQuery,
|
|
256190
|
-
limit: isPaginated ? itemsPerPage : infiniteLimit,
|
|
256191
|
-
offset: isPaginated ? (currentPage - 1) * itemsPerPage : undefined,
|
|
256192
|
-
});
|
|
256193
|
-
const totalPages = Math.ceil(result.totalCount / itemsPerPage);
|
|
256194
|
-
const handlePageChange = React__default.useCallback((page) => {
|
|
256195
|
-
setCurrentPage(page);
|
|
256196
|
-
}, []);
|
|
256197
|
-
const loadMore = React__default.useCallback(() => {
|
|
256198
|
-
setInfiniteLimit((prev) => prev + itemsPerPage);
|
|
256199
|
-
}, [itemsPerPage]);
|
|
256200
|
-
return {
|
|
256201
|
-
...result,
|
|
256202
|
-
searchQuery,
|
|
256203
|
-
setSearchQuery,
|
|
256204
|
-
debouncedQuery,
|
|
256205
|
-
currentPage,
|
|
256206
|
-
totalPages,
|
|
256207
|
-
handlePageChange,
|
|
256208
|
-
loadMore,
|
|
256209
|
-
};
|
|
256210
|
-
}
|
|
256211
|
-
|
|
256212
|
-
/**
|
|
256213
|
-
* Hook for starring / un-starring agents.
|
|
256214
|
-
*
|
|
256215
|
-
* Extracted so the star logic can be shared by any component that renders
|
|
256216
|
-
* agent cards with a favorite toggle.
|
|
256217
|
-
*/
|
|
256218
|
-
function useAgentStar({ tenantKey, username, onUnauthenticatedAction, }) {
|
|
256219
|
-
const [starAgent] = useStarMentorMutation();
|
|
256220
|
-
const [unstarAgent] = useUnstarMentorMutation();
|
|
256221
|
-
const [togglingAgentId, setTogglingAgentId] = React__default.useState(null);
|
|
256222
|
-
const toggleFavorite = React__default.useCallback(async (agent, event) => {
|
|
256223
|
-
event.stopPropagation();
|
|
256224
|
-
if (!username) {
|
|
256225
|
-
onUnauthenticatedAction === null || onUnauthenticatedAction === void 0 ? void 0 : onUnauthenticatedAction();
|
|
256226
|
-
return;
|
|
256227
|
-
}
|
|
256228
|
-
if (!tenantKey)
|
|
256229
|
-
return;
|
|
256230
|
-
setTogglingAgentId(String(agent.id));
|
|
256231
|
-
try {
|
|
256232
|
-
const mutation = agent.starred ? unstarAgent : starAgent;
|
|
256233
|
-
await mutation({
|
|
256234
|
-
org: tenantKey,
|
|
256235
|
-
// @ts-expect-error userId param type mismatch in data-layer
|
|
256236
|
-
userId: username,
|
|
256237
|
-
mentor: agent.unique_id || '',
|
|
256238
|
-
}).unwrap();
|
|
256239
|
-
}
|
|
256240
|
-
catch (error) {
|
|
256241
|
-
console.error('Error toggling favorite:', error);
|
|
256242
|
-
}
|
|
256243
|
-
finally {
|
|
256244
|
-
setTogglingAgentId(null);
|
|
256245
|
-
}
|
|
256246
|
-
}, [username, tenantKey, starAgent, unstarAgent, onUnauthenticatedAction]);
|
|
256247
|
-
return { toggleFavorite, togglingAgentId };
|
|
256248
|
-
}
|
|
256249
|
-
|
|
256250
|
-
function MentorSelectionGrid({ selectedMentorIds, onMentorSelect, searchQuery, onSearchChange, tenantKey, itemsPerPage = 8, showSearch = true, minHeight = '400px', }) {
|
|
256251
|
-
const t = useT();
|
|
256252
|
-
const { agents: mentors, isLoading: isMentorsLoading, isFetching: isMentorsFetching, currentPage, totalPages, setSearchQuery: setMentorSearch, handlePageChange, } = useAgentSearchWithPagination({ tenantKey, itemsPerPage });
|
|
256253
|
-
// Update search query with debounce effect handled by the hook
|
|
256254
|
-
React__default.useEffect(() => {
|
|
256255
|
-
setMentorSearch(searchQuery);
|
|
256256
|
-
}, [searchQuery]);
|
|
256257
|
-
const isMentorSelected = (mentorId) => {
|
|
256258
|
-
return selectedMentorIds.includes(mentorId);
|
|
256259
|
-
};
|
|
256260
|
-
return (jsxs("div", { className: "space-y-4", children: [showSearch && (jsxs("div", { className: "relative", children: [isMentorsFetching ? (jsx(Spinner, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 transform text-gray-400" })) : (jsx(Search, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 transform text-gray-400" })), jsx(Input, { placeholder: t('mentorsMentorSelectionGrid.searchAgentsPlaceholder'), value: searchQuery, onChange: (e) => onSearchChange(e.target.value), className: "h-10 border-gray-200 pl-10 focus:border-blue-500 focus:ring-0" })] })), jsxs("div", { className: "space-y-4", children: [jsx("div", { className: "grid max-h-96 auto-rows-min grid-cols-1 items-start gap-3 overflow-y-auto rounded-lg border border-gray-200 p-4 md:max-h-none md:grid-cols-2", style: { minHeight }, children: isMentorsLoading ? (jsx("div", { className: "col-span-full py-8 text-center text-gray-500", children: t('mentorsMentorSelectionGrid.loadingAgents') })) : mentors.length === 0 ? (jsx("div", { className: "col-span-full py-8 text-center text-gray-500", children: t('mentorsMentorSelectionGrid.noAgentsFound') })) : (mentors.map((mentor) => {
|
|
256261
|
-
const isSelected = isMentorSelected(mentor.unique_id || '');
|
|
256262
|
-
const isAlreadyAdded = selectedMentorIds.includes(mentor.unique_id || '');
|
|
256263
|
-
return (jsxs("button", { onClick: () => onMentorSelect(mentor), className: `flex cursor-pointer items-center gap-3 rounded-lg border-2 p-3 transition-all ${isSelected
|
|
256264
|
-
? 'border-blue-500 bg-blue-50'
|
|
256265
|
-
: isAlreadyAdded
|
|
256266
|
-
? 'bg-blue-25 border-blue-300'
|
|
256267
|
-
: 'border-gray-200 hover:border-gray-300 hover:bg-gray-50'}`, children: [jsxs(Avatar, { className: "h-12 w-12 flex-shrink-0", children: [jsx(AvatarImage, { src: mentor.profile_image || '/placeholder.svg', alt: mentor.name }), jsx(AvatarFallback, { children: mentor.name.substring(0, 2) })] }), jsxs("div", { className: "flex min-w-0 flex-1 flex-col justify-start text-left", children: [jsx("h4", { className: "truncate text-sm font-medium text-gray-900", children: mentor.name }), jsx("p", { className: "line-clamp-2 text-xs text-gray-600", children: mentor.description })] }), isSelected && (jsx("div", { className: "flex-shrink-0", children: jsx("div", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-blue-600", children: jsx(Check, { className: "h-4 w-4 text-white" }) }) })), isAlreadyAdded && !isSelected && (jsx("div", { className: "flex-shrink-0", children: jsx("div", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-blue-400", children: jsx(Check, { className: "h-4 w-4 text-white" }) }) }))] }, mentor.unique_id));
|
|
256268
|
-
})) }), jsx(IblPagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: handlePageChange, disabled: isMentorsFetching || isMentorsLoading })] })] }));
|
|
256269
|
-
}
|
|
256270
|
-
|
|
256271
256780
|
function CreateProjectModal$1({ isOpen, onClose, tenantKey, username, navigateToMentorInProject, }) {
|
|
256272
256781
|
const t = useT();
|
|
256273
256782
|
const dispatch = useDispatch();
|
|
@@ -258577,7 +259086,7 @@ function DeleteItemConfirm({ isOpen, onClose, tenantKey, username, datasetName,
|
|
|
258577
259086
|
: t('benchmarksDeleteItemConfirm.delete') })] })] }) }));
|
|
258578
259087
|
}
|
|
258579
259088
|
|
|
258580
|
-
const PAGE_SIZE$
|
|
259089
|
+
const PAGE_SIZE$5 = 10;
|
|
258581
259090
|
function BenchmarkItemsModal({ isOpen, onClose, tenantKey, username, datasetName }) {
|
|
258582
259091
|
var _a;
|
|
258583
259092
|
const t = useT();
|
|
@@ -258589,17 +259098,17 @@ function BenchmarkItemsModal({ isOpen, onClose, tenantKey, username, datasetName
|
|
|
258589
259098
|
userId: username,
|
|
258590
259099
|
datasetName,
|
|
258591
259100
|
page,
|
|
258592
|
-
limit: PAGE_SIZE$
|
|
259101
|
+
limit: PAGE_SIZE$5,
|
|
258593
259102
|
});
|
|
258594
259103
|
const items = (_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : [];
|
|
258595
|
-
const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$
|
|
259104
|
+
const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$5);
|
|
258596
259105
|
return (jsx(Dialog, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: jsxs(DialogContent, { "aria-label": "benchmark-items", className: "w-full max-w-4xl max-h-[90vh] overflow-y-auto", children: [jsxs(DialogHeader, { children: [jsx(DialogTitle, { children: datasetName }), jsx(DialogDescription, { children: t('benchmarksBenchmarkItemsModal.description') })] }), jsx("div", { className: "flex justify-end mb-4", children: jsxs(Button$1, { onClick: () => setShowAdd(true), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", children: [jsx(Plus, { className: "h-4 w-4 mr-1" }), t('benchmarksBenchmarkItemsModal.addItems')] }) }), isLoading ? (jsx("div", { className: "flex justify-center items-center h-40", children: jsx(Spinner, {}) })) : (jsxs(Fragment$1, { children: [jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-4 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[45%]", children: t('benchmarksBenchmarkItemsModal.questionColumn') }), jsx("th", { className: "px-4 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[45%]", children: t('benchmarksBenchmarkItemsModal.answerColumn') }), jsx("th", { className: "px-4 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[10%]", children: t('benchmarksBenchmarkItemsModal.actionsColumn') })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [items.map((item) => {
|
|
258597
259106
|
var _a;
|
|
258598
259107
|
return (jsxs("tr", { className: "align-top", children: [jsx("td", { className: "px-4 py-3 text-gray-900 dark:text-gray-100", children: jsx("div", { className: "line-clamp-3 break-words", children: typeof item.input === 'string' ? item.input : JSON.stringify(item.input) }) }), jsx("td", { className: "px-4 py-3 text-gray-600 dark:text-gray-300", children: jsx("div", { className: "line-clamp-3 break-words", children: (_a = item.expected_output) !== null && _a !== void 0 ? _a : jsx("span", { className: "text-gray-400", children: "\u2014" }) }) }), jsx("td", { className: "px-4 py-3 text-right", children: jsx(Button$1, { variant: "ghost", size: "sm", "aria-label": t('benchmarksBenchmarkItemsModal.deleteItemAriaLabel'), onClick: () => setDeleteItemId(item.id), children: jsx(Trash2, { className: "h-4 w-4 text-red-500" }) }) })] }, item.id));
|
|
258599
259108
|
}), items.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 3, className: "px-4 py-8 text-center text-gray-500 dark:text-gray-400", children: t('benchmarksBenchmarkItemsModal.empty') }) }))] })] }) }), totalPages > 1 && (jsx("div", { className: "mt-6", children: jsx(AdvancedPagination, { totalPages: totalPages, currentPage: page, onPageChange: setPage }) }))] })), jsx(AddItemsModal, { isOpen: showAdd, onClose: () => setShowAdd(false), tenantKey: tenantKey, username: username, datasetName: datasetName }), deleteItemId && (jsx(DeleteItemConfirm, { isOpen: !!deleteItemId, onClose: () => setDeleteItemId(null), tenantKey: tenantKey, username: username, datasetName: datasetName, itemId: deleteItemId }))] }) }));
|
|
258600
259109
|
}
|
|
258601
259110
|
|
|
258602
|
-
const PAGE_SIZE$
|
|
259111
|
+
const PAGE_SIZE$4 = 10;
|
|
258603
259112
|
function BenchmarksTab({ tenantKey, username, }) {
|
|
258604
259113
|
var _a;
|
|
258605
259114
|
const t = useT();
|
|
@@ -258611,13 +259120,13 @@ function BenchmarksTab({ tenantKey, username, }) {
|
|
|
258611
259120
|
org: tenantKey,
|
|
258612
259121
|
userId: username,
|
|
258613
259122
|
page,
|
|
258614
|
-
limit: PAGE_SIZE$
|
|
259123
|
+
limit: PAGE_SIZE$4,
|
|
258615
259124
|
});
|
|
258616
259125
|
const benchmarks = (_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : [];
|
|
258617
259126
|
const filtered = searchQuery.trim()
|
|
258618
259127
|
? benchmarks.filter((benchmark) => benchmark.name.toLowerCase().includes(searchQuery.toLowerCase()))
|
|
258619
259128
|
: benchmarks;
|
|
258620
|
-
const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$
|
|
259129
|
+
const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$4);
|
|
258621
259130
|
return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex justify-between items-center gap-1 flex-wrap", children: [jsxs("div", { className: "relative mb-6 max-w-sm w-full sm:w-auto", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { type: "text", value: searchQuery, onChange: (event) => setSearchQuery(event.target.value), placeholder: t('benchmarksIndex.searchPlaceholder'), className: "pl-10 pr-10 focus:ring-blue-500 focus:border-blue-500 h-[35px]", "aria-label": t('benchmarksIndex.searchAriaLabel') })] }), jsx("div", { className: "mb-6", children: jsxs(Button$1, { className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", onClick: () => setShowCreate(true), children: [jsx(Plus, { className: "h-4 w-4 mr-1" }), t('benchmarksIndex.newBenchmark')] }) })] }), isLoading ? (jsx("div", { className: "flex justify-center items-center h-64", children: jsx(Spinner, {}) })) : (jsxs(Fragment$1, { children: [jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[28%]", children: t('benchmarksIndex.nameColumn') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[36%]", children: t('benchmarksIndex.descriptionColumn') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[20%]", children: t('benchmarksIndex.createdColumn') }), jsx("th", { className: "px-6 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[16%]", children: t('benchmarksIndex.actionsColumn') })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [filtered.map((benchmark) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 text-gray-900 dark:text-gray-100 max-w-0", children: jsx("div", { className: "truncate font-medium", children: benchmark.name }) }), jsx("td", { className: "px-6 py-4 text-gray-600 dark:text-gray-300 max-w-0", children: jsx("div", { className: "truncate", children: benchmark.description || '—' }) }), jsx("td", { className: "px-6 py-4 text-gray-600 dark:text-gray-300 whitespace-nowrap", children: benchmark.created_at
|
|
258622
259131
|
? formatDistanceToNow(new Date(benchmark.created_at), {
|
|
258623
259132
|
addSuffix: true,
|
|
@@ -262487,7 +262996,7 @@ function PlatformSidebarFooter({ collapsed, config, }) {
|
|
|
262487
262996
|
* defined for completeness so adding "Organization" later is a one-line
|
|
262488
262997
|
* change.
|
|
262489
262998
|
*/
|
|
262490
|
-
function PlatformAccountSheet({ tab, onClose, tenantKey, username, email, onInviteClick, mainPlatformKey, authUrl, currentSpa, platformBaseDomain, }) {
|
|
262999
|
+
function PlatformAccountSheet({ tab, onClose, tenantKey, username, email, onInviteClick, mainPlatformKey, authUrl, currentSpa, platformBaseDomain, showGradebookTab = false, }) {
|
|
262491
263000
|
const t = useT();
|
|
262492
263001
|
const open = tab !== null;
|
|
262493
263002
|
const accountTabTitles = {
|
|
@@ -262510,7 +263019,7 @@ function PlatformAccountSheet({ tab, onClose, tenantKey, username, email, onInvi
|
|
|
262510
263019
|
// RBAC is off for this entry point — admin users see every
|
|
262511
263020
|
// sub-tab. Tenant-level access is already gated by the
|
|
262512
263021
|
// sidebar footer visibility rules.
|
|
262513
|
-
hasUserTabPermission: true, hasGroupsTabPermission: true, hasRolesTabPermission: true, hasPoliciesTabPermission: true, hasTeamsTabPermission: true, hasAlertsTabPermission: true, hasInviteUserPermission: true, hasCreateTeamPermission: true, enableRbac: false, rbacPermissions: {} })), tab === 'integrations' && jsx(IntegrationsTab, { tenantKey: tenantKey, username: username }), tab === 'billing' && (jsx(BillingTab, { tenant: tenantKey, username: username, mainPlatformKey: mainPlatformKey, currentUserEmail: email })), tab === 'monetization' && jsx(MonetizationTab, { platformKey: tenantKey, authURL: authUrl }), tab === 'advanced' && (jsx(AdvancedTab, { platformKey: tenantKey, username: username, currentSPA: currentSpa, authURL: authUrl, currentPlatformBaseDomain: platformBaseDomain }))] })] }) }));
|
|
263022
|
+
hasUserTabPermission: true, hasGroupsTabPermission: true, hasRolesTabPermission: true, hasPoliciesTabPermission: true, hasTeamsTabPermission: true, hasAlertsTabPermission: true, hasInviteUserPermission: true, hasCreateTeamPermission: true, enableRbac: false, rbacPermissions: {}, showGradebookTab: showGradebookTab })), tab === 'integrations' && jsx(IntegrationsTab, { tenantKey: tenantKey, username: username }), tab === 'billing' && (jsx(BillingTab, { tenant: tenantKey, username: username, mainPlatformKey: mainPlatformKey, currentUserEmail: email })), tab === 'monetization' && jsx(MonetizationTab, { platformKey: tenantKey, authURL: authUrl }), tab === 'advanced' && (jsx(AdvancedTab, { platformKey: tenantKey, username: username, currentSPA: currentSpa, authURL: authUrl, currentPlatformBaseDomain: platformBaseDomain }))] })] }) }));
|
|
262514
263023
|
}
|
|
262515
263024
|
|
|
262516
263025
|
/**
|
|
@@ -264473,8 +264982,74 @@ function canSwitchProvider(providers, name) {
|
|
|
264473
264982
|
const provider = providers.find((p) => p.name === name);
|
|
264474
264983
|
return !!(provider === null || provider === void 0 ? void 0 : provider.chat_models) && provider.chat_models.length > 0;
|
|
264475
264984
|
}
|
|
264985
|
+
/**
|
|
264986
|
+
* Whether we hold a usable LLM key for this provider — its own credentials, or
|
|
264987
|
+
* the tenant's main keys when it is allowed to borrow them. An *absent*
|
|
264988
|
+
* `main_has_credentials` means the backend did not report on the main keys and
|
|
264989
|
+
* is treated as available (matching standalone's `@/lib/utils` and
|
|
264990
|
+
* `claw-sandbox`'s copy); only an explicit `false` rules the main keys out.
|
|
264991
|
+
*/
|
|
264476
264992
|
function canSwitchLLm(llm) {
|
|
264477
|
-
|
|
264993
|
+
if (llm === null || llm === void 0 ? void 0 : llm.has_credentials) {
|
|
264994
|
+
return true;
|
|
264995
|
+
}
|
|
264996
|
+
return ((llm === null || llm === void 0 ? void 0 : llm.can_use_main_keys) &&
|
|
264997
|
+
((llm === null || llm === void 0 ? void 0 : llm.main_has_credentials) === true || (llm === null || llm === void 0 ? void 0 : llm.main_has_credentials) === undefined));
|
|
264998
|
+
}
|
|
264999
|
+
/**
|
|
265000
|
+
* Compares two raw provider names by the label the user actually sees on the
|
|
265001
|
+
* card, not by the backend key — the two diverge often enough to matter
|
|
265002
|
+
* (`bedrock` renders as "Amazon", `azure_openai` as "Microsoft", `iblai` as
|
|
265003
|
+
* "ibl.ai"). Comparison is case-insensitive (`sensitivity: 'base'`) so casing
|
|
265004
|
+
* never produces a surprising order. `getDetails` is the host-provided resolver
|
|
265005
|
+
* the grid renders with, so the sort always matches what is on screen; unknown
|
|
265006
|
+
* providers fall back to their raw name as the display name.
|
|
265007
|
+
*/
|
|
265008
|
+
function compareLLMProvidersByDisplayName(a, b, getDetails) {
|
|
265009
|
+
return getDetails(a).name.localeCompare(getDetails(b).name, undefined, {
|
|
265010
|
+
sensitivity: 'base',
|
|
265011
|
+
});
|
|
265012
|
+
}
|
|
265013
|
+
/**
|
|
265014
|
+
* Whether the user can reach *any* model of this provider.
|
|
265015
|
+
*
|
|
265016
|
+
* This is exactly the provider-level half of the per-model `isDisabled` rule in
|
|
265017
|
+
* `llm-tab/llm-provider-modal.tsx`: a model row there is disabled when
|
|
265018
|
+
* `!canSwitchLLm(provider) || !canSwitchProvider(llms, provider.name)`, and both
|
|
265019
|
+
* of those depend only on the provider — so when either fails, *every* model row
|
|
265020
|
+
* of that provider is disabled. `canSwitchProvider` is just "has at least one
|
|
265021
|
+
* `chat_models` entry", which is checked inline here to keep the helper pure and
|
|
265022
|
+
* free of the surrounding provider list.
|
|
265023
|
+
*
|
|
265024
|
+
* `canSwitchLLm` can return `undefined` (its `can_use_main_keys` branch), hence
|
|
265025
|
+
* the explicit `Boolean(...)`.
|
|
265026
|
+
*/
|
|
265027
|
+
function canAccessProvider(provider) {
|
|
265028
|
+
var _a, _b;
|
|
265029
|
+
return Boolean(canSwitchLLm(provider !== null && provider !== void 0 ? provider : {})) && ((_b = (_a = provider === null || provider === void 0 ? void 0 : provider.chat_models) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0;
|
|
265030
|
+
}
|
|
265031
|
+
/**
|
|
265032
|
+
* Orders LLM provider cards as two alphabetical groups: providers the user can
|
|
265033
|
+
* actually use (see {@link canAccessProvider}) first, then the ones they can't —
|
|
265034
|
+
* each group sorted alphabetically by display name.
|
|
265035
|
+
*
|
|
265036
|
+
* The grouping predicate is deliberately the same one the grid grays cards with,
|
|
265037
|
+
* so the two always line up: group 1 renders normally, group 2 renders grayed.
|
|
265038
|
+
* Grouping on credentials alone would let a provider that has a key but ships no
|
|
265039
|
+
* chat models sort into the "usable" group while rendering grayed.
|
|
265040
|
+
*
|
|
265041
|
+
* Pure and non-mutating: RTK Query results are frozen, so the input is copied
|
|
265042
|
+
* before sorting. `Array.prototype.sort` is stable, so providers that tie on
|
|
265043
|
+
* both group and display name keep their original relative order.
|
|
265044
|
+
*/
|
|
265045
|
+
function sortLLMProvidersByCredentials(providers, getDetails) {
|
|
265046
|
+
return [...providers].sort((a, b) => {
|
|
265047
|
+
const aUsable = canAccessProvider(a);
|
|
265048
|
+
const bUsable = canAccessProvider(b);
|
|
265049
|
+
if (aUsable !== bUsable)
|
|
265050
|
+
return aUsable ? -1 : 1;
|
|
265051
|
+
return compareLLMProvidersByDisplayName(a.name, b.name, getDetails);
|
|
265052
|
+
});
|
|
264478
265053
|
}
|
|
264479
265054
|
function extractErrorMessage(error, fallback) {
|
|
264480
265055
|
var _a, _b;
|
|
@@ -264545,12 +265120,16 @@ function LLMProviderModal({ isOpen, onClose, onSelect, llmProvider, isSelecting,
|
|
|
264545
265120
|
return (jsxs("button", { disabled: isDisabled, onClick: () => {
|
|
264546
265121
|
onSelect(llmProvider.name, llm.llm_name);
|
|
264547
265122
|
}, className: cn('flex cursor-pointer items-center gap-3 rounded-lg border border-gray-200 p-4 transition-colors', {
|
|
264548
|
-
'
|
|
265123
|
+
// Matches the provider grid's inactive treatment: tinted
|
|
265124
|
+
// card, faded logo, full-strength label.
|
|
265125
|
+
'cursor-not-allowed border-gray-100 bg-gray-50': isDisabled && !isActive,
|
|
264549
265126
|
'hover:border-blue-500 hover:bg-blue-50': !isDisabled,
|
|
264550
265127
|
'cursor-not-allowed border-blue-500 bg-blue-50': isActive,
|
|
264551
265128
|
}), children: [jsx("span", { className: "flex h-8 w-8 items-center justify-center overflow-hidden rounded-lg", children: jsx(Image$4, { src: providerDetails.logo, alt: `${providerDetails.name} icon`, className: cn('h-full w-full object-contain', {
|
|
264552
|
-
grayscale
|
|
264553
|
-
|
|
265129
|
+
// `grayscale` alone is a no-op on already-black marks,
|
|
265130
|
+
// so fade them as well — same rule as the provider grid.
|
|
265131
|
+
'opacity-40 grayscale': isDisabled && !isActive,
|
|
265132
|
+
}), width: 32, height: 32, loading: "lazy" }) }), jsx("span", { className: "text-left text-sm font-medium text-gray-900", children: llm.llm_name })] }, llm.llm_name));
|
|
264554
265133
|
}) })] }) }));
|
|
264555
265134
|
}
|
|
264556
265135
|
|
|
@@ -264575,6 +265154,10 @@ function AgentLLMTab({ showConfigurationHeader = true, getLLMProviderDetails, la
|
|
|
264575
265154
|
}, {
|
|
264576
265155
|
skip: !tenantKey || !username,
|
|
264577
265156
|
});
|
|
265157
|
+
// Two alphabetical groups: providers we have a usable LLM key for first, then
|
|
265158
|
+
// the ones we don't. Ordering is independent of the search filter below, so it
|
|
265159
|
+
// holds for whatever the filter leaves.
|
|
265160
|
+
const sortedLLMProviders = React__default.useMemo(() => sortLLMProvidersByCredentials(llmProviders !== null && llmProviders !== void 0 ? llmProviders : [], getLLMProviderDetails), [llmProviders, getLLMProviderDetails]);
|
|
264578
265161
|
const [editMentor, { isLoading: isEditingMentor }] = useEditMentorMutation();
|
|
264579
265162
|
const isDisabled = isMentorSettingsLoading || isLoadingLLMProviders || isEditingMentor;
|
|
264580
265163
|
const isLoading = isMentorSettingsLoading || isLoadingLLMProviders;
|
|
@@ -264604,10 +265187,21 @@ function AgentLLMTab({ showConfigurationHeader = true, getLLMProviderDetails, la
|
|
|
264604
265187
|
overflowX: 'hidden',
|
|
264605
265188
|
}, children: jsxs("div", { className: "space-y-6", children: [jsxs("div", { className: "relative", children: [jsx(Search, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-500" }), jsx(Input, { type: "search", placeholder: labels.search.placeholder, className: "w-full py-6 pl-9 md:w-1/2", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), disabled: isDisabled })] }), isLoading ? (jsx("div", { className: "flex items-center justify-center py-10", children: jsx(Spinner, {}) })) : (jsx(WithFormPermissions, { name: "llm_provider",
|
|
264606
265189
|
// @ts-ignore
|
|
264607
|
-
permissions: (_a = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.permissions) === null || _a === void 0 ? void 0 : _a.field, enableRBAC: enableRBAC, children: ({ disabled }) => (jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4", children:
|
|
265190
|
+
permissions: (_a = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.permissions) === null || _a === void 0 ? void 0 : _a.field, enableRBAC: enableRBAC, children: ({ disabled }) => (jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4", children: sortedLLMProviders
|
|
265191
|
+
.filter((model) => model.name.toLowerCase().includes(searchQuery.toLowerCase()))
|
|
265192
|
+
.map((model) => {
|
|
264608
265193
|
const providerDetails = getLLMProviderDetails(model.name);
|
|
264609
|
-
|
|
264610
|
-
|
|
265194
|
+
const isActive = (mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.llm_provider) === model.name;
|
|
265195
|
+
// The generated LLM response type doesn't declare the
|
|
265196
|
+
// credential flags the backend actually sends, so read them
|
|
265197
|
+
// through the access-shaped view the helper expects.
|
|
265198
|
+
const isGrayed = !canAccessProvider(model) && !isActive;
|
|
265199
|
+
return (jsxs("div", { "data-testid": "llm-provider-card", "data-provider": model.name, "data-disabled": isGrayed ? 'true' : 'false', className: cn('flex cursor-pointer items-center gap-3 rounded-lg border border-gray-200 bg-white p-4 shadow-sm transition-shadow hover:shadow-md', {
|
|
265200
|
+
'border-blue-500': isActive,
|
|
265201
|
+
// Tint the whole card too: desaturating a logo that
|
|
265202
|
+
// is already black changes nothing, so the card
|
|
265203
|
+
// itself has to carry some of the inactive signal.
|
|
265204
|
+
'border-gray-100 bg-gray-50': isGrayed,
|
|
264611
265205
|
}), onClick: () => {
|
|
264612
265206
|
if (isDisabled || disabled)
|
|
264613
265207
|
return;
|
|
@@ -264624,7 +265218,12 @@ function AgentLLMTab({ showConfigurationHeader = true, getLLMProviderDetails, la
|
|
|
264624
265218
|
// @ts-ignore - can_use_main_keys property does not exist on LLMResponse type
|
|
264625
265219
|
can_use_main_keys: model === null || model === void 0 ? void 0 : model.can_use_main_keys,
|
|
264626
265220
|
});
|
|
264627
|
-
}, children: [jsx("div", { className: "h-8 w-8 flex-shrink-0", children: jsx(Image$4, { src: providerDetails.logo, alt: t('tabsLlmTab.providerLogoAlt', { name: providerDetails.name }), className:
|
|
265221
|
+
}, children: [jsx("div", { className: "h-8 w-8 flex-shrink-0", children: jsx(Image$4, { src: providerDetails.logo, alt: t('tabsLlmTab.providerLogoAlt', { name: providerDetails.name }), className: cn('h-full w-full object-contain', {
|
|
265222
|
+
// `grayscale` only desaturates, so already-black
|
|
265223
|
+
// marks (OpenAI, xAI) looked untouched. Fading is
|
|
265224
|
+
// what actually reads as inactive at any hue.
|
|
265225
|
+
'opacity-40 grayscale': isGrayed,
|
|
265226
|
+
}), width: 32, height: 32, loading: "lazy" }) }), jsx("span", { className: "text-sm font-medium text-gray-900", children: providerDetails.name })] }, model.id));
|
|
264628
265227
|
}) })) })), selectedLLMProvider && mentorSettings && (jsx(LLMProviderModal, { isOpen: true, onClose: () => setSelectedLLMProvider(null), onSelect: updateMentorLLM, llmProvider: selectedLLMProvider, isSelecting: isEditingMentor, mentorSettings: {
|
|
264629
265228
|
llm_name: mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.llm_name,
|
|
264630
265229
|
llm_provider: mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.llm_provider,
|
|
@@ -264750,7 +265349,7 @@ const BulkDeleteMemoryModal$1 = dynamic(() => Promise.resolve().then(function ()
|
|
|
264750
265349
|
const ManageCategoriesModal$1 = dynamic(() => Promise.resolve().then(function () { return manageCategoriesModal; }).then((module) => ({
|
|
264751
265350
|
default: module.ManageCategoriesModal,
|
|
264752
265351
|
})), { ssr: false });
|
|
264753
|
-
const PAGE_SIZE$
|
|
265352
|
+
const PAGE_SIZE$3 = 20;
|
|
264754
265353
|
const SNAPSHOT_PAGE_SIZE = 1000;
|
|
264755
265354
|
function ManageMemories({ tenantKey, username, mentorId }) {
|
|
264756
265355
|
var _a, _b, _c, _d, _e;
|
|
@@ -264765,7 +265364,7 @@ function ManageMemories({ tenantKey, username, mentorId }) {
|
|
|
264765
265364
|
setPage(1);
|
|
264766
265365
|
}, [selectedLearner, dateRange, selectedCategorySlug]);
|
|
264767
265366
|
const listParams = useMemo(() => {
|
|
264768
|
-
const params = { page, page_size: PAGE_SIZE$
|
|
265367
|
+
const params = { page, page_size: PAGE_SIZE$3 };
|
|
264769
265368
|
if (selectedLearner)
|
|
264770
265369
|
params.email = selectedLearner;
|
|
264771
265370
|
if (selectedCategorySlug !== 'all')
|
|
@@ -264784,7 +265383,7 @@ function ManageMemories({ tenantKey, username, mentorId }) {
|
|
|
264784
265383
|
}, {
|
|
264785
265384
|
skip: !tenantKey || !username || !mentorId,
|
|
264786
265385
|
});
|
|
264787
|
-
const totalPages = Math.max(1, Math.ceil(((_a = listResponse === null || listResponse === void 0 ? void 0 : listResponse.count) !== null && _a !== void 0 ? _a : 0) / PAGE_SIZE$
|
|
265386
|
+
const totalPages = Math.max(1, Math.ceil(((_a = listResponse === null || listResponse === void 0 ? void 0 : listResponse.count) !== null && _a !== void 0 ? _a : 0) / PAGE_SIZE$3));
|
|
264788
265387
|
const { data: adminCategories } = useGetMemoryCategoriesAdminQuery({
|
|
264789
265388
|
org: tenantKey,
|
|
264790
265389
|
mentorId,
|
|
@@ -265070,6 +265669,7 @@ const ANALYTICS_HUB_ICONS = {
|
|
|
265070
265669
|
users: Users,
|
|
265071
265670
|
topics: MessageSquare,
|
|
265072
265671
|
transcripts: FileText,
|
|
265672
|
+
memory: Brain,
|
|
265073
265673
|
financial: DollarSign,
|
|
265074
265674
|
audit: ScrollText,
|
|
265075
265675
|
reports: ChartColumn,
|
|
@@ -265084,6 +265684,7 @@ const ANALYTICS_HUB_ORDER = [
|
|
|
265084
265684
|
{ value: 'users', key: 'users' },
|
|
265085
265685
|
{ value: 'topics', key: 'topics' },
|
|
265086
265686
|
{ value: 'transcripts', key: 'transcripts' },
|
|
265687
|
+
{ value: 'memory', key: 'memory' },
|
|
265087
265688
|
{ value: 'financial', key: 'financial' },
|
|
265088
265689
|
{ value: 'audit', key: 'audit' },
|
|
265089
265690
|
{ value: 'reports', key: 'reports' },
|
|
@@ -265119,6 +265720,10 @@ const AGENT_ANALYTICS_TAB_LABELS = {
|
|
|
265119
265720
|
label: 'Transcripts',
|
|
265120
265721
|
description: 'Read full conversation transcripts message by message.',
|
|
265121
265722
|
},
|
|
265723
|
+
memory: {
|
|
265724
|
+
label: 'Memory',
|
|
265725
|
+
description: 'What this agent remembers about each user it talks to.',
|
|
265726
|
+
},
|
|
265122
265727
|
financial: {
|
|
265123
265728
|
label: 'Costs',
|
|
265124
265729
|
description: 'Track token usage and what this agent is costing you.',
|
|
@@ -267708,7 +268313,7 @@ function toTitleCase(name) {
|
|
|
267708
268313
|
.join(' ');
|
|
267709
268314
|
}
|
|
267710
268315
|
|
|
267711
|
-
const PAGE_SIZE$
|
|
268316
|
+
const PAGE_SIZE$2 = 20;
|
|
267712
268317
|
function VoicePicker({ org, userId, provider, selectedVoiceId, onSelect, disabled, labels, }) {
|
|
267713
268318
|
var _a, _b;
|
|
267714
268319
|
const t = useT();
|
|
@@ -267728,13 +268333,13 @@ function VoicePicker({ org, userId, provider, selectedVoiceId, onSelect, disable
|
|
|
267728
268333
|
userId,
|
|
267729
268334
|
provider,
|
|
267730
268335
|
page,
|
|
267731
|
-
pageSize: PAGE_SIZE$
|
|
268336
|
+
pageSize: PAGE_SIZE$2,
|
|
267732
268337
|
...(debouncedSearch ? { search: debouncedSearch } : {}),
|
|
267733
268338
|
}, { skip: !org || !userId });
|
|
267734
268339
|
const paginated = data;
|
|
267735
268340
|
const voices = (_a = paginated === null || paginated === void 0 ? void 0 : paginated.results) !== null && _a !== void 0 ? _a : [];
|
|
267736
268341
|
const total = (_b = paginated === null || paginated === void 0 ? void 0 : paginated.count) !== null && _b !== void 0 ? _b : 0;
|
|
267737
|
-
const totalPages = total > 0 ? Math.ceil(total / PAGE_SIZE$
|
|
268342
|
+
const totalPages = total > 0 ? Math.ceil(total / PAGE_SIZE$2) : 1;
|
|
267738
268343
|
// Whenever a voice id is saved on the mentor settings, fetch it directly
|
|
267739
268344
|
// so we can pin it at the top of the list. Otherwise the user can land
|
|
267740
268345
|
// on a page that doesn't contain the selected voice and the selection
|
|
@@ -268626,11 +269231,12 @@ const AGENT_GRADER_TAB_LABELS = {
|
|
|
268626
269231
|
offHint: 'Turn it on to write grading instructions and build your rubric. Anything you set up here is kept safe if you later turn it off.',
|
|
268627
269232
|
},
|
|
268628
269233
|
subTabs: {
|
|
268629
|
-
setup: 'Grading
|
|
269234
|
+
setup: 'Grading Setup',
|
|
268630
269235
|
rubric: 'Rubric',
|
|
269236
|
+
results: 'Results',
|
|
268631
269237
|
},
|
|
268632
269238
|
denied: {
|
|
268633
|
-
title: 'No
|
|
269239
|
+
title: 'No Access to Grading Settings',
|
|
268634
269240
|
description: "You don't have permission to view this agent's grading setup. Ask an administrator for access.",
|
|
268635
269241
|
},
|
|
268636
269242
|
warnings: {
|
|
@@ -268638,12 +269244,12 @@ const AGENT_GRADER_TAB_LABELS = {
|
|
|
268638
269244
|
noCriteria: 'Grading is on but the rubric is empty — the agent will fail when asked to grade. Add at least one criterion in the Rubric tab.',
|
|
268639
269245
|
},
|
|
268640
269246
|
config: {
|
|
268641
|
-
sectionTitle: 'Grading
|
|
269247
|
+
sectionTitle: 'Grading Setup',
|
|
268642
269248
|
gradingMode: {
|
|
268643
|
-
label: 'What
|
|
269249
|
+
label: 'What Gets Graded',
|
|
268644
269250
|
options: {
|
|
268645
|
-
submission: 'A
|
|
268646
|
-
conversation: 'The
|
|
269251
|
+
submission: 'A Submission',
|
|
269252
|
+
conversation: 'The Conversation',
|
|
268647
269253
|
},
|
|
268648
269254
|
help: {
|
|
268649
269255
|
submission: 'The agent grades a piece of work the person hands in, like an essay or answer.',
|
|
@@ -268651,16 +269257,16 @@ const AGENT_GRADER_TAB_LABELS = {
|
|
|
268651
269257
|
},
|
|
268652
269258
|
},
|
|
268653
269259
|
feedbackMode: {
|
|
268654
|
-
label: 'Feedback
|
|
269260
|
+
label: 'Feedback Shared with the Person',
|
|
268655
269261
|
options: {
|
|
268656
|
-
overall: 'Overall
|
|
268657
|
-
perCriteria: 'Feedback per
|
|
268658
|
-
both: 'Overall + per
|
|
269262
|
+
overall: 'Overall Feedback Only',
|
|
269263
|
+
perCriteria: 'Feedback per Criterion',
|
|
269264
|
+
both: 'Overall + per Criterion',
|
|
268659
269265
|
},
|
|
268660
269266
|
help: 'The overall score is always calculated — this only controls how much detail is shared back.',
|
|
268661
269267
|
},
|
|
268662
269268
|
instructions: {
|
|
268663
|
-
label: 'Grading
|
|
269269
|
+
label: 'Grading Instructions',
|
|
268664
269270
|
placeholder: "Describe what's being graded and anything the grader should know beyond the rubric. E.g. 'You are grading a 500-word persuasive essay on climate policy written by a high-school student. Be encouraging but honest.'",
|
|
268665
269271
|
help: 'Required. This is the context the agent uses every time it grades.',
|
|
268666
269272
|
},
|
|
@@ -268672,7 +269278,7 @@ const AGENT_GRADER_TAB_LABELS = {
|
|
|
268672
269278
|
description: 'Each row is one thing the agent looks for and how many points it is worth. The overall score is points earned out of the total.',
|
|
268673
269279
|
needsConfigHint: 'Save your grading setup first, then add rubric criteria here.',
|
|
268674
269280
|
emptyState: 'No criteria yet. Add your first one — for example "Clarity", 10 points.',
|
|
268675
|
-
addButton: 'Add
|
|
269281
|
+
addButton: 'Add Criterion',
|
|
268676
269282
|
columns: {
|
|
268677
269283
|
name: 'Name',
|
|
268678
269284
|
criteria: 'Criteria',
|
|
@@ -268681,12 +269287,12 @@ const AGENT_GRADER_TAB_LABELS = {
|
|
|
268681
269287
|
actionsAria: (name) => `Actions for ${name}`,
|
|
268682
269288
|
edit: 'Edit',
|
|
268683
269289
|
delete: 'Delete',
|
|
268684
|
-
totalPoints: 'Total
|
|
269290
|
+
totalPoints: 'Total Possible Points: {total}',
|
|
268685
269291
|
scoreHint: 'Overall score = points earned ÷ {total}.',
|
|
268686
269292
|
lastCriterionHint: 'A rubric needs at least one criterion — add another before removing this one.',
|
|
268687
269293
|
modal: {
|
|
268688
|
-
addTitle: 'Add
|
|
268689
|
-
editTitle: 'Edit
|
|
269294
|
+
addTitle: 'Add Criterion',
|
|
269295
|
+
editTitle: 'Edit Criterion',
|
|
268690
269296
|
name: {
|
|
268691
269297
|
label: 'Name',
|
|
268692
269298
|
placeholder: 'e.g. Clarity',
|
|
@@ -268708,7 +269314,7 @@ const AGENT_GRADER_TAB_LABELS = {
|
|
|
268708
269314
|
cancel: 'Cancel',
|
|
268709
269315
|
},
|
|
268710
269316
|
deleteModal: {
|
|
268711
|
-
title: 'Delete
|
|
269317
|
+
title: 'Delete Criterion',
|
|
268712
269318
|
confirmationPrefix: 'Are you sure you want to remove',
|
|
268713
269319
|
confirmationSuffix: ' from the rubric?',
|
|
268714
269320
|
cancel: 'Cancel',
|
|
@@ -268716,6 +269322,59 @@ const AGENT_GRADER_TAB_LABELS = {
|
|
|
268716
269322
|
deleting: 'Deleting…',
|
|
268717
269323
|
},
|
|
268718
269324
|
},
|
|
269325
|
+
results: {
|
|
269326
|
+
sectionTitle: 'Grade Results',
|
|
269327
|
+
description: 'Every grade this agent has issued. Override a score to correct it — the change is pushed back to the LMS the grade came from.',
|
|
269328
|
+
filters: {
|
|
269329
|
+
searchUser: 'Search for User',
|
|
269330
|
+
searchUsersPlaceholder: 'Search users...',
|
|
269331
|
+
noUsersFound: 'No users found.',
|
|
269332
|
+
allUsers: 'All Users',
|
|
269333
|
+
statusLabel: 'Score Status',
|
|
269334
|
+
dateRangeLabel: 'Pick a Date Range',
|
|
269335
|
+
allStatuses: 'All Statuses',
|
|
269336
|
+
},
|
|
269337
|
+
statusValues: {
|
|
269338
|
+
pending: 'Pending',
|
|
269339
|
+
published: 'Published',
|
|
269340
|
+
failed: 'Failed',
|
|
269341
|
+
},
|
|
269342
|
+
columns: {
|
|
269343
|
+
learner: 'Learner',
|
|
269344
|
+
score: 'Score',
|
|
269345
|
+
status: 'Status',
|
|
269346
|
+
override: 'Override',
|
|
269347
|
+
gradedAt: 'Graded',
|
|
269348
|
+
},
|
|
269349
|
+
emptyState: 'No grades yet. They will appear here once the agent starts grading.',
|
|
269350
|
+
emptyFiltered: 'No grades match the current filters.',
|
|
269351
|
+
overriddenBadge: 'Overridden',
|
|
269352
|
+
overrideButton: 'Override',
|
|
269353
|
+
overrideButtonAria: (email) => `Override grade for ${email}`,
|
|
269354
|
+
overrideModal: {
|
|
269355
|
+
title: 'Override Grade',
|
|
269356
|
+
learnerLabel: 'Learner',
|
|
269357
|
+
aiScoreLabel: 'AI Score',
|
|
269358
|
+
currentOverrideLabel: 'Current Override',
|
|
269359
|
+
noOverride: 'None',
|
|
269360
|
+
pointsLabel: 'Override Points',
|
|
269361
|
+
pointsHelp: 'Between 0 and {total}. The score pushed to the LMS becomes points ÷ {total}.',
|
|
269362
|
+
pointsRange: 'Points must be between 0 and {total}',
|
|
269363
|
+
feedbackLabel: 'Override Feedback',
|
|
269364
|
+
feedbackPlaceholder: 'Explain the change for the learner (optional).',
|
|
269365
|
+
clearHelp: 'Clearing the override restores the AI score and pushes it back to the LMS.',
|
|
269366
|
+
save: 'Save',
|
|
269367
|
+
saving: 'Saving…',
|
|
269368
|
+
clear: 'Clear',
|
|
269369
|
+
clearing: 'Clearing…',
|
|
269370
|
+
cancel: 'Cancel',
|
|
269371
|
+
},
|
|
269372
|
+
toasts: {
|
|
269373
|
+
overrideSaved: 'Override saved and pushed to the LMS',
|
|
269374
|
+
overrideCleared: 'Override cleared — the AI score was restored',
|
|
269375
|
+
overrideError: "Couldn't save the override",
|
|
269376
|
+
},
|
|
269377
|
+
},
|
|
268719
269378
|
toasts: {
|
|
268720
269379
|
toggleOn: 'Grading turned on',
|
|
268721
269380
|
toggleOff: 'Grading turned off — your rubric is kept for next time',
|
|
@@ -268742,6 +269401,7 @@ function buildGraderTabLabels(t) {
|
|
|
268742
269401
|
subTabs: {
|
|
268743
269402
|
setup: t('graderTabLabels.subTabs.setup'),
|
|
268744
269403
|
rubric: t('graderTabLabels.subTabs.rubric'),
|
|
269404
|
+
results: t('graderTabLabels.subTabs.results'),
|
|
268745
269405
|
},
|
|
268746
269406
|
denied: {
|
|
268747
269407
|
title: t('graderTabLabels.denied.title'),
|
|
@@ -268829,6 +269489,59 @@ function buildGraderTabLabels(t) {
|
|
|
268829
269489
|
deleting: t('graderTabLabels.criteria.deleteModal.deleting'),
|
|
268830
269490
|
},
|
|
268831
269491
|
},
|
|
269492
|
+
results: {
|
|
269493
|
+
sectionTitle: t('graderTabLabels.results.sectionTitle'),
|
|
269494
|
+
description: t('graderTabLabels.results.description'),
|
|
269495
|
+
filters: {
|
|
269496
|
+
searchUser: t('graderTabLabels.results.filters.searchUser'),
|
|
269497
|
+
searchUsersPlaceholder: t('graderTabLabels.results.filters.searchUsersPlaceholder'),
|
|
269498
|
+
noUsersFound: t('graderTabLabels.results.filters.noUsersFound'),
|
|
269499
|
+
allUsers: t('graderTabLabels.results.filters.allUsers'),
|
|
269500
|
+
statusLabel: t('graderTabLabels.results.filters.statusLabel'),
|
|
269501
|
+
dateRangeLabel: t('graderTabLabels.results.filters.dateRangeLabel'),
|
|
269502
|
+
allStatuses: t('graderTabLabels.results.filters.allStatuses'),
|
|
269503
|
+
},
|
|
269504
|
+
statusValues: {
|
|
269505
|
+
pending: t('graderTabLabels.results.statusValues.pending'),
|
|
269506
|
+
published: t('graderTabLabels.results.statusValues.published'),
|
|
269507
|
+
failed: t('graderTabLabels.results.statusValues.failed'),
|
|
269508
|
+
},
|
|
269509
|
+
columns: {
|
|
269510
|
+
learner: t('graderTabLabels.results.columns.learner'),
|
|
269511
|
+
score: t('graderTabLabels.results.columns.score'),
|
|
269512
|
+
status: t('graderTabLabels.results.columns.status'),
|
|
269513
|
+
override: t('graderTabLabels.results.columns.override'),
|
|
269514
|
+
gradedAt: t('graderTabLabels.results.columns.gradedAt'),
|
|
269515
|
+
},
|
|
269516
|
+
emptyState: t('graderTabLabels.results.emptyState'),
|
|
269517
|
+
emptyFiltered: t('graderTabLabels.results.emptyFiltered'),
|
|
269518
|
+
overriddenBadge: t('graderTabLabels.results.overriddenBadge'),
|
|
269519
|
+
overrideButton: t('graderTabLabels.results.overrideButton'),
|
|
269520
|
+
overrideButtonAria: (email) => t('graderTabLabels.results.overrideButtonAria', { email }),
|
|
269521
|
+
overrideModal: {
|
|
269522
|
+
title: t('graderTabLabels.results.overrideModal.title'),
|
|
269523
|
+
learnerLabel: t('graderTabLabels.results.overrideModal.learnerLabel'),
|
|
269524
|
+
aiScoreLabel: t('graderTabLabels.results.overrideModal.aiScoreLabel'),
|
|
269525
|
+
currentOverrideLabel: t('graderTabLabels.results.overrideModal.currentOverrideLabel'),
|
|
269526
|
+
noOverride: t('graderTabLabels.results.overrideModal.noOverride'),
|
|
269527
|
+
pointsLabel: t('graderTabLabels.results.overrideModal.pointsLabel'),
|
|
269528
|
+
pointsHelp: t('graderTabLabels.results.overrideModal.pointsHelp'),
|
|
269529
|
+
pointsRange: t('graderTabLabels.results.overrideModal.pointsRange'),
|
|
269530
|
+
feedbackLabel: t('graderTabLabels.results.overrideModal.feedbackLabel'),
|
|
269531
|
+
feedbackPlaceholder: t('graderTabLabels.results.overrideModal.feedbackPlaceholder'),
|
|
269532
|
+
clearHelp: t('graderTabLabels.results.overrideModal.clearHelp'),
|
|
269533
|
+
save: t('graderTabLabels.results.overrideModal.save'),
|
|
269534
|
+
saving: t('graderTabLabels.results.overrideModal.saving'),
|
|
269535
|
+
clear: t('graderTabLabels.results.overrideModal.clear'),
|
|
269536
|
+
clearing: t('graderTabLabels.results.overrideModal.clearing'),
|
|
269537
|
+
cancel: t('graderTabLabels.results.overrideModal.cancel'),
|
|
269538
|
+
},
|
|
269539
|
+
toasts: {
|
|
269540
|
+
overrideSaved: t('graderTabLabels.results.toasts.overrideSaved'),
|
|
269541
|
+
overrideCleared: t('graderTabLabels.results.toasts.overrideCleared'),
|
|
269542
|
+
overrideError: t('graderTabLabels.results.toasts.overrideError'),
|
|
269543
|
+
},
|
|
269544
|
+
},
|
|
268832
269545
|
toasts: {
|
|
268833
269546
|
toggleOn: t('graderTabLabels.toasts.toggleOn'),
|
|
268834
269547
|
toggleOff: t('graderTabLabels.toasts.toggleOff'),
|
|
@@ -268849,6 +269562,141 @@ function resolveGraderTabLabels(override, t) {
|
|
|
268849
269562
|
return deepMerge(base, override);
|
|
268850
269563
|
}
|
|
268851
269564
|
|
|
269565
|
+
function formatPercent$1(score) {
|
|
269566
|
+
return `${Math.round(score * 100)}%`;
|
|
269567
|
+
}
|
|
269568
|
+
function errorDetail$1(error) {
|
|
269569
|
+
var _a;
|
|
269570
|
+
const detail = (_a = error === null || error === void 0 ? void 0 : error.data) === null || _a === void 0 ? void 0 : _a.detail;
|
|
269571
|
+
return typeof detail === 'string' ? detail : '';
|
|
269572
|
+
}
|
|
269573
|
+
/**
|
|
269574
|
+
* Popup that records a human override for one grade result and pushes it to
|
|
269575
|
+
* the LMS the grade came from. Points are in rubric points (0 to the
|
|
269576
|
+
* rubric's total); clearing restores the AI score.
|
|
269577
|
+
*/
|
|
269578
|
+
function GradeResultOverrideModal({ isOpen, onClose, result, tenantKey, mentorId, labels, }) {
|
|
269579
|
+
var _a, _b;
|
|
269580
|
+
const m = labels.overrideModal;
|
|
269581
|
+
// The list row doesn't carry the rubric total or existing override text —
|
|
269582
|
+
// fetch the full record while the modal is open.
|
|
269583
|
+
const { data: detail, isLoading } = useGetGradeResultQuery({ org: tenantKey, mentorId, resultId: (_a = result === null || result === void 0 ? void 0 : result.id) !== null && _a !== void 0 ? _a : '' }, { skip: !isOpen || !result });
|
|
269584
|
+
const [overrideGradeResult, { isLoading: isSaving }] = useOverrideGradeResultMutation();
|
|
269585
|
+
const [points, setPoints] = React__default.useState('');
|
|
269586
|
+
const [feedback, setFeedback] = React__default.useState('');
|
|
269587
|
+
const [showErrors, setShowErrors] = React__default.useState(false);
|
|
269588
|
+
const [isClearing, setIsClearing] = React__default.useState(false);
|
|
269589
|
+
// Prefill from the fetched record each time the modal opens.
|
|
269590
|
+
React__default.useEffect(() => {
|
|
269591
|
+
var _a;
|
|
269592
|
+
if (!isOpen)
|
|
269593
|
+
return;
|
|
269594
|
+
setShowErrors(false);
|
|
269595
|
+
setPoints((detail === null || detail === void 0 ? void 0 : detail.override_points) != null ? String(detail.override_points) : '');
|
|
269596
|
+
setFeedback((_a = detail === null || detail === void 0 ? void 0 : detail.override_feedback) !== null && _a !== void 0 ? _a : '');
|
|
269597
|
+
}, [isOpen, detail === null || detail === void 0 ? void 0 : detail.id, detail === null || detail === void 0 ? void 0 : detail.override_points, detail === null || detail === void 0 ? void 0 : detail.override_feedback]);
|
|
269598
|
+
const totalPoints = (_b = detail === null || detail === void 0 ? void 0 : detail.total_points) !== null && _b !== void 0 ? _b : 0;
|
|
269599
|
+
// Hard UI cap: overrides are entered as 0–100, additionally bounded by the
|
|
269600
|
+
// rubric's own total when it is smaller.
|
|
269601
|
+
const maxPoints = totalPoints > 0 ? Math.min(totalPoints, 100) : 100;
|
|
269602
|
+
const parsedPoints = Number.parseFloat(points);
|
|
269603
|
+
const pointsValid = Number.isFinite(parsedPoints) && parsedPoints >= 0 && parsedPoints <= maxPoints;
|
|
269604
|
+
const hasExistingOverride = (detail === null || detail === void 0 ? void 0 : detail.override_points) != null;
|
|
269605
|
+
const submit = async (formData) => {
|
|
269606
|
+
if (!result)
|
|
269607
|
+
return false;
|
|
269608
|
+
try {
|
|
269609
|
+
await overrideGradeResult({
|
|
269610
|
+
org: tenantKey,
|
|
269611
|
+
mentorId,
|
|
269612
|
+
resultId: result.id,
|
|
269613
|
+
formData,
|
|
269614
|
+
}).unwrap();
|
|
269615
|
+
return true;
|
|
269616
|
+
}
|
|
269617
|
+
catch (error) {
|
|
269618
|
+
console.error('[GradeResultOverrideModal] override error', error);
|
|
269619
|
+
toast.error(errorDetail$1(error) || labels.toasts.overrideError);
|
|
269620
|
+
return false;
|
|
269621
|
+
}
|
|
269622
|
+
};
|
|
269623
|
+
const handleSave = async () => {
|
|
269624
|
+
if (!pointsValid) {
|
|
269625
|
+
setShowErrors(true);
|
|
269626
|
+
return;
|
|
269627
|
+
}
|
|
269628
|
+
const saved = await submit({ override_points: parsedPoints, override_feedback: feedback });
|
|
269629
|
+
if (saved) {
|
|
269630
|
+
toast.success(labels.toasts.overrideSaved);
|
|
269631
|
+
onClose();
|
|
269632
|
+
}
|
|
269633
|
+
};
|
|
269634
|
+
const handleClear = async () => {
|
|
269635
|
+
setIsClearing(true);
|
|
269636
|
+
const cleared = await submit({ override_points: null });
|
|
269637
|
+
setIsClearing(false);
|
|
269638
|
+
if (cleared) {
|
|
269639
|
+
toast.success(labels.toasts.overrideCleared);
|
|
269640
|
+
onClose();
|
|
269641
|
+
}
|
|
269642
|
+
};
|
|
269643
|
+
return (jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: jsxs(DialogContent, { "aria-describedby": "grader-override-modal-description", "data-testid": "grader-override-modal", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "ibl-dialog-title", children: m.title }) }), isLoading || !detail ? (jsx("div", { className: "flex items-center justify-center py-8", "data-testid": "grader-override-loading", children: jsx(Spinner, {}) })) : (jsxs("div", { className: "space-y-4", id: "grader-override-modal-description", children: [jsxs("div", { className: "grid grid-cols-2 gap-2 rounded-lg border border-gray-200 bg-gray-50/60 p-3 text-sm", children: [jsx("span", { className: "text-gray-500", children: m.learnerLabel }), jsx("span", { className: "truncate text-gray-900", title: detail.student.email, children: detail.student.email }), jsx("span", { className: "text-gray-500", children: m.aiScoreLabel }), jsx("span", { className: "text-gray-900", children: formatPercent$1(detail.score) }), jsx("span", { className: "text-gray-500", children: m.currentOverrideLabel }), jsx("span", { className: "text-gray-900", "data-testid": "grader-override-current", children: hasExistingOverride ? `${detail.override_points} / ${totalPoints}` : m.noOverride })] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { htmlFor: "grader-override-points", children: m.pointsLabel }), jsx(Input, { id: "grader-override-points", type: "number", min: 0, max: maxPoints, step: "any", value: points, className: "w-28", onChange: (e) => setPoints(e.target.value) }), jsx("p", { className: "text-xs text-gray-500", children: m.pointsHelp.replace('{total}', String(maxPoints)) }), showErrors && !pointsValid && (jsx("p", { className: "text-xs text-red-500", children: m.pointsRange.replace('{total}', String(maxPoints)) }))] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { htmlFor: "grader-override-feedback", children: m.feedbackLabel }), jsx(Textarea, { id: "grader-override-feedback", value: feedback, placeholder: m.feedbackPlaceholder, rows: 3, onChange: (e) => setFeedback(e.target.value) })] }), hasExistingOverride && jsx("p", { className: "text-xs text-gray-500", children: m.clearHelp })] })), jsxs(DialogFooter, { className: "gap-3", children: [hasExistingOverride && (jsx(Button$1, { variant: "outline", className: "mr-auto text-red-600 hover:text-red-700", onClick: handleClear, disabled: isSaving || isLoading, "data-testid": "grader-override-clear", children: isClearing ? m.clearing : m.clear })), jsx(Button$1, { variant: "outline", onClick: onClose, children: m.cancel }), jsx(Button$1, { className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", onClick: handleSave, disabled: isSaving || isLoading, "data-testid": "grader-override-save", children: isSaving && !isClearing ? m.saving : m.save })] })] }) }));
|
|
269644
|
+
}
|
|
269645
|
+
|
|
269646
|
+
const PAGE_SIZE$1 = 10;
|
|
269647
|
+
const STATUS_ALL = 'all';
|
|
269648
|
+
function formatPercent(score) {
|
|
269649
|
+
return `${Math.round(score * 100)}%`;
|
|
269650
|
+
}
|
|
269651
|
+
function ResultsSection({ labels, tenantKey, mentorId, username, canOverride, }) {
|
|
269652
|
+
var _a, _b, _c;
|
|
269653
|
+
const [selectedEmail, setSelectedEmail] = React__default.useState('');
|
|
269654
|
+
const [status, setStatus] = React__default.useState(STATUS_ALL);
|
|
269655
|
+
const [dateRange, setDateRange] = React__default.useState(undefined);
|
|
269656
|
+
const [page, setPage] = React__default.useState(1);
|
|
269657
|
+
const [resultToOverride, setResultToOverride] = React__default.useState(null);
|
|
269658
|
+
const gradedAtAfter = (dateRange === null || dateRange === void 0 ? void 0 : dateRange.from)
|
|
269659
|
+
? `${format$1(dateRange.from, 'yyyy-MM-dd')}T00:00:00Z`
|
|
269660
|
+
: undefined;
|
|
269661
|
+
const gradedAtBefore = (dateRange === null || dateRange === void 0 ? void 0 : dateRange.to)
|
|
269662
|
+
? `${format$1(dateRange.to, 'yyyy-MM-dd')}T23:59:59Z`
|
|
269663
|
+
: undefined;
|
|
269664
|
+
const hasFilters = Boolean(selectedEmail) ||
|
|
269665
|
+
status !== STATUS_ALL ||
|
|
269666
|
+
Boolean(gradedAtAfter) ||
|
|
269667
|
+
Boolean(gradedAtBefore);
|
|
269668
|
+
// Any filter change restarts from the first page.
|
|
269669
|
+
React__default.useEffect(() => {
|
|
269670
|
+
setPage(1);
|
|
269671
|
+
}, [selectedEmail, status, gradedAtAfter, gradedAtBefore]);
|
|
269672
|
+
// Same learner list the History tab's "Search for User" control uses.
|
|
269673
|
+
const { data: chatHistoryFilter } = useGetChatHistoryFilterQuery({
|
|
269674
|
+
org: tenantKey,
|
|
269675
|
+
// @ts-expect-error userId is accepted by the API but not typed
|
|
269676
|
+
userId: username || '',
|
|
269677
|
+
mentorId,
|
|
269678
|
+
});
|
|
269679
|
+
const learners = (_a = chatHistoryFilter === null || chatHistoryFilter === void 0 ? void 0 : chatHistoryFilter.users) !== null && _a !== void 0 ? _a : [];
|
|
269680
|
+
const { data, isLoading, isFetching } = useListGradeResultsQuery({
|
|
269681
|
+
org: tenantKey,
|
|
269682
|
+
mentorId,
|
|
269683
|
+
email: selectedEmail || undefined,
|
|
269684
|
+
status: status === STATUS_ALL ? undefined : status,
|
|
269685
|
+
graded_at_after: gradedAtAfter,
|
|
269686
|
+
graded_at_before: gradedAtBefore,
|
|
269687
|
+
page,
|
|
269688
|
+
page_size: PAGE_SIZE$1,
|
|
269689
|
+
}, { skip: !tenantKey || !mentorId });
|
|
269690
|
+
const results = (_b = data === null || data === void 0 ? void 0 : data.results) !== null && _b !== void 0 ? _b : [];
|
|
269691
|
+
const totalPages = Math.max(1, Math.ceil(((_c = data === null || data === void 0 ? void 0 : data.count) !== null && _c !== void 0 ? _c : 0) / PAGE_SIZE$1));
|
|
269692
|
+
const statusText = (value) => value ? labels.statusValues[value] : '—';
|
|
269693
|
+
return (jsxs("div", { className: "space-y-3", "data-testid": "grader-results-section", children: [jsxs("div", { children: [jsx("h4", { className: "text-sm font-medium text-gray-900", children: labels.sectionTitle }), jsx("p", { className: "text-xs text-gray-600", children: labels.description })] }), jsx("div", { className: "rounded-lg border p-4", children: jsxs("div", { className: "flex flex-col gap-3 lg:flex-row", children: [jsx("div", { className: "relative min-w-[200px] flex-1", children: jsxs(Popover, { children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", role: "combobox", "aria-label": labels.filters.searchUser, className: "w-full justify-between bg-transparent font-normal", "data-testid": "grader-results-user-filter", children: [selectedEmail || labels.filters.searchUser, jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), jsx(PopoverContent, { className: "w-full p-0", align: "start", portalled: false, children: jsxs(Command, { children: [jsx(CommandInput, { placeholder: labels.filters.searchUsersPlaceholder }), jsxs(CommandList, { children: [jsx(CommandEmpty, { children: labels.filters.noUsersFound }), jsxs(CommandGroup, { children: [jsxs(CommandItem, { value: "", onSelect: () => setSelectedEmail(''), children: [jsx(Check, { className: cn('mr-2 h-4 w-4', !selectedEmail ? 'opacity-100' : 'opacity-0') }), labels.filters.allUsers] }), learners.map((learner) => (jsxs(CommandItem, { value: learner.email, onSelect: () => setSelectedEmail(learner.email), children: [jsx(Check, { className: cn('mr-2 h-4 w-4', selectedEmail === learner.email ? 'opacity-100' : 'opacity-0') }), jsx("div", { className: "flex flex-col", children: jsx("span", { className: "font-medium text-gray-700", children: learner.email }) })] }, learner.email)))] })] })] }) })] }) }), jsxs(Select$1, { value: status, onValueChange: setStatus, children: [jsx(SelectTrigger, { className: "w-full lg:w-[160px]", "aria-label": labels.filters.statusLabel, "data-testid": "grader-results-status-filter", children: jsx(SelectValue, { placeholder: labels.filters.statusLabel }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: STATUS_ALL, children: labels.filters.allStatuses }), jsx(SelectItem, { value: "pending", children: labels.statusValues.pending }), jsx(SelectItem, { value: "published", children: labels.statusValues.published }), jsx(SelectItem, { value: "failed", children: labels.statusValues.failed })] })] }), jsxs(Popover, { children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", className: "flex w-full items-center gap-2 bg-transparent font-normal whitespace-nowrap lg:w-auto", "data-testid": "grader-results-date-filter", children: [jsx(Calendar$1, { className: "h-4 w-4" }), (dateRange === null || dateRange === void 0 ? void 0 : dateRange.from) && (dateRange === null || dateRange === void 0 ? void 0 : dateRange.to)
|
|
269694
|
+
? `${format$1(dateRange.from, 'MMM dd')} - ${format$1(dateRange.to, 'MMM dd')}`
|
|
269695
|
+
: labels.filters.dateRangeLabel] }) }), jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: jsx(Calendar, { mode: "range", selected: dateRange, onSelect: setDateRange, numberOfMonths: 2, initialFocus: true }) })] })] }) }), jsx("div", { className: "overflow-hidden rounded-md border", children: jsx("div", { className: "overflow-x-auto sm:mx-0", children: jsx("div", { className: "inline-block min-w-full align-middle", children: isLoading ? (jsx("div", { className: "flex w-full items-center justify-center py-10", children: jsx(Spinner, {}) })) : (jsxs(Table$1, { className: "min-w-full", children: [jsx(TableHeader$1, { children: jsxs(TableRow$1, { className: "bg-muted/50 border-b", children: [jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: labels.columns.learner }), jsx(TableHead, { className: "p-3 text-right text-sm whitespace-nowrap text-[#646464]", children: labels.columns.score }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: labels.columns.status }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: labels.columns.override }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: labels.columns.gradedAt }), jsx(TableHead, { className: "w-10 p-3" })] }) }), jsx(TableBody, { children: results.length === 0 ? (jsx(TableRow$1, { children: jsx(TableCell$1, { colSpan: 6, className: "p-4 text-center text-[#646464]", children: hasFilters ? labels.emptyFiltered : labels.emptyState }) })) : (results.map((result) => (jsxs(TableRow$1, { className: "border-b last:border-0", "data-testid": `grader-result-row-${result.id}`, children: [jsx(TableCell$1, { className: "max-w-[220px] truncate p-3 font-medium whitespace-nowrap text-[#646464]", title: result.student.email, children: result.student.email }), jsx(TableCell$1, { className: "p-3 text-right whitespace-nowrap text-[#646464]", children: formatPercent(result.effective_score) }), jsx(TableCell$1, { className: "p-3 whitespace-nowrap text-[#646464]", children: statusText(result.status) }), jsx(TableCell$1, { className: "min-w-[200px] max-w-[320px] p-3 text-[#646464]", children: result.override_score != null
|
|
269696
|
+
? `${labels.overriddenBadge} · ${formatPercent(result.override_score)} · ${statusText(result.override_status)}`
|
|
269697
|
+
: '—' }), jsx(TableCell$1, { className: "p-3 whitespace-nowrap text-[#646464]", children: formatDistanceToNow(new Date(result.graded_at), { addSuffix: true }) }), jsx(TableCell$1, { className: "p-3 text-right", children: canOverride && (jsx(Button$1, { type: "button", variant: "outline", size: "sm", onClick: () => setResultToOverride(result), "aria-label": labels.overrideButtonAria(result.student.email), "data-testid": `grader-result-override-${result.id}`, children: labels.overrideButton })) })] }, result.id)))) })] })) }) }) }), totalPages > 1 && (jsx(IblPagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage, disabled: isLoading || isFetching })), jsx(GradeResultOverrideModal, { isOpen: resultToOverride !== null, onClose: () => setResultToOverride(null), result: resultToOverride, tenantKey: tenantKey, mentorId: mentorId, labels: labels })] }));
|
|
269698
|
+
}
|
|
269699
|
+
|
|
268852
269700
|
function CriterionDeleteModal({ isOpen, onClose, criterion, labels, isDeleting, onConfirm, }) {
|
|
268853
269701
|
const handleDelete = async () => {
|
|
268854
269702
|
if (!criterion)
|
|
@@ -268900,25 +269748,25 @@ function CriterionModal({ isOpen, onClose, criterion, labels, isSaving, onSave }
|
|
|
268900
269748
|
return (jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: jsxs(DialogContent, { "aria-describedby": "grader-criterion-modal-description", "data-testid": "grader-criterion-modal", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "ibl-dialog-title", children: isEditing ? labels.editTitle : labels.addTitle }) }), jsxs("div", { className: "space-y-4", id: "grader-criterion-modal-description", children: [jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { htmlFor: "grader-criterion-name", children: labels.name.label }), jsx(Input, { id: "grader-criterion-name", value: draft.name, placeholder: labels.name.placeholder, onChange: (e) => setDraft((prev) => ({ ...prev, name: e.target.value })) }), showErrors && errors.name && jsx("p", { className: "text-xs text-red-500", children: errors.name })] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { htmlFor: "grader-criterion-criteria", children: labels.criteria.label }), jsx(Textarea, { id: "grader-criterion-criteria", value: draft.criteria, placeholder: labels.criteria.placeholder, rows: 3, onChange: (e) => setDraft((prev) => ({ ...prev, criteria: e.target.value })) }), showErrors && errors.criteria && (jsx("p", { className: "text-xs text-red-500", children: errors.criteria }))] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { htmlFor: "grader-criterion-points", children: labels.points.label }), jsx(Input, { id: "grader-criterion-points", type: "number", min: 0, step: "any", value: draft.points, placeholder: labels.points.placeholder, className: "w-28", onChange: (e) => setDraft((prev) => ({ ...prev, points: e.target.value })) }), showErrors && errors.points && jsx("p", { className: "text-xs text-red-500", children: errors.points })] })] }), jsxs(DialogFooter, { className: "gap-3", children: [jsx(Button$1, { variant: "outline", onClick: onClose, children: labels.cancel }), jsx(Button$1, { className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", onClick: handleSubmit, disabled: isSaving, "data-testid": "grader-criterion-modal-save", children: isSaving ? labels.saving : labels.save })] })] }) }));
|
|
268901
269749
|
}
|
|
268902
269750
|
|
|
268903
|
-
function RubricSection({ labels, criteria, hasConfig, isLoading, isMutating, totalPoints, onAdd, onEdit, onDelete, }) {
|
|
269751
|
+
function RubricSection({ labels, criteria, hasConfig, isLoading, isMutating, totalPoints, canAdd, canEdit, canDelete, onAdd, onEdit, onDelete, }) {
|
|
268904
269752
|
const [showCreate, setShowCreate] = React__default.useState(false);
|
|
268905
269753
|
const [criterionToEdit, setCriterionToEdit] = React__default.useState(null);
|
|
268906
269754
|
const [criterionToDelete, setCriterionToDelete] = React__default.useState(null);
|
|
268907
269755
|
const isLastCriterion = criteria.length === 1;
|
|
268908
|
-
return (jsxs("div", { className: "space-y-3", "data-testid": "grader-criteria-section", children: [jsxs("div", { className: "flex items-start justify-between gap-4", children: [jsxs("div", { children: [jsx("h4", { className: "text-sm font-medium text-gray-900", children: labels.sectionTitle }), jsx("p", { className: "text-xs text-gray-600", children: labels.description })] }), jsxs(Button$1, { className: "ibl-button-primary flex-shrink-0", onClick: () => setShowCreate(true), disabled: !hasConfig || isMutating, "data-testid": "grader-add-criterion-button", children: [jsx(Plus, { className: "mr-1 h-4 w-4" }), labels.addButton] })] }), jsx("div", { className: "overflow-hidden rounded-md border", children: jsx("div", { className: "overflow-x-auto sm:mx-0", children: jsx("div", { className: "inline-block min-w-full align-middle", children: isLoading ? (jsx("div", { className: "flex w-full items-center justify-center py-10", children: jsx(Spinner, {}) })) : (jsxs(Table$1, { className: "min-w-full", children: [jsx(TableHeader$1, { children: jsxs(TableRow$1, { className: "bg-muted/50 border-b", children: [jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: labels.columns.name }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: labels.columns.criteria }), jsx(TableHead, { className: "p-3 text-right text-sm whitespace-nowrap text-[#646464]", children: labels.columns.points }), jsx(TableHead, { className: "w-10 p-3" })] }) }), jsx(TableBody, { children: criteria.length === 0 ? (jsx(TableRow$1, { children: jsx(TableCell$1, { colSpan: 4, className: "p-4 text-center text-[#646464]", children: hasConfig ? labels.emptyState : labels.needsConfigHint }) })) : (criteria.map((criterion) => (jsxs(TableRow$1, { className: "border-b last:border-0", "data-testid": `grader-criterion-row-${criterion.id}`, children: [jsx(TableCell$1, { className: "max-w-[160px] truncate p-3 font-medium whitespace-nowrap text-[#646464]", children: criterion.name }), jsx(TableCell$1, { className: "max-w-[280px] truncate p-3 text-[#646464]", title: criterion.criteria, children: criterion.criteria }), jsx(TableCell$1, { className: "p-3 text-right whitespace-nowrap text-[#646464]", children: criterion.points }), jsx(TableCell$1, { className: "p-3 text-right", children: jsxs(DropdownMenu, { children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsx(Button$1, { type: "button", variant: "ghost", size: "icon", "aria-label": labels.actionsAria(criterion.name), children: jsx(Ellipsis, { className: "h-4 w-4" }) }) }), jsxs(DropdownMenuContent, { align: "end", children: [jsxs(DropdownMenuItem, { onClick: () => setCriterionToEdit(criterion), children: [jsx(Pencil, { className: "mr-2 h-4 w-4" }), labels.edit] }), jsxs(DropdownMenuItem, { className: "text-red-600 focus:text-red-700", disabled: isLastCriterion, onClick: () => {
|
|
269756
|
+
return (jsxs("div", { className: "space-y-3", "data-testid": "grader-criteria-section", children: [jsxs("div", { className: "flex items-start justify-between gap-4", children: [jsxs("div", { children: [jsx("h4", { className: "text-sm font-medium text-gray-900", children: labels.sectionTitle }), jsx("p", { className: "text-xs text-gray-600", children: labels.description })] }), canAdd && (jsxs(Button$1, { className: "ibl-button-primary flex-shrink-0", onClick: () => setShowCreate(true), disabled: !hasConfig || isMutating, "data-testid": "grader-add-criterion-button", children: [jsx(Plus, { className: "mr-1 h-4 w-4" }), labels.addButton] }))] }), jsx("div", { className: "overflow-hidden rounded-md border", children: jsx("div", { className: "overflow-x-auto sm:mx-0", children: jsx("div", { className: "inline-block min-w-full align-middle", children: isLoading ? (jsx("div", { className: "flex w-full items-center justify-center py-10", children: jsx(Spinner, {}) })) : (jsxs(Table$1, { className: "min-w-full", children: [jsx(TableHeader$1, { children: jsxs(TableRow$1, { className: "bg-muted/50 border-b", children: [jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: labels.columns.name }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: labels.columns.criteria }), jsx(TableHead, { className: "p-3 text-right text-sm whitespace-nowrap text-[#646464]", children: labels.columns.points }), jsx(TableHead, { className: "w-10 p-3" })] }) }), jsx(TableBody, { children: criteria.length === 0 ? (jsx(TableRow$1, { children: jsx(TableCell$1, { colSpan: 4, className: "p-4 text-center text-[#646464]", children: hasConfig ? labels.emptyState : labels.needsConfigHint }) })) : (criteria.map((criterion) => (jsxs(TableRow$1, { className: "border-b last:border-0", "data-testid": `grader-criterion-row-${criterion.id}`, children: [jsx(TableCell$1, { className: "max-w-[160px] truncate p-3 font-medium whitespace-nowrap text-[#646464]", children: criterion.name }), jsx(TableCell$1, { className: "max-w-[280px] truncate p-3 text-[#646464]", title: criterion.criteria, children: criterion.criteria }), jsx(TableCell$1, { className: "p-3 text-right whitespace-nowrap text-[#646464]", children: criterion.points }), jsx(TableCell$1, { className: "p-3 text-right", children: (canEdit || canDelete) && (jsxs(DropdownMenu, { children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsx(Button$1, { type: "button", variant: "ghost", size: "icon", "aria-label": labels.actionsAria(criterion.name), children: jsx(Ellipsis, { className: "h-4 w-4" }) }) }), jsxs(DropdownMenuContent, { align: "end", children: [canEdit && (jsxs(DropdownMenuItem, { onClick: () => setCriterionToEdit(criterion), children: [jsx(Pencil, { className: "mr-2 h-4 w-4" }), labels.edit] })), canDelete && (jsxs(DropdownMenuItem, { className: "text-red-600 focus:text-red-700", disabled: isLastCriterion, onClick: () => {
|
|
268909
269757
|
// Radix marks the item disabled but a raw click can
|
|
268910
269758
|
// still land — the backend refuses to delete the
|
|
268911
269759
|
// last criterion, so hard-guard here too.
|
|
268912
269760
|
if (isLastCriterion)
|
|
268913
269761
|
return;
|
|
268914
269762
|
setCriterionToDelete(criterion);
|
|
268915
|
-
}, children: [jsx(Trash2, { className: "mr-2 h-4 w-4" }), labels.delete] })] })] }) })] }, criterion.id)))) })] })) }) }) }), criteria.length > 0 && !isLoading && (jsxs(Fragment$1, { children: [jsxs("div", { className: "flex items-center justify-between pt-1 text-xs", children: [jsx("span", { className: "font-medium text-gray-900", children: labels.totalPoints.replace('{total}', String(totalPoints)) }), jsx("span", { className: "text-gray-500", children: labels.scoreHint.replace('{total}', String(totalPoints)) })] }), isLastCriterion && (
|
|
269763
|
+
}, children: [jsx(Trash2, { className: "mr-2 h-4 w-4" }), labels.delete] }))] })] })) })] }, criterion.id)))) })] })) }) }) }), criteria.length > 0 && !isLoading && (jsxs(Fragment$1, { children: [jsxs("div", { className: "flex items-center justify-between pt-1 text-xs", children: [jsx("span", { className: "font-medium text-gray-900", children: labels.totalPoints.replace('{total}', String(totalPoints)) }), jsx("span", { className: "text-gray-500", children: labels.scoreHint.replace('{total}', String(totalPoints)) })] }), isLastCriterion && (
|
|
268916
269764
|
// The backend refuses to delete the last criterion — explain why
|
|
268917
269765
|
// its Delete menu action is disabled.
|
|
268918
269766
|
jsx("p", { className: "text-xs text-gray-500", "data-testid": "grader-last-criterion-hint", children: labels.lastCriterionHint }))] })), jsx(CriterionModal, { isOpen: showCreate, onClose: () => setShowCreate(false), criterion: null, labels: labels.modal, isSaving: isMutating, onSave: onAdd }), jsx(CriterionModal, { isOpen: criterionToEdit !== null, onClose: () => setCriterionToEdit(null), criterion: criterionToEdit, labels: labels.modal, isSaving: isMutating, onSave: (values) => onEdit(criterionToEdit.id, values) }), jsx(CriterionDeleteModal, { isOpen: criterionToDelete !== null, onClose: () => setCriterionToDelete(null), criterion: criterionToDelete, labels: labels.deleteModal, isDeleting: isMutating, onConfirm: onDelete })] }));
|
|
268919
269767
|
}
|
|
268920
269768
|
|
|
268921
|
-
function SetupSection({ labels, config, isSaving, onSave }) {
|
|
269769
|
+
function SetupSection({ labels, config, isSaving, canSave: canSavePermission, onSave, }) {
|
|
268922
269770
|
const [gradingMode, setGradingMode] = React__default.useState('submission');
|
|
268923
269771
|
const [feedbackMode, setFeedbackMode] = React__default.useState('both');
|
|
268924
269772
|
const [instructions, setInstructions] = React__default.useState('');
|
|
@@ -268937,11 +269785,11 @@ function SetupSection({ labels, config, isSaving, onSave }) {
|
|
|
268937
269785
|
const canSave = instructions.trim().length > 0 && isDirty && !isSaving;
|
|
268938
269786
|
return (jsxs("div", { className: "space-y-4", "data-testid": "grader-setup-section", children: [jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { className: "text-xs font-medium text-gray-700", children: labels.gradingMode.label }), jsxs(Select$1, { value: gradingMode, onValueChange: (value) => setGradingMode(value), children: [jsx(SelectTrigger, { className: "h-9", "data-testid": "grader-grading-mode-select", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "submission", children: labels.gradingMode.options.submission }), jsx(SelectItem, { value: "conversation", children: labels.gradingMode.options.conversation })] })] }), jsx("p", { className: "text-xs text-gray-500", children: gradingMode === 'submission'
|
|
268939
269787
|
? labels.gradingMode.help.submission
|
|
268940
|
-
: labels.gradingMode.help.conversation })] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { className: "text-xs font-medium text-gray-700", children: labels.feedbackMode.label }), jsxs(Select$1, { value: feedbackMode, onValueChange: (value) => setFeedbackMode(value), children: [jsx(SelectTrigger, { className: "h-9", "data-testid": "grader-feedback-mode-select", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "overall", children: labels.feedbackMode.options.overall }), jsx(SelectItem, { value: "per_criteria", children: labels.feedbackMode.options.perCriteria }), jsx(SelectItem, { value: "both", children: labels.feedbackMode.options.both })] })] }), jsx("p", { className: "text-xs text-gray-500", children: labels.feedbackMode.help })] })] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { className: "text-xs font-medium text-gray-700", children: labels.instructions.label }), jsx(Textarea, { value: instructions, onChange: (e) => setInstructions(e.target.value), placeholder: labels.instructions.placeholder, rows: 4, "data-testid": "grader-instructions-textarea" }), jsx("p", { className: "text-xs text-gray-500", children: labels.instructions.help })] }), jsx("div", { className: "flex items-center justify-end", children: jsx("button", { type: "button", onClick: () => onSave({
|
|
269788
|
+
: labels.gradingMode.help.conversation })] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { className: "text-xs font-medium text-gray-700", children: labels.feedbackMode.label }), jsxs(Select$1, { value: feedbackMode, onValueChange: (value) => setFeedbackMode(value), children: [jsx(SelectTrigger, { className: "h-9", "data-testid": "grader-feedback-mode-select", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "overall", children: labels.feedbackMode.options.overall }), jsx(SelectItem, { value: "per_criteria", children: labels.feedbackMode.options.perCriteria }), jsx(SelectItem, { value: "both", children: labels.feedbackMode.options.both })] })] }), jsx("p", { className: "text-xs text-gray-500", children: labels.feedbackMode.help })] })] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { className: "text-xs font-medium text-gray-700", children: labels.instructions.label }), jsx(Textarea, { value: instructions, onChange: (e) => setInstructions(e.target.value), placeholder: labels.instructions.placeholder, rows: 4, "data-testid": "grader-instructions-textarea" }), jsx("p", { className: "text-xs text-gray-500", children: labels.instructions.help })] }), canSavePermission && (jsx("div", { className: "flex items-center justify-end", children: jsx("button", { type: "button", onClick: () => onSave({
|
|
268941
269789
|
grading_mode: gradingMode,
|
|
268942
269790
|
feedback_mode: feedbackMode,
|
|
268943
269791
|
grader_instructions: instructions,
|
|
268944
|
-
}), disabled: !canSave, "data-testid": "grader-save-button", className: "inline-flex items-center gap-2 rounded-md bg-gradient-to-r from-[#2563EB] to-[#93C5FD] px-4 py-2 text-sm font-medium text-white hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50", children: isSaving ? labels.savingButton : labels.saveButton }) })] }));
|
|
269792
|
+
}), disabled: !canSave, "data-testid": "grader-save-button", className: "inline-flex items-center gap-2 rounded-md bg-gradient-to-r from-[#2563EB] to-[#93C5FD] px-4 py-2 text-sm font-medium text-white hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50", children: isSaving ? labels.savingButton : labels.saveButton }) }))] }));
|
|
268945
269793
|
}
|
|
268946
269794
|
|
|
268947
269795
|
/**
|
|
@@ -268958,7 +269806,7 @@ function errorDetail(error) {
|
|
|
268958
269806
|
const detail = (_a = error === null || error === void 0 ? void 0 : error.data) === null || _a === void 0 ? void 0 : _a.detail;
|
|
268959
269807
|
return typeof detail === 'string' ? detail : '';
|
|
268960
269808
|
}
|
|
268961
|
-
function useGrader({ tenantKey, mentorId, username, labels }) {
|
|
269809
|
+
function useGrader({ tenantKey, mentorId, username, labels, enableRBAC = false, rbacPermissions = {}, }) {
|
|
268962
269810
|
var _a;
|
|
268963
269811
|
const identityReady = Boolean(tenantKey && mentorId && username);
|
|
268964
269812
|
const { data: mentorSettings, isLoading: isSettingsLoading } = useGetMentorSettingsQuery({
|
|
@@ -268995,6 +269843,25 @@ function useGrader({ tenantKey, mentorId, username, labels }) {
|
|
|
268995
269843
|
const configNotFound = errorStatus(configError) === 404;
|
|
268996
269844
|
const hasConfig = Boolean(config);
|
|
268997
269845
|
const isForbidden = errorStatus(configError) === 403 || errorStatus(criteriaError) === 403;
|
|
269846
|
+
// Grader permissions are flat actions on the mentor resource
|
|
269847
|
+
// (`/mentors/{dbId}/#write_grader_config`, `#view_grade_results`, …) — the
|
|
269848
|
+
// same entry every other mentor check uses. The check endpoint may predate
|
|
269849
|
+
// these actions, so they are only enforced when the tree actually contains
|
|
269850
|
+
// the mentor entry; otherwise everything stays visible and the server's
|
|
269851
|
+
// 403s remain the source of truth.
|
|
269852
|
+
const mentorDbId = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.mentor_id;
|
|
269853
|
+
const mentorEntry = rbacPermissions[`/mentors/${mentorDbId}/`];
|
|
269854
|
+
const allow = (action) => !mentorEntry ||
|
|
269855
|
+
checkRbacPermission(rbacPermissions, `/mentors/${mentorDbId}/#${action}`, enableRBAC);
|
|
269856
|
+
const canReadConfig = allow('read_grader_config');
|
|
269857
|
+
// First save POSTs (create_grader_config), later saves PATCH (write_grader_config).
|
|
269858
|
+
const canSaveConfig = allow(hasConfig ? 'write_grader_config' : 'create_grader_config');
|
|
269859
|
+
const canViewCriteria = allow('view_grader_criteria');
|
|
269860
|
+
const canAddCriterion = allow('create_grader_criteria');
|
|
269861
|
+
const canEditCriterion = allow('write_grader_criteria');
|
|
269862
|
+
const canDeleteCriterion = allow('delete_grader_criteria');
|
|
269863
|
+
const canViewResults = allow('view_grade_results');
|
|
269864
|
+
const canOverrideResults = allow('override_grade_results');
|
|
268998
269865
|
const totalPoints = criteria.reduce((sum, criterion) => sum + (Number(criterion.points) || 0), 0);
|
|
268999
269866
|
const toggleGrading = async (checked) => {
|
|
269000
269867
|
var _a, _b, _c;
|
|
@@ -269104,6 +269971,14 @@ function useGrader({ tenantKey, mentorId, username, labels }) {
|
|
|
269104
269971
|
return {
|
|
269105
269972
|
isLoading: isSettingsLoading || isConfigLoading,
|
|
269106
269973
|
isForbidden,
|
|
269974
|
+
canReadConfig,
|
|
269975
|
+
canSaveConfig,
|
|
269976
|
+
canViewCriteria,
|
|
269977
|
+
canAddCriterion,
|
|
269978
|
+
canEditCriterion,
|
|
269979
|
+
canDeleteCriterion,
|
|
269980
|
+
canViewResults,
|
|
269981
|
+
canOverrideResults,
|
|
269107
269982
|
enabled,
|
|
269108
269983
|
isToggling,
|
|
269109
269984
|
toggleGrading,
|
|
@@ -269125,6 +270000,7 @@ function useGrader({ tenantKey, mentorId, username, labels }) {
|
|
|
269125
270000
|
const GRADER_SUB_TABS = {
|
|
269126
270001
|
setup: 'setup',
|
|
269127
270002
|
rubric: 'rubric',
|
|
270003
|
+
results: 'results',
|
|
269128
270004
|
};
|
|
269129
270005
|
/**
|
|
269130
270006
|
* Standalone top-level tab for the agent's grading setup: the in-tab toggle
|
|
@@ -269137,15 +270013,26 @@ const GRADER_SUB_TABS = {
|
|
|
269137
270013
|
* rubric has at least one criterion — the tab surfaces a warning whenever
|
|
269138
270014
|
* the tool is on but either of the other two is missing.
|
|
269139
270015
|
*/
|
|
269140
|
-
function AgentGraderTab({ labels: labelsOverride, tenantKey: tenantKeyProp, mentorId: mentorIdProp, username: usernameProp, }) {
|
|
269141
|
-
var _a, _b, _c;
|
|
270016
|
+
function AgentGraderTab({ labels: labelsOverride, tenantKey: tenantKeyProp, mentorId: mentorIdProp, username: usernameProp, enableRBAC: enableRBACProp, rbacPermissions: rbacPermissionsProp, }) {
|
|
270017
|
+
var _a, _b, _c, _d, _e;
|
|
269142
270018
|
const ctx = useAgentSettingsOptional();
|
|
269143
270019
|
const tenantKey = (_a = tenantKeyProp !== null && tenantKeyProp !== void 0 ? tenantKeyProp : ctx === null || ctx === void 0 ? void 0 : ctx.tenantKey) !== null && _a !== void 0 ? _a : '';
|
|
269144
270020
|
const mentorId = (_b = mentorIdProp !== null && mentorIdProp !== void 0 ? mentorIdProp : ctx === null || ctx === void 0 ? void 0 : ctx.mentorId) !== null && _b !== void 0 ? _b : '';
|
|
269145
270021
|
const username = (_c = usernameProp !== null && usernameProp !== void 0 ? usernameProp : ctx === null || ctx === void 0 ? void 0 : ctx.username) !== null && _c !== void 0 ? _c : '';
|
|
270022
|
+
const enableRBAC = (_d = enableRBACProp !== null && enableRBACProp !== void 0 ? enableRBACProp : ctx === null || ctx === void 0 ? void 0 : ctx.enableRBAC) !== null && _d !== void 0 ? _d : false;
|
|
270023
|
+
const rbacPermissions = (_e = rbacPermissionsProp !== null && rbacPermissionsProp !== void 0 ? rbacPermissionsProp : ctx === null || ctx === void 0 ? void 0 : ctx.rbacPermissions) !== null && _e !== void 0 ? _e : {};
|
|
269146
270024
|
const t = useT();
|
|
269147
270025
|
const labels = React__default.useMemo(() => resolveGraderTabLabels(labelsOverride, t), [labelsOverride, t]);
|
|
269148
|
-
const { isLoading, isForbidden, enabled, isToggling, toggleGrading, config, hasConfig, isSavingConfig, saveConfig, criteria, isCriteriaLoading, totalPoints, addCriterion, editCriterion, removeCriterion, isMutatingCriteria, } = useGrader({ tenantKey, mentorId, username, labels });
|
|
270026
|
+
const { isLoading, isForbidden, enabled, isToggling, toggleGrading, config, hasConfig, isSavingConfig, saveConfig, criteria, isCriteriaLoading, totalPoints, addCriterion, editCriterion, removeCriterion, isMutatingCriteria, canReadConfig, canSaveConfig, canViewCriteria, canAddCriterion, canEditCriterion, canDeleteCriterion, canViewResults, canOverrideResults, } = useGrader({ tenantKey, mentorId, username, labels, enableRBAC, rbacPermissions });
|
|
270027
|
+
const defaultSubTab = canReadConfig
|
|
270028
|
+
? GRADER_SUB_TABS.setup
|
|
270029
|
+
: canViewCriteria
|
|
270030
|
+
? GRADER_SUB_TABS.rubric
|
|
270031
|
+
: GRADER_SUB_TABS.results;
|
|
270032
|
+
// With every grader view action denied, no sub-tab trigger renders — treat
|
|
270033
|
+
// it like a read denial rather than showing an empty shell (the default
|
|
270034
|
+
// tab's content would otherwise leak without its trigger).
|
|
270035
|
+
const nothingViewable = !canReadConfig && !canViewCriteria && !canViewResults;
|
|
269149
270036
|
const showNoCriteriaWarning = enabled && hasConfig && !isCriteriaLoading && criteria.length === 0;
|
|
269150
270037
|
const showNoConfigWarning = enabled && !isLoading && !hasConfig && !isForbidden;
|
|
269151
270038
|
const warningMessage = showNoConfigWarning
|
|
@@ -269153,7 +270040,7 @@ function AgentGraderTab({ labels: labelsOverride, tenantKey: tenantKeyProp, ment
|
|
|
269153
270040
|
: showNoCriteriaWarning
|
|
269154
270041
|
? labels.warnings.noCriteria
|
|
269155
270042
|
: null;
|
|
269156
|
-
return (jsxs(Fragment$1, { children: [jsx("div", { className: "flex h-[73px] flex-shrink-0 items-center border-b border-gray-200 bg-white p-4 lg:block", children: jsxs("div", { children: [jsx("h3", { className: "mb-1 text-base font-medium text-gray-900", children: labels.header.title }), jsx("p", { className: "text-xs text-gray-600", children: labels.header.description })] }) }), jsx("div", { className: "flex-1 space-y-4 p-3 lg:p-4", style: { overflowY: 'auto', overflowX: 'hidden' }, "data-testid": "grader-tab-body", children: isLoading ? (jsx("div", { className: "flex items-center justify-center py-12", "data-testid": "grader-tab-loading", children: jsx(Spinner, {}) })) : isForbidden ? (jsxs("div", { className: "flex flex-col items-center gap-2 rounded-lg border border-gray-200 bg-gray-50 px-4 py-10 text-center", "data-testid": "grader-tab-denied", children: [jsx(ShieldAlert, { className: "h-6 w-6 text-gray-400" }), jsx("p", { className: "text-sm font-medium text-gray-900", children: labels.denied.title }), jsx("p", { className: "max-w-sm text-xs text-gray-600", children: labels.denied.description })] })) : (jsxs(CapabilityGate, { title: labels.capability.title, description: labels.capability.description, offHint: labels.capability.offHint, enabled: enabled, onToggle: toggleGrading, disabled: isToggling, ariaLabel: labels.capability.title, toggleTestId: "grader-capability-toggle", children: [warningMessage && (jsxs("div", { className: "mb-4 flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 p-3", "data-testid": "grader-misconfigured-warning", children: [jsx(TriangleAlert, { className: "mt-0.5 h-4 w-4 flex-shrink-0 text-amber-600" }), jsx("p", { className: "text-xs leading-relaxed text-amber-800", children: warningMessage })] })), jsxs(Tabs, { defaultValue:
|
|
270043
|
+
return (jsxs(Fragment$1, { children: [jsx("div", { className: "flex h-[73px] flex-shrink-0 items-center border-b border-gray-200 bg-white p-4 lg:block", children: jsxs("div", { children: [jsx("h3", { className: "mb-1 text-base font-medium text-gray-900", children: labels.header.title }), jsx("p", { className: "text-xs text-gray-600", children: labels.header.description })] }) }), jsx("div", { className: "flex-1 space-y-4 p-3 lg:p-4", style: { overflowY: 'auto', overflowX: 'hidden' }, "data-testid": "grader-tab-body", children: isLoading ? (jsx("div", { className: "flex items-center justify-center py-12", "data-testid": "grader-tab-loading", children: jsx(Spinner, {}) })) : isForbidden || nothingViewable ? (jsxs("div", { className: "flex flex-col items-center gap-2 rounded-lg border border-gray-200 bg-gray-50 px-4 py-10 text-center", "data-testid": "grader-tab-denied", children: [jsx(ShieldAlert, { className: "h-6 w-6 text-gray-400" }), jsx("p", { className: "text-sm font-medium text-gray-900", children: labels.denied.title }), jsx("p", { className: "max-w-sm text-xs text-gray-600", children: labels.denied.description })] })) : (jsxs(CapabilityGate, { title: labels.capability.title, description: labels.capability.description, offHint: labels.capability.offHint, enabled: enabled, onToggle: toggleGrading, disabled: isToggling, ariaLabel: labels.capability.title, toggleTestId: "grader-capability-toggle", children: [warningMessage && (jsxs("div", { className: "mb-4 flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 p-3", "data-testid": "grader-misconfigured-warning", children: [jsx(TriangleAlert, { className: "mt-0.5 h-4 w-4 flex-shrink-0 text-amber-600" }), jsx("p", { className: "text-xs leading-relaxed text-amber-800", children: warningMessage })] })), jsxs(Tabs, { defaultValue: defaultSubTab, className: "w-full", children: [jsxs(TabsList, { "aria-label": labels.header.title, "data-testid": "grader-sub-tabs", children: [canReadConfig && (jsx(TabsTrigger, { value: GRADER_SUB_TABS.setup, "data-testid": "grader-sub-tab-setup", children: labels.subTabs.setup })), canViewCriteria && (jsx(TabsTrigger, { value: GRADER_SUB_TABS.rubric, "data-testid": "grader-sub-tab-rubric", children: labels.subTabs.rubric })), canViewResults && (jsx(TabsTrigger, { value: GRADER_SUB_TABS.results, "data-testid": "grader-sub-tab-results", children: labels.subTabs.results }))] }), jsx(TabsContent, { value: GRADER_SUB_TABS.setup, className: "space-y-4", children: jsx(SetupSection, { labels: labels.config, config: config, isSaving: isSavingConfig, canSave: canSaveConfig, onSave: saveConfig }) }), jsx(TabsContent, { value: GRADER_SUB_TABS.rubric, className: "space-y-4", children: jsx(RubricSection, { labels: labels.criteria, criteria: criteria, hasConfig: hasConfig, isLoading: isCriteriaLoading, isMutating: isMutatingCriteria, totalPoints: totalPoints, canAdd: canAddCriterion, canEdit: canEditCriterion, canDelete: canDeleteCriterion, onAdd: addCriterion, onEdit: editCriterion, onDelete: removeCriterion }) }), jsx(TabsContent, { value: GRADER_SUB_TABS.results, className: "space-y-4", children: jsx(ResultsSection, { labels: labels.results, tenantKey: tenantKey, mentorId: mentorId, username: username, canOverride: canOverrideResults }) })] })] })) })] }));
|
|
269157
270044
|
}
|
|
269158
270045
|
|
|
269159
270046
|
function ApiKeyModal({ isOpen, onClose, apiKey, labels }) {
|