@iblai/iblai-js 2.21.0 → 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { useRef, useEffect, useMemo, useCallback, useState, createContext, useContext, forwardRef, createElement as createElement$1, useLayoutEffect, useReducer, useImperativeHandle, isValidElement, Children, PureComponent, cloneElement, Component, Fragment as Fragment$2, useId as useId$2, useDebugValue, lazy, Suspense } from 'react';
3
3
  import * as dataLayer from '@iblai/data-layer';
4
- import { useGetLlmsQuery, useCreateSessionIdMutation, useTimeTrackingMutation, useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useGetUserProfileSummaryQuery, 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, useUpdateGlobalMemoryMutation, useUpdateMentorMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useGetAllMentorMemoriesQuery, useDeleteGlobalMemoryMutation, useDeleteMentorMemoryMutation, useGetAiSearchMentorsQuery, useGetUserChatHistoryReportsQuery, USER_CHAT_HISTORY_REPORT_ACTIVE_STATES, useCreateUserChatHistoryReportMutation, useLazyGetDownloadReportFromURLQuery, useGetUserChatHistoryReportStatusQuery, userChatHistoryApiSlice, USER_CHAT_HISTORY_QUERY_KEYS, useGetUserChatHistoryQuery, useGetUserChatHistoryFilterQuery, useGetMentorsQuery, useGetUserChatHistorySessionQuery, useUserLlmUsageSummary, useUserLlmSpendOverTime, useUserLlmCostByModel, useUserLlmCostByService, useUserLlmRecentActivity, USER_LLM_RECENT_ACTIVITY_PAGE_SIZE, useUserLlmTraceObservations, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useGetVectorDocumentsQuery, 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, useGetTenantMetadataQuery, useUpdateTenantMetadataMutation, useLazyGetTenantMetadataQuery, useDeleteApiKeyMutation, useGetApiKeyQuery, useGetApiKeyFieldPermissionsQuery, useUpdateApiKeyMutation, useGetApiKeysQuery, unwrapApiTokenList, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useGetAgentSpendCapQuery, useGetTenantSpendCapQuery, useListAgentUserSpendCapsQuery, useUpsertAgentSpendCapMutation, useDeleteAgentSpendCapMutation, useUpsertTenantSpendCapMutation, useDeleteTenantSpendCapMutation, useUpsertUserSpendCapMutation, useDeleteUserSpendCapMutation, useGetLlmUsageMetricsQuery, useListAgentSpendCapsQuery, useGetCreditTransactionsQuery, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, VERCEL_SPA, useGetCustomDomainsQuery, useGetHostingProjectsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useCreateHostingProjectDomainMutation, useUpdateHostingDomainMutation, useDeleteHostingDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useGetMemsearchConfigQuery, useUpdateMemsearchConfigMutation, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useCreateMentorMemoryMutation, useGetNotificationsCountQuery, useLazyGetNotificationsQuery, useMarkAllAsReadMutation, useCreateNotificationPreviewMutation, useSendNotificationMutation, USER_PROGRESS_DATA_POINTS, useResetTemplateMutation, useSendTestTemplateEmailMutation, useUpdateTemplateMutation, useGetTemplateDetailsQuery, USER_PROGRESS_SUMMARY_TYPE, useGetTemplatesQuery, useLazyGetTemplateDetailsQuery, useToggleTemplateMutation, useGetLlmUsageTracesQuery, useGetLlmUsageObservationsQuery, useGetTopicsStatsQuery, useGetUsersStatsQuery, useGetSessionStatsQuery, useGetTopicsDetailsStatsQuery, useGetTranscriptsConversationHeadlineQuery, useGetAccessTimeHeatmapQuery, useGetUserDetailsStatsQuery, useGetAverageRatingQuery, useGetModelCostsQuery, useGetPerUserCostsQuery, useGetTenantCostQuery, useGetAgentCostQuery, useGetTranscriptsMessagesDetailsQuery, useGetTranscriptsMessagesQuery, useGetReportDetailQuery, useGetMentorPublicSettingsQuery, useGetReportsQuery, useCreateReportMutation, useGetContentAnalyticsQuery, useGetContentAnalyticsDetailsQuery, useGetRevenueQuery, useListSubscribersQuery, useGetAuditLogsQuery, useGetPlatformAuditLogsQuery, PLATFORM_AUDIT_EVENT_TYPES, PLATFORM_AUDIT_ACTION_CODES, useGetMentorMemoriesQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetUserEnrolledCoursesQuery, useLazyGetUserAssignedCoursesQuery, useLazyGetUserCredentialsQuery, useLazyGetOverTimeActivityQuery, useLazyGetCatalogSearchQuery, useCreateOrUpdateUserReportedSkillMutation, useCreateOrUpdateUserDesiredSkillMutation, useLazyGetPathwayListQuery, useLazyGetUserAssignedPathwaysQuery, useLazyGetUserEnrolledPathwaysQuery, useLazyGetPathwayCompletionQuery, useLazyGetProgramListQuery, useLazyGetProgramCompletionQuery, useLazyGetUserEnrolledProgramsQuery, useLazyGetAssignedProgramsQuery, useLazyGetUserSkillsPointsQuery, useLazyGetUserReportedSkillsQuery, useLazyGetUserDesiredSkillsQuery, useLazyGetUserCatalogPathwaysQuery, useLazyGetPerLearnerInfoQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useLazyGetPersonnalizedSearchQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetMentorSettingsQuery, useEditMentorMutation, useGetClawMentorConfigQuery, useGetClawInstancesQuery, useGetAgentConfigQuery, useUpdateClawMentorConfigMutation, useCreateClawMentorConfigMutation, useDeleteClawMentorConfigMutation, usePushClawConfigMutation, useCreateClawInstanceMutation, useDeleteClawInstanceMutation, useUpdateAgentConfigMutation, useHealthCheckClawInstanceMutation, useTestConnectivityClawInstanceMutation, useUpdateClawInstanceMutation, useGetAgentSkillResourcesQuery, useCreateAgentSkillResourceMutation, useUpdateAgentSkillResourceMutation, useUploadAgentSkillResourceAssetMutation, useDeleteAgentSkillResourceMutation, useGetMentorSkillAssignmentsQuery, useGetAgentSkillsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, filterSlashSkills, useGetMentorSkillAssignmentsInfiniteQuery, MENTOR_SKILL_ASSIGNMENTS_PAGE_SIZE, useCreateCheckoutMutation, useGetUserProjectsQuery, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useLazyGetConnectedServiceAuthUrlQuery, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorCategoriesQuery, useCreateMentorMutation, useUpdateUserPlatformMetadataMutation, useGetApplicationStatusQuery, useListOwnApplicationsQuery, useGetApplicationFormQuery, useWithdrawApplicationMutation, useRenewApplicationMutation, useCreateApplicationDraftMutation, useSubmitApplicationMutation, useUpdateApplicationMutation, useUploadApplicationAttachmentMutation, useDeleteApplicationAttachmentMutation, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useGetPromptCategoriesQuery, useCreatePromptMutation, useDeletePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation } from '@iblai/data-layer';
4
+ import { useGetLlmsQuery, useCreateSessionIdMutation, useTimeTrackingMutation, useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useGetUserProfileSummaryQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useGetLearnerCourseOutlineQuery, getSections, findResumeBlock, flattenOutline, normalizeLearnerCompletionError, useGetLearnerDetailsQuery, useGetUserEnrolledCoursesQuery, useGetUserEnrolledProgramsQuery, useGetUserCatalogPathwaysQuery, useGetUsersAsAssertionsQuery, useGetUserEarnedSkillsQuery, useGetUserReportedSkillsQuery, useGetUserDesiredSkillsQuery, useCreateGlobalMemoryMutation, useUpdateGlobalMemoryMutation, useUpdateMentorMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useGetAllMentorMemoriesQuery, useDeleteGlobalMemoryMutation, useDeleteMentorMemoryMutation, useGetAiSearchMentorsQuery, useGetUserChatHistoryReportsQuery, USER_CHAT_HISTORY_REPORT_ACTIVE_STATES, useCreateUserChatHistoryReportMutation, useLazyGetDownloadReportFromURLQuery, useGetUserChatHistoryReportStatusQuery, userChatHistoryApiSlice, USER_CHAT_HISTORY_QUERY_KEYS, useGetUserChatHistoryQuery, useGetUserChatHistoryFilterQuery, useGetMentorsQuery, useGetUserChatHistorySessionQuery, useUserLlmUsageSummary, useUserLlmSpendOverTime, useUserLlmCostByModel, useUserLlmCostByService, useUserLlmRecentActivity, USER_LLM_RECENT_ACTIVITY_PAGE_SIZE, useUserLlmTraceObservations, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useGetVectorDocumentsQuery, 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, useGetTenantMetadataQuery, useUpdateTenantMetadataMutation, useLazyGetTenantMetadataQuery, useDeleteApiKeyMutation, useGetApiKeyQuery, useGetApiKeyFieldPermissionsQuery, useUpdateApiKeyMutation, useGetApiKeysQuery, unwrapApiTokenList, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useGetAgentSpendCapQuery, useGetTenantSpendCapQuery, useListAgentUserSpendCapsQuery, useUpsertAgentSpendCapMutation, useDeleteAgentSpendCapMutation, useUpsertTenantSpendCapMutation, useDeleteTenantSpendCapMutation, useUpsertUserSpendCapMutation, useDeleteUserSpendCapMutation, useGetLlmUsageMetricsQuery, useListAgentSpendCapsQuery, useGetCreditTransactionsQuery, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, VERCEL_SPA, useGetCustomDomainsQuery, useGetHostingProjectsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useCreateHostingProjectDomainMutation, useUpdateHostingDomainMutation, useDeleteHostingDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useGetMemsearchConfigQuery, useUpdateMemsearchConfigMutation, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useCreateMentorMemoryMutation, useGetNotificationsCountQuery, useLazyGetNotificationsQuery, useMarkAllAsReadMutation, useCreateNotificationPreviewMutation, useSendNotificationMutation, USER_PROGRESS_DATA_POINTS, useResetTemplateMutation, useSendTestTemplateEmailMutation, useUpdateTemplateMutation, useGetTemplateDetailsQuery, USER_PROGRESS_SUMMARY_TYPE, useGetTemplatesQuery, useLazyGetTemplateDetailsQuery, useToggleTemplateMutation, useGetLlmUsageTracesQuery, useGetLlmUsageObservationsQuery, useGetTopicsStatsQuery, useGetUsersStatsQuery, useGetSessionStatsQuery, useGetTopicsDetailsStatsQuery, useGetTranscriptsConversationHeadlineQuery, useGetAccessTimeHeatmapQuery, useGetUserDetailsStatsQuery, useGetAverageRatingQuery, useGetModelCostsQuery, useGetPerUserCostsQuery, useGetTenantCostQuery, useGetAgentCostQuery, useGetTranscriptsMessagesDetailsQuery, useGetTranscriptsMessagesQuery, useGetReportDetailQuery, useGetMentorPublicSettingsQuery, useGetReportsQuery, useCreateReportMutation, useGetContentAnalyticsQuery, useGetContentAnalyticsDetailsQuery, useGetRevenueQuery, useListSubscribersQuery, useGetAuditLogsQuery, useGetPlatformAuditLogsQuery, PLATFORM_AUDIT_EVENT_TYPES, PLATFORM_AUDIT_ACTION_CODES, useGetMentorMemoriesQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetUserEnrolledCoursesQuery, useLazyGetUserAssignedCoursesQuery, useLazyGetUserCredentialsQuery, useLazyGetOverTimeActivityQuery, useLazyGetCatalogSearchQuery, useCreateOrUpdateUserReportedSkillMutation, useCreateOrUpdateUserDesiredSkillMutation, useLazyGetPathwayListQuery, useLazyGetUserAssignedPathwaysQuery, useLazyGetUserEnrolledPathwaysQuery, useLazyGetPathwayCompletionQuery, useLazyGetProgramListQuery, useLazyGetProgramCompletionQuery, useLazyGetUserEnrolledProgramsQuery, useLazyGetAssignedProgramsQuery, useLazyGetUserSkillsPointsQuery, useLazyGetUserReportedSkillsQuery, useLazyGetUserDesiredSkillsQuery, useLazyGetUserCatalogPathwaysQuery, useLazyGetPerLearnerInfoQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useLazyGetPersonnalizedSearchQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetMentorSettingsQuery, useEditMentorMutation, useGetClawMentorConfigQuery, useGetClawInstancesQuery, useGetAgentConfigQuery, useUpdateClawMentorConfigMutation, useCreateClawMentorConfigMutation, useDeleteClawMentorConfigMutation, usePushClawConfigMutation, useCreateClawInstanceMutation, useDeleteClawInstanceMutation, useUpdateAgentConfigMutation, useHealthCheckClawInstanceMutation, useTestConnectivityClawInstanceMutation, useUpdateClawInstanceMutation, useGetAgentSkillResourcesQuery, useCreateAgentSkillResourceMutation, useUpdateAgentSkillResourceMutation, useUploadAgentSkillResourceAssetMutation, useDeleteAgentSkillResourceMutation, useGetMentorSkillAssignmentsQuery, useGetAgentSkillsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, filterSlashSkills, useGetMentorSkillAssignmentsInfiniteQuery, MENTOR_SKILL_ASSIGNMENTS_PAGE_SIZE, useCreateCheckoutMutation, useGetUserProjectsQuery, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useLazyGetConnectedServiceAuthUrlQuery, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorCategoriesQuery, useCreateMentorMutation, useUpdateUserPlatformMetadataMutation, useGetApplicationStatusQuery, useListOwnApplicationsQuery, useGetApplicationFormQuery, useWithdrawApplicationMutation, useRenewApplicationMutation, useCreateApplicationDraftMutation, useSubmitApplicationMutation, useUpdateApplicationMutation, useUploadApplicationAttachmentMutation, useDeleteApplicationAttachmentMutation, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useGetPromptCategoriesQuery, useCreatePromptMutation, useDeletePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation } from '@iblai/data-layer';
5
5
  import { useDispatch, useSelector } from 'react-redux';
6
- import { selectSessionId, selectActiveChatMessages, useCachedSessionId, chatActions, LOCAL_STORAGE_KEYS, TimeTracker, selectRbacPermissions, useCurrentTenant, canViewOtherUsersChatHistory, isPureWatcher, getInitials, useTenantMetadata, useUsername, selectStreaming, isLoggedIn, TOOL_NAME_MAP, WRITE_TODOS_TOOL, WithPermissions, canWriteField, useStripeUpgrade, openExternalUrl, CHAT_AREA_SIZE, isAlphaNumeric32, checkRbacPermission, getTimeAgo, REQUIRED_ACTIONS_FOR_GROUPS, getVisibleAnalyticsTabs, getUserName as getUserName$2, formatRelativeTime as formatRelativeTime$2, ANONYMOUS_USERNAME, combineCSVData, WATCHER_HIDDEN_REPORTS, canViewPlatformAuditLogs, redirectToAuthSpaJoinTenant, redirectToAuthSpa, getAuthSpaJoinUrl, useOS, selectNumberOfActiveChatMessages, TOOLS, hasRemoteAiConfig, isSafariBrowser, useShowAttachment, useShowVoiceCall, useShowVoiceRecorder, useMentorSettings, selectShowingSharedChat, useShowFreeTrialDialog, useEmbedMode, chatInputSliceSelectors, useResponsive, useAccessingPublicRoute, useVisitingTenant, useModelFileUploadCapabilities, useChatFileUpload, useVoiceChat, selectAttachedFiles, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, chatInputSliceActions, removeFile, WithFormPermissions, MENTOR_VISIBILITY } from '@iblai/web-utils';
6
+ import { selectSessionId, selectActiveChatMessages, useCachedSessionId, chatActions, LOCAL_STORAGE_KEYS, TimeTracker, selectRbacPermissions, useCurrentTenant, canViewOtherUsersChatHistory, isPureWatcher, getInitials, useTenantMetadata, useUsername, selectStreaming, isLoggedIn, TOOL_NAME_MAP, WRITE_TODOS_TOOL, WithPermissions, canWriteField, useStripeUpgrade, openExternalUrl, CHAT_AREA_SIZE, isAlphaNumeric32, checkRbacPermission, getTimeAgo, REQUIRED_ACTIONS_FOR_GROUPS, getVisibleAnalyticsTabs, canViewMonetizationAnalytics, getUserName as getUserName$2, formatRelativeTime as formatRelativeTime$2, ANONYMOUS_USERNAME, combineCSVData, WATCHER_HIDDEN_REPORTS, canViewPlatformAuditLogs, redirectToAuthSpaJoinTenant, redirectToAuthSpa, getAuthSpaJoinUrl, useOS, selectNumberOfActiveChatMessages, TOOLS, hasRemoteAiConfig, isSafariBrowser, useShowAttachment, useShowVoiceCall, useShowVoiceRecorder, useMentorSettings, selectShowingSharedChat, useShowFreeTrialDialog, useEmbedMode, chatInputSliceSelectors, useResponsive, useAccessingPublicRoute, useVisitingTenant, useModelFileUploadCapabilities, useChatFileUpload, useVoiceChat, selectAttachedFiles, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, chatInputSliceActions, removeFile, WithFormPermissions, MENTOR_VISIBILITY } from '@iblai/web-utils';
7
7
  import { toast } from 'sonner';
8
8
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
9
9
  import * as ReactDOM from 'react-dom';
@@ -2325,6 +2325,8 @@ var analyticsAnalyticsMonetizationStats$3 = {
2325
2325
  tableHeadPlan: "Plan",
2326
2326
  tableHeadAmount: "Amount",
2327
2327
  tableHeadStatus: "Status",
2328
+ tableHeadUser: "User",
2329
+ tableHeadSubscribed: "Subscribed",
2328
2330
  subscriberCountTotal: "{count} subscriber{plural} total",
2329
2331
  previous: "Previous",
2330
2332
  pageLabel: "Page {page}",
@@ -3834,7 +3836,9 @@ var datasetsTabAddResourceModal$3 = {
3834
3836
  title: "Add Resources",
3835
3837
  description: "Add knowledge to help your agent provide more relevant insights. Others with edit access can reuse these sources for more topics.",
3836
3838
  googleDrivePickerError: "Google Drive Picker Error",
3837
- forceClosePicker: "Force Close Picker"
3839
+ forceClosePicker: "Force Close Picker",
3840
+ notConfigured: "Not configured for this tenant",
3841
+ scrollRegionAriaLabel: "Resource types"
3838
3842
  };
3839
3843
  var datasetsTabDatasetItem$3 = {
3840
3844
  scheduleRetrain: "Schedule retrain",
@@ -5752,7 +5756,11 @@ var resourceModalGithubFileUploadModal$3 = {
5752
5756
  errorAddingDocument: "Error adding training document",
5753
5757
  githubRepoUrlPlaceholder: "Github Repo URL",
5754
5758
  selectBranchPlaceholder: "Select Branch",
5755
- submit: "Submit"
5759
+ submit: "Submit",
5760
+ description: "Add a GitHub repository and pick a branch to train your agent on.",
5761
+ scrollRegionAriaLabel: "Repository details",
5762
+ repoUrlLabel: "Repository URL",
5763
+ branchLabel: "Branch"
5756
5764
  };
5757
5765
  var resourceModalLocalFileUploadModal$3 = {
5758
5766
  fileNotFound: "File not found",
@@ -5766,7 +5774,9 @@ var resourceModalLocalFileUploadModal$3 = {
5766
5774
  descriptionOptional: "Description (optional)",
5767
5775
  descriptionPlaceholder: "Add a description for this image...",
5768
5776
  submitting: "Submitting",
5769
- submit: "Submit"
5777
+ submit: "Submit",
5778
+ description: "Upload a file to train your agent on its contents.",
5779
+ scrollRegionAriaLabel: "File upload"
5770
5780
  };
5771
5781
  var resourceModalUrlUploadModal$3 = {
5772
5782
  urlPlaceholder: "URL",
@@ -5775,11 +5785,15 @@ var resourceModalUrlUploadModal$3 = {
5775
5785
  invalidYoutubeUrl: "Invalid YouTube URL",
5776
5786
  invalidBlackboardUrl: "Invalid Blackboard URL",
5777
5787
  invalidUrl: "Invalid URL",
5778
- submit: "Submit"
5788
+ submit: "Submit",
5789
+ description: "Add a link to train your agent on its content.",
5790
+ scrollRegionAriaLabel: "Link details",
5791
+ urlLabel: "URL"
5779
5792
  };
5780
5793
  var resourceModalWebsiteCrawlModal$3 = {
5781
- title: "Web Crawler Configuration",
5782
5794
  description: "Configure your web crawler settings and URL patterns",
5795
+ infoBox: "Crawl a website and train your agent on its pages. Set how deep to follow links, how many pages to fetch, and which URLs to include.",
5796
+ scrollRegionAriaLabel: "Web crawler settings",
5783
5797
  formAriaLabel: "Web crawler configuration form",
5784
5798
  urlRequired: "URL is required",
5785
5799
  invalidUrl: "Invalid URL",
@@ -5794,6 +5808,9 @@ var resourceModalWebsiteCrawlModal$3 = {
5794
5808
  selectPatternTypeAriaLabel: "Select pattern type",
5795
5809
  globPattern: "Glob Pattern",
5796
5810
  regularExpression: "Regular Expression",
5811
+ userAgentLabel: "User-Agent (optional)",
5812
+ userAgentPlaceholder: "Iblai-bot/1.0 (+https://ibl.ai/bot)",
5813
+ userAgentHelpText: "Optional. Overrides the default crawler User-Agent for every request. Leave blank to use the default.",
5797
5814
  crawlerMatchPatternsLabel: "Crawler Match Patterns",
5798
5815
  globPlaceholder: "https://example.com/",
5799
5816
  regexPlaceholder: "(http|https)://www.example.com/(.*)",
@@ -9646,6 +9663,8 @@ var analyticsAnalyticsMonetizationStats$2 = {
9646
9663
  tableHeadPlan: "Plan",
9647
9664
  tableHeadAmount: "Montant",
9648
9665
  tableHeadStatus: "Statut",
9666
+ tableHeadUser: "Utilisateur",
9667
+ tableHeadSubscribed: "Abonné le",
9649
9668
  subscriberCountTotal: "{count} abonné{plural} au total",
9650
9669
  previous: "Précédent",
9651
9670
  pageLabel: "Page {page}",
@@ -11321,7 +11340,9 @@ var datasetsTabAddResourceModal$2 = {
11321
11340
  title: "Ajouter des ressources",
11322
11341
  description: "Ajoutez des connaissances pour aider votre agent à fournir des informations plus pertinentes. Les autres utilisateurs avec accès en modification peuvent réutiliser ces sources pour d'autres sujets.",
11323
11342
  googleDrivePickerError: "Erreur du sélecteur Google Drive",
11324
- forceClosePicker: "Forcer la fermeture du sélecteur"
11343
+ forceClosePicker: "Forcer la fermeture du sélecteur",
11344
+ notConfigured: "Non configuré pour ce locataire",
11345
+ scrollRegionAriaLabel: "Types de ressources"
11325
11346
  };
11326
11347
  var datasetsTabDatasetItem$2 = {
11327
11348
  scheduleRetrain: "Planifier le réentraînement",
@@ -13239,7 +13260,11 @@ var resourceModalGithubFileUploadModal$2 = {
13239
13260
  errorAddingDocument: "Erreur lors de l'ajout du document d'entraînement",
13240
13261
  githubRepoUrlPlaceholder: "URL du dépôt GitHub",
13241
13262
  selectBranchPlaceholder: "Sélectionner une branche",
13242
- submit: "Soumettre"
13263
+ submit: "Soumettre",
13264
+ description: "Ajoutez un dépôt GitHub et choisissez une branche pour entraîner votre agent.",
13265
+ scrollRegionAriaLabel: "Détails du dépôt",
13266
+ repoUrlLabel: "URL du dépôt",
13267
+ branchLabel: "Branche"
13243
13268
  };
13244
13269
  var resourceModalLocalFileUploadModal$2 = {
13245
13270
  fileNotFound: "Fichier introuvable",
@@ -13253,7 +13278,9 @@ var resourceModalLocalFileUploadModal$2 = {
13253
13278
  descriptionOptional: "Description (facultative)",
13254
13279
  descriptionPlaceholder: "Ajoutez une description pour cette image...",
13255
13280
  submitting: "Envoi en cours",
13256
- submit: "Soumettre"
13281
+ submit: "Soumettre",
13282
+ description: "Importez un fichier pour entraîner votre agent sur son contenu.",
13283
+ scrollRegionAriaLabel: "Import de fichier"
13257
13284
  };
13258
13285
  var resourceModalUrlUploadModal$2 = {
13259
13286
  urlPlaceholder: "URL",
@@ -13262,11 +13289,15 @@ var resourceModalUrlUploadModal$2 = {
13262
13289
  invalidYoutubeUrl: "URL YouTube invalide",
13263
13290
  invalidBlackboardUrl: "URL Blackboard invalide",
13264
13291
  invalidUrl: "URL invalide",
13265
- submit: "Soumettre"
13292
+ submit: "Soumettre",
13293
+ description: "Ajoutez un lien pour entraîner votre agent sur son contenu.",
13294
+ scrollRegionAriaLabel: "Détails du lien",
13295
+ urlLabel: "URL"
13266
13296
  };
13267
13297
  var resourceModalWebsiteCrawlModal$2 = {
13268
- title: "Configuration du robot d'exploration web",
13269
13298
  description: "Configurez les paramètres et les modèles d'URL de votre robot d'exploration web",
13299
+ infoBox: "Explorez un site web et entraînez votre agent sur ses pages. Définissez la profondeur des liens, le nombre de pages à récupérer et les URL à inclure.",
13300
+ scrollRegionAriaLabel: "Paramètres du robot d'exploration",
13270
13301
  formAriaLabel: "Formulaire de configuration du robot d'exploration web",
13271
13302
  urlRequired: "L'URL est requise",
13272
13303
  invalidUrl: "URL invalide",
@@ -13281,6 +13312,9 @@ var resourceModalWebsiteCrawlModal$2 = {
13281
13312
  selectPatternTypeAriaLabel: "Sélectionner le type de modèle",
13282
13313
  globPattern: "Modèle Glob",
13283
13314
  regularExpression: "Expression régulière",
13315
+ userAgentLabel: "User-Agent (facultatif)",
13316
+ userAgentPlaceholder: "Iblai-bot/1.0 (+https://ibl.ai/bot)",
13317
+ userAgentHelpText: "Facultatif. Remplace le User-Agent par défaut du robot d'exploration pour chaque requête. Laissez vide pour utiliser celui par défaut.",
13284
13318
  crawlerMatchPatternsLabel: "Modèles de correspondance du robot",
13285
13319
  globPlaceholder: "https://example.com/",
13286
13320
  regexPlaceholder: "(http|https)://www.example.com/(.*)",
@@ -16967,6 +17001,8 @@ var analyticsAnalyticsMonetizationStats$1 = {
16967
17001
  tableHeadPlan: "Plan",
16968
17002
  tableHeadAmount: "Monto",
16969
17003
  tableHeadStatus: "Estado",
17004
+ tableHeadUser: "Usuario",
17005
+ tableHeadSubscribed: "Suscrito el",
16970
17006
  subscriberCountTotal: "{count} suscriptor{plural} en total",
16971
17007
  previous: "Anterior",
16972
17008
  pageLabel: "Página {page}",
@@ -18642,7 +18678,9 @@ var datasetsTabAddResourceModal$1 = {
18642
18678
  title: "Agregar recursos",
18643
18679
  description: "Agregue conocimiento para ayudar a su agente a proporcionar información más relevante. Otros usuarios con acceso de edición pueden reutilizar estas fuentes para más temas.",
18644
18680
  googleDrivePickerError: "Error del selector de Google Drive",
18645
- forceClosePicker: "Forzar cierre del selector"
18681
+ forceClosePicker: "Forzar cierre del selector",
18682
+ notConfigured: "No configurado para este inquilino",
18683
+ scrollRegionAriaLabel: "Tipos de recursos"
18646
18684
  };
18647
18685
  var datasetsTabDatasetItem$1 = {
18648
18686
  scheduleRetrain: "Programar reentrenamiento",
@@ -20560,7 +20598,11 @@ var resourceModalGithubFileUploadModal$1 = {
20560
20598
  errorAddingDocument: "Error al agregar el documento de entrenamiento",
20561
20599
  githubRepoUrlPlaceholder: "URL del repositorio de GitHub",
20562
20600
  selectBranchPlaceholder: "Seleccionar rama",
20563
- submit: "Enviar"
20601
+ submit: "Enviar",
20602
+ description: "Agrega un repositorio de GitHub y elige una rama para entrenar a tu agente.",
20603
+ scrollRegionAriaLabel: "Detalles del repositorio",
20604
+ repoUrlLabel: "URL del repositorio",
20605
+ branchLabel: "Rama"
20564
20606
  };
20565
20607
  var resourceModalLocalFileUploadModal$1 = {
20566
20608
  fileNotFound: "Archivo no encontrado",
@@ -20574,7 +20616,9 @@ var resourceModalLocalFileUploadModal$1 = {
20574
20616
  descriptionOptional: "Descripción (opcional)",
20575
20617
  descriptionPlaceholder: "Añade una descripción para esta imagen...",
20576
20618
  submitting: "Enviando",
20577
- submit: "Enviar"
20619
+ submit: "Enviar",
20620
+ description: "Sube un archivo para entrenar a tu agente con su contenido.",
20621
+ scrollRegionAriaLabel: "Carga de archivo"
20578
20622
  };
20579
20623
  var resourceModalUrlUploadModal$1 = {
20580
20624
  urlPlaceholder: "URL",
@@ -20583,11 +20627,15 @@ var resourceModalUrlUploadModal$1 = {
20583
20627
  invalidYoutubeUrl: "URL de YouTube no válida",
20584
20628
  invalidBlackboardUrl: "URL de Blackboard no válida",
20585
20629
  invalidUrl: "URL no válida",
20586
- submit: "Enviar"
20630
+ submit: "Enviar",
20631
+ description: "Agrega un enlace para entrenar a tu agente con su contenido.",
20632
+ scrollRegionAriaLabel: "Detalles del enlace",
20633
+ urlLabel: "URL"
20587
20634
  };
20588
20635
  var resourceModalWebsiteCrawlModal$1 = {
20589
- title: "Configuración del rastreador web",
20590
20636
  description: "Configure los ajustes de su rastreador web y los patrones de URL",
20637
+ infoBox: "Rastrea un sitio web y entrena a tu agente con sus páginas. Define la profundidad de los enlaces, cuántas páginas obtener y qué URL incluir.",
20638
+ scrollRegionAriaLabel: "Configuración del rastreador web",
20591
20639
  formAriaLabel: "Formulario de configuración del rastreador web",
20592
20640
  urlRequired: "La URL es obligatoria",
20593
20641
  invalidUrl: "URL no válida",
@@ -20602,6 +20650,9 @@ var resourceModalWebsiteCrawlModal$1 = {
20602
20650
  selectPatternTypeAriaLabel: "Seleccionar tipo de patrón",
20603
20651
  globPattern: "Patrón Glob",
20604
20652
  regularExpression: "Expresión regular",
20653
+ userAgentLabel: "User-Agent (opcional)",
20654
+ userAgentPlaceholder: "Iblai-bot/1.0 (+https://ibl.ai/bot)",
20655
+ userAgentHelpText: "Opcional. Sustituye el User-Agent predeterminado del rastreador en cada solicitud. Déjalo en blanco para usar el predeterminado.",
20605
20656
  crawlerMatchPatternsLabel: "Patrones de coincidencia del rastreador",
20606
20657
  globPlaceholder: "https://example.com/",
20607
20658
  regexPlaceholder: "(http|https)://www.example.com/(.*)",
@@ -24288,6 +24339,8 @@ var analyticsAnalyticsMonetizationStats = {
24288
24339
  tableHeadPlan: "方案",
24289
24340
  tableHeadAmount: "金额",
24290
24341
  tableHeadStatus: "状态",
24342
+ tableHeadUser: "用户",
24343
+ tableHeadSubscribed: "订阅日期",
24291
24344
  subscriberCountTotal: "共 {count} 位订阅者",
24292
24345
  previous: "上一页",
24293
24346
  pageLabel: "第 {page} 页",
@@ -25963,7 +26016,9 @@ var datasetsTabAddResourceModal = {
25963
26016
  title: "添加资源",
25964
26017
  description: "添加知识以帮助您的代理提供更相关的见解。其他具有编辑权限的用户可以为更多主题重复使用这些来源。",
25965
26018
  googleDrivePickerError: "Google Drive 选择器错误",
25966
- forceClosePicker: "强制关闭选择器"
26019
+ forceClosePicker: "强制关闭选择器",
26020
+ notConfigured: "未为此租户配置",
26021
+ scrollRegionAriaLabel: "资源类型"
25967
26022
  };
25968
26023
  var datasetsTabDatasetItem = {
25969
26024
  scheduleRetrain: "安排重新训练",
@@ -27881,7 +27936,11 @@ var resourceModalGithubFileUploadModal = {
27881
27936
  errorAddingDocument: "添加训练文档时出错",
27882
27937
  githubRepoUrlPlaceholder: "GitHub 仓库 URL",
27883
27938
  selectBranchPlaceholder: "选择分支",
27884
- submit: "提交"
27939
+ submit: "提交",
27940
+ description: "添加 GitHub 仓库并选择分支来训练您的智能体。",
27941
+ scrollRegionAriaLabel: "仓库详情",
27942
+ repoUrlLabel: "仓库 URL",
27943
+ branchLabel: "分支"
27885
27944
  };
27886
27945
  var resourceModalLocalFileUploadModal = {
27887
27946
  fileNotFound: "未找到文件",
@@ -27895,7 +27954,9 @@ var resourceModalLocalFileUploadModal = {
27895
27954
  descriptionOptional: "描述(可选)",
27896
27955
  descriptionPlaceholder: "为此图片添加描述...",
27897
27956
  submitting: "提交中",
27898
- submit: "提交"
27957
+ submit: "提交",
27958
+ description: "上传文件,用其内容训练您的智能体。",
27959
+ scrollRegionAriaLabel: "文件上传"
27899
27960
  };
27900
27961
  var resourceModalUrlUploadModal = {
27901
27962
  urlPlaceholder: "URL",
@@ -27904,11 +27965,15 @@ var resourceModalUrlUploadModal = {
27904
27965
  invalidYoutubeUrl: "无效的 YouTube URL",
27905
27966
  invalidBlackboardUrl: "无效的 Blackboard URL",
27906
27967
  invalidUrl: "无效的 URL",
27907
- submit: "提交"
27968
+ submit: "提交",
27969
+ description: "添加链接,用其内容训练您的智能体。",
27970
+ scrollRegionAriaLabel: "链接详情",
27971
+ urlLabel: "URL"
27908
27972
  };
27909
27973
  var resourceModalWebsiteCrawlModal = {
27910
- title: "网络爬虫配置",
27911
27974
  description: "配置您的网络爬虫设置和 URL 模式",
27975
+ infoBox: "抓取网站并用其页面训练您的智能体。设置链接跟踪深度、抓取页面数量以及要包含的网址。",
27976
+ scrollRegionAriaLabel: "网络爬虫设置",
27912
27977
  formAriaLabel: "网络爬虫配置表单",
27913
27978
  urlRequired: "URL 为必填项",
27914
27979
  invalidUrl: "无效的 URL",
@@ -27923,6 +27988,9 @@ var resourceModalWebsiteCrawlModal = {
27923
27988
  selectPatternTypeAriaLabel: "选择模式类型",
27924
27989
  globPattern: "Glob 模式",
27925
27990
  regularExpression: "正则表达式",
27991
+ userAgentLabel: "User-Agent(可选)",
27992
+ userAgentPlaceholder: "Iblai-bot/1.0 (+https://ibl.ai/bot)",
27993
+ userAgentHelpText: "可选。为每个请求覆盖默认的抓取工具 User-Agent。留空则使用默认值。",
27926
27994
  crawlerMatchPatternsLabel: "爬虫匹配模式",
27927
27995
  globPlaceholder: "https://example.com/",
27928
27996
  regexPlaceholder: "(http|https)://www.example.com/(.*)",
@@ -145975,7 +146043,205 @@ const EmptyStats = ({ title = 'No data available' }) => {
145975
146043
  return (jsx("div", { className: "flex justify-center items-center h-full", children: jsx("p", { className: "text-gray-500 text-sm", children: title }) }));
145976
146044
  };
145977
146045
 
145978
- const COMPLETED_COLOR = '#ED8936';
146046
+ var COLLAPSIBLE_NAME = "Collapsible";
146047
+ var [createCollapsibleContext] = createContextScope$1(COLLAPSIBLE_NAME);
146048
+ var [CollapsibleProvider, useCollapsibleContext] = createCollapsibleContext(COLLAPSIBLE_NAME);
146049
+ var Collapsible$1 = React.forwardRef(
146050
+ (props, forwardedRef) => {
146051
+ const {
146052
+ __scopeCollapsible,
146053
+ open: openProp,
146054
+ defaultOpen,
146055
+ disabled,
146056
+ onOpenChange,
146057
+ ...collapsibleProps
146058
+ } = props;
146059
+ const [open, setOpen] = useControllableState$2({
146060
+ prop: openProp,
146061
+ defaultProp: defaultOpen ?? false,
146062
+ onChange: onOpenChange,
146063
+ caller: COLLAPSIBLE_NAME
146064
+ });
146065
+ return /* @__PURE__ */ jsx(
146066
+ CollapsibleProvider,
146067
+ {
146068
+ scope: __scopeCollapsible,
146069
+ disabled,
146070
+ contentId: useId$1(),
146071
+ open,
146072
+ onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
146073
+ children: /* @__PURE__ */ jsx(
146074
+ Primitive$4.div,
146075
+ {
146076
+ "data-state": getState$3(open),
146077
+ "data-disabled": disabled ? "" : void 0,
146078
+ ...collapsibleProps,
146079
+ ref: forwardedRef
146080
+ }
146081
+ )
146082
+ }
146083
+ );
146084
+ }
146085
+ );
146086
+ Collapsible$1.displayName = COLLAPSIBLE_NAME;
146087
+ var TRIGGER_NAME$3 = "CollapsibleTrigger";
146088
+ var CollapsibleTrigger$1 = React.forwardRef(
146089
+ (props, forwardedRef) => {
146090
+ const { __scopeCollapsible, ...triggerProps } = props;
146091
+ const context = useCollapsibleContext(TRIGGER_NAME$3, __scopeCollapsible);
146092
+ return /* @__PURE__ */ jsx(
146093
+ Primitive$4.button,
146094
+ {
146095
+ type: "button",
146096
+ "aria-controls": context.contentId,
146097
+ "aria-expanded": context.open || false,
146098
+ "data-state": getState$3(context.open),
146099
+ "data-disabled": context.disabled ? "" : void 0,
146100
+ disabled: context.disabled,
146101
+ ...triggerProps,
146102
+ ref: forwardedRef,
146103
+ onClick: composeEventHandlers$2(props.onClick, context.onOpenToggle)
146104
+ }
146105
+ );
146106
+ }
146107
+ );
146108
+ CollapsibleTrigger$1.displayName = TRIGGER_NAME$3;
146109
+ var CONTENT_NAME$4 = "CollapsibleContent";
146110
+ var CollapsibleContent$1 = React.forwardRef(
146111
+ (props, forwardedRef) => {
146112
+ const { forceMount, ...contentProps } = props;
146113
+ const context = useCollapsibleContext(CONTENT_NAME$4, props.__scopeCollapsible);
146114
+ return /* @__PURE__ */ jsx(Presence$2, { present: forceMount || context.open, children: ({ present }) => /* @__PURE__ */ jsx(CollapsibleContentImpl, { ...contentProps, ref: forwardedRef, present }) });
146115
+ }
146116
+ );
146117
+ CollapsibleContent$1.displayName = CONTENT_NAME$4;
146118
+ var CollapsibleContentImpl = React.forwardRef((props, forwardedRef) => {
146119
+ const { __scopeCollapsible, present, children, ...contentProps } = props;
146120
+ const context = useCollapsibleContext(CONTENT_NAME$4, __scopeCollapsible);
146121
+ const [isPresent, setIsPresent] = React.useState(present);
146122
+ const ref = React.useRef(null);
146123
+ const composedRefs = useComposedRefs$1(forwardedRef, ref);
146124
+ const heightRef = React.useRef(0);
146125
+ const height = heightRef.current;
146126
+ const widthRef = React.useRef(0);
146127
+ const width = widthRef.current;
146128
+ const isOpen = context.open || isPresent;
146129
+ const isMountAnimationPreventedRef = React.useRef(isOpen);
146130
+ const originalStylesRef = React.useRef(void 0);
146131
+ React.useEffect(() => {
146132
+ const rAF = requestAnimationFrame(() => isMountAnimationPreventedRef.current = false);
146133
+ return () => cancelAnimationFrame(rAF);
146134
+ }, []);
146135
+ useLayoutEffect2$1(() => {
146136
+ const node = ref.current;
146137
+ if (node) {
146138
+ originalStylesRef.current = originalStylesRef.current || {
146139
+ transitionDuration: node.style.transitionDuration,
146140
+ animationName: node.style.animationName
146141
+ };
146142
+ node.style.transitionDuration = "0s";
146143
+ node.style.animationName = "none";
146144
+ const rect = node.getBoundingClientRect();
146145
+ heightRef.current = rect.height;
146146
+ widthRef.current = rect.width;
146147
+ if (!isMountAnimationPreventedRef.current) {
146148
+ node.style.transitionDuration = originalStylesRef.current.transitionDuration;
146149
+ node.style.animationName = originalStylesRef.current.animationName;
146150
+ }
146151
+ setIsPresent(present);
146152
+ }
146153
+ }, [context.open, present]);
146154
+ return /* @__PURE__ */ jsx(
146155
+ Primitive$4.div,
146156
+ {
146157
+ "data-state": getState$3(context.open),
146158
+ "data-disabled": context.disabled ? "" : void 0,
146159
+ id: context.contentId,
146160
+ hidden: !isOpen,
146161
+ ...contentProps,
146162
+ ref: composedRefs,
146163
+ style: {
146164
+ [`--radix-collapsible-content-height`]: height ? `${height}px` : void 0,
146165
+ [`--radix-collapsible-content-width`]: width ? `${width}px` : void 0,
146166
+ ...props.style
146167
+ },
146168
+ children: isOpen && children
146169
+ }
146170
+ );
146171
+ });
146172
+ function getState$3(open) {
146173
+ return open ? "open" : "closed";
146174
+ }
146175
+ var Root$5 = Collapsible$1;
146176
+
146177
+ const Collapsible = Root$5;
146178
+ const CollapsibleTrigger = CollapsibleTrigger$1;
146179
+ const CollapsibleContent = CollapsibleContent$1;
146180
+
146181
+ const BAR_COLOR$1 = 'var(--color-amber-500, #f59e0b)';
146182
+ const ERROR_MESSAGES = {
146183
+ forbidden: 'Completion breakdown is not available for this learner.',
146184
+ not_enrolled: 'This learner is not enrolled in this course.',
146185
+ unavailable: 'Could not load the completion breakdown. Please try again later.',
146186
+ unauthorized: 'Completion breakdown is not available for this learner.',
146187
+ invalid_request: 'Completion breakdown is not available for this course.',
146188
+ unknown: 'Could not load the completion breakdown.',
146189
+ };
146190
+ // Backend values are already rounded to 2 decimals; show whole numbers
146191
+ // unless the value is fractional (e.g. 33.33).
146192
+ const formatPct = (value) => {
146193
+ const pct = value !== null && value !== void 0 ? value : 0;
146194
+ return `${Number.isInteger(pct) ? pct : pct.toFixed(2).replace(/\.?0+$/, '')}%`;
146195
+ };
146196
+ function CompletionBar({ value, label }) {
146197
+ const clamped = Math.min(Math.max(value, 0), 100);
146198
+ return (jsx("span", { className: "block h-1.5 w-full rounded-full bg-gray-200", role: "progressbar", "aria-label": label, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": clamped, children: jsx("span", { className: "block h-1.5 rounded-full", style: { width: `${clamped}%`, backgroundColor: BAR_COLOR$1 } }) }));
146199
+ }
146200
+ function SubsectionRow({ block }) {
146201
+ return (jsxs("li", { className: "space-y-1 py-2", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs("span", { className: "flex min-w-0 items-center gap-1.5 text-sm text-gray-700", children: [jsx("span", { className: "truncate", children: block.display_name }), block.special_exam_info ? (jsxs("span", { className: "inline-flex shrink-0 items-center gap-1 rounded-full bg-gray-100 px-2 py-0.5 text-[11px] text-gray-600", children: [jsx(Clock, { className: "h-3 w-3", "aria-hidden": "true" }), block.special_exam_info.short_description] })) : null] }), jsx("span", { className: "shrink-0 text-xs font-medium text-gray-600", children: formatPct(block.completion_percentage) })] }), jsx(CompletionBar, { value: block.completion_percentage, label: `${block.display_name} completion` })] }));
146202
+ }
146203
+ function SectionRow({ block }) {
146204
+ var _a;
146205
+ const [open, setOpen] = useState(false);
146206
+ const subsections = (_a = block.children) !== null && _a !== void 0 ? _a : [];
146207
+ return (jsx(Collapsible, { open: open, onOpenChange: setOpen, asChild: true, children: jsxs("li", { className: "py-2.5", children: [jsxs(CollapsibleTrigger, { className: "flex w-full items-center gap-2 rounded text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-amber-500 disabled:cursor-default", disabled: subsections.length === 0, children: [jsx(ChevronRight, { className: `h-4 w-4 shrink-0 text-gray-400 transition-transform ${open ? 'rotate-90' : ''} ${subsections.length === 0 ? 'invisible' : ''}`, "aria-hidden": "true" }), jsxs("span", { className: "block min-w-0 flex-1 space-y-1.5", children: [jsxs("span", { className: "flex items-center justify-between gap-3", children: [jsxs("span", { className: "flex min-w-0 items-center gap-1.5 text-sm font-medium text-gray-900", children: [jsx("span", { className: "truncate", children: block.display_name }), block.complete ? (jsx(CircleCheck, { className: "h-4 w-4 shrink-0 text-green-600", "aria-label": "Complete" })) : null] }), jsx("span", { className: "shrink-0 text-sm font-semibold text-gray-700", children: formatPct(block.completion_percentage) })] }), jsx(CompletionBar, { value: block.completion_percentage, label: `${block.display_name} completion` })] })] }), subsections.length > 0 ? (jsx(CollapsibleContent, { children: jsx("ul", { className: "ml-6 mt-1 divide-y divide-gray-100", children: subsections.map((subsection) => (jsx(SubsectionRow, { block: subsection }, subsection.id))) }) })) : null] }) }));
146208
+ }
146209
+ /**
146210
+ * Per-section completion for one learner in one course, from the DM
146211
+ * completion outline. Percentages come from the backend as-is.
146212
+ */
146213
+ function CourseCompletionBreakdown({ username, courseId, tenantKey, skip = false, }) {
146214
+ const { data, error, isLoading, isFetching, refetch } = useGetLearnerCourseOutlineQuery({ username, course_id: courseId, platform_key: tenantKey }, { skip: skip || !username || !courseId || !tenantKey });
146215
+ const sections = useMemo(() => (data ? getSections(data) : []), [data]);
146216
+ const resumePath = useMemo(() => {
146217
+ if (!data)
146218
+ return null;
146219
+ const resume = findResumeBlock(data);
146220
+ if (!resume || resume.id === data.id)
146221
+ return null;
146222
+ const entry = flattenOutline(data).find(({ block }) => block.id === resume.id);
146223
+ // Drop the course name; the modal header already shows it.
146224
+ return entry ? entry.path.slice(1).join(' › ') : null;
146225
+ }, [data]);
146226
+ const normalizedError = normalizeLearnerCompletionError(error);
146227
+ let body;
146228
+ if (isLoading || (isFetching && !data)) {
146229
+ body = jsx("p", { className: "py-4 text-sm text-gray-500", children: "Loading completion breakdown..." });
146230
+ }
146231
+ else if (normalizedError) {
146232
+ body = (jsxs("div", { className: "flex items-center justify-between gap-3 py-2", children: [jsx("p", { className: "text-sm text-gray-500", children: ERROR_MESSAGES[normalizedError.kind] }), normalizedError.retryable ? (jsx(Button$1, { variant: "outline", size: "sm", onClick: () => refetch(), disabled: isFetching, children: "Retry" })) : null] }));
146233
+ }
146234
+ else if (sections.length === 0) {
146235
+ body = jsx("p", { className: "py-2 text-sm text-gray-500", children: "No sections in this course yet." });
146236
+ }
146237
+ else {
146238
+ body = (jsxs(Fragment$1, { children: [resumePath ? (jsxs("p", { className: "text-xs text-gray-500", children: ["Last visited: ", jsx("span", { className: "font-medium text-gray-700", children: resumePath })] })) : null, jsx("ul", { className: "divide-y divide-[oklch(0.922_0_0)]", children: sections.map((section) => (jsx(SectionRow, { block: section.block }, section.id))) })] }));
146239
+ }
146240
+ return (jsxs("section", { className: "space-y-2 rounded-lg border p-4", style: { borderColor: 'oklch(.922 0 0)' }, "aria-labelledby": "completion-breakdown-heading", children: [jsxs("div", { children: [jsx("h4", { id: "completion-breakdown-heading", className: "text-sm font-semibold text-gray-900", children: "Completion breakdown" }), jsx("p", { className: "text-xs text-gray-500", children: "Progress through each section of this course." })] }), body] }));
146241
+ }
146242
+
146243
+ // Theme token (the same one bg-amber-500 resolves to), with Tailwind's default as fallback.
146244
+ const COMPLETED_COLOR = 'var(--color-amber-500, #f59e0b)';
145979
146245
  const REMAINING_COLOR = '#E5E7EB';
145980
146246
  const formatDate$2 = (value) => {
145981
146247
  if (!value)
@@ -146081,7 +146347,7 @@ function EnrolledUserProgressModal({ open, onOpenChange, username, userName, ema
146081
146347
  const passingPct = getPassingPct((_h = (_g = item === null || item === void 0 ? void 0 : item.edx_progress) === null || _g === void 0 ? void 0 : _g.grading_policy) === null || _h === void 0 ? void 0 : _h.grade_range);
146082
146348
  return (jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: jsxs(DialogContent, { className: "max-w-2xl max-h-[85vh] overflow-y-auto", "aria-label": "Enrolled user progress", children: [jsxs(DialogHeader, { children: [jsx(DialogTitle, { children: userName || username || 'Learner progress' }), jsxs(DialogDescription, { children: [email ? `${email} · ` : '', resolvedName || (isProgram ? 'Program progress' : 'Course progress')] })] }), loading ? (jsx("div", { className: "flex items-center justify-center py-12", children: jsx("div", { className: "text-sm text-gray-500", children: "Loading..." }) })) : !item ? (jsx(EmptyStats, { title: "No progress data available" })) : (jsxs("div", { className: "space-y-6", children: [jsxs("div", { className: "relative mx-auto", style: { width: 220, height: 220 }, children: [jsx(ResponsiveContainer, { width: "100%", height: "100%", children: jsx(PieChart, { children: jsxs(Pie, { data: pieData, dataKey: "value", cx: "50%", cy: "50%", innerRadius: 75, outerRadius: 100, startAngle: 90, endAngle: -270, stroke: "none", isAnimationActive: false, children: [jsx(Cell, { fill: COMPLETED_COLOR }), jsx(Cell, { fill: REMAINING_COLOR })] }) }) }), jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center pointer-events-none", children: [jsxs("span", { className: "text-3xl font-bold text-gray-700", children: [percentage, "%"] }), jsx("span", { className: "text-sm text-gray-500", children: "completed" })] })] }), jsxs("div", { className: "divide-y divide-[oklch(0.922_0_0)]", children: [jsx(DetailRow$1, { label: "Status", children: jsx("span", { className: `inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${((_j = item.completion) === null || _j === void 0 ? void 0 : _j.passed)
146083
146349
  ? 'bg-green-50 text-green-700'
146084
- : 'bg-gray-100 text-gray-600'}`, children: ((_k = item.completion) === null || _k === void 0 ? void 0 : _k.passed) ? 'Passed' : 'Not passed' }) }), jsx(DetailRow$1, { label: "Passed on", children: formatDate$2((_l = item.completion) === null || _l === void 0 ? void 0 : _l.passed_date) }), jsx(DetailRow$1, { label: "Time spent", children: item.time_spent || '—' }), jsx(DetailRow$1, { label: "Enrollment date", children: formatDate$2((_o = (_m = item.enrollment) === null || _m === void 0 ? void 0 : _m.started) !== null && _o !== void 0 ? _o : (_p = item.enrollment) === null || _p === void 0 ? void 0 : _p.created) })] }), ((_s = (_r = (_q = item.edx_progress) === null || _q === void 0 ? void 0 : _q.grading_policy) === null || _r === void 0 ? void 0 : _r.assignment_policies) === null || _s === void 0 ? void 0 : _s.length) ? (jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "rounded-lg border p-4", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx("h4", { className: "text-sm font-semibold text-gray-900", children: "Grades" }), jsx("p", { className: "text-xs text-gray-500", children: "This represents the weighted grade against the grade needed to pass this course." }), jsx(GradeBar, { currentPct: currentGradePct, passingPct: passingPct })] }), jsxs("div", { className: "flex items-start gap-2 rounded-md border border-amber-200 bg-amber-50 px-4 py-3", children: [jsx(TriangleAlert, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-600" }), jsxs("span", { className: "text-sm font-medium text-gray-800", children: ["A weighted grade of ", passingPct, "% is required to pass in this course"] })] }), jsxs("div", { className: "rounded-lg border p-4 space-y-3", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx("h4", { className: "text-sm font-semibold text-gray-900", children: "Grade summary" }), jsx("div", { className: "overflow-x-auto", children: jsxs("table", { className: "w-full border-collapse text-sm", children: [jsx("thead", { children: jsxs("tr", { className: "bg-amber-50 text-[11px] uppercase tracking-wide text-gray-600", children: [jsx("th", { className: "px-3 py-2 text-left font-medium", children: "Assignment type" }), jsx("th", { className: "px-3 py-2 text-right font-medium", children: "Weight" }), jsx("th", { className: "px-3 py-2 text-right font-medium", children: "Grade" }), jsx("th", { className: "px-3 py-2 text-right font-medium", children: "Weighted grade" })] }) }), jsxs("tbody", { children: [gradeSummary === null || gradeSummary === void 0 ? void 0 : gradeSummary.rows.map((row, index) => (jsxs("tr", { className: index % 2 === 0 ? '' : 'bg-gray-50', children: [jsxs("td", { className: "px-3 py-2 text-gray-800", children: [row.type, row.footnote ? (jsx("sup", { className: "ml-0.5 text-amber-500", children: row.footnote })) : null] }), jsxs("td", { className: "px-3 py-2 text-right text-gray-700", children: [row.weightPct, "%"] }), jsxs("td", { className: "px-3 py-2 text-right text-gray-700", children: [row.gradePct, "%"] }), jsxs("td", { className: "px-3 py-2 text-right font-semibold text-amber-600", children: [row.weightedGradePct, "%"] })] }, row.type))), jsxs("tr", { className: "border-l-2 border-amber-400 bg-amber-50", children: [jsx("td", { className: "px-3 py-2 font-medium text-gray-800", colSpan: 3, children: "Current weighted grade summary" }), jsxs("td", { className: "px-3 py-2 text-right font-bold text-amber-600", children: [currentGradePct, "%"] })] })] })] }) }), gradeSummary && gradeSummary.footnotes.length > 0 ? (jsx("div", { className: "space-y-1", children: gradeSummary.footnotes.map((note, index) => (jsxs("p", { className: "text-xs text-gray-500", children: [jsx("sup", { className: "text-amber-500", children: index + 1 }), " ", note] }, note))) })) : null] })] })) : null] }))] }) }));
146350
+ : 'bg-gray-100 text-gray-600'}`, children: ((_k = item.completion) === null || _k === void 0 ? void 0 : _k.passed) ? 'Passed' : 'Not passed' }) }), jsx(DetailRow$1, { label: "Passed on", children: formatDate$2((_l = item.completion) === null || _l === void 0 ? void 0 : _l.passed_date) }), jsx(DetailRow$1, { label: "Time spent", children: item.time_spent || '—' }), jsx(DetailRow$1, { label: "Enrollment date", children: formatDate$2((_o = (_m = item.enrollment) === null || _m === void 0 ? void 0 : _m.started) !== null && _o !== void 0 ? _o : (_p = item.enrollment) === null || _p === void 0 ? void 0 : _p.created) })] }), !isProgram ? (jsx(CourseCompletionBreakdown, { username: username, courseId: normalizedId, tenantKey: tenantKey, skip: !open })) : null, ((_s = (_r = (_q = item.edx_progress) === null || _q === void 0 ? void 0 : _q.grading_policy) === null || _r === void 0 ? void 0 : _r.assignment_policies) === null || _s === void 0 ? void 0 : _s.length) ? (jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "rounded-lg border p-4", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx("h4", { className: "text-sm font-semibold text-gray-900", children: "Grades" }), jsx("p", { className: "text-xs text-gray-500", children: "This represents the weighted grade against the grade needed to pass this course." }), jsx(GradeBar, { currentPct: currentGradePct, passingPct: passingPct })] }), jsxs("div", { className: "flex items-start gap-2 rounded-md border border-amber-200 bg-amber-50 px-4 py-3", children: [jsx(TriangleAlert, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-600" }), jsxs("span", { className: "text-sm font-medium text-gray-800", children: ["A weighted grade of ", passingPct, "% is required to pass in this course"] })] }), jsxs("div", { className: "rounded-lg border p-4 space-y-3", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx("h4", { className: "text-sm font-semibold text-gray-900", children: "Grade summary" }), jsx("div", { className: "overflow-x-auto", children: jsxs("table", { className: "w-full border-collapse text-sm", children: [jsx("thead", { children: jsxs("tr", { className: "bg-amber-50 text-[11px] uppercase tracking-wide text-gray-600", children: [jsx("th", { className: "px-3 py-2 text-left font-medium", children: "Assignment type" }), jsx("th", { className: "px-3 py-2 text-right font-medium", children: "Weight" }), jsx("th", { className: "px-3 py-2 text-right font-medium", children: "Grade" }), jsx("th", { className: "px-3 py-2 text-right font-medium", children: "Weighted grade" })] }) }), jsxs("tbody", { children: [gradeSummary === null || gradeSummary === void 0 ? void 0 : gradeSummary.rows.map((row, index) => (jsxs("tr", { className: index % 2 === 0 ? '' : 'bg-gray-50', children: [jsxs("td", { className: "px-3 py-2 text-gray-800", children: [row.type, row.footnote ? (jsx("sup", { className: "ml-0.5 text-amber-500", children: row.footnote })) : null] }), jsxs("td", { className: "px-3 py-2 text-right text-gray-700", children: [row.weightPct, "%"] }), jsxs("td", { className: "px-3 py-2 text-right text-gray-700", children: [row.gradePct, "%"] }), jsxs("td", { className: "px-3 py-2 text-right font-semibold text-amber-600", children: [row.weightedGradePct, "%"] })] }, row.type))), jsxs("tr", { className: "border-l-2 border-amber-400 bg-amber-50", children: [jsx("td", { className: "px-3 py-2 font-medium text-gray-800", colSpan: 3, children: "Current weighted grade summary" }), jsxs("td", { className: "px-3 py-2 text-right font-bold text-amber-600", children: [currentGradePct, "%"] })] })] })] }) }), gradeSummary && gradeSummary.footnotes.length > 0 ? (jsx("div", { className: "space-y-1", children: gradeSummary.footnotes.map((note, index) => (jsxs("p", { className: "text-xs text-gray-500", children: [jsx("sup", { className: "text-amber-500", children: index + 1 }), " ", note] }, note))) })) : null] })] })) : null] }))] }) }));
146085
146351
  }
146086
146352
  function DetailRow$1({ label, children }) {
146087
146353
  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 })] }));
@@ -146497,20 +146763,20 @@ var MenuPortal = (props) => {
146497
146763
  return /* @__PURE__ */ jsx(PortalProvider$1, { scope: __scopeMenu, forceMount, children: /* @__PURE__ */ jsx(Presence$1, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Portal$6, { asChild: true, container, children }) }) });
146498
146764
  };
146499
146765
  MenuPortal.displayName = PORTAL_NAME$3;
146500
- var CONTENT_NAME$4 = "MenuContent";
146501
- var [MenuContentProvider, useMenuContentContext] = createMenuContext(CONTENT_NAME$4);
146766
+ var CONTENT_NAME$3 = "MenuContent";
146767
+ var [MenuContentProvider, useMenuContentContext] = createMenuContext(CONTENT_NAME$3);
146502
146768
  var MenuContent = React.forwardRef(
146503
146769
  (props, forwardedRef) => {
146504
- const portalContext = usePortalContext$1(CONTENT_NAME$4, props.__scopeMenu);
146770
+ const portalContext = usePortalContext$1(CONTENT_NAME$3, props.__scopeMenu);
146505
146771
  const { forceMount = portalContext.forceMount, ...contentProps } = props;
146506
- const context = useMenuContext(CONTENT_NAME$4, props.__scopeMenu);
146507
- const rootContext = useMenuRootContext(CONTENT_NAME$4, props.__scopeMenu);
146772
+ const context = useMenuContext(CONTENT_NAME$3, props.__scopeMenu);
146773
+ const rootContext = useMenuRootContext(CONTENT_NAME$3, props.__scopeMenu);
146508
146774
  return /* @__PURE__ */ jsx(Collection$1.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx(Presence$1, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Collection$1.Slot, { scope: props.__scopeMenu, children: rootContext.modal ? /* @__PURE__ */ jsx(MenuRootContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(MenuRootContentNonModal, { ...contentProps, ref: forwardedRef }) }) }) });
146509
146775
  }
146510
146776
  );
146511
146777
  var MenuRootContentModal = React.forwardRef(
146512
146778
  (props, forwardedRef) => {
146513
- const context = useMenuContext(CONTENT_NAME$4, props.__scopeMenu);
146779
+ const context = useMenuContext(CONTENT_NAME$3, props.__scopeMenu);
146514
146780
  const ref = React.useRef(null);
146515
146781
  const composedRefs = useComposedRefs$1(forwardedRef, ref);
146516
146782
  React.useEffect(() => {
@@ -146536,7 +146802,7 @@ var MenuRootContentModal = React.forwardRef(
146536
146802
  }
146537
146803
  );
146538
146804
  var MenuRootContentNonModal = React.forwardRef((props, forwardedRef) => {
146539
- const context = useMenuContext(CONTENT_NAME$4, props.__scopeMenu);
146805
+ const context = useMenuContext(CONTENT_NAME$3, props.__scopeMenu);
146540
146806
  return /* @__PURE__ */ jsx(
146541
146807
  MenuContentImpl,
146542
146808
  {
@@ -146568,8 +146834,8 @@ var MenuContentImpl = React.forwardRef(
146568
146834
  disableOutsideScroll,
146569
146835
  ...contentProps
146570
146836
  } = props;
146571
- const context = useMenuContext(CONTENT_NAME$4, __scopeMenu);
146572
- const rootContext = useMenuRootContext(CONTENT_NAME$4, __scopeMenu);
146837
+ const context = useMenuContext(CONTENT_NAME$3, __scopeMenu);
146838
+ const rootContext = useMenuRootContext(CONTENT_NAME$3, __scopeMenu);
146573
146839
  const popperScope = usePopperScope$1(__scopeMenu);
146574
146840
  const rovingFocusGroupScope = useRovingFocusGroupScope$1(__scopeMenu);
146575
146841
  const getItems = useCollection$1(__scopeMenu);
@@ -146732,7 +146998,7 @@ var MenuContentImpl = React.forwardRef(
146732
146998
  );
146733
146999
  }
146734
147000
  );
146735
- MenuContent.displayName = CONTENT_NAME$4;
147001
+ MenuContent.displayName = CONTENT_NAME$3;
146736
147002
  var GROUP_NAME$2 = "MenuGroup";
146737
147003
  var MenuGroup = React.forwardRef(
146738
147004
  (props, forwardedRef) => {
@@ -147106,10 +147372,10 @@ MenuSubTrigger.displayName = SUB_TRIGGER_NAME$1;
147106
147372
  var SUB_CONTENT_NAME$1 = "MenuSubContent";
147107
147373
  var MenuSubContent = React.forwardRef(
147108
147374
  (props, forwardedRef) => {
147109
- const portalContext = usePortalContext$1(CONTENT_NAME$4, props.__scopeMenu);
147375
+ const portalContext = usePortalContext$1(CONTENT_NAME$3, props.__scopeMenu);
147110
147376
  const { forceMount = portalContext.forceMount, ...subContentProps } = props;
147111
- const context = useMenuContext(CONTENT_NAME$4, props.__scopeMenu);
147112
- const rootContext = useMenuRootContext(CONTENT_NAME$4, props.__scopeMenu);
147377
+ const context = useMenuContext(CONTENT_NAME$3, props.__scopeMenu);
147378
+ const rootContext = useMenuRootContext(CONTENT_NAME$3, props.__scopeMenu);
147113
147379
  const subContext = useMenuSubContext(SUB_CONTENT_NAME$1, props.__scopeMenu);
147114
147380
  const ref = React.useRef(null);
147115
147381
  const composedRefs = useComposedRefs$1(forwardedRef, ref);
@@ -147261,11 +147527,11 @@ var DropdownMenu$1 = (props) => {
147261
147527
  );
147262
147528
  };
147263
147529
  DropdownMenu$1.displayName = DROPDOWN_MENU_NAME;
147264
- var TRIGGER_NAME$3 = "DropdownMenuTrigger";
147530
+ var TRIGGER_NAME$2 = "DropdownMenuTrigger";
147265
147531
  var DropdownMenuTrigger$1 = React.forwardRef(
147266
147532
  (props, forwardedRef) => {
147267
147533
  const { __scopeDropdownMenu, disabled = false, ...triggerProps } = props;
147268
- const context = useDropdownMenuContext(TRIGGER_NAME$3, __scopeDropdownMenu);
147534
+ const context = useDropdownMenuContext(TRIGGER_NAME$2, __scopeDropdownMenu);
147269
147535
  const menuScope = useMenuScope(__scopeDropdownMenu);
147270
147536
  return /* @__PURE__ */ jsx(Anchor2$1, { asChild: true, ...menuScope, children: /* @__PURE__ */ jsx(
147271
147537
  Primitive$3.button,
@@ -147296,7 +147562,7 @@ var DropdownMenuTrigger$1 = React.forwardRef(
147296
147562
  ) });
147297
147563
  }
147298
147564
  );
147299
- DropdownMenuTrigger$1.displayName = TRIGGER_NAME$3;
147565
+ DropdownMenuTrigger$1.displayName = TRIGGER_NAME$2;
147300
147566
  var PORTAL_NAME$2 = "DropdownMenuPortal";
147301
147567
  var DropdownMenuPortal$1 = (props) => {
147302
147568
  const { __scopeDropdownMenu, ...portalProps } = props;
@@ -147304,11 +147570,11 @@ var DropdownMenuPortal$1 = (props) => {
147304
147570
  return /* @__PURE__ */ jsx(Portal$1, { ...menuScope, ...portalProps });
147305
147571
  };
147306
147572
  DropdownMenuPortal$1.displayName = PORTAL_NAME$2;
147307
- var CONTENT_NAME$3 = "DropdownMenuContent";
147573
+ var CONTENT_NAME$2 = "DropdownMenuContent";
147308
147574
  var DropdownMenuContent$1 = React.forwardRef(
147309
147575
  (props, forwardedRef) => {
147310
147576
  const { __scopeDropdownMenu, ...contentProps } = props;
147311
- const context = useDropdownMenuContext(CONTENT_NAME$3, __scopeDropdownMenu);
147577
+ const context = useDropdownMenuContext(CONTENT_NAME$2, __scopeDropdownMenu);
147312
147578
  const menuScope = useMenuScope(__scopeDropdownMenu);
147313
147579
  const hasInteractedOutsideRef = React.useRef(false);
147314
147580
  return /* @__PURE__ */ jsx(
@@ -147345,7 +147611,7 @@ var DropdownMenuContent$1 = React.forwardRef(
147345
147611
  );
147346
147612
  }
147347
147613
  );
147348
- DropdownMenuContent$1.displayName = CONTENT_NAME$3;
147614
+ DropdownMenuContent$1.displayName = CONTENT_NAME$2;
147349
147615
  var GROUP_NAME$1 = "DropdownMenuGroup";
147350
147616
  var DropdownMenuGroup$1 = React.forwardRef(
147351
147617
  (props, forwardedRef) => {
@@ -149455,7 +149721,7 @@ function PreviousMonthButton(props) {
149455
149721
  * @group Components
149456
149722
  * @see https://daypicker.dev/guides/custom-components
149457
149723
  */
149458
- function Root$5(props) {
149724
+ function Root$4(props) {
149459
149725
  const { rootRef, ...rest } = props;
149460
149726
  return React__default.createElement("div", { ...rest, ref: rootRef });
149461
149727
  }
@@ -149563,7 +149829,7 @@ var components$1 = /*#__PURE__*/Object.freeze({
149563
149829
  NextMonthButton: NextMonthButton,
149564
149830
  Option: Option,
149565
149831
  PreviousMonthButton: PreviousMonthButton,
149566
- Root: Root$5,
149832
+ Root: Root$4,
149567
149833
  Select: Select,
149568
149834
  Week: Week,
149569
149835
  WeekNumber: WeekNumber,
@@ -151633,11 +151899,11 @@ var PopoverAnchor$1 = React.forwardRef(
151633
151899
  }
151634
151900
  );
151635
151901
  PopoverAnchor$1.displayName = ANCHOR_NAME;
151636
- var TRIGGER_NAME$2 = "PopoverTrigger";
151902
+ var TRIGGER_NAME$1 = "PopoverTrigger";
151637
151903
  var PopoverTrigger$1 = React.forwardRef(
151638
151904
  (props, forwardedRef) => {
151639
151905
  const { __scopePopover, ...triggerProps } = props;
151640
- const context = usePopoverContext(TRIGGER_NAME$2, __scopePopover);
151906
+ const context = usePopoverContext(TRIGGER_NAME$1, __scopePopover);
151641
151907
  const popperScope = usePopperScope(__scopePopover);
151642
151908
  const composedTriggerRef = useComposedRefs$1(forwardedRef, context.triggerRef);
151643
151909
  const trigger = /* @__PURE__ */ jsx(
@@ -151647,7 +151913,7 @@ var PopoverTrigger$1 = React.forwardRef(
151647
151913
  "aria-haspopup": "dialog",
151648
151914
  "aria-expanded": context.open,
151649
151915
  "aria-controls": context.contentId,
151650
- "data-state": getState$3(context.open),
151916
+ "data-state": getState$2(context.open),
151651
151917
  ...triggerProps,
151652
151918
  ref: composedTriggerRef,
151653
151919
  onClick: composeEventHandlers$1(props.onClick, context.onOpenToggle)
@@ -151656,7 +151922,7 @@ var PopoverTrigger$1 = React.forwardRef(
151656
151922
  return context.hasCustomAnchor ? trigger : /* @__PURE__ */ jsx(Anchor$1, { asChild: true, ...popperScope, children: trigger });
151657
151923
  }
151658
151924
  );
151659
- PopoverTrigger$1.displayName = TRIGGER_NAME$2;
151925
+ PopoverTrigger$1.displayName = TRIGGER_NAME$1;
151660
151926
  var PORTAL_NAME$1 = "PopoverPortal";
151661
151927
  var [PortalProvider, usePortalContext] = createPopoverContext(PORTAL_NAME$1, {
151662
151928
  forceMount: void 0
@@ -151667,20 +151933,20 @@ var PopoverPortal = (props) => {
151667
151933
  return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopePopover, forceMount, children: /* @__PURE__ */ jsx(Presence$1, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Portal$6, { asChild: true, container, children }) }) });
151668
151934
  };
151669
151935
  PopoverPortal.displayName = PORTAL_NAME$1;
151670
- var CONTENT_NAME$2 = "PopoverContent";
151936
+ var CONTENT_NAME$1 = "PopoverContent";
151671
151937
  var PopoverContent$1 = React.forwardRef(
151672
151938
  (props, forwardedRef) => {
151673
- const portalContext = usePortalContext(CONTENT_NAME$2, props.__scopePopover);
151939
+ const portalContext = usePortalContext(CONTENT_NAME$1, props.__scopePopover);
151674
151940
  const { forceMount = portalContext.forceMount, ...contentProps } = props;
151675
- const context = usePopoverContext(CONTENT_NAME$2, props.__scopePopover);
151941
+ const context = usePopoverContext(CONTENT_NAME$1, props.__scopePopover);
151676
151942
  return /* @__PURE__ */ jsx(Presence$1, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(PopoverContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(PopoverContentNonModal, { ...contentProps, ref: forwardedRef }) });
151677
151943
  }
151678
151944
  );
151679
- PopoverContent$1.displayName = CONTENT_NAME$2;
151945
+ PopoverContent$1.displayName = CONTENT_NAME$1;
151680
151946
  var Slot = createSlot("PopoverContent.RemoveScroll");
151681
151947
  var PopoverContentModal = React.forwardRef(
151682
151948
  (props, forwardedRef) => {
151683
- const context = usePopoverContext(CONTENT_NAME$2, props.__scopePopover);
151949
+ const context = usePopoverContext(CONTENT_NAME$1, props.__scopePopover);
151684
151950
  const contentRef = React.useRef(null);
151685
151951
  const composedRefs = useComposedRefs$1(forwardedRef, contentRef);
151686
151952
  const isRightClickOutsideRef = React.useRef(false);
@@ -151720,7 +151986,7 @@ var PopoverContentModal = React.forwardRef(
151720
151986
  );
151721
151987
  var PopoverContentNonModal = React.forwardRef(
151722
151988
  (props, forwardedRef) => {
151723
- const context = usePopoverContext(CONTENT_NAME$2, props.__scopePopover);
151989
+ const context = usePopoverContext(CONTENT_NAME$1, props.__scopePopover);
151724
151990
  const hasInteractedOutsideRef = React.useRef(false);
151725
151991
  const hasPointerDownOutsideRef = React.useRef(false);
151726
151992
  return /* @__PURE__ */ jsx(
@@ -151772,7 +152038,7 @@ var PopoverContentImpl = React.forwardRef(
151772
152038
  onInteractOutside,
151773
152039
  ...contentProps
151774
152040
  } = props;
151775
- const context = usePopoverContext(CONTENT_NAME$2, __scopePopover);
152041
+ const context = usePopoverContext(CONTENT_NAME$1, __scopePopover);
151776
152042
  const popperScope = usePopperScope(__scopePopover);
151777
152043
  useFocusGuards();
151778
152044
  return /* @__PURE__ */ jsx(
@@ -151796,7 +152062,7 @@ var PopoverContentImpl = React.forwardRef(
151796
152062
  children: /* @__PURE__ */ jsx(
151797
152063
  Content$2,
151798
152064
  {
151799
- "data-state": getState$3(context.open),
152065
+ "data-state": getState$2(context.open),
151800
152066
  role: "dialog",
151801
152067
  id: context.contentId,
151802
152068
  ...popperScope,
@@ -151847,7 +152113,7 @@ var PopoverArrow = React.forwardRef(
151847
152113
  }
151848
152114
  );
151849
152115
  PopoverArrow.displayName = ARROW_NAME;
151850
- function getState$3(open) {
152116
+ function getState$2(open) {
151851
152117
  return open ? "open" : "closed";
151852
152118
  }
151853
152119
  var Root2$2 = Popover$1;
@@ -188555,7 +188821,7 @@ var Checkbox$1 = React.forwardRef(
188555
188821
  role: "checkbox",
188556
188822
  "aria-checked": isIndeterminate(checked) ? "mixed" : checked,
188557
188823
  "aria-required": required,
188558
- "data-state": getState$2(checked),
188824
+ "data-state": getState$1(checked),
188559
188825
  "data-disabled": disabled ? "" : void 0,
188560
188826
  disabled,
188561
188827
  value,
@@ -188600,7 +188866,7 @@ var CheckboxIndicator = React.forwardRef(
188600
188866
  return /* @__PURE__ */ jsx(Presence$3, { present: forceMount || isIndeterminate(context.state) || context.state === true, children: /* @__PURE__ */ jsx(
188601
188867
  Primitive$2.span,
188602
188868
  {
188603
- "data-state": getState$2(context.state),
188869
+ "data-state": getState$1(context.state),
188604
188870
  "data-disabled": context.disabled ? "" : void 0,
188605
188871
  ...indicatorProps,
188606
188872
  ref: forwardedRef,
@@ -188666,14 +188932,14 @@ CheckboxBubbleInput.displayName = BUBBLE_INPUT_NAME;
188666
188932
  function isIndeterminate(checked) {
188667
188933
  return checked === "indeterminate";
188668
188934
  }
188669
- function getState$2(checked) {
188935
+ function getState$1(checked) {
188670
188936
  return isIndeterminate(checked) ? "indeterminate" : checked ? "checked" : "unchecked";
188671
188937
  }
188672
- var Root$4 = Checkbox$1;
188938
+ var Root$3 = Checkbox$1;
188673
188939
  var Indicator$1 = CheckboxIndicator;
188674
188940
 
188675
- const Checkbox = React.forwardRef(({ className, ...props }, ref) => (jsx(Root$4, { ref: ref, className: cn("peer border-primary focus-visible:ring-ring h-4 w-4 shrink-0 rounded-sm border shadow-sm focus-visible:ring-1 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-blue-500 data-[state=checked]:text-white", className), ...props, children: jsx(Indicator$1, { className: cn("flex items-center justify-center text-current"), children: jsx(Check, { className: "h-4 w-4" }) }) })));
188676
- Checkbox.displayName = Root$4.displayName;
188941
+ const Checkbox = React.forwardRef(({ className, ...props }, ref) => (jsx(Root$3, { ref: ref, className: cn("peer border-primary focus-visible:ring-ring h-4 w-4 shrink-0 rounded-sm border shadow-sm focus-visible:ring-1 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-blue-500 data-[state=checked]:text-white", className), ...props, children: jsx(Indicator$1, { className: cn("flex items-center justify-center text-current"), children: jsx(Check, { className: "h-4 w-4" }) }) })));
188942
+ Checkbox.displayName = Root$3.displayName;
188677
188943
 
188678
188944
  function CoursesTab({ tenant, currentPage, itemsPerPage, hasManageUsersPermission = false, }) {
188679
188945
  var _a;
@@ -189647,141 +189913,6 @@ function RetrievedDocumentsButton({ sessionId = '', documents, className, label,
189647
189913
  }, "data-testid": "retrieved-documents-button", children: [jsx(FileText, { className: "h-4 w-4 text-blue-600" }), jsx("span", { children: label !== null && label !== void 0 ? label : 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 border-gray-200 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: "min-h-0 flex-1 overflow-y-auto", "data-testid": "retrieved-documents-scroll", children: jsx(DocumentSidebar, { isModal: true, sessionId: sessionId, documents: documents }) })] }) })] }));
189648
189914
  }
189649
189915
 
189650
- var COLLAPSIBLE_NAME = "Collapsible";
189651
- var [createCollapsibleContext] = createContextScope$1(COLLAPSIBLE_NAME);
189652
- var [CollapsibleProvider, useCollapsibleContext] = createCollapsibleContext(COLLAPSIBLE_NAME);
189653
- var Collapsible$1 = React.forwardRef(
189654
- (props, forwardedRef) => {
189655
- const {
189656
- __scopeCollapsible,
189657
- open: openProp,
189658
- defaultOpen,
189659
- disabled,
189660
- onOpenChange,
189661
- ...collapsibleProps
189662
- } = props;
189663
- const [open, setOpen] = useControllableState$2({
189664
- prop: openProp,
189665
- defaultProp: defaultOpen ?? false,
189666
- onChange: onOpenChange,
189667
- caller: COLLAPSIBLE_NAME
189668
- });
189669
- return /* @__PURE__ */ jsx(
189670
- CollapsibleProvider,
189671
- {
189672
- scope: __scopeCollapsible,
189673
- disabled,
189674
- contentId: useId$1(),
189675
- open,
189676
- onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
189677
- children: /* @__PURE__ */ jsx(
189678
- Primitive$4.div,
189679
- {
189680
- "data-state": getState$1(open),
189681
- "data-disabled": disabled ? "" : void 0,
189682
- ...collapsibleProps,
189683
- ref: forwardedRef
189684
- }
189685
- )
189686
- }
189687
- );
189688
- }
189689
- );
189690
- Collapsible$1.displayName = COLLAPSIBLE_NAME;
189691
- var TRIGGER_NAME$1 = "CollapsibleTrigger";
189692
- var CollapsibleTrigger$1 = React.forwardRef(
189693
- (props, forwardedRef) => {
189694
- const { __scopeCollapsible, ...triggerProps } = props;
189695
- const context = useCollapsibleContext(TRIGGER_NAME$1, __scopeCollapsible);
189696
- return /* @__PURE__ */ jsx(
189697
- Primitive$4.button,
189698
- {
189699
- type: "button",
189700
- "aria-controls": context.contentId,
189701
- "aria-expanded": context.open || false,
189702
- "data-state": getState$1(context.open),
189703
- "data-disabled": context.disabled ? "" : void 0,
189704
- disabled: context.disabled,
189705
- ...triggerProps,
189706
- ref: forwardedRef,
189707
- onClick: composeEventHandlers$2(props.onClick, context.onOpenToggle)
189708
- }
189709
- );
189710
- }
189711
- );
189712
- CollapsibleTrigger$1.displayName = TRIGGER_NAME$1;
189713
- var CONTENT_NAME$1 = "CollapsibleContent";
189714
- var CollapsibleContent$1 = React.forwardRef(
189715
- (props, forwardedRef) => {
189716
- const { forceMount, ...contentProps } = props;
189717
- const context = useCollapsibleContext(CONTENT_NAME$1, props.__scopeCollapsible);
189718
- return /* @__PURE__ */ jsx(Presence$2, { present: forceMount || context.open, children: ({ present }) => /* @__PURE__ */ jsx(CollapsibleContentImpl, { ...contentProps, ref: forwardedRef, present }) });
189719
- }
189720
- );
189721
- CollapsibleContent$1.displayName = CONTENT_NAME$1;
189722
- var CollapsibleContentImpl = React.forwardRef((props, forwardedRef) => {
189723
- const { __scopeCollapsible, present, children, ...contentProps } = props;
189724
- const context = useCollapsibleContext(CONTENT_NAME$1, __scopeCollapsible);
189725
- const [isPresent, setIsPresent] = React.useState(present);
189726
- const ref = React.useRef(null);
189727
- const composedRefs = useComposedRefs$1(forwardedRef, ref);
189728
- const heightRef = React.useRef(0);
189729
- const height = heightRef.current;
189730
- const widthRef = React.useRef(0);
189731
- const width = widthRef.current;
189732
- const isOpen = context.open || isPresent;
189733
- const isMountAnimationPreventedRef = React.useRef(isOpen);
189734
- const originalStylesRef = React.useRef(void 0);
189735
- React.useEffect(() => {
189736
- const rAF = requestAnimationFrame(() => isMountAnimationPreventedRef.current = false);
189737
- return () => cancelAnimationFrame(rAF);
189738
- }, []);
189739
- useLayoutEffect2$1(() => {
189740
- const node = ref.current;
189741
- if (node) {
189742
- originalStylesRef.current = originalStylesRef.current || {
189743
- transitionDuration: node.style.transitionDuration,
189744
- animationName: node.style.animationName
189745
- };
189746
- node.style.transitionDuration = "0s";
189747
- node.style.animationName = "none";
189748
- const rect = node.getBoundingClientRect();
189749
- heightRef.current = rect.height;
189750
- widthRef.current = rect.width;
189751
- if (!isMountAnimationPreventedRef.current) {
189752
- node.style.transitionDuration = originalStylesRef.current.transitionDuration;
189753
- node.style.animationName = originalStylesRef.current.animationName;
189754
- }
189755
- setIsPresent(present);
189756
- }
189757
- }, [context.open, present]);
189758
- return /* @__PURE__ */ jsx(
189759
- Primitive$4.div,
189760
- {
189761
- "data-state": getState$1(context.open),
189762
- "data-disabled": context.disabled ? "" : void 0,
189763
- id: context.contentId,
189764
- hidden: !isOpen,
189765
- ...contentProps,
189766
- ref: composedRefs,
189767
- style: {
189768
- [`--radix-collapsible-content-height`]: height ? `${height}px` : void 0,
189769
- [`--radix-collapsible-content-width`]: width ? `${width}px` : void 0,
189770
- ...props.style
189771
- },
189772
- children: isOpen && children
189773
- }
189774
- );
189775
- });
189776
- function getState$1(open) {
189777
- return open ? "open" : "closed";
189778
- }
189779
- var Root$3 = Collapsible$1;
189780
-
189781
- const Collapsible = Root$3;
189782
- const CollapsibleTrigger = CollapsibleTrigger$1;
189783
- const CollapsibleContent = CollapsibleContent$1;
189784
-
189785
189916
  function getFriendlyToolName(toolName) {
189786
189917
  if (TOOL_NAME_MAP === null || TOOL_NAME_MAP === void 0 ? void 0 : TOOL_NAME_MAP[toolName])
189787
189918
  return TOOL_NAME_MAP[toolName];
@@ -228252,7 +228383,9 @@ function NotificationDropdown({ org, userId, className, onViewNotifications, })
228252
228383
  return (jsx(Fragment$1, { children: jsxs(DropdownMenu, { open: notificationsOpen, onOpenChange: setNotificationsOpen, children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs(Button$1, { variant: "ghost", size: "icon", className: `relative ${className}`, "aria-label": t('notificationsNotificationDropdown.bellAriaLabel', {
228253
228384
  count: unreadCount,
228254
228385
  plural: unreadCount === 1 ? '' : 's',
228255
- }), children: [jsx(Bell, { className: "h-6 w-6 text-[#646464]" }), !isNotificationCountLoading && unreadCount > 0 && (jsx("span", { className: "absolute -top-1 -right-1 flex h-4 w-4 items-center justify-center rounded-full bg-red-500 text-xs text-white", children: unreadCount }))] }) }), jsxs(DropdownMenuContent, { align: "end", className: "w-[300px] p-2 z-[9999] border border-gray-100 max-h-[300px] overflow-y-auto", children: [jsxs("div", { className: "px-4 py-3 text-sm font-semibold border-b border-gray-100 flex items-center justify-between", children: [jsx("span", { children: t('notificationsNotificationDropdown.notificationsHeader') }), jsx(Button$1, { variant: "link", size: "sm", className: "text-sm text-blue-600 h-auto p-0", onClick: () => onViewNotifications === null || onViewNotifications === void 0 ? void 0 : onViewNotifications(), children: t('notificationsNotificationDropdown.viewAll') })] }), isLoading && (jsx("div", { className: "px-3 py-2 text-sm text-gray-500", children: t('notificationsNotificationDropdown.loading') })), (!isLoading && isError) ||
228386
+ }), children: [jsx(Bell, { className: "h-6 w-6 text-[#646464]" }), !isNotificationCountLoading && unreadCount > 0 && (
228387
+ // Anchored from the left so wider counts (e.g. "99+") grow away from the bell
228388
+ jsx("span", { "aria-hidden": "true", className: "pointer-events-none absolute top-0.5 left-[55%] flex h-5 min-w-5 items-center justify-center rounded-full bg-red-500 px-1 text-[10px] font-semibold leading-none tabular-nums text-white ring-2 ring-white", children: unreadCount > 99 ? '99+' : unreadCount }))] }) }), jsxs(DropdownMenuContent, { align: "end", className: "w-[300px] p-2 z-[9999] border border-gray-100 max-h-[300px] overflow-y-auto", children: [jsxs("div", { className: "px-3 py-3 text-sm font-semibold border-b border-gray-100 flex items-center justify-between", children: [jsx("span", { children: t('notificationsNotificationDropdown.notificationsHeader') }), jsx(Button$1, { variant: "link", size: "sm", className: "text-sm text-blue-600 h-auto p-0", onClick: () => onViewNotifications === null || onViewNotifications === void 0 ? void 0 : onViewNotifications(), children: t('notificationsNotificationDropdown.viewAll') })] }), isLoading && (jsx("div", { className: "px-3 py-2 text-sm text-gray-500", children: t('notificationsNotificationDropdown.loading') })), (!isLoading && isError) ||
228256
228389
  (!isLoading && !isError && filteredNotifications.length === 0) ? (jsx("div", { className: "px-3 py-2 text-sm text-gray-500", children: t('notificationsNotificationDropdown.noNewNotifications') })) : (jsxs(Fragment$1, { children: [!isLoading &&
228257
228390
  !isError &&
228258
228391
  filteredNotifications.length > 0 &&
@@ -232032,11 +232165,18 @@ const defaultTabs = [
232032
232165
  label: 'Audit',
232033
232166
  value: 'audit',
232034
232167
  },
232035
- /*{
232036
- label: 'Monetization',
232037
- value: 'monetization',
232038
- },*/
232168
+ {
232169
+ // Opt-in via `enableMonetization`, and then only for a user holding
232170
+ // `can_sell_items` on the tenant — see `canViewMonetizationAnalytics`.
232171
+ label: 'Monetization',
232172
+ value: 'monetization',
232173
+ },
232039
232174
  ];
232175
+ /**
232176
+ * Tab value gated on `enableMonetization` and the selling permission,
232177
+ * whichever `tabs` it comes from.
232178
+ */
232179
+ const MONETIZATION_TAB = 'monetization';
232040
232180
  /**
232041
232181
  * How many results the `dbId` lookup asks for. The query is the agent's own
232042
232182
  * `unique_id`, so the match is normally first; a handful of rows covers a
@@ -232044,7 +232184,7 @@ const defaultTabs = [
232044
232184
  */
232045
232185
  const SCOPE_LOOKUP_LIMIT = 5;
232046
232186
  const className = 'inline-flex h-7 shrink-0 items-center justify-center whitespace-nowrap rounded-[5px] px-2 sm:px-2.5 py-0 text-sm text-gray-500 ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-blue-600 data-[state=active]:font-semibold font-medium data-[state=active]:bg-[#f5f7fb] data-[state=active]:shadow-none cursor-pointer';
232047
- function AnalyticsLayout({ children, currentPath, basePath, onTabChange, tabs = defaultTabs, activeTabClassName = '', beforeDataReports, excludeTabs = [], showPicker = false, tenantKey, scopedMentor, onScopedMentorChange, }) {
232187
+ function AnalyticsLayout({ children, currentPath, basePath, onTabChange, tabs = defaultTabs, activeTabClassName = '', beforeDataReports, excludeTabs = [], showPicker = false, tenantKey, scopedMentor, onScopedMentorChange, enableMonetization = false, }) {
232048
232188
  var _a, _b;
232049
232189
  const { currentTenant } = useCurrentTenant();
232050
232190
  const rbacPermissions = useSelector(selectRbacPermissions);
@@ -232113,10 +232253,18 @@ function AnalyticsLayout({ children, currentPath, basePath, onTabChange, tabs =
232113
232253
  // the caller passed, custom tabs included.
232114
232254
  const isRestricted = isPureWatcher(rbacPermissions, currentTenant);
232115
232255
  const allowedTabs = useMemo(() => getVisibleAnalyticsTabs(rbacPermissions, currentTenant), [rbacPermissions, currentTenant]);
232116
- const canAccessTab = useCallback(
232117
- // Callers may pass custom tab values, so compare as plain strings: anything
232118
- // outside the watcher allow-list stays hidden from a restricted user.
232119
- (tabValue) => !isRestricted || allowedTabs.includes(tabValue), [isRestricted, allowedTabs]);
232256
+ // Monetization is a host opt-in (the tenant's `enable_monetization` flag)
232257
+ // and, on top of that, has its own RBAC action rather than a place in the
232258
+ // watcher allow-list: only a user who may sell on this tenant sees the tab,
232259
+ // admins included — the rule the sidebar and profile Account panel apply.
232260
+ const canViewMonetization = useMemo(() => enableMonetization && canViewMonetizationAnalytics(rbacPermissions, currentTenant), [enableMonetization, rbacPermissions, currentTenant]);
232261
+ const canAccessTab = useCallback((tabValue) => {
232262
+ if (tabValue === MONETIZATION_TAB && !canViewMonetization)
232263
+ return false;
232264
+ // Callers may pass custom tab values, so compare as plain strings: anything
232265
+ // outside the watcher allow-list stays hidden from a restricted user.
232266
+ return !isRestricted || allowedTabs.includes(tabValue);
232267
+ }, [isRestricted, allowedTabs, canViewMonetization]);
232120
232268
  useEffect(() => {
232121
232269
  const mainContentContainer = document.getElementById('main-content-container');
232122
232270
  if (mainContentContainer) {
@@ -232161,18 +232309,20 @@ function AnalyticsLayout({ children, currentPath, basePath, onTabChange, tabs =
232161
232309
  latestPropsRef.current = { onTabChange, excludeTabs };
232162
232310
  });
232163
232311
  // A watcher who deep-links into a restricted tab (e.g. /analytics/users, or
232164
- // the Overview landing page) gets sent to the first tab they may open. It has
232165
- // to skip `excludeTabs`: a host that drops a tab has no route behind it, so
232312
+ // the Overview landing page) gets sent to the first tab they may open, as
232313
+ // does anyone landing on Monetization while the host has it off or without
232314
+ // the selling permission. It has to skip `excludeTabs`: a host that drops a
232315
+ // tab has no route behind it, so
232166
232316
  // redirecting there would 404 (mentorai excludes courses/programs).
232167
232317
  useEffect(() => {
232168
232318
  if (isActiveTabAllowed)
232169
232319
  return;
232170
232320
  const { onTabChange: notify, excludeTabs: excluded } = latestPropsRef.current;
232171
- const fallbackTab = allowedTabs.find((tab) => !excluded.includes(tab));
232321
+ const fallbackTab = allowedTabs.find((tab) => !excluded.includes(tab) && canAccessTab(tab));
232172
232322
  if (fallbackTab === undefined)
232173
232323
  return;
232174
232324
  notify(fallbackTab);
232175
- }, [isActiveTabAllowed, allowedTabs]);
232325
+ }, [isActiveTabAllowed, allowedTabs, canAccessTab]);
232176
232326
  const handleTabClick = (tabValue) => {
232177
232327
  if (!canAccessTab(tabValue))
232178
232328
  return;
@@ -236092,31 +236242,12 @@ const useMonetization = ({ tenantKey }) => {
236092
236242
  itemType: pw.item_type,
236093
236243
  }));
236094
236244
  })();
236095
- const generateResemblingColors = (totalColors) => {
236096
- const baseColorVariations = [
236097
- '#2b7fff',
236098
- '#4d8fff',
236099
- '#6fa0ff',
236100
- '#91b1ff',
236101
- '#b3c2ff',
236102
- '#1a6fee',
236103
- '#0961dd',
236104
- '#0056cc',
236105
- '#004bbb',
236106
- '#0040aa',
236107
- ];
236108
- const colors = [];
236109
- for (let i = 0; i < totalColors && i < baseColorVariations.length; i++) {
236110
- colors.push(baseColorVariations[i]);
236111
- }
236112
- while (colors.length < totalColors) {
236113
- const hue = Math.floor(Math.random() * 360);
236114
- colors.push(`hsl(${hue}, 70%, 50%)`);
236115
- }
236116
- return colors;
236117
- };
236118
- const statusColors = generateResemblingColors(statusDistribution.length);
236119
- const itemTypeColors = generateResemblingColors(itemTypeDistribution.length);
236245
+ // Slices take the shared categorical palette in order, so neighbouring
236246
+ // statuses and item types are told apart by hue rather than by shades of
236247
+ // one blue. Past six slices the palette cycles, as it does on every other
236248
+ // multi-series chart (see chart-palette.ts).
236249
+ const statusColors = statusDistribution.map((_, index) => colorForRank(index));
236250
+ const itemTypeColors = itemTypeDistribution.map((_, index) => colorForRank(index));
236120
236251
  return {
236121
236252
  revenueData,
236122
236253
  isLoadingRevenue,
@@ -236140,6 +236271,15 @@ const useMonetization = ({ tenantKey }) => {
236140
236271
  };
236141
236272
  };
236142
236273
 
236274
+ /** What a cell shows when the row carries nothing for it, as the other tables do. */
236275
+ const EMPTY_CELL = '\u2014';
236276
+ /** The day a subscription started, or a dash when the row has no usable date. */
236277
+ function formatSubscribedOn(iso) {
236278
+ if (!iso)
236279
+ return EMPTY_CELL;
236280
+ const date = new Date(iso);
236281
+ return Number.isNaN(date.getTime()) ? EMPTY_CELL : format$1(date, 'MMM dd, yyyy');
236282
+ }
236143
236283
  function statusBadgeStyle(status) {
236144
236284
  switch (status) {
236145
236285
  case 'active':
@@ -236154,11 +236294,15 @@ function statusBadgeStyle(status) {
236154
236294
  return 'bg-gray-100 text-gray-500 border-gray-200 hover:bg-gray-100';
236155
236295
  }
236156
236296
  }
236157
- function AnalyticsMonetizationStats({ tenantKey }) {
236297
+ function AnalyticsMonetizationStats({ tenantKey, currentSPA, }) {
236158
236298
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
236159
236299
  const t = useT();
236160
236300
  const { revenueData, isLoadingRevenue, paywallsData, isLoadingPaywalls, subscribersData, isLoadingSubscribers, paywallTypeFilter, setPaywallTypeFilter, subscriberStatusFilter, setSubscriberStatusFilter, paywallPage, setPaywallPage, subscriberPage, setSubscriberPage, statusDistribution, itemTypeDistribution, statusColors, itemTypeColors, } = useMonetization({ tenantKey });
236161
- return (jsxs("div", { className: "space-y-8", children: [jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6", children: [jsx(StatCard, { loading: isLoadingRevenue, title: t('analyticsAnalyticsMonetizationStats.totalRevenue'), value: Number((revenueData === null || revenueData === void 0 ? void 0 : revenueData.sales_volume) || 0).toLocaleString(), showDollarSign: true, description: t('analyticsAnalyticsMonetizationStats.totalRevenueDescription') }), jsx(StatCard, { loading: isLoadingRevenue, title: t('analyticsAnalyticsMonetizationStats.totalSales'), value: (_a = revenueData === null || revenueData === void 0 ? void 0 : revenueData.sales_count) !== null && _a !== void 0 ? _a : 0, description: t('analyticsAnalyticsMonetizationStats.totalSalesDescription') }), jsx(StatCard, { loading: isLoadingPaywalls, title: t('analyticsAnalyticsMonetizationStats.activePaywalls'), value: (_b = paywallsData === null || paywallsData === void 0 ? void 0 : paywallsData.count) !== null && _b !== void 0 ? _b : 0, description: t('analyticsAnalyticsMonetizationStats.activePaywallsDescription') }), jsx(StatCard, { loading: isLoadingSubscribers, title: t('analyticsAnalyticsMonetizationStats.totalSubscribers'), value: (_c = subscribersData === null || subscribersData === void 0 ? void 0 : subscribersData.count) !== null && _c !== void 0 ? _c : 0, description: t('analyticsAnalyticsMonetizationStats.totalSubscribersDescription') })] }), jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-5", children: [jsx(Card$1, { className: "w-full bg-white rounded-lg border border-gray-100 overflow-hidden shadow-sm", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsMonetizationStats.subscriptionStatusChartCardAriaLabel'), children: [jsx("div", { className: "mb-6", children: jsxs("div", { className: "flex items-center gap-1", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsMonetizationStats.subscribersByStatus') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsMonetizationStats.subscribersByStatus'), description: t('analyticsAnalyticsMonetizationStats.subscribersByStatusDescription') })] }) }), jsx("div", { className: "w-full", style: { height: '350px' }, children: jsx(ChartContainer, { title: t('analyticsAnalyticsMonetizationStats.subscribersByStatus'), config: {
236301
+ return (jsxs("div", { className: "space-y-8", children: [jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6", children: [jsx(StatCard, { loading: isLoadingRevenue, title: t('analyticsAnalyticsMonetizationStats.totalRevenue'),
236302
+ // Fixed two decimals with no locale grouping, the way every cost
236303
+ // card on the Cost tab reads — `toLocaleString` gave "4 180,5" in a
236304
+ // French browser.
236305
+ value: Number((revenueData === null || revenueData === void 0 ? void 0 : revenueData.sales_volume) || 0).toFixed(2), showDollarSign: true, description: t('analyticsAnalyticsMonetizationStats.totalRevenueDescription') }), jsx(StatCard, { loading: isLoadingRevenue, title: t('analyticsAnalyticsMonetizationStats.totalSales'), value: (_a = revenueData === null || revenueData === void 0 ? void 0 : revenueData.sales_count) !== null && _a !== void 0 ? _a : 0, description: t('analyticsAnalyticsMonetizationStats.totalSalesDescription') }), jsx(StatCard, { loading: isLoadingPaywalls, title: t('analyticsAnalyticsMonetizationStats.activePaywalls'), value: (_b = paywallsData === null || paywallsData === void 0 ? void 0 : paywallsData.count) !== null && _b !== void 0 ? _b : 0, description: t('analyticsAnalyticsMonetizationStats.activePaywallsDescription') }), jsx(StatCard, { loading: isLoadingSubscribers, title: t('analyticsAnalyticsMonetizationStats.totalSubscribers'), value: (_c = subscribersData === null || subscribersData === void 0 ? void 0 : subscribersData.count) !== null && _c !== void 0 ? _c : 0, description: t('analyticsAnalyticsMonetizationStats.totalSubscribersDescription') })] }), jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-5", children: [jsx(Card$1, { className: "w-full bg-white rounded-lg border border-gray-100 overflow-hidden shadow-sm", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", "aria-label": t('analyticsAnalyticsMonetizationStats.subscriptionStatusChartCardAriaLabel'), children: [jsx("div", { className: "mb-6", children: jsxs("div", { className: "flex items-center gap-1", children: [jsx("h3", { className: "text-base font-medium text-gray-700", children: t('analyticsAnalyticsMonetizationStats.subscribersByStatus') }), jsx(CardInfoIcon, { title: t('analyticsAnalyticsMonetizationStats.subscribersByStatus'), description: t('analyticsAnalyticsMonetizationStats.subscribersByStatusDescription') })] }) }), jsx("div", { className: "w-full", style: { height: '350px' }, children: jsx(ChartContainer, { title: t('analyticsAnalyticsMonetizationStats.subscribersByStatus'), config: {
236162
236306
  value: {
236163
236307
  label: t('analyticsAnalyticsMonetizationStats.subscribersLabel'),
236164
236308
  color: '#38A1E5',
@@ -236193,11 +236337,11 @@ function AnalyticsMonetizationStats({ tenantKey }) {
236193
236337
  }), description: t('analyticsAnalyticsMonetizationStats.subscribersTableDescription') })] }), jsxs(Select$1, { value: subscriberStatusFilter, onValueChange: (v) => {
236194
236338
  setSubscriberStatusFilter(v);
236195
236339
  setSubscriberPage(1);
236196
- }, children: [jsx(SelectTrigger, { className: "w-[130px]", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: t('analyticsAnalyticsMonetizationStats.filterAll') }), jsx(SelectItem, { value: "active", children: t('analyticsAnalyticsMonetizationStats.filterActive') }), jsx(SelectItem, { value: "trialing", children: t('analyticsAnalyticsMonetizationStats.filterTrialing') }), jsx(SelectItem, { value: "canceled", children: t('analyticsAnalyticsMonetizationStats.filterCanceled') }), jsx(SelectItem, { value: "past_due", children: t('analyticsAnalyticsMonetizationStats.filterPastDue') })] })] })] }) }), jsx("div", { className: "rounded-md overflow-auto", style: { borderColor: 'oklch(.922 0 0)', borderWidth: '1px' }, children: jsxs(Table, { children: [jsx(TableHeader, { children: jsxs(TableRow, { className: "h-[48px]", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableHead, { className: "w-[250px]", children: t('analyticsAnalyticsMonetizationStats.tableHeadItem') }), jsx(TableHead, { className: "w-[100px]", children: t('analyticsAnalyticsMonetizationStats.tableHeadType') }), jsx(TableHead, { className: "w-[120px]", children: t('analyticsAnalyticsMonetizationStats.tableHeadPlan') }), jsx(TableHead, { className: "w-[100px]", children: t('analyticsAnalyticsMonetizationStats.tableHeadAmount') }), jsx(TableHead, { className: "text-right", children: t('analyticsAnalyticsMonetizationStats.tableHeadStatus') })] }) }), jsx(TableBody, { children: (_f = subscribersData === null || subscribersData === void 0 ? void 0 : subscribersData.results) === null || _f === void 0 ? void 0 : _f.map((sub, index) => {
236340
+ }, children: [jsx(SelectTrigger, { className: "w-[130px]", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: t('analyticsAnalyticsMonetizationStats.filterAll') }), jsx(SelectItem, { value: "active", children: t('analyticsAnalyticsMonetizationStats.filterActive') }), jsx(SelectItem, { value: "trialing", children: t('analyticsAnalyticsMonetizationStats.filterTrialing') }), jsx(SelectItem, { value: "canceled", children: t('analyticsAnalyticsMonetizationStats.filterCanceled') }), jsx(SelectItem, { value: "past_due", children: t('analyticsAnalyticsMonetizationStats.filterPastDue') })] })] })] }) }), jsx("div", { className: "rounded-md overflow-auto", style: { borderColor: 'oklch(.922 0 0)', borderWidth: '1px' }, children: jsxs(Table, { className: "table-fixed min-w-[900px]", children: [jsx(TableHeader, { children: jsxs(TableRow, { className: "h-[48px]", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableHead, { className: "w-[24%]", children: t('analyticsAnalyticsMonetizationStats.tableHeadUser') }), jsx(TableHead, { className: "w-[24%]", children: t('analyticsAnalyticsMonetizationStats.tableHeadItem') }), jsx(TableHead, { className: "w-[10.4%]", children: t('analyticsAnalyticsMonetizationStats.tableHeadType') }), jsx(TableHead, { className: "w-[10.4%]", children: t('analyticsAnalyticsMonetizationStats.tableHeadPlan') }), jsx(TableHead, { className: "w-[10.4%]", children: t('analyticsAnalyticsMonetizationStats.tableHeadAmount') }), jsx(TableHead, { className: "w-[10.4%]", children: t('analyticsAnalyticsMonetizationStats.tableHeadSubscribed') }), jsx(TableHead, { className: "w-[10.4%] text-right", children: t('analyticsAnalyticsMonetizationStats.tableHeadStatus') })] }) }), jsx(TableBody, { children: (_f = subscribersData === null || subscribersData === void 0 ? void 0 : subscribersData.results) === null || _f === void 0 ? void 0 : _f.map((sub, index) => {
236197
236341
  var _a, _b, _c;
236198
- return (jsxs(TableRow, { className: cn(index % 2 === 0 ? 'bg-gray-50' : '', 'h-[48px]'), style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableCell, { className: "font-medium", children: sub.item_name || sub.item_id }), jsx(TableCell, { children: jsx(Badge, { variant: "secondary", className: "text-xs capitalize", children: sub.item_type }) }), jsx(TableCell, { children: (_a = sub.price) === null || _a === void 0 ? void 0 : _a.name }), jsx(TableCell, { children: sub.status === 'grandfathered' ? null : (jsxs(Fragment$1, { children: ["$", (_b = sub.price) === null || _b === void 0 ? void 0 : _b.amount, ((_c = sub.price) === null || _c === void 0 ? void 0 : _c.interval) && sub.price.interval !== 'one_time'
236342
+ return (jsxs(TableRow, { className: cn(index % 2 === 0 ? 'bg-gray-50' : '', 'h-[48px]'), style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableCell, { className: "font-medium", children: jsx(UserProfileLink, { tenantKey: tenantKey, currentSPA: currentSPA, username: sub.username, display: sub.email || sub.username || EMPTY_CELL }) }), jsx(TableCell, { className: "font-medium truncate", title: sub.item_name || sub.item_id, children: sub.item_name || sub.item_id }), jsx(TableCell, { children: jsx(Badge, { variant: "secondary", className: "text-xs capitalize", children: sub.item_type }) }), jsx(TableCell, { children: (_a = sub.price) === null || _a === void 0 ? void 0 : _a.name }), jsx(TableCell, { className: "whitespace-nowrap", children: sub.status === 'grandfathered' ? null : (jsxs(Fragment$1, { children: ["$", (_b = sub.price) === null || _b === void 0 ? void 0 : _b.amount, ((_c = sub.price) === null || _c === void 0 ? void 0 : _c.interval) && sub.price.interval !== 'one_time'
236199
236343
  ? `/${sub.price.interval}`
236200
- : ''] })) }), jsx(TableCell, { className: "text-right", children: jsx(Badge, { className: statusBadgeStyle(sub.status), children: sub.status }) })] }, sub.unique_id));
236344
+ : ''] })) }), jsx(TableCell, { className: "whitespace-nowrap", children: formatSubscribedOn(sub.created_at) }), jsx(TableCell, { className: "text-right", children: jsx(Badge, { className: statusBadgeStyle(sub.status), children: sub.status }) })] }, sub.unique_id));
236201
236345
  }) })] }) }), (!((_g = subscribersData === null || subscribersData === void 0 ? void 0 : subscribersData.results) === null || _g === void 0 ? void 0 : _g.length) || ((_h = subscribersData === null || subscribersData === void 0 ? void 0 : subscribersData.results) === null || _h === void 0 ? void 0 : _h.length) === 0) && (jsx("div", { className: "h-[60px]", children: jsx(EmptyStats, {}) })), subscribersData &&
236202
236346
  (subscribersData.previous_page !== null || subscribersData.next_page !== null) && (jsxs("div", { className: "flex items-center justify-between py-3", children: [jsx("div", { className: "text-sm text-gray-700", children: t('analyticsAnalyticsMonetizationStats.subscriberCountTotal', {
236203
236347
  count: subscribersData.count,
@@ -236211,9 +236355,9 @@ function AnalyticsMonetizationStats({ tenantKey }) {
236211
236355
  }), description: t('analyticsAnalyticsMonetizationStats.paywallsTableDescription') })] }), jsxs(Select$1, { value: paywallTypeFilter, onValueChange: (v) => {
236212
236356
  setPaywallTypeFilter(v);
236213
236357
  setPaywallPage(1);
236214
- }, children: [jsx(SelectTrigger, { className: "w-[130px]", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: t('analyticsAnalyticsMonetizationStats.filterAllTypes') }), jsx(SelectItem, { value: "mentor", children: t('analyticsAnalyticsMonetizationStats.filterAgent') }), jsx(SelectItem, { value: "course", children: t('analyticsAnalyticsMonetizationStats.filterCourse') })] })] })] }) }), jsx("div", { className: "rounded-md overflow-auto", style: { borderColor: 'oklch(.922 0 0)', borderWidth: '1px' }, children: jsxs(Table, { children: [jsx(TableHeader, { children: jsxs(TableRow, { className: "h-[48px]", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableHead, { className: "w-[250px]", children: t('analyticsAnalyticsMonetizationStats.tableHeadItem') }), jsx(TableHead, { className: "w-[100px]", children: t('analyticsAnalyticsMonetizationStats.tableHeadType') }), jsx(TableHead, { className: "w-[100px]", children: t('analyticsAnalyticsMonetizationStats.tableHeadPrices') }), jsx(TableHead, { className: "text-right", children: t('analyticsAnalyticsMonetizationStats.tableHeadStatus') })] }) }), jsx(TableBody, { children: (_l = paywallsData === null || paywallsData === void 0 ? void 0 : paywallsData.results) === null || _l === void 0 ? void 0 : _l.map((pw, index) => {
236358
+ }, children: [jsx(SelectTrigger, { className: "w-[130px]", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: t('analyticsAnalyticsMonetizationStats.filterAllTypes') }), jsx(SelectItem, { value: "mentor", children: t('analyticsAnalyticsMonetizationStats.filterAgent') }), jsx(SelectItem, { value: "course", children: t('analyticsAnalyticsMonetizationStats.filterCourse') })] })] })] }) }), jsx("div", { className: "rounded-md overflow-auto", style: { borderColor: 'oklch(.922 0 0)', borderWidth: '1px' }, children: jsxs(Table, { className: "table-fixed min-w-[640px]", children: [jsx(TableHeader, { children: jsxs(TableRow, { className: "h-[48px]", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableHead, { className: "w-[40%]", children: t('analyticsAnalyticsMonetizationStats.tableHeadItem') }), jsx(TableHead, { className: "w-[20%]", children: t('analyticsAnalyticsMonetizationStats.tableHeadType') }), jsx(TableHead, { className: "w-[20%]", children: t('analyticsAnalyticsMonetizationStats.tableHeadPrices') }), jsx(TableHead, { className: "w-[20%] text-right", children: t('analyticsAnalyticsMonetizationStats.tableHeadStatus') })] }) }), jsx(TableBody, { children: (_l = paywallsData === null || paywallsData === void 0 ? void 0 : paywallsData.results) === null || _l === void 0 ? void 0 : _l.map((pw, index) => {
236215
236359
  var _a, _b;
236216
- return (jsxs(TableRow, { className: cn(index % 2 === 0 ? 'bg-gray-50' : '', 'h-[48px]'), style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableCell, { className: "font-medium", children: pw.item_name || pw.item_id }), jsx(TableCell, { children: jsx(Badge, { variant: "secondary", className: "text-xs capitalize", children: pw.item_type }) }), jsx(TableCell, { children: t('analyticsAnalyticsMonetizationStats.activePricesCount', {
236360
+ return (jsxs(TableRow, { className: cn(index % 2 === 0 ? 'bg-gray-50' : '', 'h-[48px]'), style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx(TableCell, { className: "font-medium truncate", title: pw.item_name || pw.item_id, children: pw.item_name || pw.item_id }), jsx(TableCell, { children: jsx(Badge, { variant: "secondary", className: "text-xs capitalize", children: pw.item_type }) }), jsx(TableCell, { children: t('analyticsAnalyticsMonetizationStats.activePricesCount', {
236217
236361
  count: (_b = (_a = pw.prices) === null || _a === void 0 ? void 0 : _a.filter((p) => p.is_active).length) !== null && _b !== void 0 ? _b : 0,
236218
236362
  }) }), jsx(TableCell, { className: "text-right", children: jsx(Badge, { className: pw.is_enabled
236219
236363
  ? 'bg-blue-100 text-blue-700 border-blue-200 hover:bg-blue-100'
@@ -244129,7 +244273,7 @@ const ProjectFilesModal$1 = lazy(() => Promise.resolve().then(function () { retu
244129
244273
  const AddMentorToProjectModal$1 = lazy(() => Promise.resolve().then(function () { return addMentorToProjectModal; }).then((mod) => ({
244130
244274
  default: mod.AddMentorToProjectModal,
244131
244275
  })));
244132
- function ProjectLandingPage({ project, sessionId, onSubmit, onScreenSharingClick, isScreenSharingModalOpen, onPhoneCallClick, stopGenerating, tenantKey, username, enableSafetyDisclaimer, enableWebBrowsing, isStreaming, updateSessionTools, setSessionTools, activeTools, screenSharing, deepResearch, studyMode, imageGeneration, codeInterpreter, promptsIsEnabled, isPreviewMode, setMessage, mentorId, mentorUniqueId, projectId, googleSlidesIsEnabled, googleDocumentIsEnabled, artifactsEnabled, userIsStudent, isPublicRoute, navigateToProject, showExploreMentors = false, }) {
244276
+ function ProjectLandingPage({ project, sessionId, onSubmit, onScreenSharingClick, isScreenSharingModalOpen, onPhoneCallClick, stopGenerating, tenantKey, username, enableSafetyDisclaimer, enableWebBrowsing, isStreaming, updateSessionTools, setSessionTools, activeTools, screenSharing, deepResearch, studyMode, imageGeneration, codeInterpreter, promptsIsEnabled, isPreviewMode, setMessage, mentorId, mentorUniqueId, projectId, googleSlidesIsEnabled, googleDocumentIsEnabled, artifactsEnabled, userIsStudent, isPublicRoute, navigateToProject, showExploreMentors = false, disabledResourceTypes, maxUploadSizeMb, dropboxExtensions, }) {
244133
244277
  var _a;
244134
244278
  const [isInstructionsModalOpen, setIsInstructionsModalOpen] = useState(false);
244135
244279
  const [isFilesModalOpen, setIsFilesModalOpen] = useState(false);
@@ -244142,7 +244286,7 @@ function ProjectLandingPage({ project, sessionId, onSubmit, onScreenSharingClick
244142
244286
  name: mentor.name,
244143
244287
  avatar: mentor.profile_image,
244144
244288
  description: mentor.description,
244145
- })), onAddMentorClick: () => setIsAddMentorModalOpen(true), showTitle: true, tenantKey: tenantKey, mentorId: mentorId, projectId: projectId, username: username, navigateToProject: navigateToProject }))] })] })] }), isInstructionsModalOpen && (jsx(Suspense, { fallback: null, children: jsx(ProjectInstructionsModal$1, { isOpen: isInstructionsModalOpen, onClose: () => setIsInstructionsModalOpen(false), tenantKey: tenantKey, projectId: projectId, username: username }) })), isFilesModalOpen && (jsx(Suspense, { fallback: null, children: jsx(ProjectFilesModal$1, { isOpen: isFilesModalOpen, onClose: () => setIsFilesModalOpen(false), tenantKey: tenantKey, mentorId: mentorId, username: username }) })), isAddMentorModalOpen && (jsx(Suspense, { fallback: null, children: jsx(AddMentorToProjectModal$1, { isOpen: isAddMentorModalOpen, onClose: () => setIsAddMentorModalOpen(false), projectName: project.name, tenantKey: tenantKey, projectId: projectId, username: username, isPublicRoute: isPublicRoute }) }))] }));
244289
+ })), onAddMentorClick: () => setIsAddMentorModalOpen(true), showTitle: true, tenantKey: tenantKey, mentorId: mentorId, projectId: projectId, username: username, navigateToProject: navigateToProject }))] })] })] }), isInstructionsModalOpen && (jsx(Suspense, { fallback: null, children: jsx(ProjectInstructionsModal$1, { isOpen: isInstructionsModalOpen, onClose: () => setIsInstructionsModalOpen(false), tenantKey: tenantKey, projectId: projectId, username: username }) })), isFilesModalOpen && (jsx(Suspense, { fallback: null, children: jsx(ProjectFilesModal$1, { isOpen: isFilesModalOpen, onClose: () => setIsFilesModalOpen(false), tenantKey: tenantKey, mentorId: mentorId, username: username, disabledResourceTypes: disabledResourceTypes, maxUploadSizeMb: maxUploadSizeMb, dropboxExtensions: dropboxExtensions }) })), isAddMentorModalOpen && (jsx(Suspense, { fallback: null, children: jsx(AddMentorToProjectModal$1, { isOpen: isAddMentorModalOpen, onClose: () => setIsAddMentorModalOpen(false), projectName: project.name, tenantKey: tenantKey, projectId: projectId, username: username, isPublicRoute: isPublicRoute }) }))] }));
244146
244290
  }
244147
244291
 
244148
244292
  function MinimumMentorAlert({ open, onOpenChange }) {
@@ -244415,8 +244559,9 @@ const TrainOrDeleteModal$1 = dynamic(() => Promise.resolve().then(function () {
244415
244559
  */
244416
244560
  function isCrawlableDocType(documentType) {
244417
244561
  const docType = documentType === null || documentType === void 0 ? void 0 : documentType.toLowerCase();
244418
- // Uploaded documents (local files like PDF, DOCX, etc.)
244419
- const uploadedFileTypes = ['file'];
244562
+ // Uploaded documents: generic local files ('file') plus the local resource
244563
+ // types that send their own fileType as the document type.
244564
+ const uploadedFileTypes = ['file', 'image', 'audio', 'video', 'zip'];
244420
244565
  if (uploadedFileTypes.some((type) => docType === null || docType === void 0 ? void 0 : docType.includes(type))) {
244421
244566
  return false;
244422
244567
  }
@@ -244427,6 +244572,12 @@ function isCrawlableDocType(documentType) {
244427
244572
  }
244428
244573
  return true;
244429
244574
  }
244575
+ /**
244576
+ * The crawler User-Agent override only applies to web crawler documents.
244577
+ */
244578
+ function isWebCrawlerDocType(documentType) {
244579
+ return !!(documentType === null || documentType === void 0 ? void 0 : documentType.toLowerCase().includes('webcrawler'));
244580
+ }
244430
244581
  function DatasetItem({ dataset, onSelect, isSelected, labels }) {
244431
244582
  var _a, _b, _c, _d, _e;
244432
244583
  const t = useT();
@@ -244503,7 +244654,7 @@ function DatasetItem({ dataset, onSelect, isSelected, labels }) {
244503
244654
  }
244504
244655
  }, className: "text-gray-500 hover:text-gray-700", disabled: isEditTrainingDocumentLoading || disabled, children: dataset.access === 'private' ? (jsxs(Fragment$1, { children: [jsx(EyeOff, { className: "h-4 w-4" }), jsx("span", { className: "sr-only", children: t('datasetsTabDatasetItem.makePublic') })] })) : (jsxs(Fragment$1, { children: [jsx(Eye, { className: "h-4 w-4" }), jsx("span", { className: "sr-only", children: t('datasetsTabDatasetItem.makePrivate') })] })) })) }) }), jsx(TableCell, { className: "p-3 whitespace-nowrap", children: jsx(WithFormPermissions, { name: "is_trained",
244505
244656
  // @ts-ignore
244506
- permissions: (_e = dataset === null || dataset === void 0 ? void 0 : dataset.permissions) === null || _e === void 0 ? void 0 : _e.field, children: ({ disabled }) => (jsx(TrainingStatusSwitch, { is_trained: dataset.is_trained, url: dataset.url, disabled: disabled, training_status: dataset.training_status, handleEditTrainingDocument: handleEditTrainingDocument, onUntrainSuccess: () => setIsDeleteDatasetModalOpen(true), onTrainRequest: () => setIsTrainOrDeleteModalOpen(true) })) }) })] }, dataset.id), isDeleteDatasetModalOpen && (jsx(DeleteDatasetModal$1, { isOpen: isDeleteDatasetModalOpen, onClose: () => setIsDeleteDatasetModalOpen(false), dataset: dataset, labels: labels })), isRetrainScheduleModalOpen && (jsx(RetrainScheduleModal$1, { isOpen: isRetrainScheduleModalOpen, onClose: () => setIsRetrainScheduleModalOpen(false), dataset: dataset, labels: labels })), isTrainOrDeleteModalOpen && (jsx(TrainOrDeleteModal$1, { isOpen: isTrainOrDeleteModalOpen, onClose: () => setIsTrainOrDeleteModalOpen(false), onTrain: handleTrainDataset, onDelete: handleDeleteFromTrainModal, showUserAgentField: isCrawlableDocType(dataset.document_type), isLoading: isEditTrainingDocumentLoading, labels: labels }))] }));
244657
+ permissions: (_e = dataset === null || dataset === void 0 ? void 0 : dataset.permissions) === null || _e === void 0 ? void 0 : _e.field, children: ({ disabled }) => (jsx(TrainingStatusSwitch, { is_trained: dataset.is_trained, url: dataset.url, disabled: disabled, training_status: dataset.training_status, handleEditTrainingDocument: handleEditTrainingDocument, onUntrainSuccess: () => setIsDeleteDatasetModalOpen(true), onTrainRequest: () => setIsTrainOrDeleteModalOpen(true) })) }) })] }, dataset.id), isDeleteDatasetModalOpen && (jsx(DeleteDatasetModal$1, { isOpen: isDeleteDatasetModalOpen, onClose: () => setIsDeleteDatasetModalOpen(false), dataset: dataset, labels: labels })), isRetrainScheduleModalOpen && (jsx(RetrainScheduleModal$1, { isOpen: isRetrainScheduleModalOpen, onClose: () => setIsRetrainScheduleModalOpen(false), dataset: dataset, labels: labels })), isTrainOrDeleteModalOpen && (jsx(TrainOrDeleteModal$1, { isOpen: isTrainOrDeleteModalOpen, onClose: () => setIsTrainOrDeleteModalOpen(false), onTrain: handleTrainDataset, onDelete: handleDeleteFromTrainModal, showUserAgentField: isWebCrawlerDocType(dataset.document_type), isLoading: isEditTrainingDocumentLoading, labels: labels }))] }));
244507
244658
  }
244508
244659
  function TrainingStatusSwitch({ is_trained, url, training_status, disabled, handleEditTrainingDocument, onUntrainSuccess, onTrainRequest, }) {
244509
244660
  const t = useT();
@@ -244770,6 +244921,15 @@ const resourceTypes = [
244770
244921
  accept: 'text/plain',
244771
244922
  icon: (jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("rect", { width: "24", height: "24", rx: "4", fill: "url(#paint0_linear_text)" }), jsx("path", { d: "M7 7H17V9H13V17H11V9H7V7Z", fill: "white" }), jsx("defs", { children: jsxs("linearGradient", { id: "paint0_linear_text", x1: "0", y1: "0", x2: "24", y2: "24", gradientUnits: "userSpaceOnUse", children: [jsx("stop", { stopColor: "#4F46E5" }), jsx("stop", { offset: "1", stopColor: "#06B6D4" })] }) })] })),
244772
244923
  },
244924
+ {
244925
+ id: 'markdown',
244926
+ name: 'Markdown',
244927
+ bgColor: 'bg-blue-100',
244928
+ isActive: true,
244929
+ type: 'local',
244930
+ accept: 'text/markdown,.md,.markdown',
244931
+ icon: (jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [jsx("rect", { width: "24", height: "24", rx: "4", fill: "#1F2937" }), jsx("path", { d: "M4 16V8h2l2 3 2-3h2v8H9.5v-4.6L8 13.7l-1.5-2.3V16H4Zm11.5 0L13 13h1.75V8h1.5v5H18l-2.5 3Z", fill: "white" })] })),
244932
+ },
244773
244933
  {
244774
244934
  id: 'audio',
244775
244935
  name: 'Audio',
@@ -244831,6 +244991,26 @@ const resourceTypes = [
244831
244991
  },
244832
244992
  ];
244833
244993
 
244994
+ /**
244995
+ * Shared chrome for the Add Resources picker and every per-type resource
244996
+ * dialog, mirroring the Datasets tab: a fixed header (title + description bar
244997
+ * with a divider), a body that scrolls on its own (`ResourceDialogBody`), and
244998
+ * an optional fixed footer (`ResourceDialogFooter`).
244999
+ */
245000
+ function ResourceDialogContent({ title, description, className, children, }) {
245001
+ return (jsxs(DialogContent, { className: cn('flex max-h-[80vh] w-full max-w-lg flex-col gap-0 overflow-hidden p-0', className), children: [jsxs(DialogHeader, { className: "flex-shrink-0 space-y-1 border-b border-gray-200 bg-white px-4 pt-4 pr-10 pb-3 text-left", children: [jsx(DialogTitle, { className: "text-muted-foreground text-base", children: title }), jsx(DialogDescription, { className: "text-xs text-gray-600", children: description })] }), children] }));
245002
+ }
245003
+ /** The only scrolling part of a resource dialog; focusable so keyboard users can scroll it. */
245004
+ function ResourceDialogBody({ label, children }) {
245005
+ return (jsx("div", { className: "min-h-0 flex-1 space-y-4 overflow-x-hidden overflow-y-auto p-4", tabIndex: 0, role: "region", "aria-label": label, children: children }));
245006
+ }
245007
+ /** Actions pinned below the scroll region so they stay visible. */
245008
+ function ResourceDialogFooter({ children }) {
245009
+ return (jsx("div", { className: "flex flex-shrink-0 justify-end border-t border-gray-200 bg-white px-4 py-3", children: children }));
245010
+ }
245011
+ /** Submit button styling shared by every resource dialog footer. */
245012
+ const RESOURCE_SUBMIT_BUTTON_CLASS = 'bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-sm text-white hover:text-white hover:opacity-90';
245013
+
244834
245014
  /**
244835
245015
  * Spend-cap blocks (HTTP 429) carry the machine code in `error`/`error_code`
244836
245016
  * and a friendly, learner-safe sentence in `message`. Detection keys on
@@ -244925,7 +245105,7 @@ function GithubFileUploadModal() {
244925
245105
  const { branches, error, isLoading } = useGithubRepoDetails(debouncedGithubUrl, tenantKey);
244926
245106
  const isLoadingDisabled = !githubUrl || isLoading || isAddTrainingDocumentLoading;
244927
245107
  const isDisabled = isLoadingDisabled || !branch;
244928
- return (jsxs("div", { className: "flex flex-col space-y-4", children: [jsx(Input, { type: "url", placeholder: t('resourceModalGithubFileUploadModal.githubRepoUrlPlaceholder'), value: githubUrl, onChange: (e) => setGithubUrl(e.target.value), autoComplete: "url", disabled: isAddTrainingDocumentLoading }), jsx("p", { className: "text-xs font-light text-red-500", children: error }), jsxs(Select$1, { value: branch, onValueChange: (value) => setBranch(value), disabled: isLoadingDisabled, children: [jsx(SelectTrigger, { className: "w-full rounded-md border p-2", children: jsx(SelectValue, { placeholder: t('resourceModalGithubFileUploadModal.selectBranchPlaceholder') }) }), jsx(SelectContent, { children: branches.map((b) => (jsx(SelectItem, { value: b, children: b }, b))) })] }), jsx("div", { className: "flex justify-end", children: jsx(Button$1, { onClick: handleSubmit, disabled: isDisabled, className: `${githubUrl ? 'bg-gradient-to-r from-blue-600 to-blue-400 text-white' : 'bg-gray-100 text-gray-500'} hover:opacity-90`, children: t('resourceModalGithubFileUploadModal.submit') }) })] }));
245108
+ return (jsxs(Fragment$1, { children: [jsxs(ResourceDialogBody, { label: t('resourceModalGithubFileUploadModal.scrollRegionAriaLabel'), children: [jsxs("div", { className: "grid gap-2", children: [jsx(Label$2, { htmlFor: "github-repo-url", children: t('resourceModalGithubFileUploadModal.repoUrlLabel') }), jsx(Input, { id: "github-repo-url", type: "url", placeholder: t('resourceModalGithubFileUploadModal.githubRepoUrlPlaceholder'), value: githubUrl, onChange: (e) => setGithubUrl(e.target.value), autoComplete: "url", disabled: isAddTrainingDocumentLoading, "aria-describedby": error ? 'github-repo-url-error' : undefined, "aria-invalid": !!error }), error ? (jsx("p", { id: "github-repo-url-error", className: "text-destructive -mt-1 text-xs", role: "alert", children: error })) : null] }), jsxs("div", { className: "grid gap-2", children: [jsx(Label$2, { htmlFor: "github-branch", children: t('resourceModalGithubFileUploadModal.branchLabel') }), jsxs(Select$1, { value: branch, onValueChange: (value) => setBranch(value), disabled: isLoadingDisabled, children: [jsx(SelectTrigger, { id: "github-branch", className: "w-full", children: jsx(SelectValue, { placeholder: t('resourceModalGithubFileUploadModal.selectBranchPlaceholder') }) }), jsx(SelectContent, { children: branches.map((b) => (jsx(SelectItem, { value: b, children: b }, b))) })] })] })] }), jsx(ResourceDialogFooter, { children: jsx(Button$1, { onClick: handleSubmit, disabled: isDisabled, className: RESOURCE_SUBMIT_BUTTON_CLASS, children: t('resourceModalGithubFileUploadModal.submit') }) })] }));
244929
245109
  }
244930
245110
 
244931
245111
  /**
@@ -245045,18 +245225,18 @@ function LocalFileUploadModal({ resource, maxFileSizeMB = DEFAULT_MAX_FILE_SIZE_
245045
245225
  handleUploadFile();
245046
245226
  }
245047
245227
  };
245048
- return (jsxs("div", { className: "flex flex-col items-center", children: [jsxs("div", { className: `w-full max-w-sm border-2 border-dashed ${isDraggingFile
245049
- ? 'border-blue-400 bg-blue-50/50 backdrop-blur-sm'
245050
- : 'border-gray-300 bg-gray-50'} flex flex-col items-center justify-center rounded-lg p-8 transition-all duration-200 ${!isDraggingFile && 'hover:bg-gray-100'}`, onDragOver: handleDragOver, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [jsx("div", { className: "mb-4 rounded-full bg-blue-100 p-3", children: jsx(Upload, { className: "h-8 w-8 text-blue-600" }) }), jsx("h3", { className: "mb-1 text-lg font-medium text-gray-700", children: t('resourceModalLocalFileUploadModal.dragAndDrop') }), jsx("p", { className: "mb-4 text-sm text-gray-500", children: t('resourceModalLocalFileUploadModal.or') }), jsxs("label", { htmlFor: "file-upload", className: "cursor-pointer", children: [jsx("div", { className: "rounded-md bg-gradient-to-r from-blue-600 to-blue-400 px-4 py-2 font-medium text-white transition-colors hover:opacity-90", children: t('resourceModalLocalFileUploadModal.browseFiles') }), jsx("input", { id: "file-upload", type: "file", accept: resource.accept, className: "hidden", ref: fileInputRef, onChange: handleFileChange })] }), jsx("p", { className: "mt-4 text-xs text-gray-500", children: t('resourceModalLocalFileUploadModal.maximumFileSize', {
245051
- value: maxFileSize.value,
245052
- unit: maxFileSize.unit,
245053
- }) }), file && (jsxs(Fragment$1, { children: [jsx("div", { className: "mt-4 flex w-full items-center rounded-md border border-gray-200 bg-white p-3", children: jsxs("div", { className: "flex w-full items-center", children: [jsx("div", { className: "mr-3 flex-shrink-0 rounded-md bg-blue-100 p-2", children: jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("path", { d: "M14 2H6C4.9 2 4 2.9 4 4V20C4 21.1 4.9 22 6 22H18C19.1 22 20 21.1 20 20V8L14 2Z", fill: "#4285F4" }), jsx("path", { d: "M14 2V8H20L14 2Z", fill: "#A1C2FA" })] }) }), jsxs("div", { className: "isolate z-50 min-w-0 flex-1 overflow-hidden", children: [jsx("p", { className: "truncate text-sm font-medium", children: file.name }), jsxs("p", { className: "text-xs text-gray-500", children: [convertFromBytes(file.size).value, " ", convertFromBytes(file.size).unit] })] }), jsx("button", { onClick: () => {
245054
- setFile(null);
245055
- setDescription('');
245056
- if (fileInputRef.current) {
245057
- fileInputRef.current.value = '';
245058
- }
245059
- }, className: "ml-2 flex-shrink-0 rounded-full p-1 transition-colors hover:bg-gray-100", children: jsx(X$1, { className: "h-4 w-4 text-gray-500" }) })] }) }), isImageFile(file) && (jsxs("div", { className: "mt-3 w-full", children: [jsx("label", { htmlFor: "image-description", className: "mb-1 block text-sm font-medium text-gray-700", children: t('resourceModalLocalFileUploadModal.descriptionOptional') }), jsx(Textarea, { id: "image-description", value: description, onChange: (e) => setDescription(e.target.value), placeholder: t('resourceModalLocalFileUploadModal.descriptionPlaceholder'), className: "resize-none", rows: 3 })] }))] }))] }), jsx("div", { className: "mt-4 flex w-full justify-end", children: jsx(Button$1, { onClick: handleSubmit, disabled: !file || isDisabled, className: `${file ? 'bg-gradient-to-r from-blue-600 to-blue-400 text-white' : 'bg-gray-100 text-gray-500'} hover:opacity-90`, children: isAddTrainingDocumentLoading ? (jsxs(Fragment$1, { children: [jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" }), ' ', t('resourceModalLocalFileUploadModal.submitting')] })) : (jsx(Fragment$1, { children: t('resourceModalLocalFileUploadModal.submit') })) }) })] }));
245228
+ return (jsxs(Fragment$1, { children: [jsx(ResourceDialogBody, { label: t('resourceModalLocalFileUploadModal.scrollRegionAriaLabel'), children: jsxs("div", { className: `w-full border-2 border-dashed ${isDraggingFile
245229
+ ? 'border-blue-400 bg-blue-50/50 backdrop-blur-sm'
245230
+ : 'border-gray-300 bg-gray-50'} flex flex-col items-center justify-center rounded-lg p-8 transition-all duration-200 ${!isDraggingFile && 'hover:bg-gray-100'}`, onDragOver: handleDragOver, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [jsx("div", { className: "mb-4 rounded-full bg-blue-100 p-3", children: jsx(Upload, { className: "h-8 w-8 text-blue-600" }) }), jsx("h3", { className: "mb-1 text-lg font-medium text-gray-700", children: t('resourceModalLocalFileUploadModal.dragAndDrop') }), jsx("p", { className: "mb-4 text-sm text-gray-500", children: t('resourceModalLocalFileUploadModal.or') }), jsxs("label", { htmlFor: "file-upload", className: "cursor-pointer", children: [jsx("div", { className: "rounded-md bg-gradient-to-r from-blue-600 to-blue-400 px-4 py-2 font-medium text-white transition-colors hover:opacity-90", children: t('resourceModalLocalFileUploadModal.browseFiles') }), jsx("input", { id: "file-upload", type: "file", accept: resource.accept, className: "hidden", ref: fileInputRef, onChange: handleFileChange })] }), jsx("p", { className: "mt-4 text-xs text-gray-500", children: t('resourceModalLocalFileUploadModal.maximumFileSize', {
245231
+ value: maxFileSize.value,
245232
+ unit: maxFileSize.unit,
245233
+ }) }), file && (jsxs(Fragment$1, { children: [jsx("div", { className: "mt-4 flex w-full items-center rounded-md border border-gray-200 bg-white p-3", children: jsxs("div", { className: "flex w-full items-center", children: [jsx("div", { className: "mr-3 flex-shrink-0 rounded-md bg-blue-100 p-2", children: jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("path", { d: "M14 2H6C4.9 2 4 2.9 4 4V20C4 21.1 4.9 22 6 22H18C19.1 22 20 21.1 20 20V8L14 2Z", fill: "#4285F4" }), jsx("path", { d: "M14 2V8H20L14 2Z", fill: "#A1C2FA" })] }) }), jsxs("div", { className: "isolate z-50 min-w-0 flex-1 overflow-hidden", children: [jsx("p", { className: "truncate text-sm font-medium", children: file.name }), jsxs("p", { className: "text-xs text-gray-500", children: [convertFromBytes(file.size).value, " ", convertFromBytes(file.size).unit] })] }), jsx("button", { onClick: () => {
245234
+ setFile(null);
245235
+ setDescription('');
245236
+ if (fileInputRef.current) {
245237
+ fileInputRef.current.value = '';
245238
+ }
245239
+ }, className: "ml-2 flex-shrink-0 rounded-full p-1 transition-colors hover:bg-gray-100", children: jsx(X$1, { className: "h-4 w-4 text-gray-500" }) })] }) }), isImageFile(file) && (jsxs("div", { className: "mt-3 grid w-full gap-2", children: [jsx(Label$2, { htmlFor: "image-description", children: t('resourceModalLocalFileUploadModal.descriptionOptional') }), jsx(Textarea, { id: "image-description", value: description, onChange: (e) => setDescription(e.target.value), placeholder: t('resourceModalLocalFileUploadModal.descriptionPlaceholder'), className: "resize-none", rows: 3 })] }))] }))] }) }), jsx(ResourceDialogFooter, { children: jsx(Button$1, { onClick: handleSubmit, disabled: !file || isDisabled, className: RESOURCE_SUBMIT_BUTTON_CLASS, children: isAddTrainingDocumentLoading ? (jsxs(Fragment$1, { children: [jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" }), ' ', t('resourceModalLocalFileUploadModal.submitting')] })) : (jsx(Fragment$1, { children: t('resourceModalLocalFileUploadModal.submit') })) }) })] }));
245060
245240
  }
245061
245241
 
245062
245242
  function UrlUploadModal({ resource }) {
@@ -245125,9 +245305,7 @@ function UrlUploadModal({ resource }) {
245125
245305
  handleSubmitUrl();
245126
245306
  }
245127
245307
  };
245128
- return (jsxs("div", { className: "flex flex-col space-y-4", children: [jsx(Input, { type: "url", placeholder: t('resourceModalUrlUploadModal.urlPlaceholder'), value: url, onChange: handleUrlChange, autoComplete: "url" }), jsx("div", { className: "flex justify-end", children: jsx(Button$1, { onClick: handleSubmit, disabled: !url || isDisabled, className: cn('cursor-pointer hover:opacity-90', url
245129
- ? 'bg-gradient-to-r from-blue-600 to-blue-400 text-white'
245130
- : 'bg-gray-100 text-gray-500'), children: t('resourceModalUrlUploadModal.submit') }) })] }));
245308
+ return (jsxs(Fragment$1, { children: [jsx(ResourceDialogBody, { label: t('resourceModalUrlUploadModal.scrollRegionAriaLabel'), children: jsxs("div", { className: "grid gap-2", children: [jsx(Label$2, { htmlFor: "resource-url", children: t('resourceModalUrlUploadModal.urlLabel') }), jsx(Input, { id: "resource-url", type: "url", placeholder: t('resourceModalUrlUploadModal.urlPlaceholder'), value: url, onChange: handleUrlChange, autoComplete: "url" })] }) }), jsx(ResourceDialogFooter, { children: jsx(Button$1, { onClick: handleSubmit, disabled: !url || isDisabled, className: RESOURCE_SUBMIT_BUTTON_CLASS, children: t('resourceModalUrlUploadModal.submit') }) })] }));
245131
245309
  }
245132
245310
 
245133
245311
  function useWebsiteCrawlerResource(resource) {
@@ -245152,9 +245330,11 @@ function useWebsiteCrawlerResource(resource) {
245152
245330
  crawler_match_patterns: [],
245153
245331
  crawler_pattern_type: 'glob',
245154
245332
  temp_crawler_match_patterns: '',
245333
+ crawler_user_agent: '',
245155
245334
  },
245156
245335
  onSubmit: async ({ value }) => {
245157
245336
  try {
245337
+ const crawlerUserAgent = value.crawler_user_agent.trim();
245158
245338
  await addTrainingDocument({
245159
245339
  org: tenantKey,
245160
245340
  formData: {
@@ -245166,6 +245346,11 @@ function useWebsiteCrawlerResource(resource) {
245166
245346
  crawler_match_patterns: crawlerMatchPatterns,
245167
245347
  //@ts-expect-error crawler_pattern_type may not be on the typed args but is accepted by the API
245168
245348
  crawler_pattern_type: value.crawler_pattern_type,
245349
+ // Per-document User-Agent override; sent only when set so the
245350
+ // backend default applies otherwise.
245351
+ ...(crawlerUserAgent
245352
+ ? { crawler_extra_headers: { 'User-Agent': crawlerUserAgent } }
245353
+ : {}),
245169
245354
  },
245170
245355
  userId: username !== null && username !== void 0 ? username : '',
245171
245356
  }).unwrap();
@@ -245192,30 +245377,30 @@ function useWebsiteCrawlerResource(resource) {
245192
245377
  function WebsiteCrawlModal({ resource }) {
245193
245378
  const t = useT();
245194
245379
  const { form, handleCheckUrlIsValid, crawlerMatchPatterns, setCrawlerMatchPatterns } = useWebsiteCrawlerResource(resource);
245195
- return (jsxs(Card$1, { className: "mx-auto w-full max-w-2xl", role: "dialog", "aria-labelledby": "crawler-title", "aria-describedby": "crawler-description", children: [jsxs(CardHeader, { children: [jsx(CardTitle, { id: "crawler-title", className: "text-md font-semibold text-gray-600", children: t('resourceModalWebsiteCrawlModal.title') }), jsx("p", { id: "crawler-description", className: "text-muted-foreground text-sm", children: t('resourceModalWebsiteCrawlModal.description') })] }), jsx(CardContent, { children: jsx("form", { className: "space-y-4", onSubmit: (e) => {
245196
- e.preventDefault();
245197
- e.stopPropagation();
245198
- form.handleSubmit();
245199
- }, "aria-label": t('resourceModalWebsiteCrawlModal.formAriaLabel'), children: jsxs(Fragment$1, { children: [jsx(form.Field, { name: "url", validators: {
245380
+ return (jsxs("form", { className: "flex min-h-0 flex-1 flex-col", onSubmit: (e) => {
245381
+ e.preventDefault();
245382
+ e.stopPropagation();
245383
+ form.handleSubmit();
245384
+ }, "aria-label": t('resourceModalWebsiteCrawlModal.formAriaLabel'), children: [jsxs(ResourceDialogBody, { label: t('resourceModalWebsiteCrawlModal.scrollRegionAriaLabel'), children: [jsx("div", { className: "rounded-md border border-gray-200 bg-gray-50 p-3 text-xs text-gray-600", children: t('resourceModalWebsiteCrawlModal.infoBox') }), jsxs(Fragment$1, { children: [jsx(form.Field, { name: "url", validators: {
245200
245385
  onChange: ({ value }) => (!value && t('resourceModalWebsiteCrawlModal.urlRequired')) ||
245201
245386
  (!handleCheckUrlIsValid(value) && t('resourceModalWebsiteCrawlModal.invalidUrl')),
245202
245387
  }, children: (field) => {
245203
245388
  var _a, _b, _c;
245204
- return (jsxs("div", { className: "grid gap-2", children: [jsx(Label$2, { htmlFor: field.name, children: t('resourceModalWebsiteCrawlModal.urlLabel') }), jsx(Input, { id: field.name, type: "url", value: field.state.value, onChange: (e) => field.handleChange(e.target.value), placeholder: t('resourceModalWebsiteCrawlModal.urlPlaceholder'), "aria-describedby": ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) ? `${field.name}-error` : undefined, "aria-invalid": !!((_b = field.state.meta.errors) === null || _b === void 0 ? void 0 : _b.length), "aria-required": "true" }), ((_c = field.state.meta.errors) === null || _c === void 0 ? void 0 : _c.length) ? (jsx("p", { id: `${field.name}-error`, className: "text-destructive mb-2 text-sm", role: "alert", children: field.state.meta.errors })) : null] }));
245389
+ return (jsxs("div", { className: "grid gap-2", children: [jsx(Label$2, { htmlFor: field.name, children: t('resourceModalWebsiteCrawlModal.urlLabel') }), jsx(Input, { id: field.name, type: "url", value: field.state.value, onChange: (e) => field.handleChange(e.target.value), placeholder: t('resourceModalWebsiteCrawlModal.urlPlaceholder'), "aria-describedby": ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) ? `${field.name}-error` : undefined, "aria-invalid": !!((_b = field.state.meta.errors) === null || _b === void 0 ? void 0 : _b.length), "aria-required": "true" }), ((_c = field.state.meta.errors) === null || _c === void 0 ? void 0 : _c.length) ? (jsx("p", { id: `${field.name}-error`, className: "text-destructive -mt-1 text-xs", role: "alert", children: field.state.meta.errors })) : null] }));
245205
245390
  } }), jsxs("div", { className: "grid grid-cols-2 gap-4", children: [jsx(form.Field, { name: "crawler_max_depth", validators: {
245206
245391
  onChange: ({ value }) => (!value && t('resourceModalWebsiteCrawlModal.fieldRequired')) ||
245207
245392
  (value < 1 && t('resourceModalWebsiteCrawlModal.mustBeGreaterThanZero')) ||
245208
245393
  (value > 10000 && t('resourceModalWebsiteCrawlModal.mustBeLessThan10000')),
245209
245394
  }, children: (field) => {
245210
245395
  var _a, _b, _c;
245211
- return (jsxs("div", { className: "grid gap-2", children: [jsx(Label$2, { htmlFor: field.name, children: t('resourceModalWebsiteCrawlModal.maxCrawlDepthLabel') }), jsx(Input, { id: field.name, type: "number", min: "1", max: "10000", value: field.state.value, onChange: (e) => field.handleChange(Number.parseInt(e.target.value)), "aria-describedby": ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) ? `${field.name}-error` : undefined, "aria-invalid": !!((_b = field.state.meta.errors) === null || _b === void 0 ? void 0 : _b.length), "aria-required": "true" }), ((_c = field.state.meta.errors) === null || _c === void 0 ? void 0 : _c.length) ? (jsx("p", { id: `${field.name}-error`, className: "text-destructive mb-2 text-sm", role: "alert", children: field.state.meta.errors })) : null] }));
245396
+ return (jsxs("div", { className: "grid gap-2", children: [jsx(Label$2, { htmlFor: field.name, children: t('resourceModalWebsiteCrawlModal.maxCrawlDepthLabel') }), jsx(Input, { id: field.name, type: "number", min: "1", max: "10000", value: field.state.value, onChange: (e) => field.handleChange(Number.parseInt(e.target.value)), "aria-describedby": ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) ? `${field.name}-error` : undefined, "aria-invalid": !!((_b = field.state.meta.errors) === null || _b === void 0 ? void 0 : _b.length), "aria-required": "true" }), ((_c = field.state.meta.errors) === null || _c === void 0 ? void 0 : _c.length) ? (jsx("p", { id: `${field.name}-error`, className: "text-destructive -mt-1 text-xs", role: "alert", children: field.state.meta.errors })) : null] }));
245212
245397
  } }), jsx(form.Field, { name: "crawler_max_pages_limit", validators: {
245213
245398
  onChange: ({ value }) => (!value && t('resourceModalWebsiteCrawlModal.fieldRequired')) ||
245214
245399
  (value < 1 && t('resourceModalWebsiteCrawlModal.mustBeGreaterThanZero')),
245215
245400
  }, children: (field) => {
245216
245401
  var _a, _b, _c;
245217
- return (jsxs("div", { className: "grid gap-2", children: [jsx(Label$2, { htmlFor: field.name, children: t('resourceModalWebsiteCrawlModal.maxPagesLimitLabel') }), jsx(Input, { id: field.name, type: "number", min: "1", value: field.state.value, onChange: (e) => field.handleChange(Number.parseInt(e.target.value)), "aria-describedby": ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) ? `${field.name}-error` : undefined, "aria-invalid": !!((_b = field.state.meta.errors) === null || _b === void 0 ? void 0 : _b.length), "aria-required": "true" }), ((_c = field.state.meta.errors) === null || _c === void 0 ? void 0 : _c.length) ? (jsx("p", { id: `${field.name}-error`, className: "text-destructive mb-2 text-sm", role: "alert", children: field.state.meta.errors })) : null] }));
245218
- } })] }), jsx(form.Field, { name: "crawler_pattern_type", children: (field) => (jsxs("div", { className: "grid gap-2", children: [jsx(Label$2, { htmlFor: "pattern-type", children: t('resourceModalWebsiteCrawlModal.patternTypeLabel') }), jsxs(Select$1, { value: field.state.value, onValueChange: (value) => field.handleChange(value), children: [jsx(SelectTrigger, { id: "pattern-type", "aria-label": t('resourceModalWebsiteCrawlModal.selectPatternTypeAriaLabel'), children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "glob", children: t('resourceModalWebsiteCrawlModal.globPattern') }), jsx(SelectItem, { value: "regex", children: t('resourceModalWebsiteCrawlModal.regularExpression') })] })] })] })) }), jsx(form.Subscribe, { selector: (state) => [
245402
+ return (jsxs("div", { className: "grid gap-2", children: [jsx(Label$2, { htmlFor: field.name, children: t('resourceModalWebsiteCrawlModal.maxPagesLimitLabel') }), jsx(Input, { id: field.name, type: "number", min: "1", value: field.state.value, onChange: (e) => field.handleChange(Number.parseInt(e.target.value)), "aria-describedby": ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) ? `${field.name}-error` : undefined, "aria-invalid": !!((_b = field.state.meta.errors) === null || _b === void 0 ? void 0 : _b.length), "aria-required": "true" }), ((_c = field.state.meta.errors) === null || _c === void 0 ? void 0 : _c.length) ? (jsx("p", { id: `${field.name}-error`, className: "text-destructive -mt-1 text-xs", role: "alert", children: field.state.meta.errors })) : null] }));
245403
+ } })] }), jsx(form.Field, { name: "crawler_pattern_type", children: (field) => (jsxs("div", { className: "grid gap-2", children: [jsx(Label$2, { htmlFor: "pattern-type", children: t('resourceModalWebsiteCrawlModal.patternTypeLabel') }), jsxs(Select$1, { value: field.state.value, onValueChange: (value) => field.handleChange(value), children: [jsx(SelectTrigger, { id: "pattern-type", "aria-label": t('resourceModalWebsiteCrawlModal.selectPatternTypeAriaLabel'), children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "glob", children: t('resourceModalWebsiteCrawlModal.globPattern') }), jsx(SelectItem, { value: "regex", children: t('resourceModalWebsiteCrawlModal.regularExpression') })] })] })] })) }), jsx(form.Field, { name: "crawler_user_agent", children: (field) => (jsxs("div", { className: "grid gap-2", children: [jsx(Label$2, { htmlFor: field.name, children: t('resourceModalWebsiteCrawlModal.userAgentLabel') }), jsx(Input, { id: field.name, type: "text", value: field.state.value, onChange: (e) => field.handleChange(e.target.value), placeholder: t('resourceModalWebsiteCrawlModal.userAgentPlaceholder'), "aria-describedby": "user-agent-help" }), jsx("p", { id: "user-agent-help", className: "text-muted-foreground -mt-1 text-xs", children: t('resourceModalWebsiteCrawlModal.userAgentHelpText') })] })) }), jsx(form.Subscribe, { selector: (state) => [
245219
245404
  state.values.temp_crawler_match_patterns,
245220
245405
  state.values.crawler_pattern_type,
245221
245406
  ], children: ([tempCrawlerMatchPatterns, crawlerPatternType]) => (jsx(form.Field, { name: "temp_crawler_match_patterns", validators: {
@@ -245246,14 +245431,24 @@ function WebsiteCrawlModal({ resource }) {
245246
245431
  ]);
245247
245432
  field.handleChange('');
245248
245433
  }
245249
- }, disabled: !String(tempCrawlerMatchPatterns).trim(), size: "sm", "aria-label": t('resourceModalWebsiteCrawlModal.addPatternAriaLabel'), children: jsx(Plus, { className: "h-4 w-4" }) })] }), ((_c = field.state.meta.errors) === null || _c === void 0 ? void 0 : _c.length) ? (jsx("p", { id: "pattern-error", className: "text-destructive mb-2 text-sm", role: "alert", children: field.state.meta.errors })) : null, jsx("p", { id: "pattern-help", className: "text-muted-foreground text-sm", children: t('resourceModalWebsiteCrawlModal.patternHelpText') }), jsx("div", { className: "bg-muted/50 flex min-h-[2rem] flex-wrap gap-2 rounded-md border p-2", role: "list", "aria-label": t('resourceModalWebsiteCrawlModal.addedPatternsAriaLabel'), children: crawlerMatchPatterns.length === 0 ? (jsx("span", { className: "text-muted-foreground text-sm", children: t('resourceModalWebsiteCrawlModal.noPatternsAdded') })) : (crawlerMatchPatterns.map((pattern, index) => (jsxs(Badge, { variant: "secondary", className: "flex items-center gap-1", children: [jsx("span", { className: "text-xs", children: pattern }), jsx("button", { type: "button", onClick: () => setCrawlerMatchPatterns(crawlerMatchPatterns.filter((p) => p !== pattern)), className: "hover:bg-destructive/20 ml-1 rounded-full p-0.5", "aria-label": t('resourceModalWebsiteCrawlModal.removePatternAriaLabel', { pattern }), children: jsx(X$1, { className: "h-3 w-3" }) })] }, index)))) })] })] }));
245250
- } })) }), jsx(form.Subscribe, { selector: (state) => [state.isSubmitting], children: ([isSubmitting]) => (jsxs("div", { className: "flex gap-3 pt-4", children: [jsx(Button$1, { type: "submit", className: "w-full bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-sm text-white hover:text-white hover:opacity-90", disabled: isSubmitting, "aria-describedby": isSubmitting ? 'submitting-status' : undefined, children: isSubmitting
245251
- ? t('resourceModalWebsiteCrawlModal.submitting')
245252
- : t('resourceModalWebsiteCrawlModal.submit') }), isSubmitting && (jsx("div", { id: "submitting-status", className: "sr-only", role: "status", "aria-live": "polite", children: t('resourceModalWebsiteCrawlModal.formBeingSubmitted') }))] })) })] }) }) })] }));
245253
- }
245254
-
245255
- function ResourceModal({ resource, isOpen, onClose }) {
245256
- return (jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: jsxs(DialogContent, { className: "w-full max-w-md", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "text-muted-foreground text-base", children: resource.name }) }), resource.type === 'github' && jsx(GithubFileUploadModal, {}), resource.type === 'local' && jsx(LocalFileUploadModal, { resource: resource }), resource.type === 'webcrawler' && jsx(WebsiteCrawlModal, { resource: resource }), resource.type === 'url' && jsx(UrlUploadModal, { resource: resource })] }) }));
245434
+ }, disabled: !String(tempCrawlerMatchPatterns).trim(), size: "sm", "aria-label": t('resourceModalWebsiteCrawlModal.addPatternAriaLabel'), children: jsx(Plus, { className: "h-4 w-4" }) })] }), ((_c = field.state.meta.errors) === null || _c === void 0 ? void 0 : _c.length) ? (jsx("p", { id: "pattern-error", className: "text-destructive -mt-1 text-xs", role: "alert", children: field.state.meta.errors })) : null, jsx("p", { id: "pattern-help", className: "text-muted-foreground -mt-1 text-xs", children: t('resourceModalWebsiteCrawlModal.patternHelpText') }), jsx("div", { className: "bg-muted/50 flex min-h-[2rem] flex-wrap gap-2 rounded-md border p-2", role: "list", "aria-label": t('resourceModalWebsiteCrawlModal.addedPatternsAriaLabel'), children: crawlerMatchPatterns.length === 0 ? (jsx("span", { className: "text-muted-foreground text-xs", children: t('resourceModalWebsiteCrawlModal.noPatternsAdded') })) : (crawlerMatchPatterns.map((pattern, index) => (jsxs(Badge, { variant: "secondary", className: "flex items-center gap-1", children: [jsx("span", { className: "text-xs", children: pattern }), jsx("button", { type: "button", onClick: () => setCrawlerMatchPatterns(crawlerMatchPatterns.filter((p) => p !== pattern)), className: "hover:bg-destructive/20 ml-1 rounded-full p-0.5", "aria-label": t('resourceModalWebsiteCrawlModal.removePatternAriaLabel', { pattern }), children: jsx(X$1, { className: "h-3 w-3" }) })] }, index)))) })] })] }));
245435
+ } })) })] })] }), jsx(form.Subscribe, { selector: (state) => [state.isSubmitting], children: ([isSubmitting]) => (jsxs(ResourceDialogFooter, { children: [jsx(Button$1, { type: "submit", className: RESOURCE_SUBMIT_BUTTON_CLASS, disabled: isSubmitting, "aria-describedby": isSubmitting ? 'submitting-status' : undefined, children: isSubmitting
245436
+ ? t('resourceModalWebsiteCrawlModal.submitting')
245437
+ : t('resourceModalWebsiteCrawlModal.submit') }), isSubmitting && (jsx("div", { id: "submitting-status", className: "sr-only", role: "status", "aria-live": "polite", children: t('resourceModalWebsiteCrawlModal.formBeingSubmitted') }))] })) })] }));
245438
+ }
245439
+
245440
+ // `link` types open a cloud picker instead of this dialog; it maps to the
245441
+ // generic Add Resources copy only to keep the record total.
245442
+ const DESCRIPTION_KEYS = {
245443
+ github: 'resourceModalGithubFileUploadModal.description',
245444
+ local: 'resourceModalLocalFileUploadModal.description',
245445
+ url: 'resourceModalUrlUploadModal.description',
245446
+ webcrawler: 'resourceModalWebsiteCrawlModal.description',
245447
+ link: 'datasetsTabAddResourceModal.description',
245448
+ };
245449
+ function ResourceModal({ resource, isOpen, onClose, maxFileSizeMB }) {
245450
+ const t = useT();
245451
+ return (jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: jsxs(ResourceDialogContent, { title: resource.name, description: t(DESCRIPTION_KEYS[resource.type]), children: [resource.type === 'github' && jsx(GithubFileUploadModal, {}), resource.type === 'local' && (jsx(LocalFileUploadModal, { resource: resource, maxFileSizeMB: maxFileSizeMB })), resource.type === 'webcrawler' && jsx(WebsiteCrawlModal, { resource: resource }), resource.type === 'url' && jsx(UrlUploadModal, { resource: resource })] }) }));
245257
245452
  }
245258
245453
 
245259
245454
  var bundle = {exports: {}};
@@ -245266,6 +245461,8 @@ var bundle = {exports: {}};
245266
245461
  var bundleExports = bundle.exports;
245267
245462
  var GoogleDrivePicker = /*@__PURE__*/getDefaultExportFromCjs(bundleExports);
245268
245463
 
245464
+ /** Least-privilege scope: only files the user picks/creates via the picker. */
245465
+ const GOOGLE_DRIVE_SCOPES = ['https://www.googleapis.com/auth/drive.file'];
245269
245466
  const useGoogleDrivePicker = ({ tenantKey, mentorId }) => {
245270
245467
  const [authToken, setAuthToken] = React__default.useState(null);
245271
245468
  const [driveFiles, setDriveFiles] = React__default.useState([]);
@@ -245340,10 +245537,7 @@ const useGoogleDrivePicker = ({ tenantKey, mentorId }) => {
245340
245537
  refresh_token: 'test-refresh token',
245341
245538
  client_id: credentials.client_id,
245342
245539
  token: authToken === null || authToken === void 0 ? void 0 : authToken.access_token,
245343
- scopes: [
245344
- 'https://www.googleapis.com/auth/drive.metadata.readonly',
245345
- 'https://www.googleapis.com/auth/drive.readonly',
245346
- ],
245540
+ scopes: GOOGLE_DRIVE_SCOPES,
245347
245541
  token_type: authToken === null || authToken === void 0 ? void 0 : authToken.token_type,
245348
245542
  expiry_date: new Date(Date.now() + ((authToken === null || authToken === void 0 ? void 0 : authToken.expires_in) || 0) * 1000).toISOString(),
245349
245543
  },
@@ -245437,10 +245631,7 @@ const useGoogleDrivePicker = ({ tenantKey, mentorId }) => {
245437
245631
  openPicker({
245438
245632
  clientId: credentials.client_id,
245439
245633
  developerKey: credentials.developer_key,
245440
- customScopes: [
245441
- 'https://www.googleapis.com/auth/drive.metadata.readonly',
245442
- 'https://www.googleapis.com/auth/drive.readonly',
245443
- ],
245634
+ customScopes: GOOGLE_DRIVE_SCOPES,
245444
245635
  // @ts-expect-error - token accepts null to force fresh auth per google-drive-picker API
245445
245636
  token: null, // Always start with null token to force fresh auth
245446
245637
  showUploadView: true,
@@ -245528,6 +245719,8 @@ const useGoogleDrivePicker = ({ tenantKey, mentorId }) => {
245528
245719
  forceClosePickerModal,
245529
245720
  pickerError,
245530
245721
  resetPickerState,
245722
+ credentialsLoaded: credentialLoaded,
245723
+ isConfigured: Boolean(credentials.client_id),
245531
245724
  };
245532
245725
  };
245533
245726
 
@@ -245598,6 +245791,7 @@ function ieOnEnd (script, cb) {
245598
245791
 
245599
245792
  var loadScript = /*@__PURE__*/getDefaultExportFromCjs(loadScript$1);
245600
245793
 
245794
+ /** Default file types offered by the Dropbox chooser. Hosts override via `extensions`. */
245601
245795
  const DROPBOX_EXTENSIONS = [
245602
245796
  '.pdf',
245603
245797
  '.doc',
@@ -245609,6 +245803,12 @@ const DROPBOX_EXTENSIONS = [
245609
245803
  '.xlsx',
245610
245804
  '.ppt',
245611
245805
  '.pptx',
245806
+ '.png',
245807
+ '.jpeg',
245808
+ '.jpg',
245809
+ '.mp3',
245810
+ '.wav',
245811
+ '.m4a',
245612
245812
  ];
245613
245813
  const DROPBOX_SDK_URL = 'https://www.dropbox.com/static/api/2/dropins.js';
245614
245814
  const SCRIPT_ID = 'dropboxjs';
@@ -245617,6 +245817,7 @@ const useDropboxPicker = ({ tenantKey, mentorId, cancel = () => { }, linkType =
245617
245817
  const [dropboxReady, setDropboxReady] = useState(false);
245618
245818
  const [openChooser, setOpenChooser] = useState(false);
245619
245819
  const [appKey, setAppKey] = useState(null);
245820
+ const [credentialsLoaded, setCredentialsLoaded] = useState(false);
245620
245821
  // Use RTK Query hooks
245621
245822
  const [getCredentials] = useLazyGetCredentialsQuery();
245622
245823
  const [addTrainingDocument] = useAddTrainingDocumentMutation();
@@ -245639,6 +245840,7 @@ const useDropboxPicker = ({ tenantKey, mentorId, cancel = () => { }, linkType =
245639
245840
  catch (error) {
245640
245841
  console.error(JSON.stringify({ tenant: tenantKey, error }));
245641
245842
  }
245843
+ setCredentialsLoaded(true);
245642
245844
  }
245643
245845
  };
245644
245846
  handleFetchAppKey();
@@ -245736,6 +245938,8 @@ const useDropboxPicker = ({ tenantKey, mentorId, cancel = () => { }, linkType =
245736
245938
  openChooser: onChoose,
245737
245939
  dropboxReady,
245738
245940
  appKey,
245941
+ credentialsLoaded,
245942
+ isConfigured: Boolean(appKey),
245739
245943
  };
245740
245944
  };
245741
245945
 
@@ -245745,6 +245949,7 @@ const useOneDrivePicker = ({ tenantKey, mentorId }) => {
245745
245949
  const [onedriveAppId, setOnedriveAppId] = useState(null);
245746
245950
  const [fullDomain, setFullDomain] = useState(null);
245747
245951
  const [isSDKLoaded, setIsSDKLoaded] = useState(false);
245952
+ const [credentialsLoaded, setCredentialsLoaded] = useState(false);
245748
245953
  // Use RTK Query hooks
245749
245954
  const [getCredentials] = useLazyGetCredentialsQuery();
245750
245955
  const [addTrainingDocument] = useAddTrainingDocumentMutation();
@@ -245859,6 +246064,7 @@ const useOneDrivePicker = ({ tenantKey, mentorId }) => {
245859
246064
  catch (error) {
245860
246065
  console.error(JSON.stringify({ tenant: tenantKey, error }));
245861
246066
  }
246067
+ setCredentialsLoaded(true);
245862
246068
  }
245863
246069
  };
245864
246070
  handleFetchAppId();
@@ -245951,46 +246157,81 @@ const useOneDrivePicker = ({ tenantKey, mentorId }) => {
245951
246157
  pickOneDriveFile,
245952
246158
  onedriveAppId,
245953
246159
  isSDKLoaded,
246160
+ credentialsLoaded,
246161
+ isConfigured: Boolean(onedriveAppId),
245954
246162
  };
245955
246163
  };
245956
246164
 
245957
- function AddResourceModal({ isOpen, onClose, disabledDatasets = [], }) {
246165
+ function AddResourceModal({ isOpen, onClose, disabledDatasets = [], maxFileSizeMB, dropboxExtensions, }) {
245958
246166
  const t = useT();
245959
246167
  const { tenantKey, mentorId } = useAgentSettings();
245960
246168
  const [selectedResource, setSelectedResource] = React__default.useState(null);
245961
- const { openChooser } = useDropboxPicker({
246169
+ const dropbox = useDropboxPicker({
245962
246170
  autoShow: false,
245963
246171
  tenantKey,
245964
246172
  mentorId,
245965
- });
245966
- const { handlePickerOpen, loadGoogleApiScript, isPickerLoaded, forceClosePickerModal, pickerError, } = useGoogleDrivePicker({ tenantKey, mentorId });
245967
- const { pickOneDriveFile } = useOneDrivePicker({ tenantKey, mentorId });
245968
- return (jsxs(Fragment$1, { children: [jsx(Script, { src: "https://apis.google.com/js/api.js", onLoad: loadGoogleApiScript, strategy: "lazyOnload" }), jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: jsxs(DialogContent, { className: "max-h-[90vh] overflow-y-auto sm:max-w-[800px]", children: [jsx(DialogHeader, { className: "flex flex-row items-center justify-between", children: jsx(DialogTitle, { children: t('datasetsTabAddResourceModal.title') }) }), jsx("div", { className: "pt-4", children: jsxs("div", { children: [jsx("p", { className: "mb-6 text-gray-600", children: t('datasetsTabAddResourceModal.description') }), pickerError && (jsx("div", { className: "mb-4 rounded-lg border border-red-200 bg-red-50 p-4", children: jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { children: [jsx("h4", { className: "text-sm font-medium text-red-800", children: t('datasetsTabAddResourceModal.googleDrivePickerError') }), jsx("p", { className: "mt-1 text-sm text-red-600", children: pickerError })] }), jsx("button", { onClick: forceClosePickerModal, className: "ml-4 rounded bg-red-100 px-3 py-1 text-sm font-medium text-red-800 hover:bg-red-200", children: t('datasetsTabAddResourceModal.forceClosePicker') })] }) })), jsx("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: resourceTypes.map((resource) => (jsxs("button", { className: cn('flex items-center rounded-lg border p-4 transition-colors duration-200 hover:bg-gray-50', resource.isActive && !disabledDatasets.includes(resource.id.toLowerCase())
245969
- ? 'cursor-pointer'
245970
- : 'cursor-not-allowed opacity-50'), onClick: () => {
245971
- if (resource.type !== 'link') {
245972
- setSelectedResource(resource);
245973
- return;
245974
- }
245975
- if (resource.name === 'Google Drive') {
245976
- if (isPickerLoaded) {
245977
- handlePickerOpen();
245978
- }
245979
- else {
245980
- // Show loading state or toast
245981
- console.log('Google Picker is still loading...');
245982
- }
245983
- return;
245984
- }
245985
- if (resource.name === 'Dropbox') {
245986
- openChooser();
245987
- return;
246173
+ extensions: dropboxExtensions,
246174
+ });
246175
+ const { handlePickerOpen, loadGoogleApiScript, isPickerLoaded, forceClosePickerModal, pickerError, credentialsLoaded: googleCredentialsLoaded, isConfigured: googleIsConfigured, } = useGoogleDrivePicker({ tenantKey, mentorId });
246176
+ const oneDrive = useOneDrivePicker({ tenantKey, mentorId });
246177
+ // A cloud provider only works once the tenant has OAuth credentials for it
246178
+ // (GET .../integration-credential/?name=<provider>). Without them the SDK is
246179
+ // handed an empty client id and the click does nothing at all — no popup, no
246180
+ // error — which reads as a broken button. Disable and say why instead.
246181
+ // `loaded` gates on the lookup having finished so the buttons are not
246182
+ // disabled during the in-flight fetch.
246183
+ const cloudProviders = {
246184
+ 'google-drive': {
246185
+ loaded: googleCredentialsLoaded,
246186
+ configured: googleIsConfigured,
246187
+ },
246188
+ onedrive: {
246189
+ loaded: oneDrive.credentialsLoaded,
246190
+ configured: oneDrive.isConfigured,
246191
+ },
246192
+ dropbox: {
246193
+ loaded: dropbox.credentialsLoaded,
246194
+ configured: dropbox.isConfigured,
246195
+ },
246196
+ };
246197
+ return (jsxs(Fragment$1, { children: [jsx(Script, { src: "https://apis.google.com/js/api.js", onLoad: loadGoogleApiScript, strategy: "lazyOnload" }), jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: jsx(ResourceDialogContent, { title: t('datasetsTabAddResourceModal.title'), description: t('datasetsTabAddResourceModal.description'), className: "sm:max-w-[800px]", children: jsxs(ResourceDialogBody, { label: t('datasetsTabAddResourceModal.scrollRegionAriaLabel'), children: [pickerError && (jsx("div", { className: "rounded-lg border border-red-200 bg-red-50 p-4", children: jsxs("div", { className: "flex items-center justify-between", children: [jsxs("div", { children: [jsx("h4", { className: "text-sm font-medium text-red-800", children: t('datasetsTabAddResourceModal.googleDrivePickerError') }), jsx("p", { className: "mt-1 text-sm text-red-600", children: pickerError })] }), jsx("button", { onClick: forceClosePickerModal, className: "ml-4 rounded bg-red-100 px-3 py-1 text-sm font-medium text-red-800 hover:bg-red-200", children: t('datasetsTabAddResourceModal.forceClosePicker') })] }) })), jsx("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: resourceTypes.map((resource) => {
246198
+ const cloudProvider = cloudProviders[resource.id];
246199
+ const notConfigured = cloudProvider
246200
+ ? cloudProvider.loaded && !cloudProvider.configured
246201
+ : false;
246202
+ const isDisabled = !resource.isActive ||
246203
+ disabledDatasets.includes(resource.id.toLowerCase()) ||
246204
+ notConfigured;
246205
+ return (jsxs("button", { title: notConfigured ? t('datasetsTabAddResourceModal.notConfigured') : undefined, className: cn('flex items-center rounded-lg border p-4 transition-colors duration-200 hover:bg-gray-50', !isDisabled ? 'cursor-pointer' : 'cursor-not-allowed opacity-50'), onClick: () => {
246206
+ if (resource.type !== 'link') {
246207
+ setSelectedResource(resource);
246208
+ return;
246209
+ }
246210
+ if (resource.name === 'Google Drive') {
246211
+ if (isPickerLoaded) {
246212
+ handlePickerOpen();
245988
246213
  }
245989
- if (resource.name === 'Microsoft OneDrive') {
245990
- pickOneDriveFile();
245991
- return;
246214
+ else {
246215
+ // Show loading state or toast
246216
+ console.log('Google Picker is still loading...');
245992
246217
  }
245993
- }, disabled: !resource.isActive || disabledDatasets.includes(resource.id.toLowerCase()), children: [jsx("div", { className: "mr-3 flex h-10 w-10 items-center justify-center rounded-md bg-blue-100", children: resource.icon }), jsx("span", { className: "text-gray-700", children: resource.name })] }, resource.id))) })] }) })] }) }), selectedResource && (jsx(ResourceModal, { resource: selectedResource, isOpen: !!selectedResource, onClose: () => setSelectedResource(null) }))] }));
246218
+ return;
246219
+ }
246220
+ if (resource.name === 'Dropbox') {
246221
+ dropbox.openChooser();
246222
+ return;
246223
+ }
246224
+ if (resource.name === 'Microsoft OneDrive') {
246225
+ oneDrive.pickOneDriveFile();
246226
+ return;
246227
+ }
246228
+ }, disabled: isDisabled, children: [jsx("div", { className: "mr-3 flex h-10 w-10 items-center justify-center rounded-md bg-blue-100", children: resource.icon }), jsxs("span", { className: "flex flex-col items-start text-left", children: [jsx("span", { className: "text-gray-700", children: resource.name }), notConfigured && (
246229
+ // aria-hidden: the same text is already the button's
246230
+ // `title`, so exposing it here too would append it to
246231
+ // the accessible name ("Dropbox Not configured for
246232
+ // this tenant") and break name-based lookups.
246233
+ jsx("span", { "aria-hidden": "true", className: "text-xs text-gray-500", children: t('datasetsTabAddResourceModal.notConfigured') }))] })] }, resource.id));
246234
+ }) })] }) }) }), selectedResource && (jsx(ResourceModal, { resource: selectedResource, isOpen: !!selectedResource, onClose: () => setSelectedResource(null), maxFileSizeMB: maxFileSizeMB }))] }));
245994
246235
  }
245995
246236
 
245996
246237
  // DatasetItemList requires a full labels object; without it the empty-state
@@ -246002,7 +246243,7 @@ const PROJECT_FILES_DATASET_LABELS = resolveDatasetsTabLabels({
246002
246243
  function ProjectFilesModal(props) {
246003
246244
  return (jsx(AgentSettingsProvider, { tenantKey: props.tenantKey, mentorId: props.mentorId, username: props.username, enableRBAC: false, children: jsx(ProjectFilesModalInner, { ...props }) }));
246004
246245
  }
246005
- function ProjectFilesModalInner({ isOpen, onClose }) {
246246
+ function ProjectFilesModalInner({ isOpen, onClose, disabledResourceTypes, maxUploadSizeMb, dropboxExtensions, }) {
246006
246247
  var _a;
246007
246248
  const t = useT();
246008
246249
  const [showAddResourceModal, setShowAddResourceModal] = React__default.useState(false);
@@ -246017,7 +246258,7 @@ function ProjectFilesModalInner({ isOpen, onClose }) {
246017
246258
  // @ts-expect-error - Type mismatch between RetrieverDocumentEmbedding[] and Dataset[], id property type difference
246018
246259
  , {
246019
246260
  // @ts-expect-error - Type mismatch between RetrieverDocumentEmbedding[] and Dataset[], id property type difference
246020
- datasets: (_a = datasets === null || datasets === void 0 ? void 0 : datasets.results) !== null && _a !== void 0 ? _a : [], labels: PROJECT_FILES_DATASET_LABELS })] })) }) }) }), jsx(IblPagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: handlePageChange, disabled: isDatasetsFetching || isDatasetsLoading }), jsx(AddResourceModal, { isOpen: showAddResourceModal, onClose: () => closeAddResourceModal(), keepParentOpen: true }), isModalOpen && FreeTrialDialog && (jsx(FreeTrialDialog, { isOpen: isModalOpen, onClose: closeModal }))] }) })] }) }) }));
246261
+ datasets: (_a = datasets === null || datasets === void 0 ? void 0 : datasets.results) !== null && _a !== void 0 ? _a : [], labels: PROJECT_FILES_DATASET_LABELS })] })) }) }) }), jsx(IblPagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: handlePageChange, disabled: isDatasetsFetching || isDatasetsLoading }), jsx(AddResourceModal, { isOpen: showAddResourceModal, onClose: () => closeAddResourceModal(), keepParentOpen: true, disabledDatasets: disabledResourceTypes, maxFileSizeMB: maxUploadSizeMb, dropboxExtensions: dropboxExtensions }), isModalOpen && FreeTrialDialog && (jsx(FreeTrialDialog, { isOpen: isModalOpen, onClose: closeModal }))] }) })] }) }) }));
246021
246262
  }
246022
246263
 
246023
246264
  var projectFilesModal = /*#__PURE__*/Object.freeze({