@iblai/iblai-js 2.19.1 → 2.21.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.
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
3
  import React__default, { useState, useEffect, forwardRef, createElement as createElement$3, useLayoutEffect, createContext, useContext, useMemo, useReducer, useRef, useImperativeHandle, useCallback, isValidElement, Children, PureComponent, cloneElement, Component as Component$1, Fragment as Fragment$2, useId as useId$2, useDebugValue, lazy, Suspense } from 'react';
4
4
  import * as dataLayer from '@iblai/data-layer';
5
- import { 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, useStarMentorMutation, useUnstarMentorMutation, 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, useGetLlmsQuery, 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, useGetCustomDomainsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, 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, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetAgentSkillResourcesQuery, useCreateAgentSkillResourceMutation, useUpdateAgentSkillResourceMutation, useUploadAgentSkillResourceAssetMutation, useDeleteAgentSkillResourceMutation, useGetMentorSkillAssignmentsQuery, useGetAgentSkillsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, filterSlashSkills, useGetMentorSkillAssignmentsInfiniteQuery, MENTOR_SKILL_ASSIGNMENTS_PAGE_SIZE, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useLazyGetConnectedServiceAuthUrlQuery, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorSettingsQuery, useEditMentorMutation, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, LOGO_ENDPOINTS, useCreateEvalDatasetMutation, useAddEvalDatasetItemsMutation, useUploadEvalDatasetCsvMutation, useDeleteEvalDatasetItemMutation, useListEvalDatasetItemsQuery, evalTotalPages, useListEvalDatasetsQuery, useGetUserProjectsQuery, useCreateSessionIdMutation, useGetMentorCategoriesQuery, useGetTenantChatPrivacyConfigQuery as useGetTenantChatPrivacyConfigQuery$1, useGetCallConfigurationsQuery, useCreateCallConfigurationMutation, useUpdateCallConfigurationMutation, chatPrivacyApiSlice, useDeleteMentorMutation, useForkMentorMutation, useGetToolsQuery, useLazyGetMCPServersQuery, useOauthFindMutation, useLazyStartOAuthFlowQuery, useCreateMCPServerMutation, usePartialUpdateMCPServerMutation, useCreateMCPServerConnectionMutation, usePatchMCPServerConnectionMutation, useGetConnectedServicesQuery, useGetMCPServersQuery, useGetMCPServerConnectionsQuery, useUpdateMCPServerMutation, useDeleteMCPServerMutation, useEditMentorJsonMutation, useDisconnectServiceMutation, useGetPromptCategoriesQuery, PRIVACY_ACTIONS, PRIVACY_ENTITY_TYPES, useGetVoicesQuery, useGetVoiceQuery, isBaseAgentMentor, useGetGradeResultQuery, useOverrideGradeResultMutation, useGetChatHistoryFilterQuery, useListGradeResultsQuery, useGetMentorGraderConfigurationQuery, useListGraderCriteriaQuery, useCreateMentorGraderConfigurationMutation, useUpdateMentorGraderConfigurationMutation, useCreateGraderCriterionMutation, useUpdateGraderCriterionMutation, useDeleteGraderCriterionMutation, useGetSpendCapStatusQuery, useGetMentorPublicSettingsQuery, useGetChatHistoryQuery, useGetMentorSummariesQuery, useGetConversationMemoriesQuery, useGetSupportTicketsQuery, useGetSupportTicketMessagesQuery, useCreateSupportTicketMessageMutation, usePatchSupportTicketMutation, useCloseSupportTicketMutation, useCreateLtiMentorMutation, useUpdateLtiMentorMutation, useGetLtiMentorsQuery, useDeleteLtiMentorMutation, useCreateLtiKeyMutation, useUpdateLtiKeyMutation, useDeleteLtiKeyMutation, useGetLtiKeysQuery, useCreateLtiToolMutation, useUpdateLtiToolMutation, useGetLtiToolsQuery, useGetPlatformInfoQuery, useCreatePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useCreateRedirectTokenMutation, useGetShareableLinkQuery, useCreateShareableLinkMutation, useUpdateShareableLinkMutation, useCreateDisclaimerMutation, useUpdateDisclaimerMutation, useGetDisclaimersQuery, useUpdateRbacMentorAccessMutation, useGetRbacMentorAccessListQuery, useStartEvalRunMutation, useEvaluateEvalRunMutation, useGetEvalRunQuery, useDeleteEvalScoreMutation, useListEvalRunJudgesQuery, useCreateEvalScoreMutation, useDeleteEvalRunMutation, useExportEvalRunMutation, useListEvalRunsQuery, useLazyGetEvalRunQuery, evaluationsApiSlice, EVALUATIONS_TAGS, useGetPersonnalizedMentorsQuery, useCreateCallCredentialsMutation, useGetGuidedPromptsQuery, useUpdateChatSessionSharedMutation, useUpdateMessageFeedbackMutation, useLazyGetPromptsSearchQuery, useLazyGetGuidedPromptsQuery, useGetPublicMentorsQuery, useGetPeriodicAgentsQuery, useGetPeriodicAgentLogsListQuery, useCreatePeriodicAgentMutation, useDeletePeriodicAgentMutation, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useDeletePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation, useUpdateArtifactMutation, useLazyGetArtifactVersionQuery, useLazyListArtifactVersionsQuery, useSetCurrentVersionMutation, useListArtifactVersionsQuery, useLazyGetArtifactQuery, useLazyListArtifactsQuery, useEditSessionMutation } from '@iblai/data-layer';
5
+ import { 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, useStarMentorMutation, useUnstarMentorMutation, 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, useGetLlmsQuery, 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, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetAgentSkillResourcesQuery, useCreateAgentSkillResourceMutation, useUpdateAgentSkillResourceMutation, useUploadAgentSkillResourceAssetMutation, useDeleteAgentSkillResourceMutation, useGetMentorSkillAssignmentsQuery, useGetAgentSkillsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, filterSlashSkills, useGetMentorSkillAssignmentsInfiniteQuery, MENTOR_SKILL_ASSIGNMENTS_PAGE_SIZE, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useLazyGetConnectedServiceAuthUrlQuery, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorSettingsQuery, useEditMentorMutation, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, LOGO_ENDPOINTS, useCreateEvalDatasetMutation, useAddEvalDatasetItemsMutation, useUploadEvalDatasetCsvMutation, useDeleteEvalDatasetItemMutation, useListEvalDatasetItemsQuery, evalTotalPages, useListEvalDatasetsQuery, useGetUserProjectsQuery, useCreateSessionIdMutation, useGetMentorCategoriesQuery, useGetTenantChatPrivacyConfigQuery as useGetTenantChatPrivacyConfigQuery$1, useGetCallConfigurationsQuery, useCreateCallConfigurationMutation, useUpdateCallConfigurationMutation, chatPrivacyApiSlice, useDeleteMentorMutation, useForkMentorMutation, useGetToolsQuery, useLazyGetMCPServersQuery, useOauthFindMutation, useLazyStartOAuthFlowQuery, useCreateMCPServerMutation, usePartialUpdateMCPServerMutation, useCreateMCPServerConnectionMutation, usePatchMCPServerConnectionMutation, useGetConnectedServicesQuery, useGetMCPServersQuery, useGetMCPServerConnectionsQuery, useUpdateMCPServerMutation, useDeleteMCPServerMutation, useEditMentorJsonMutation, useDisconnectServiceMutation, useGetPromptCategoriesQuery, PRIVACY_ACTIONS, PRIVACY_ENTITY_TYPES, useGetVoicesQuery, useGetVoiceQuery, isBaseAgentMentor, useGetGradeResultQuery, useOverrideGradeResultMutation, useGetChatHistoryFilterQuery, useListGradeResultsQuery, useGetMentorGraderConfigurationQuery, useListGraderCriteriaQuery, useCreateMentorGraderConfigurationMutation, useUpdateMentorGraderConfigurationMutation, useCreateGraderCriterionMutation, useUpdateGraderCriterionMutation, useDeleteGraderCriterionMutation, useGetSpendCapStatusQuery, useGetMentorPublicSettingsQuery, useGetChatHistoryQuery, useGetMentorSummariesQuery, useGetConversationMemoriesQuery, useGetSupportTicketsQuery, useGetSupportTicketMessagesQuery, useCreateSupportTicketMessageMutation, usePatchSupportTicketMutation, useCloseSupportTicketMutation, useCreateLtiMentorMutation, useUpdateLtiMentorMutation, useGetLtiMentorsQuery, useDeleteLtiMentorMutation, useCreateLtiKeyMutation, useUpdateLtiKeyMutation, useDeleteLtiKeyMutation, useGetLtiKeysQuery, useCreateLtiToolMutation, useUpdateLtiToolMutation, useGetLtiToolsQuery, useGetPlatformInfoQuery, useCreatePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useCreateRedirectTokenMutation, useGetShareableLinkQuery, useCreateShareableLinkMutation, useUpdateShareableLinkMutation, useCreateDisclaimerMutation, useUpdateDisclaimerMutation, useGetDisclaimersQuery, useUpdateRbacMentorAccessMutation, useGetRbacMentorAccessListQuery, useStartEvalRunMutation, useEvaluateEvalRunMutation, useGetEvalRunQuery, useDeleteEvalScoreMutation, useListEvalRunJudgesQuery, useCreateEvalScoreMutation, useDeleteEvalRunMutation, useExportEvalRunMutation, useListEvalRunsQuery, useLazyGetEvalRunQuery, evaluationsApiSlice, EVALUATIONS_TAGS, useGetPersonnalizedMentorsQuery, useCreateCallCredentialsMutation, useGetGuidedPromptsQuery, useUpdateChatSessionSharedMutation, useUpdateMessageFeedbackMutation, useLazyGetPromptsSearchQuery, useLazyGetGuidedPromptsQuery, useGetPublicMentorsQuery, useGetPeriodicAgentsQuery, useGetPeriodicAgentLogsListQuery, useCreatePeriodicAgentMutation, useDeletePeriodicAgentMutation, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useDeletePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation, useGetDisclaimerAgreementsQuery, useUpdateArtifactMutation, useLazyGetArtifactVersionQuery, useLazyListArtifactVersionsQuery, useSetCurrentVersionMutation, useListArtifactVersionsQuery, useLazyGetArtifactQuery, useLazyListArtifactsQuery, useEditSessionMutation } from '@iblai/data-layer';
6
6
  import { removeAuthItem, setAuthItem, isTauriEmbeddedLLMHost, selectRbacPermissions, useCurrentTenant, canViewOtherUsersChatHistory, isPureWatcher, getInitials, useTenantMetadata, useUsername, selectStreaming, isLoggedIn, TOOL_NAME_MAP, WRITE_TODOS_TOOL, WithPermissions, canWriteField, useStripeUpgrade, openExternalUrl, CHAT_AREA_SIZE, isAlphaNumeric32, checkRbacPermission, selectNumberOfActiveChatMessages, TOOLS, hasRemoteAiConfig, isSafariBrowser, useShowAttachment, useShowVoiceCall, useShowVoiceRecorder, useMentorSettings, selectShowingSharedChat, useShowFreeTrialDialog, useEmbedMode, chatInputSliceSelectors, useResponsive, useAccessingPublicRoute, useVisitingTenant, useModelFileUploadCapabilities, useChatFileUpload, useVoiceChat, selectAttachedFiles, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, removeFile, chatInputSliceActions, chatActions, WithFormPermissions, useTenantContext, TimeTracker, advancedTabsProperties, defaultSessionIds, pickWritableFields, ANONYMOUS_USERNAME as ANONYMOUS_USERNAME$3, redirectToAuthSpaJoinTenant, selectActiveTab, useAxdToken, useWelcomeMessage, markdownToPlainText, useCachedSessionId, use402ErrorCheck, use401TokenRefresh, selectTokenEnabled, selectToken, useServiceWorker, useUserAgreement, useAdvancedChat, sendMessageToParentWebsite, useMentorTools, useFileDragDrop, eventBus, RemoteEvents, selectEnableChatActionsPopup, advancedTabs, isInIframe, getAuthSpaJoinUrl, addMessage, clearFiles, MENTOR_VISIBILITY } from '@iblai/web-utils';
7
7
  import { useDispatch, useSelector } from 'react-redux';
8
8
  import { toast } from 'sonner';
@@ -96347,37 +96347,58 @@ var advancedChatPrivacy$3 = {
96347
96347
  switchAriaDisabled: "User chat privacy control disabled"
96348
96348
  };
96349
96349
  var advancedCustomDomain$3 = {
96350
- dnsConfiguration: "DNS Configuration",
96350
+ dnsConfiguration: "Domains",
96351
96351
  add: "Add",
96352
- dialogTitle: "Your custom domain",
96353
- verificationNecessary: "Domain verification is necessary after making changes",
96354
- customDomainLabel: "Custom Domain",
96352
+ dialogTitle: "Add a domain",
96353
+ dialogDescription: "Point a domain you own at this organization’s sign-in site or at one of your deployed apps.",
96354
+ kindLabel: "What is this domain for?",
96355
+ kindPlatform: "Sign-in site",
96356
+ kindApp: "Deployed app",
96357
+ projectLabel: "App",
96358
+ projectPlaceholder: "Choose an app",
96359
+ noProjects: "You have not deployed any apps yet. Deploy one first, then come back to give it a domain.",
96360
+ customDomainLabel: "Domain",
96361
+ domainHelpPlatform: "Without the scheme or a leading “www.” — for example, app.example.com.",
96362
+ domainHelpApp: "Leave this empty and a subdomain will be assigned to the app for you, with no DNS records to set.",
96355
96363
  cancel: "Cancel",
96356
96364
  save: "Save",
96357
- expandAriaLabel: "Expand custom domain",
96358
- collapseAriaLabel: "Collapse custom domain",
96359
- loading: "Loading custom domain...",
96360
- verifying: "Verifying...",
96361
- verified: "Verified",
96362
- unregistered: "Unregistered",
96363
- notVerified: "Not Verified",
96364
- retry: "Retry",
96365
+ expandAriaLabel: "Expand domains",
96366
+ collapseAriaLabel: "Collapse domains",
96367
+ loading: "Loading domains…",
96368
+ verifying: "Checking…",
96369
+ reverify: "Check again",
96370
+ reverifyAriaLabel: "Check {domain} again",
96371
+ removeAriaLabel: "Remove {domain}",
96365
96372
  "delete": "Delete",
96366
- domainVerificationHeading: "Domain verification",
96367
- domainVerificationInstruction: "To verify your domain ownership and enable it to point to your application, you need to add the following DNS records at your domain registrar (like Namecheap, GoDaddy, or Google Domains).",
96368
- domainRecords: "Domain records",
96373
+ detach: "Detach",
96374
+ statusVerified: "Verified",
96375
+ statusUnverified: "Verification required",
96376
+ statusUnregistered: "Not registered",
96377
+ statusUnknown: "Could not check",
96369
96378
  tableType: "Type",
96370
96379
  tableNameHost: "Name/Host",
96371
96380
  tableValue: "Value",
96372
- tableStatus: "Status",
96373
96381
  copyNameHostAriaLabel: "Copy name/host: {domain}",
96374
96382
  copyValueAriaLabel: "Copy value/target",
96375
- noDomainConfigured: "No custom domain configured for this application.",
96376
- deleteSuccess: "Custom domain deleted successfully",
96377
- deleteError: "Failed to delete custom domain",
96378
- pleaseEnterDomain: "Please enter a custom domain",
96379
- createSuccess: "Custom domain created successfully",
96380
- createError: "Failed to create custom domain",
96383
+ noRecordsYet: "No records yet. Check the domain again to fetch them.",
96384
+ confirmRemoveTitle: "Remove this domain?",
96385
+ confirmDeleteBody: "{domain} will stop signing users in to this organization.",
96386
+ confirmDetachBody: "{domain} will stop serving the app, here and at the hosting provider.",
96387
+ noDomainConfigured: "No domains yet.",
96388
+ deleteSuccess: "Domain removed",
96389
+ deleteError: "The domain could not be removed",
96390
+ pleaseEnterDomain: "Enter a domain",
96391
+ createSuccess: "Domain added",
96392
+ createError: "The domain could not be added",
96393
+ verifySuccess: "The domain is verified and serving",
96394
+ verifyPending: "The records are not visible yet. Add them at your registrar and check again.",
96395
+ verifyError: "The domain could not be checked",
96396
+ verifyUnavailable: "The domain could not be checked from this browser",
96397
+ errorRefused: "This domain cannot be used here",
96398
+ errorForbidden: "Domains are managed by an organization admin",
96399
+ errorRateLimited: "Too many requests — try again shortly",
96400
+ errorUpstream: "The hosting provider rejected this organization’s credential",
96401
+ errorUnavailable: "This is not available on this instance yet",
96381
96402
  copiedToClipboard: "Copied to clipboard",
96382
96403
  unableToCopy: "Unable to copy"
96383
96404
  };
@@ -98466,6 +98487,7 @@ var disclaimersTabLabels$3 = {
98466
98487
  title: "Disclaimers",
98467
98488
  description: "Configure disclaimer settings for your agent."
98468
98489
  },
98490
+ infoBox: "Show your users the fine print. Add notices — like 'This is an AI assistant' or a compliance statement — that appear in the chat so people know what to expect.",
98469
98491
  userAgreement: {
98470
98492
  title: "User Agreement",
98471
98493
  tooltip: "Controls User Agreement",
@@ -98486,7 +98508,8 @@ var disclaimersTabLabels$3 = {
98486
98508
  edit: "Edit",
98487
98509
  save: "Save",
98488
98510
  saving: "Saving...",
98489
- cancel: "Cancel"
98511
+ cancel: "Cancel",
98512
+ viewAgreements: "View Agreements"
98490
98513
  },
98491
98514
  toasts: {
98492
98515
  advisorySuccess: "Agent updated successfully",
@@ -98496,6 +98519,20 @@ var disclaimersTabLabels$3 = {
98496
98519
  userAgreementEnabled: "User agreement enabled successfully",
98497
98520
  userAgreementDisabled: "User agreement disabled successfully",
98498
98521
  toggleError: "Failed to update user agreement"
98522
+ },
98523
+ agreements: {
98524
+ title: "Agreements",
98525
+ dialogDescription: "Users who have accepted this agent's User Agreement.",
98526
+ totalAgreements: "{count} Total Agreements",
98527
+ summaryDescription: "Review the users who have accepted this agent's User Agreement. Each entry shows the user's name, email and when they agreed. Users who haven't accepted yet aren't listed. Search matches the exact username.",
98528
+ searchPlaceholder: "Search by username",
98529
+ searchAriaLabel: "Search agreements by username",
98530
+ columnUser: "User",
98531
+ columnAgreedAt: "Agreed at",
98532
+ empty: "No agreements yet",
98533
+ emptyDescription: "Users who accept the User Agreement will appear here with the time they agreed.",
98534
+ noMatches: "No users match your search",
98535
+ noMatchesDescription: "Search matches the exact username — try the full username."
98499
98536
  }
98500
98537
  };
98501
98538
  var documentSidebar$3 = {
@@ -103631,39 +103668,60 @@ var advancedChatPrivacy$2 = {
103631
103668
  switchAriaDisabled: "Contrôle de la confidentialité du chat désactivé"
103632
103669
  };
103633
103670
  var advancedCustomDomain$2 = {
103634
- dnsConfiguration: "Configuration DNS",
103671
+ dnsConfiguration: "Domaines",
103635
103672
  add: "Ajouter",
103636
- dialogTitle: "Votre domaine personnalisé",
103637
- verificationNecessary: "La vérification du domaine est nécessaire après toute modification",
103638
- customDomainLabel: "Domaine personnalisé",
103673
+ dialogTitle: "Ajouter un domaine",
103674
+ dialogDescription: "Faites pointer un domaine qui vous appartient vers le site de connexion de cette organisation ou vers l’une de vos applications déployées.",
103675
+ kindLabel: "À quoi sert ce domaine ?",
103676
+ kindPlatform: "Site de connexion",
103677
+ kindApp: "Application déployée",
103678
+ projectLabel: "Application",
103679
+ projectPlaceholder: "Choisissez une application",
103680
+ noProjects: "Vous n’avez encore déployé aucune application. Déployez-en une, puis revenez lui donner un domaine.",
103681
+ customDomainLabel: "Domaine",
103682
+ domainHelpPlatform: "Sans le schéma ni un « www. » en tête — par exemple, app.example.com.",
103683
+ domainHelpApp: "Laissez ce champ vide et un sous-domaine sera attribué à l’application, sans aucun enregistrement DNS à créer.",
103639
103684
  cancel: "Annuler",
103640
103685
  save: "Enregistrer",
103641
- expandAriaLabel: "Développer le domaine personnalisé",
103642
- collapseAriaLabel: "Réduire le domaine personnalisé",
103643
- loading: "Chargement du domaine personnalisé...",
103644
- verifying: "Vérification...",
103645
- verified: "Vérifié",
103646
- unregistered: "Non enregistré",
103647
- notVerified: "Non vérifié",
103648
- retry: "Réessayer",
103686
+ expandAriaLabel: "Déplier les domaines",
103687
+ collapseAriaLabel: "Replier les domaines",
103688
+ loading: "Chargement des domaines…",
103689
+ verifying: "Vérification…",
103690
+ reverify: "Vérifier à nouveau",
103691
+ reverifyAriaLabel: "Vérifier à nouveau {domain}",
103692
+ removeAriaLabel: "Supprimer {domain}",
103649
103693
  "delete": "Supprimer",
103650
- domainVerificationHeading: "Vérification du domaine",
103651
- domainVerificationInstruction: "Pour vérifier la propriété de votre domaine et lui permettre de pointer vers votre application, vous devez ajouter les enregistrements DNS suivants chez votre registraire de domaine (comme Namecheap, GoDaddy ou Google Domains).",
103652
- domainRecords: "Enregistrements de domaine",
103694
+ detach: "Détacher",
103695
+ statusVerified: "Vérifié",
103696
+ statusUnverified: "Vérification requise",
103697
+ statusUnregistered: "Non enregistré",
103698
+ statusUnknown: "Vérification impossible",
103653
103699
  tableType: "Type",
103654
103700
  tableNameHost: "Nom/Hôte",
103655
103701
  tableValue: "Valeur",
103656
- tableStatus: "Statut",
103657
103702
  copyNameHostAriaLabel: "Copier le nom/hôte : {domain}",
103658
103703
  copyValueAriaLabel: "Copier la valeur/cible",
103659
- noDomainConfigured: "Aucun domaine personnalisé configuré pour cette application.",
103660
- deleteSuccess: "Domaine personnalisé supprimé avec succès",
103661
- deleteError: "Échec de la suppression du domaine personnalisé",
103662
- pleaseEnterDomain: "Veuillez saisir un domaine personnalisé",
103663
- createSuccess: "Domaine personnalisé créé avec succès",
103664
- createError: "Échec de la création du domaine personnalisé",
103704
+ noRecordsYet: "Aucun enregistrement pour l’instant. Vérifiez le domaine à nouveau pour les obtenir.",
103705
+ confirmRemoveTitle: "Supprimer ce domaine ?",
103706
+ confirmDeleteBody: "{domain} ne permettra plus de se connecter à cette organisation.",
103707
+ confirmDetachBody: "{domain} cessera de servir l’application, ici comme chez l’hébergeur.",
103708
+ noDomainConfigured: "Aucun domaine pour l’instant.",
103709
+ deleteSuccess: "Domaine supprimé",
103710
+ deleteError: "Le domaine n’a pas pu être supprimé",
103711
+ pleaseEnterDomain: "Saisissez un domaine",
103712
+ createSuccess: "Domaine ajouté",
103713
+ createError: "Le domaine n’a pas pu être ajouté",
103714
+ verifySuccess: "Le domaine est vérifié et sert l’application",
103715
+ verifyPending: "Les enregistrements ne sont pas encore visibles. Ajoutez-les chez votre registraire puis vérifiez à nouveau.",
103716
+ verifyError: "Le domaine n’a pas pu être vérifié",
103717
+ verifyUnavailable: "Le domaine n’a pas pu être vérifié depuis ce navigateur",
103718
+ errorRefused: "Ce domaine ne peut pas être utilisé ici",
103719
+ errorForbidden: "Les domaines sont gérés par un administrateur de l’organisation",
103720
+ errorRateLimited: "Trop de requêtes — réessayez dans un instant",
103721
+ errorUpstream: "L’hébergeur a rejeté l’identifiant de cette organisation",
103722
+ errorUnavailable: "Ce n’est pas encore disponible sur cette instance",
103665
103723
  copiedToClipboard: "Copié dans le presse-papiers",
103666
- unableToCopy: "Impossible de copier"
103724
+ unableToCopy: "Copie impossible"
103667
103725
  };
103668
103726
  var advancedExternalMapping$2 = {
103669
103727
  regionAriaLabel: "Correspondance d'identifiants externes",
@@ -105916,6 +105974,7 @@ var disclaimersTabLabels$2 = {
105916
105974
  title: "Avertissements",
105917
105975
  description: "Configurez les paramètres d'avertissement pour votre agent."
105918
105976
  },
105977
+ infoBox: "Affichez les mentions légales à vos utilisateurs. Ajoutez des avis — comme « Ceci est un assistant IA » ou une déclaration de conformité — qui apparaissent dans la conversation pour que les gens sachent à quoi s'attendre.",
105919
105978
  userAgreement: {
105920
105979
  title: "Accord utilisateur",
105921
105980
  tooltip: "Contrôle l'accord utilisateur",
@@ -105936,7 +105995,8 @@ var disclaimersTabLabels$2 = {
105936
105995
  edit: "Modifier",
105937
105996
  save: "Enregistrer",
105938
105997
  saving: "Enregistrement...",
105939
- cancel: "Annuler"
105998
+ cancel: "Annuler",
105999
+ viewAgreements: "Voir les acceptations"
105940
106000
  },
105941
106001
  toasts: {
105942
106002
  advisorySuccess: "Agent mis à jour avec succès",
@@ -105946,6 +106006,20 @@ var disclaimersTabLabels$2 = {
105946
106006
  userAgreementEnabled: "Accord utilisateur activé avec succès",
105947
106007
  userAgreementDisabled: "Accord utilisateur désactivé avec succès",
105948
106008
  toggleError: "Échec de la mise à jour de l'accord utilisateur"
106009
+ },
106010
+ agreements: {
106011
+ title: "Acceptations",
106012
+ dialogDescription: "Utilisateurs ayant accepté l'Accord utilisateur de cet agent.",
106013
+ totalAgreements: "{count} acceptations au total",
106014
+ summaryDescription: "Consultez les utilisateurs ayant accepté l'Accord utilisateur de cet agent. Chaque entrée indique le nom et l'e-mail de l'utilisateur ainsi que la date de son acceptation. Les utilisateurs qui ne l'ont pas encore accepté n'apparaissent pas. La recherche correspond au nom d'utilisateur exact.",
106015
+ searchPlaceholder: "Rechercher par nom d'utilisateur",
106016
+ searchAriaLabel: "Rechercher les acceptations par nom d'utilisateur",
106017
+ columnUser: "Utilisateur",
106018
+ columnAgreedAt: "Accepté le",
106019
+ empty: "Aucune acceptation pour le moment",
106020
+ emptyDescription: "Les utilisateurs qui acceptent l'Accord utilisateur apparaîtront ici avec l'heure de leur acceptation.",
106021
+ noMatches: "Aucun utilisateur ne correspond à votre recherche",
106022
+ noMatchesDescription: "La recherche correspond au nom d'utilisateur exact : essayez le nom d'utilisateur complet."
105949
106023
  }
105950
106024
  };
105951
106025
  var documentSidebar$2 = {
@@ -110915,39 +110989,60 @@ var advancedChatPrivacy$1 = {
110915
110989
  switchAriaDisabled: "Control de privacidad del chat deshabilitado"
110916
110990
  };
110917
110991
  var advancedCustomDomain$1 = {
110918
- dnsConfiguration: "Configuración DNS",
110919
- add: "Agregar",
110920
- dialogTitle: "Tu dominio personalizado",
110921
- verificationNecessary: "La verificación del dominio es necesaria después de realizar cambios",
110922
- customDomainLabel: "Dominio personalizado",
110992
+ dnsConfiguration: "Dominios",
110993
+ add: "Añadir",
110994
+ dialogTitle: "Añadir un dominio",
110995
+ dialogDescription: "Dirige un dominio tuyo al sitio de inicio de sesión de esta organización o a una de tus aplicaciones desplegadas.",
110996
+ kindLabel: "¿Para qué es este dominio?",
110997
+ kindPlatform: "Sitio de inicio de sesión",
110998
+ kindApp: "Aplicación desplegada",
110999
+ projectLabel: "Aplicación",
111000
+ projectPlaceholder: "Elige una aplicación",
111001
+ noProjects: "Todavía no has desplegado ninguna aplicación. Despliega una primero y vuelve para darle un dominio.",
111002
+ customDomainLabel: "Dominio",
111003
+ domainHelpPlatform: "Sin el esquema ni un “www.” inicial — por ejemplo, app.example.com.",
111004
+ domainHelpApp: "Déjalo vacío y se asignará un subdominio a la aplicación, sin registros DNS que configurar.",
110923
111005
  cancel: "Cancelar",
110924
111006
  save: "Guardar",
110925
- expandAriaLabel: "Expandir dominio personalizado",
110926
- collapseAriaLabel: "Contraer dominio personalizado",
110927
- loading: "Cargando dominio personalizado...",
110928
- verifying: "Verificando...",
110929
- verified: "Verificado",
110930
- unregistered: "No registrado",
110931
- notVerified: "No verificado",
110932
- retry: "Reintentar",
111007
+ expandAriaLabel: "Expandir dominios",
111008
+ collapseAriaLabel: "Contraer dominios",
111009
+ loading: "Cargando dominios…",
111010
+ verifying: "Comprobando…",
111011
+ reverify: "Comprobar de nuevo",
111012
+ reverifyAriaLabel: "Comprobar {domain} de nuevo",
111013
+ removeAriaLabel: "Eliminar {domain}",
110933
111014
  "delete": "Eliminar",
110934
- domainVerificationHeading: "Verificación de dominio",
110935
- domainVerificationInstruction: "Para verificar la propiedad de tu dominio y permitir que apunte a tu aplicación, debes agregar los siguientes registros DNS en tu registrador de dominio (como Namecheap, GoDaddy o Google Domains).",
110936
- domainRecords: "Registros de dominio",
111015
+ detach: "Desvincular",
111016
+ statusVerified: "Verificado",
111017
+ statusUnverified: "Verificación necesaria",
111018
+ statusUnregistered: "No registrado",
111019
+ statusUnknown: "No se pudo comprobar",
110937
111020
  tableType: "Tipo",
110938
111021
  tableNameHost: "Nombre/Host",
110939
111022
  tableValue: "Valor",
110940
- tableStatus: "Estado",
110941
111023
  copyNameHostAriaLabel: "Copiar nombre/host: {domain}",
110942
111024
  copyValueAriaLabel: "Copiar valor/destino",
110943
- noDomainConfigured: "No hay dominio personalizado configurado para esta aplicación.",
110944
- deleteSuccess: "Dominio personalizado eliminado correctamente",
110945
- deleteError: "Error al eliminar el dominio personalizado",
110946
- pleaseEnterDomain: "Por favor, introduce un dominio personalizado",
110947
- createSuccess: "Dominio personalizado creado correctamente",
110948
- createError: "Error al crear el dominio personalizado",
111025
+ noRecordsYet: "Aún no hay registros. Comprueba el dominio de nuevo para obtenerlos.",
111026
+ confirmRemoveTitle: "¿Eliminar este dominio?",
111027
+ confirmDeleteBody: "{domain} dejará de permitir el inicio de sesión en esta organización.",
111028
+ confirmDetachBody: "{domain} dejará de servir la aplicación, aquí y en el proveedor de alojamiento.",
111029
+ noDomainConfigured: "Todavía no hay dominios.",
111030
+ deleteSuccess: "Dominio eliminado",
111031
+ deleteError: "No se pudo eliminar el dominio",
111032
+ pleaseEnterDomain: "Introduce un dominio",
111033
+ createSuccess: "Dominio añadido",
111034
+ createError: "No se pudo añadir el dominio",
111035
+ verifySuccess: "El dominio está verificado y sirviendo",
111036
+ verifyPending: "Los registros aún no son visibles. Añádelos en tu registrador y comprueba de nuevo.",
111037
+ verifyError: "No se pudo comprobar el dominio",
111038
+ verifyUnavailable: "No se pudo comprobar el dominio desde este navegador",
111039
+ errorRefused: "Este dominio no se puede usar aquí",
111040
+ errorForbidden: "Los dominios los gestiona un administrador de la organización",
111041
+ errorRateLimited: "Demasiadas solicitudes: inténtalo de nuevo en breve",
111042
+ errorUpstream: "El proveedor de alojamiento rechazó la credencial de esta organización",
111043
+ errorUnavailable: "Esto todavía no está disponible en esta instancia",
110949
111044
  copiedToClipboard: "Copiado al portapapeles",
110950
- unableToCopy: "No se puede copiar"
111045
+ unableToCopy: "No se pudo copiar"
110951
111046
  };
110952
111047
  var advancedExternalMapping$1 = {
110953
111048
  regionAriaLabel: "Mapeo de credenciales externas",
@@ -113200,6 +113295,7 @@ var disclaimersTabLabels$1 = {
113200
113295
  title: "Avisos legales",
113201
113296
  description: "Configure los ajustes de aviso legal para su agente."
113202
113297
  },
113298
+ infoBox: "Muestra la letra pequeña a tus usuarios. Agrega avisos —como «Este es un asistente de IA» o una declaración de cumplimiento— que aparecen en el chat para que las personas sepan qué esperar.",
113203
113299
  userAgreement: {
113204
113300
  title: "Acuerdo de usuario",
113205
113301
  tooltip: "Controla el acuerdo de usuario",
@@ -113220,7 +113316,8 @@ var disclaimersTabLabels$1 = {
113220
113316
  edit: "Editar",
113221
113317
  save: "Guardar",
113222
113318
  saving: "Guardando...",
113223
- cancel: "Cancelar"
113319
+ cancel: "Cancelar",
113320
+ viewAgreements: "Ver aceptaciones"
113224
113321
  },
113225
113322
  toasts: {
113226
113323
  advisorySuccess: "Agente actualizado correctamente",
@@ -113230,6 +113327,20 @@ var disclaimersTabLabels$1 = {
113230
113327
  userAgreementEnabled: "Acuerdo de usuario habilitado correctamente",
113231
113328
  userAgreementDisabled: "Acuerdo de usuario deshabilitado correctamente",
113232
113329
  toggleError: "Error al actualizar el acuerdo de usuario"
113330
+ },
113331
+ agreements: {
113332
+ title: "Aceptaciones",
113333
+ dialogDescription: "Usuarios que han aceptado el Acuerdo de usuario de este agente.",
113334
+ totalAgreements: "{count} aceptaciones en total",
113335
+ summaryDescription: "Revisa los usuarios que han aceptado el Acuerdo de usuario de este agente. Cada entrada muestra el nombre y el correo electrónico del usuario y cuándo lo aceptó. Los usuarios que aún no lo han aceptado no aparecen. La búsqueda coincide con el nombre de usuario exacto.",
113336
+ searchPlaceholder: "Buscar por nombre de usuario",
113337
+ searchAriaLabel: "Buscar aceptaciones por nombre de usuario",
113338
+ columnUser: "Usuario",
113339
+ columnAgreedAt: "Aceptado el",
113340
+ empty: "Aún no hay aceptaciones",
113341
+ emptyDescription: "Los usuarios que acepten el Acuerdo de usuario aparecerán aquí con la hora en que lo aceptaron.",
113342
+ noMatches: "Ningún usuario coincide con tu búsqueda",
113343
+ noMatchesDescription: "La búsqueda coincide con el nombre de usuario exacto: prueba con el nombre de usuario completo."
113233
113344
  }
113234
113345
  };
113235
113346
  var documentSidebar$1 = {
@@ -118199,37 +118310,58 @@ var advancedChatPrivacy = {
118199
118310
  switchAriaDisabled: "用户聊天隐私控制已禁用"
118200
118311
  };
118201
118312
  var advancedCustomDomain = {
118202
- dnsConfiguration: "DNS 配置",
118313
+ dnsConfiguration: "域名",
118203
118314
  add: "添加",
118204
- dialogTitle: "您的自定义域名",
118205
- verificationNecessary: "更改后需要进行域名验证",
118206
- customDomainLabel: "自定义域名",
118315
+ dialogTitle: "添加域名",
118316
+ dialogDescription: "将你拥有的域名指向该组织的登录站点,或指向你已部署的某个应用。",
118317
+ kindLabel: "这个域名用于什么?",
118318
+ kindPlatform: "登录站点",
118319
+ kindApp: "已部署的应用",
118320
+ projectLabel: "应用",
118321
+ projectPlaceholder: "选择一个应用",
118322
+ noProjects: "你还没有部署任何应用。请先部署一个,然后回来为它设置域名。",
118323
+ customDomainLabel: "域名",
118324
+ domainHelpPlatform: "不要带协议前缀或开头的“www.”,例如 app.example.com。",
118325
+ domainHelpApp: "留空即可自动为该应用分配一个子域名,无需设置任何 DNS 记录。",
118207
118326
  cancel: "取消",
118208
118327
  save: "保存",
118209
- expandAriaLabel: "展开自定义域名",
118210
- collapseAriaLabel: "收起自定义域名",
118211
- loading: "正在加载自定义域名...",
118212
- verifying: "验证中...",
118213
- verified: "已验证",
118214
- unregistered: "未注册",
118215
- notVerified: "未验证",
118216
- retry: "重试",
118328
+ expandAriaLabel: "展开域名",
118329
+ collapseAriaLabel: "收起域名",
118330
+ loading: "正在加载域名…",
118331
+ verifying: "正在检查…",
118332
+ reverify: "重新检查",
118333
+ reverifyAriaLabel: "重新检查 {domain}",
118334
+ removeAriaLabel: "移除 {domain}",
118217
118335
  "delete": "删除",
118218
- domainVerificationHeading: "域名验证",
118219
- domainVerificationInstruction: "要验证您的域名所有权并使其指向您的应用程序,您需要在域名注册商(如 Namecheap、GoDaddy 或 Google Domains)处添加以下 DNS 记录。",
118220
- domainRecords: "域名记录",
118336
+ detach: "解除绑定",
118337
+ statusVerified: "已验证",
118338
+ statusUnverified: "需要验证",
118339
+ statusUnregistered: "未注册",
118340
+ statusUnknown: "无法检查",
118221
118341
  tableType: "类型",
118222
118342
  tableNameHost: "名称/主机",
118223
118343
  tableValue: "值",
118224
- tableStatus: "状态",
118225
118344
  copyNameHostAriaLabel: "复制名称/主机:{domain}",
118226
118345
  copyValueAriaLabel: "复制值/目标",
118227
- noDomainConfigured: "此应用程序未配置自定义域名。",
118228
- deleteSuccess: "自定义域名已成功删除",
118229
- deleteError: "删除自定义域名失败",
118230
- pleaseEnterDomain: "请输入自定义域名",
118231
- createSuccess: "自定义域名已成功创建",
118232
- createError: "创建自定义域名失败",
118346
+ noRecordsYet: "暂无记录。请重新检查该域名以获取记录。",
118347
+ confirmRemoveTitle: "要移除这个域名吗?",
118348
+ confirmDeleteBody: "{domain} 将不再用于登录该组织。",
118349
+ confirmDetachBody: "{domain} 将不再为该应用提供服务,本处和托管服务商处都会解除。",
118350
+ noDomainConfigured: "暂无域名。",
118351
+ deleteSuccess: "域名已移除",
118352
+ deleteError: "无法移除该域名",
118353
+ pleaseEnterDomain: "请输入域名",
118354
+ createSuccess: "域名已添加",
118355
+ createError: "无法添加该域名",
118356
+ verifySuccess: "域名已验证并正常服务",
118357
+ verifyPending: "记录尚未生效。请在域名注册商处添加后再检查。",
118358
+ verifyError: "无法检查该域名",
118359
+ verifyUnavailable: "无法从当前浏览器检查该域名",
118360
+ errorRefused: "该域名不能在此使用",
118361
+ errorForbidden: "域名由组织管理员管理",
118362
+ errorRateLimited: "请求过于频繁,请稍后再试",
118363
+ errorUpstream: "托管服务商拒绝了该组织的凭据",
118364
+ errorUnavailable: "此实例尚不支持该功能",
118233
118365
  copiedToClipboard: "已复制到剪贴板",
118234
118366
  unableToCopy: "无法复制"
118235
118367
  };
@@ -120484,6 +120616,7 @@ var disclaimersTabLabels = {
120484
120616
  title: "免责声明",
120485
120617
  description: "为您的智能体配置免责声明设置。"
120486
120618
  },
120619
+ infoBox: "向用户展示必要的声明。添加提示——例如“这是一个 AI 助手”或合规声明——它们会显示在对话中,让用户知道会得到什么。",
120487
120620
  userAgreement: {
120488
120621
  title: "用户协议",
120489
120622
  tooltip: "控制用户协议",
@@ -120504,7 +120637,8 @@ var disclaimersTabLabels = {
120504
120637
  edit: "编辑",
120505
120638
  save: "保存",
120506
120639
  saving: "保存中……",
120507
- cancel: "取消"
120640
+ cancel: "取消",
120641
+ viewAgreements: "查看同意记录"
120508
120642
  },
120509
120643
  toasts: {
120510
120644
  advisorySuccess: "智能体更新成功",
@@ -120514,6 +120648,20 @@ var disclaimersTabLabels = {
120514
120648
  userAgreementEnabled: "用户协议已成功启用",
120515
120649
  userAgreementDisabled: "用户协议已成功停用",
120516
120650
  toggleError: "更新用户协议失败"
120651
+ },
120652
+ agreements: {
120653
+ title: "同意记录",
120654
+ dialogDescription: "已接受此智能体用户协议的用户。",
120655
+ totalAgreements: "共 {count} 条同意记录",
120656
+ summaryDescription: "查看已接受此智能体用户协议的用户。每条记录显示用户的姓名、邮箱和同意时间。尚未接受的用户不会列出。搜索需与用户名完全匹配。",
120657
+ searchPlaceholder: "按用户名搜索",
120658
+ searchAriaLabel: "按用户名搜索同意记录",
120659
+ columnUser: "用户",
120660
+ columnAgreedAt: "同意时间",
120661
+ empty: "尚无同意记录",
120662
+ emptyDescription: "接受用户协议的用户将与其同意时间一起显示在此处。",
120663
+ noMatches: "没有匹配的用户",
120664
+ noMatchesDescription: "搜索需与用户名完全匹配,请尝试输入完整的用户名。"
120517
120665
  }
120518
120666
  };
120519
120667
  var documentSidebar = {
@@ -179304,7 +179452,7 @@ function DetailRow({ label, children }) {
179304
179452
  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 })] }));
179305
179453
  }
179306
179454
 
179307
- const PAGE_SIZE$e = 8;
179455
+ const PAGE_SIZE$f = 8;
179308
179456
  const CONTENT_TYPES = [
179309
179457
  { value: 'courses', labelKey: 'gradebookGradebookTab.typeCourses', icon: GraduationCap },
179310
179458
  { value: 'programs', labelKey: 'gradebookGradebookTab.typePrograms', icon: Layers },
@@ -179335,14 +179483,14 @@ function useGradebookData(type, org, username, page, search) {
179335
179483
  username,
179336
179484
  query: {
179337
179485
  page,
179338
- page_size: PAGE_SIZE$e,
179486
+ page_size: PAGE_SIZE$f,
179339
179487
  platform_key: org,
179340
179488
  ...(trimmed ? { course_name: trimmed } : {}),
179341
179489
  },
179342
179490
  }, { skip: type !== 'courses', refetchOnMountOrArgChange: true });
179343
179491
  const programsQ = useGetUserEnrolledProgramsQuery([{ username, platformKey: org }], { skip: type !== 'programs' });
179344
179492
  const pathwaysQ = useGetUserCatalogPathwaysQuery({ username, platform_key: org }, { skip: type !== 'pathways' });
179345
- const credentialsQ = useGetUsersAsAssertionsQuery({ platformKey: org, userId: username, page, pageSize: PAGE_SIZE$e }, { skip: type !== 'credentials', refetchOnMountOrArgChange: true });
179493
+ const credentialsQ = useGetUsersAsAssertionsQuery({ platformKey: org, userId: username, page, pageSize: PAGE_SIZE$f }, { skip: type !== 'credentials', refetchOnMountOrArgChange: true });
179346
179494
  const earnedQ = useGetUserEarnedSkillsQuery([{ org, userId: username }], { skip: type !== 'skills' });
179347
179495
  const reportedQ = useGetUserReportedSkillsQuery([{ username }], { skip: type !== 'skills' });
179348
179496
  const desiredQ = useGetUserDesiredSkillsQuery([{ username }], { skip: type !== 'skills' });
@@ -179352,12 +179500,12 @@ function useGradebookData(type, org, username, page, search) {
179352
179500
  const filtered = trimmed
179353
179501
  ? rows.filter((row) => row.name.toLowerCase().includes(trimmed.toLowerCase()))
179354
179502
  : rows;
179355
- const start = (page - 1) * PAGE_SIZE$e;
179503
+ const start = (page - 1) * PAGE_SIZE$f;
179356
179504
  return {
179357
- rows: filtered.slice(start, start + PAGE_SIZE$e),
179505
+ rows: filtered.slice(start, start + PAGE_SIZE$f),
179358
179506
  total: filtered.length,
179359
179507
  hasPrev: page > 1,
179360
- hasNext: start + PAGE_SIZE$e < filtered.length,
179508
+ hasNext: start + PAGE_SIZE$f < filtered.length,
179361
179509
  };
179362
179510
  };
179363
179511
  switch (type) {
@@ -179414,7 +179562,7 @@ function useGradebookData(type, org, username, page, search) {
179414
179562
  rows,
179415
179563
  total,
179416
179564
  hasPrev: page > 1,
179417
- hasNext: page * PAGE_SIZE$e < total,
179565
+ hasNext: page * PAGE_SIZE$f < total,
179418
179566
  isLoading: credentialsQ.isLoading,
179419
179567
  isFetching: credentialsQ.isFetching,
179420
179568
  isError: credentialsQ.isError,
@@ -222398,7 +222546,7 @@ const AdvancedPagination = ({ currentPage, totalPages, onPageChange, totalCount,
222398
222546
  return (jsxs("div", { className: cn('flex items-center gap-2', showSummary ? 'justify-between' : 'justify-center', variant === 'footer' && 'border-t border-gray-200 bg-gray-50 px-3 py-3 sm:px-6 sm:py-4', className), children: [showSummary && (jsx("p", { className: "hidden text-sm text-gray-700 sm:block", children: t('advancePagination.showing', { from, to, totalCount, itemLabel }) })), jsxs("div", { className: "flex items-center justify-center gap-1 sm:gap-2", children: [jsx(Button$1, { variant: "outline", size: "sm", className: "hidden h-8 w-8 items-center justify-center rounded-md border-gray-300 bg-transparent p-0 hover:bg-gray-100 sm:flex", onClick: () => onPageChange(1), disabled: currentPage === 1, "aria-label": t('advancePagination.goToFirstPage'), children: jsx(ChevronFirst, { className: "h-4 w-4" }) }), jsxs(Button$1, { variant: "outline", size: "sm", className: "flex h-8 w-8 items-center justify-center rounded-md border-none bg-transparent px-2 text-xs hover:bg-gray-100 sm:border-gray-300 sm:p-0 sm:text-sm", onClick: () => onPageChange(currentPage - 1), disabled: currentPage === 1, "aria-label": t('advancePagination.goToPreviousPage'), children: [jsx(ChevronLeft, { className: "mr-1 h-4 w-4 sm:mr-0" }), jsx("span", { className: "sm:hidden", children: t('advancePagination.prev') })] }), jsxs("span", { className: "mx-1 px-2 text-xs text-gray-700 sm:mx-2 sm:text-sm", children: [jsxs("span", { className: "hidden sm:inline", children: [t('advancePagination.page'), " "] }), currentPage, " ", jsxs("span", { className: "hidden sm:inline", children: [t('advancePagination.of'), " "] }), jsxs("span", { className: "inline sm:hidden", children: [" ", t('advancePagination.mobileSeparator'), " "] }), totalPages] }), jsxs(Button$1, { variant: "outline", size: "sm", className: "flex h-8 w-8 items-center justify-center rounded-md border-none bg-transparent px-2 text-xs hover:bg-gray-100 sm:border-gray-300 sm:p-0 sm:text-sm", onClick: () => onPageChange(currentPage + 1), disabled: currentPage === totalPages, "aria-label": t('advancePagination.goToNextPage'), children: [jsx("span", { className: "sm:hidden", children: t('advancePagination.next') }), jsx(ChevronRight, { className: "ml-1 h-4 w-4 sm:ml-0" })] }), jsx(Button$1, { variant: "outline", size: "sm", className: "hidden h-8 w-8 items-center justify-center rounded-md border-gray-300 bg-transparent p-0 hover:bg-gray-100 sm:flex", onClick: () => onPageChange(totalPages), disabled: currentPage === totalPages, "aria-label": t('advancePagination.goToLastPage'), children: jsx(ChevronLast, { className: "h-4 w-4" }) })] })] }));
222399
222547
  };
222400
222548
 
222401
- const PAGE_SIZE$d = 10;
222549
+ const PAGE_SIZE$e = 10;
222402
222550
  function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false, }) {
222403
222551
  var _a, _b;
222404
222552
  const t = useT();
@@ -222421,7 +222569,7 @@ function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false,
222421
222569
  const isWatcher = isPureWatcher(rbacPermissions, currentTenant);
222422
222570
  const { data: users, refetch: refetchPlatformUsers, isLoading: isLoadingPlatformUsers, } = usePlatformUsersQuery({
222423
222571
  page,
222424
- page_size: PAGE_SIZE$d,
222572
+ page_size: PAGE_SIZE$e,
222425
222573
  platform_key: tenant,
222426
222574
  platform_org: tenant,
222427
222575
  query: debouncedSearchQuery,
@@ -222435,7 +222583,7 @@ function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false,
222435
222583
  // TODO to use required_action: 'Ibl.Core/Users/read',
222436
222584
  required_action: 'Ibl.Mentor/Memory/list',
222437
222585
  page,
222438
- page_size: PAGE_SIZE$d,
222586
+ page_size: PAGE_SIZE$e,
222439
222587
  sort: 'name',
222440
222588
  ...(debouncedSearchQuery.includes('@')
222441
222589
  ? { email: debouncedSearchQuery }
@@ -222610,7 +222758,7 @@ function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false,
222610
222758
  managed: user,
222611
222759
  }));
222612
222760
  const totalCount = (_b = (isWatcher ? accessibleUsers === null || accessibleUsers === void 0 ? void 0 : accessibleUsers.count : users === null || users === void 0 ? void 0 : users.count)) !== null && _b !== void 0 ? _b : 0;
222613
- const totalPages = Math.ceil(totalCount / PAGE_SIZE$d);
222761
+ const totalPages = Math.ceil(totalCount / PAGE_SIZE$e);
222614
222762
  return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex justify-between items-center gap-1", children: [jsxs("div", { className: "relative mb-6 max-w-sm", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { type: "text", value: searchQuery, onChange: (event) => setQuerySearch(event.target.value), placeholder: t('tabsUserstab.searchPlaceholder'), className: "pl-10 pr-10 focus:ring-blue-500 focus:border-blue-500 h-[35px]", "aria-label": t('tabsUserstab.searchAriaLabel') }), searchQuery.length > 0 && (searchQuery !== debouncedSearchQuery || isLoading) && (jsx(LoaderCircle, { "data-testid": "search-spinner", className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400 animate-spin", "aria-hidden": "true" }))] }), !isWatcher && (jsx("div", { className: "mb-6", children: jsx(Button$1, { className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", onClick: onInviteClick, children: t('tabsUserstab.inviteButton') }) }))] }), isLoading ? (jsx("div", { className: "flex justify-center items-center h-64", children: jsx(Spinner, {}) })) : (jsxs(Fragment$1, { children: [jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: `px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 ${isWatcher ? 'w-full' : 'w-[41%]'}`, children: t('tabsUserstab.columnEmail') }), !isWatcher && (jsxs(Fragment$1, { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[16%]", children: t('tabsUserstab.columnRole') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[25%]", children: t('tabsUserstab.columnPolicies') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[18%]", children: t('tabsUserstab.columnStatus') })] }))] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [rows.map((row) => {
222615
222763
  var _a;
222616
222764
  // Only set on the admin path — see {@link UserRow}.
@@ -222641,7 +222789,7 @@ function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false,
222641
222789
  })] }) })] }) }), jsx("td", { className: "px-6 py-4", onClick: (e) => e.stopPropagation(), children: jsx(Switch, { checked: user.active, onCheckedChange: (checked) => handleUserStatusChange(user, checked), disabled: updatingUserIds.has(user === null || user === void 0 ? void 0 : user.user_id), "aria-label": t('tabsUserstab.toggleStatusAriaLabel', {
222642
222790
  name: user.name,
222643
222791
  }), className: "cursor-pointer data-[state=checked]:bg-blue-500 disabled:cursor-not-allowed disabled:opacity-50" }) })] }))] }, row.key));
222644
- }), rows.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: isWatcher ? 2 : 5, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: t('tabsUserstab.noUsersFound') }) }))] })] }) }), jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (_page) => handlePageChange(_page), totalCount: totalCount, itemsPerPage: PAGE_SIZE$d, itemLabel: "users" })] })), selectedUser && (jsx(Dialog, { open: !!selectedUser, onOpenChange: (open) => {
222792
+ }), rows.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: isWatcher ? 2 : 5, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: t('tabsUserstab.noUsersFound') }) }))] })] }) }), jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (_page) => handlePageChange(_page), totalCount: totalCount, itemsPerPage: PAGE_SIZE$e, itemLabel: "users" })] })), selectedUser && (jsx(Dialog, { open: !!selectedUser, onOpenChange: (open) => {
222645
222793
  if (!open)
222646
222794
  setSelectedUser(null);
222647
222795
  }, children: jsxs(DialogContent, { autoFocus: false, className: "max-w-7xl w-[85vw] p-0 gap-0 overflow-hidden bg-white profile-component-dialog", style: { height: '85vh', display: 'flex', flexDirection: 'column' }, children: [jsx(DialogTitle, { className: "sr-only", children: t('tabsUserstab.profileDialogTitle') }), jsx(DialogDescription, { className: "sr-only", children: t('tabsUserstab.profileDialogDescription') }), jsx(Profile, { tenant: tenant, tenants: [], username: selectedUser.username, isAdmin: selectedUser.isAdmin, currentSPA: currentSpa, onClose: () => setSelectedUser(null), customization: {
@@ -223861,7 +224009,7 @@ function PoliciesTab({ tenant }) {
223861
224009
  : t('tabsPoliciestab.createPolicy')] }) }) }), editing && (policyDetails === null || policyDetails === void 0 ? void 0 : policyDetails.is_internal) && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsPoliciestab.cannotEditInternal') }) }))] }) })] })] }) }), jsx(ResourcePickerModal, { open: isResourcePickerOpen, onOpenChange: setIsResourcePickerOpen, tenant: tenant, onSelect: addPickedResource })] }));
223862
224010
  }
223863
224011
 
223864
- const PAGE_SIZE$c = 10;
224012
+ const PAGE_SIZE$d = 10;
223865
224013
  function normalizeEvents(events) {
223866
224014
  if (!events)
223867
224015
  return [];
@@ -223910,8 +224058,8 @@ function AlertsTab({ tenant }) {
223910
224058
  const { data: watchedGroupsData, isLoading, isError, refetch, } = useGetWatchedGroupsQuery({
223911
224059
  params: {
223912
224060
  platform_key: tenant,
223913
- limit: PAGE_SIZE$c,
223914
- offset: (page - 1) * PAGE_SIZE$c,
224061
+ limit: PAGE_SIZE$d,
224062
+ offset: (page - 1) * PAGE_SIZE$d,
223915
224063
  },
223916
224064
  });
223917
224065
  const groups = useMemo(() => {
@@ -223924,7 +224072,7 @@ function AlertsTab({ tenant }) {
223924
224072
  return results;
223925
224073
  }, [watchedGroupsData, debouncedSearchQuery]);
223926
224074
  const totalPages = watchedGroupsData
223927
- ? Math.max(1, Math.ceil(watchedGroupsData.count / PAGE_SIZE$c))
224075
+ ? Math.max(1, Math.ceil(watchedGroupsData.count / PAGE_SIZE$d))
223928
224076
  : 0;
223929
224077
  const handlePageChange = async (newPage) => {
223930
224078
  setPage(newPage);
@@ -224233,7 +224381,7 @@ function AlertsTab({ tenant }) {
224233
224381
  setDeletingGroupId(null);
224234
224382
  }
224235
224383
  }
224236
- return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex mb-6 gap-2 flex-row items-center justify-between", children: [jsxs("div", { className: "relative max-w-sm w-full sm:w-auto", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: t('tabsAlertstab.searchAlertsPlaceholder'), "aria-label": t('tabsAlertstab.searchAlertsAriaLabel'), className: "pl-10 pr-10 focus:ring-blue-500 focus:border-blue-500 h-[35px]" }), isLoading && (jsx(LoaderCircle, { "data-testid": "search-spinner", className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400 animate-spin", "aria-hidden": "true" }))] }), jsx("div", { className: "flex gap-2", children: jsx(Button$1, { onClick: openNew, "aria-label": t('tabsAlertstab.newAlertAriaLabel'), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", children: t('tabsAlertstab.newAlert') }) })] }), isLoading && (jsx("div", { className: "flex justify-center items-center h-64", children: jsx("div", { className: "py-8 text-center text-sm text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.loading') }) })), isError && (jsx("div", { className: "py-8 text-center text-sm text-red-500", children: t('tabsAlertstab.failedToLoadAlerts') })), !isLoading && !isError && (jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.columnName') }), jsx("th", { className: "px-6 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[120px]" })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [groups.map((g) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 text-gray-900 dark:text-gray-100 text-sm", children: g.name }), jsx("td", { className: "px-6 py-4", children: jsxs("div", { className: "flex gap-2 justify-end", children: [jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => openEdit(g), disabled: deletingGroupId === g.id, "aria-label": t('tabsAlertstab.editAlertAriaLabel', { name: g.name }), children: jsx(Pencil, { className: "h-4 w-4", "aria-hidden": "true" }) }), jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => onDelete(g), className: "text-red-600 hover:text-red-700", disabled: deletingGroupId === g.id, "aria-label": t('tabsAlertstab.deleteAlertAriaLabel', { name: g.name }), children: deletingGroupId === g.id ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" })) : (jsx(Trash2, { className: "h-4 w-4", "aria-hidden": "true" })) })] }) })] }, g.id))), groups.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 2, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.noAlertsFound') }) }))] })] }) })), !isLoading && !isError && (jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (newPage) => handlePageChange(newPage), totalCount: watchedGroupsData === null || watchedGroupsData === void 0 ? void 0 : watchedGroupsData.count, itemsPerPage: PAGE_SIZE$c, itemLabel: "alerts" })), jsx(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: jsxs(DialogContent, { "aria-describedby": undefined, className: "max-w-2xl max-h-[90vh] overflow-y-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { children: editingGroup ? t('tabsAlertstab.editAlert') : t('tabsAlertstab.newAlert') }) }), jsxs("div", { className: "space-y-5", children: [jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { htmlFor: "wg-name", children: t('tabsAlertstab.nameLabel') }), jsx(Input, { id: "wg-name", value: name, onChange: (e) => setName(e.target.value), placeholder: t('tabsAlertstab.enterAlertNamePlaceholder'), required: true })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { children: t('tabsAlertstab.watchedUsersLabel') }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.watchedUsersDescription') }), watchedUsers.length > 0 ? (jsx("div", { className: "space-y-2 max-h-48 overflow-y-auto border border-gray-200 dark:border-gray-700 rounded-md p-2", children: watchedUsers.map((user) => (jsxs("div", { className: "flex items-center justify-between bg-gray-50 dark:bg-gray-800 p-2 rounded-md", children: [jsxs("div", { className: "flex flex-col", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: user.name || user.username }), user.email && (jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: user.email }))] }), jsx(Button$1, { type: "button", variant: "ghost", size: "sm", onClick: () => removeWatchedUserDraft(user.id), className: "h-8 w-8 p-0 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20", "aria-label": t('tabsAlertstab.removeWatchedUserAriaLabel', {
224384
+ return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex mb-6 gap-2 flex-row items-center justify-between", children: [jsxs("div", { className: "relative max-w-sm w-full sm:w-auto", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: t('tabsAlertstab.searchAlertsPlaceholder'), "aria-label": t('tabsAlertstab.searchAlertsAriaLabel'), className: "pl-10 pr-10 focus:ring-blue-500 focus:border-blue-500 h-[35px]" }), isLoading && (jsx(LoaderCircle, { "data-testid": "search-spinner", className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400 animate-spin", "aria-hidden": "true" }))] }), jsx("div", { className: "flex gap-2", children: jsx(Button$1, { onClick: openNew, "aria-label": t('tabsAlertstab.newAlertAriaLabel'), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", children: t('tabsAlertstab.newAlert') }) })] }), isLoading && (jsx("div", { className: "flex justify-center items-center h-64", children: jsx("div", { className: "py-8 text-center text-sm text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.loading') }) })), isError && (jsx("div", { className: "py-8 text-center text-sm text-red-500", children: t('tabsAlertstab.failedToLoadAlerts') })), !isLoading && !isError && (jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.columnName') }), jsx("th", { className: "px-6 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[120px]" })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [groups.map((g) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 text-gray-900 dark:text-gray-100 text-sm", children: g.name }), jsx("td", { className: "px-6 py-4", children: jsxs("div", { className: "flex gap-2 justify-end", children: [jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => openEdit(g), disabled: deletingGroupId === g.id, "aria-label": t('tabsAlertstab.editAlertAriaLabel', { name: g.name }), children: jsx(Pencil, { className: "h-4 w-4", "aria-hidden": "true" }) }), jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => onDelete(g), className: "text-red-600 hover:text-red-700", disabled: deletingGroupId === g.id, "aria-label": t('tabsAlertstab.deleteAlertAriaLabel', { name: g.name }), children: deletingGroupId === g.id ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" })) : (jsx(Trash2, { className: "h-4 w-4", "aria-hidden": "true" })) })] }) })] }, g.id))), groups.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 2, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.noAlertsFound') }) }))] })] }) })), !isLoading && !isError && (jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (newPage) => handlePageChange(newPage), totalCount: watchedGroupsData === null || watchedGroupsData === void 0 ? void 0 : watchedGroupsData.count, itemsPerPage: PAGE_SIZE$d, itemLabel: "alerts" })), jsx(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: jsxs(DialogContent, { "aria-describedby": undefined, className: "max-w-2xl max-h-[90vh] overflow-y-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { children: editingGroup ? t('tabsAlertstab.editAlert') : t('tabsAlertstab.newAlert') }) }), jsxs("div", { className: "space-y-5", children: [jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { htmlFor: "wg-name", children: t('tabsAlertstab.nameLabel') }), jsx(Input, { id: "wg-name", value: name, onChange: (e) => setName(e.target.value), placeholder: t('tabsAlertstab.enterAlertNamePlaceholder'), required: true })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { children: t('tabsAlertstab.watchedUsersLabel') }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('tabsAlertstab.watchedUsersDescription') }), watchedUsers.length > 0 ? (jsx("div", { className: "space-y-2 max-h-48 overflow-y-auto border border-gray-200 dark:border-gray-700 rounded-md p-2", children: watchedUsers.map((user) => (jsxs("div", { className: "flex items-center justify-between bg-gray-50 dark:bg-gray-800 p-2 rounded-md", children: [jsxs("div", { className: "flex flex-col", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: user.name || user.username }), user.email && (jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: user.email }))] }), jsx(Button$1, { type: "button", variant: "ghost", size: "sm", onClick: () => removeWatchedUserDraft(user.id), className: "h-8 w-8 p-0 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20", "aria-label": t('tabsAlertstab.removeWatchedUserAriaLabel', {
224237
224385
  username: user.username,
224238
224386
  }), children: jsx(X$2, { className: "h-4 w-4" }) })] }, user.id))) })) : (jsx("div", { className: "text-sm text-gray-500 dark:text-gray-400 p-4 text-center border border-dashed border-gray-300 dark:border-gray-600 rounded-md", children: t('tabsAlertstab.noWatchedUsersAdded') })), jsxs("div", { className: "relative", children: [jsx(Input, { value: watchedUserSearch, onChange: (e) => {
224239
224387
  setWatchedUserSearch(e.target.value);
@@ -225421,7 +225569,7 @@ function BlocksView({ platformKey, onBack, }) {
225421
225569
  }
225422
225570
 
225423
225571
  const FILTER_ORDER = ['all', ...APPLICATION_STATUSES];
225424
- const PAGE_SIZE$b = 20;
225572
+ const PAGE_SIZE$c = 20;
225425
225573
  const SEARCH_DEBOUNCE_MS$1 = 300;
225426
225574
  /**
225427
225575
  * The public application URL on the auth SPA for one form of a platform
@@ -225564,7 +225712,7 @@ function SubmissionsPipeline({ platformKey, form, onBack, onOpen, }) {
225564
225712
  ...(sort !== '-created' ? { sort } : {}),
225565
225713
  ...candidateParams,
225566
225714
  page,
225567
- page_size: PAGE_SIZE$b,
225715
+ page_size: PAGE_SIZE$c,
225568
225716
  }, {
225569
225717
  refetchOnMountOrArgChange: true,
225570
225718
  });
@@ -225573,7 +225721,7 @@ function SubmissionsPipeline({ platformKey, form, onBack, onOpen, }) {
225573
225721
  : [];
225574
225722
  const rows = form ? allRows.filter((row) => row.form_id === form.id) : allRows;
225575
225723
  const count = typeof (pipeline === null || pipeline === void 0 ? void 0 : pipeline.count) === 'number' ? pipeline.count : allRows.length;
225576
- const totalPages = Math.max(1, Math.ceil(count / PAGE_SIZE$b));
225724
+ const totalPages = Math.max(1, Math.ceil(count / PAGE_SIZE$c));
225577
225725
  const counts = statsCounts(stats);
225578
225726
  const countFor = (key) => {
225579
225727
  if (!stats)
@@ -225611,7 +225759,7 @@ function SubmissionsPipeline({ platformKey, form, onBack, onOpen, }) {
225611
225759
  }) }) }), jsx("td", { className: "whitespace-nowrap px-6 py-4 text-sm text-gray-600 dark:text-gray-300", children: formatDate(row) }), jsx("td", { className: "px-6 py-4", children: jsx(Badge, { variant: "outline", className: approvalTone(row.status), children: STATUS_LABEL_KEYS[row.status]
225612
225760
  ? t(STATUS_LABEL_KEYS[row.status])
225613
225761
  : row.status }) })] }, row.id));
225614
- })) })] }) }), jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (newPage) => setPage(newPage), totalCount: count, itemsPerPage: PAGE_SIZE$b, itemLabel: "applications" })] }))] }));
225762
+ })) })] }) }), jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (newPage) => setPage(newPage), totalCount: count, itemsPerPage: PAGE_SIZE$c, itemLabel: "applications" })] }))] }));
225615
225763
  }
225616
225764
 
225617
225765
  // The user-onboarding form contract: the schema an admin authors in the admin
@@ -229267,6 +229415,325 @@ const PlatformMembershipContent = ({ platformKey, authURL, }) => {
229267
229415
  return (jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-6", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm font-medium text-[#646464]", children: t('advancedPlatformMembership.publicRegistrationLabel') }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { "aria-label": t('advancedPlatformMembership.infoAriaLabel'), className: "hidden sm:block", children: jsx(Info$3, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { className: "rounded-lg bg-gray-700 px-3 py-2 text-sm font-medium whitespace-nowrap text-white shadow-sm transition-opacity duration-300 z-50", children: jsx("p", { children: t('advancedPlatformMembership.infoTooltip') }) })] }) }), (membershipData === null || membershipData === void 0 ? void 0 : membershipData.allow_self_linking) && (jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { onClick: handleCopyToClipboard, "aria-label": t('advancedPlatformMembership.copyAriaLabel'), className: "cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 p-1 rounded transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1", children: jsx(Copy, { className: "h-4 w-4 text-gray-400 hover:text-blue-500" }) }), jsx(TooltipContent, { className: "rounded-lg bg-gray-700 px-3 py-2 text-sm font-medium whitespace-nowrap text-white shadow-sm transition-opacity duration-300 z-50", children: jsx("p", { children: t('advancedPlatformMembership.copyTooltip') }) })] }) }))] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Switch, { checked: membershipData === null || membershipData === void 0 ? void 0 : membershipData.allow_self_linking, onCheckedChange: handleToggleMembership, disabled: isUpdating, "aria-label": `${t('advancedPlatformMembership.switchAriaLabel')} ${(membershipData === null || membershipData === void 0 ? void 0 : membershipData.allow_self_linking) ? t('advancedPlatformMembership.switchEnabled') : t('advancedPlatformMembership.switchDisabled')}`, className: "cursor-pointer data-[state=checked]:bg-blue-500" }), isUpdating && (jsx("div", { className: "w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" }))] })] }));
229268
229416
  };
229269
229417
 
229418
+ /**
229419
+ * Paste-tolerant: a copied address brings a scheme, a path and often a `www.`
229420
+ * with it, and a typed one may carry capitals. The backend takes only a
229421
+ * lowercase bare host and refuses anything else with a field error.
229422
+ */
229423
+ const sanitizeDomain = (domain) => domain
229424
+ .trim()
229425
+ .toLowerCase()
229426
+ .replace(/^https?:\/\//, '')
229427
+ .replace(/\/.*$/, '')
229428
+ .replace(/^www\./, '');
229429
+ const AddDomainDialog = ({ open, onOpenChange, canAddPlatformDomain, projects, isLoadingProjects, isSubmitting, onSubmitPlatformDomain, onSubmitAppDomain, }) => {
229430
+ const t = useT();
229431
+ const [mode, setMode] = useState(canAddPlatformDomain ? 'platform' : 'app');
229432
+ const [domainValue, setDomainValue] = useState('');
229433
+ const [projectId, setProjectId] = useState('');
229434
+ const reset = () => {
229435
+ setDomainValue('');
229436
+ setProjectId('');
229437
+ setMode(canAddPlatformDomain ? 'platform' : 'app');
229438
+ };
229439
+ const close = () => {
229440
+ reset();
229441
+ onOpenChange(false);
229442
+ };
229443
+ const handleSubmit = async (event) => {
229444
+ event.preventDefault();
229445
+ if (mode === 'platform') {
229446
+ await onSubmitPlatformDomain(sanitizeDomain(domainValue));
229447
+ }
229448
+ else {
229449
+ await onSubmitAppDomain(Number(projectId), sanitizeDomain(domainValue));
229450
+ }
229451
+ };
229452
+ const canSubmit = mode === 'platform' ? domainValue.trim().length > 0 : projectId.trim().length > 0;
229453
+ return (jsx(Dialog, { open: open, onOpenChange: (next) => {
229454
+ if (!next) {
229455
+ reset();
229456
+ }
229457
+ onOpenChange(next);
229458
+ }, children: jsxs(DialogContent, { className: "sm:max-w-[480px]", children: [jsxs(DialogHeader, { children: [jsx(DialogTitle, { children: t('advancedCustomDomain.dialogTitle') }), jsx(DialogDescription, { children: t('advancedCustomDomain.dialogDescription') })] }), jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "add-domain-kind", className: "text-sm", children: t('advancedCustomDomain.kindLabel') }), jsxs(Select$1, { value: mode, onValueChange: (next) => setMode(next), children: [jsx(SelectTrigger, { id: "add-domain-kind", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { children: [canAddPlatformDomain && (jsx(SelectItem, { value: "platform", children: t('advancedCustomDomain.kindPlatform') })), jsx(SelectItem, { value: "app", children: t('advancedCustomDomain.kindApp') })] })] })] }), mode === 'app' && (jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "add-domain-project", className: "text-sm", children: t('advancedCustomDomain.projectLabel') }), isLoadingProjects ? (jsx("p", { className: "text-sm text-[#646464]", children: t('advancedCustomDomain.loading') })) : projects.length === 0 ? (
229459
+ // The backend lists only the caller's own projects, so this is
229460
+ // "you have not deployed anything", not "the platform has not".
229461
+ jsx("p", { className: "text-sm text-[#646464]", children: t('advancedCustomDomain.noProjects') })) : (jsxs(Select$1, { value: projectId, onValueChange: setProjectId, children: [jsx(SelectTrigger, { id: "add-domain-project", children: jsx(SelectValue, { placeholder: t('advancedCustomDomain.projectPlaceholder') }) }), jsx(SelectContent, { children: projects.map((project) => (jsx(SelectItem, { value: String(project.id), children: project.name }, project.id))) })] }))] })), jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "add-domain-name", className: "text-sm", children: t('advancedCustomDomain.customDomainLabel') }), jsx(Input, { id: "add-domain-name", value: domainValue, onChange: (event) => setDomainValue(event.target.value), placeholder: "example.com", className: "w-full", required: mode === 'platform' }), jsx("p", { className: "text-xs text-[#646464]", children: mode === 'app'
229462
+ ? t('advancedCustomDomain.domainHelpApp')
229463
+ : t('advancedCustomDomain.domainHelpPlatform') })] }), jsxs("div", { className: "flex justify-end gap-2", children: [jsx(Button$1, { type: "button", variant: "outline", onClick: close, children: t('advancedCustomDomain.cancel') }), jsxs(Button$1, { type: "submit", disabled: isSubmitting || !canSubmit, children: [isSubmitting && jsx(LoaderCircle, { className: "mr-2 h-4 w-4 animate-spin" }), t('advancedCustomDomain.save')] })] })] })] }) }));
229464
+ };
229465
+
229466
+ var SLOTTABLE_IDENTIFIER = Symbol("radix.slottable");
229467
+ // @__NO_SIDE_EFFECTS__
229468
+ function createSlottable(ownerName) {
229469
+ const Slottable2 = ({ children }) => {
229470
+ return /* @__PURE__ */ jsx(Fragment$1, { children });
229471
+ };
229472
+ Slottable2.displayName = `${ownerName}.Slottable`;
229473
+ Slottable2.__radixId = SLOTTABLE_IDENTIFIER;
229474
+ return Slottable2;
229475
+ }
229476
+
229477
+ var ROOT_NAME = "AlertDialog";
229478
+ var [createAlertDialogContext] = createContextScope$1(ROOT_NAME, [
229479
+ createDialogScope
229480
+ ]);
229481
+ var useDialogScope = createDialogScope();
229482
+ var AlertDialog$1 = (props) => {
229483
+ const { __scopeAlertDialog, ...alertDialogProps } = props;
229484
+ const dialogScope = useDialogScope(__scopeAlertDialog);
229485
+ return /* @__PURE__ */ jsx(DialogPrimitive.Root, { ...dialogScope, ...alertDialogProps, modal: true });
229486
+ };
229487
+ AlertDialog$1.displayName = ROOT_NAME;
229488
+ var TRIGGER_NAME$1 = "AlertDialogTrigger";
229489
+ var AlertDialogTrigger = React.forwardRef(
229490
+ (props, forwardedRef) => {
229491
+ const { __scopeAlertDialog, ...triggerProps } = props;
229492
+ const dialogScope = useDialogScope(__scopeAlertDialog);
229493
+ return /* @__PURE__ */ jsx(DialogPrimitive.Trigger, { ...dialogScope, ...triggerProps, ref: forwardedRef });
229494
+ }
229495
+ );
229496
+ AlertDialogTrigger.displayName = TRIGGER_NAME$1;
229497
+ var PORTAL_NAME$1 = "AlertDialogPortal";
229498
+ var AlertDialogPortal$1 = (props) => {
229499
+ const { __scopeAlertDialog, ...portalProps } = props;
229500
+ const dialogScope = useDialogScope(__scopeAlertDialog);
229501
+ return /* @__PURE__ */ jsx(DialogPrimitive.Portal, { ...dialogScope, ...portalProps });
229502
+ };
229503
+ AlertDialogPortal$1.displayName = PORTAL_NAME$1;
229504
+ var OVERLAY_NAME = "AlertDialogOverlay";
229505
+ var AlertDialogOverlay$1 = React.forwardRef(
229506
+ (props, forwardedRef) => {
229507
+ const { __scopeAlertDialog, ...overlayProps } = props;
229508
+ const dialogScope = useDialogScope(__scopeAlertDialog);
229509
+ return /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { ...dialogScope, ...overlayProps, ref: forwardedRef });
229510
+ }
229511
+ );
229512
+ AlertDialogOverlay$1.displayName = OVERLAY_NAME;
229513
+ var CONTENT_NAME$2 = "AlertDialogContent";
229514
+ var [AlertDialogContentProvider, useAlertDialogContentContext] = createAlertDialogContext(CONTENT_NAME$2);
229515
+ var Slottable = createSlottable("AlertDialogContent");
229516
+ var AlertDialogContent$1 = React.forwardRef(
229517
+ (props, forwardedRef) => {
229518
+ const { __scopeAlertDialog, children, ...contentProps } = props;
229519
+ const dialogScope = useDialogScope(__scopeAlertDialog);
229520
+ const contentRef = React.useRef(null);
229521
+ const composedRefs = useComposedRefs$1(forwardedRef, contentRef);
229522
+ const cancelRef = React.useRef(null);
229523
+ return /* @__PURE__ */ jsx(
229524
+ DialogPrimitive.WarningProvider,
229525
+ {
229526
+ contentName: CONTENT_NAME$2,
229527
+ titleName: TITLE_NAME,
229528
+ docsSlug: "alert-dialog",
229529
+ children: /* @__PURE__ */ jsx(AlertDialogContentProvider, { scope: __scopeAlertDialog, cancelRef, children: /* @__PURE__ */ jsxs(
229530
+ DialogPrimitive.Content,
229531
+ {
229532
+ role: "alertdialog",
229533
+ ...dialogScope,
229534
+ ...contentProps,
229535
+ ref: composedRefs,
229536
+ onOpenAutoFocus: composeEventHandlers$2(contentProps.onOpenAutoFocus, (event) => {
229537
+ event.preventDefault();
229538
+ cancelRef.current?.focus({ preventScroll: true });
229539
+ }),
229540
+ onPointerDownOutside: (event) => event.preventDefault(),
229541
+ onInteractOutside: (event) => event.preventDefault(),
229542
+ children: [
229543
+ /* @__PURE__ */ jsx(Slottable, { children }),
229544
+ /* @__PURE__ */ jsx(DescriptionWarning, { contentRef })
229545
+ ]
229546
+ }
229547
+ ) })
229548
+ }
229549
+ );
229550
+ }
229551
+ );
229552
+ AlertDialogContent$1.displayName = CONTENT_NAME$2;
229553
+ var TITLE_NAME = "AlertDialogTitle";
229554
+ var AlertDialogTitle$1 = React.forwardRef(
229555
+ (props, forwardedRef) => {
229556
+ const { __scopeAlertDialog, ...titleProps } = props;
229557
+ const dialogScope = useDialogScope(__scopeAlertDialog);
229558
+ return /* @__PURE__ */ jsx(DialogPrimitive.Title, { ...dialogScope, ...titleProps, ref: forwardedRef });
229559
+ }
229560
+ );
229561
+ AlertDialogTitle$1.displayName = TITLE_NAME;
229562
+ var DESCRIPTION_NAME = "AlertDialogDescription";
229563
+ var AlertDialogDescription$1 = React.forwardRef((props, forwardedRef) => {
229564
+ const { __scopeAlertDialog, ...descriptionProps } = props;
229565
+ const dialogScope = useDialogScope(__scopeAlertDialog);
229566
+ return /* @__PURE__ */ jsx(DialogPrimitive.Description, { ...dialogScope, ...descriptionProps, ref: forwardedRef });
229567
+ });
229568
+ AlertDialogDescription$1.displayName = DESCRIPTION_NAME;
229569
+ var ACTION_NAME = "AlertDialogAction";
229570
+ var AlertDialogAction$1 = React.forwardRef(
229571
+ (props, forwardedRef) => {
229572
+ const { __scopeAlertDialog, ...actionProps } = props;
229573
+ const dialogScope = useDialogScope(__scopeAlertDialog);
229574
+ return /* @__PURE__ */ jsx(DialogPrimitive.Close, { ...dialogScope, ...actionProps, ref: forwardedRef });
229575
+ }
229576
+ );
229577
+ AlertDialogAction$1.displayName = ACTION_NAME;
229578
+ var CANCEL_NAME = "AlertDialogCancel";
229579
+ var AlertDialogCancel$1 = React.forwardRef(
229580
+ (props, forwardedRef) => {
229581
+ const { __scopeAlertDialog, ...cancelProps } = props;
229582
+ const { cancelRef } = useAlertDialogContentContext(CANCEL_NAME, __scopeAlertDialog);
229583
+ const dialogScope = useDialogScope(__scopeAlertDialog);
229584
+ const ref = useComposedRefs$1(forwardedRef, cancelRef);
229585
+ return /* @__PURE__ */ jsx(DialogPrimitive.Close, { ...dialogScope, ...cancelProps, ref });
229586
+ }
229587
+ );
229588
+ AlertDialogCancel$1.displayName = CANCEL_NAME;
229589
+ var DescriptionWarning = ({ contentRef }) => {
229590
+ const MESSAGE = `\`${CONTENT_NAME$2}\` requires a description for the component to be accessible for screen reader users.
229591
+
229592
+ You can add a description to the \`${CONTENT_NAME$2}\` by passing a \`${DESCRIPTION_NAME}\` component as a child, which also benefits sighted users by adding visible context to the dialog.
229593
+
229594
+ Alternatively, you can use your own component as a description by assigning it an \`id\` and passing the same value to the \`aria-describedby\` prop in \`${CONTENT_NAME$2}\`. If the description is confusing or duplicative for sighted users, you can use the \`@radix-ui/react-visually-hidden\` primitive as a wrapper around your description component.
229595
+
229596
+ For more information, see https://radix-ui.com/primitives/docs/components/alert-dialog`;
229597
+ React.useEffect(() => {
229598
+ const hasDescription = document.getElementById(
229599
+ contentRef.current?.getAttribute("aria-describedby")
229600
+ );
229601
+ if (!hasDescription) console.warn(MESSAGE);
229602
+ }, [MESSAGE, contentRef]);
229603
+ return null;
229604
+ };
229605
+ var Root2$2 = AlertDialog$1;
229606
+ var Portal2 = AlertDialogPortal$1;
229607
+ var Overlay2 = AlertDialogOverlay$1;
229608
+ var Content2$1 = AlertDialogContent$1;
229609
+ var Action = AlertDialogAction$1;
229610
+ var Cancel = AlertDialogCancel$1;
229611
+ var Title2 = AlertDialogTitle$1;
229612
+ var Description2 = AlertDialogDescription$1;
229613
+
229614
+ const AlertDialog = Root2$2;
229615
+ const AlertDialogPortal = Portal2;
229616
+ const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => (jsx(Overlay2, { className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80', className), ...props, ref: ref })));
229617
+ AlertDialogOverlay.displayName = Overlay2.displayName;
229618
+ const AlertDialogContent = React.forwardRef(({ className, ...props }, ref) => (jsxs(AlertDialogPortal, { children: [jsx(AlertDialogOverlay, {}), jsx(Content2$1, { ref: ref, className: cn('bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg', className), ...props })] })));
229619
+ AlertDialogContent.displayName = Content2$1.displayName;
229620
+ const AlertDialogHeader = ({ className, ...props }) => (jsx("div", { className: cn('flex flex-col space-y-2 text-center sm:text-left', className), ...props }));
229621
+ AlertDialogHeader.displayName = 'AlertDialogHeader';
229622
+ const AlertDialogFooter = ({ className, ...props }) => (jsx("div", { className: cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className), ...props }));
229623
+ AlertDialogFooter.displayName = 'AlertDialogFooter';
229624
+ const AlertDialogTitle = React.forwardRef(({ className, ...props }, ref) => (jsx(Title2, { ref: ref, className: cn('text-lg font-semibold', className), ...props })));
229625
+ AlertDialogTitle.displayName = Title2.displayName;
229626
+ const AlertDialogDescription = React.forwardRef(({ className, ...props }, ref) => (jsx(Description2, { ref: ref, className: cn('text-muted-foreground text-sm', className), ...props })));
229627
+ AlertDialogDescription.displayName = Description2.displayName;
229628
+ const AlertDialogAction = React.forwardRef(({ className, ...props }, ref) => (jsx(Action, { ref: ref, className: cn(buttonVariants(), className), ...props })));
229629
+ AlertDialogAction.displayName = Action.displayName;
229630
+ const AlertDialogCancel = React.forwardRef(({ className, ...props }, ref) => (jsx(Cancel, { ref: ref, className: cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', className), ...props })));
229631
+ AlertDialogCancel.displayName = Cancel.displayName;
229632
+
229633
+ const hostedDomainStatus = (row) => {
229634
+ // A domain that was taken over keeps this organization's old `verified_at`,
229635
+ // so `lost_at` has to outrank it: the row is waiting on DNS again until a
229636
+ // re-verify reclaims it. The panel does not say who took it.
229637
+ if (row.lost_at) {
229638
+ return 'unverified';
229639
+ }
229640
+ return row.verified_at ? 'verified' : 'unverified';
229641
+ };
229642
+ /**
229643
+ * Every SPA domain CNAMEs to the same instance-wide host, so this answers "is
229644
+ * DNS pointing at us" and nothing more — it cannot tell which organization owns
229645
+ * the name. That is why it is only ever used for SPA rows.
229646
+ */
229647
+ const resolveCname = async (domain, target) => {
229648
+ var _a;
229649
+ const response = await fetch(`https://dns.google/resolve?name=${domain}&type=CNAME`, {
229650
+ cache: 'no-store',
229651
+ });
229652
+ const body = await response.json();
229653
+ return Boolean((_a = body === null || body === void 0 ? void 0 : body.Answer) === null || _a === void 0 ? void 0 : _a.some((answer) => { var _a; return ((_a = answer.data) !== null && _a !== void 0 ? _a : '').replace(/\.$/, '') === target; }));
229654
+ };
229655
+ const DomainRow = ({ row, sslValue, onReverify, onRemove, isBusy, onStatusChange, }) => {
229656
+ var _a;
229657
+ const t = useT();
229658
+ const isHosted = row.spa === VERCEL_SPA;
229659
+ const [copiedKey, setCopiedKey] = useState(null);
229660
+ const [confirmOpen, setConfirmOpen] = useState(false);
229661
+ const [spaStatus, setSpaStatus] = useState('checking');
229662
+ const checkSpaDomain = useCallback(async () => {
229663
+ if (isHosted) {
229664
+ return;
229665
+ }
229666
+ if (!row.registered_with_dns_pro) {
229667
+ setSpaStatus('unregistered');
229668
+ return;
229669
+ }
229670
+ setSpaStatus('checking');
229671
+ try {
229672
+ setSpaStatus((await resolveCname(row.custom_domain, sslValue)) ? 'verified' : 'unverified');
229673
+ }
229674
+ catch (_a) {
229675
+ // A blocked or failed lookup is not the same answer as "the record is
229676
+ // missing" — the OS content-security-policy can refuse the request
229677
+ // outright — so say so instead of showing a confident "Not verified".
229678
+ setSpaStatus('unknown');
229679
+ toast.error(t('advancedCustomDomain.verifyUnavailable'));
229680
+ }
229681
+ }, [isHosted, row.custom_domain, row.registered_with_dns_pro, sslValue, t]);
229682
+ useEffect(() => {
229683
+ void checkSpaDomain();
229684
+ }, [checkSpaDomain]);
229685
+ useEffect(() => {
229686
+ if (isHosted) {
229687
+ return;
229688
+ }
229689
+ onStatusChange === null || onStatusChange === void 0 ? void 0 : onStatusChange(row.id, spaStatus);
229690
+ }, [isHosted, onStatusChange, row.id, spaStatus]);
229691
+ const status = isHosted ? hostedDomainStatus(row) : spaStatus;
229692
+ // A hosted row's records come from the provider and carry a reason each; an
229693
+ // SPA row has none stored, and its single CNAME is the same for every
229694
+ // organization on the instance, so it is computed here.
229695
+ const records = isHosted
229696
+ ? ((_a = row.records) !== null && _a !== void 0 ? _a : [])
229697
+ : [{ type: 'CNAME', name: row.custom_domain, value: sslValue }];
229698
+ const handleCopy = async (value, key) => {
229699
+ try {
229700
+ await navigator.clipboard.writeText(value);
229701
+ setCopiedKey(key);
229702
+ toast.success(t('advancedCustomDomain.copiedToClipboard'));
229703
+ setTimeout(() => setCopiedKey(null), 5000);
229704
+ }
229705
+ catch (_a) {
229706
+ toast.error(t('advancedCustomDomain.unableToCopy'));
229707
+ }
229708
+ };
229709
+ // Spelled out rather than built from `status`: the i18n coverage check reads
229710
+ // literal t('…') calls out of the source, so a computed key is invisible to
229711
+ // it and a typo in one would only surface in the running UI.
229712
+ const statusLabel = () => {
229713
+ switch (status) {
229714
+ case 'verified':
229715
+ return t('advancedCustomDomain.statusVerified');
229716
+ case 'unregistered':
229717
+ return t('advancedCustomDomain.statusUnregistered');
229718
+ case 'unknown':
229719
+ return t('advancedCustomDomain.statusUnknown');
229720
+ default:
229721
+ return t('advancedCustomDomain.statusUnverified');
229722
+ }
229723
+ };
229724
+ const statusBadge = (jsx("span", { className: status === 'verified'
229725
+ ? 'rounded bg-green-100 px-2 py-1 text-xs text-green-800'
229726
+ : 'rounded bg-gray-100 px-2 py-1 text-xs text-gray-600', children: status === 'checking' ? (jsxs("span", { className: "flex items-center gap-1", children: [jsx(LoaderCircle, { className: "h-3 w-3 animate-spin" }), t('advancedCustomDomain.verifying')] })) : (statusLabel()) }));
229727
+ return (jsxs("div", { className: "space-y-3 rounded-lg border border-gray-200 p-3 dark:border-gray-700", children: [jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm", children: row.custom_domain }), jsx("span", { className: "text-xs text-[#646464]", children: isHosted ? t('advancedCustomDomain.kindApp') : t('advancedCustomDomain.kindPlatform') }), statusBadge] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(Button$1, { variant: "outline", size: "sm", onClick: () => (isHosted ? void onReverify(row) : void checkSpaDomain()), disabled: isBusy || status === 'checking' || (!isHosted && !row.registered_with_dns_pro), "aria-label": t('advancedCustomDomain.reverifyAriaLabel', { domain: row.custom_domain }), children: isBusy || status === 'checking' ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" })) : (jsxs(Fragment$1, { children: [jsx(RefreshCw, { className: "mr-1 h-4 w-4", "aria-hidden": "true" }), t('advancedCustomDomain.reverify')] })) }), jsx(Button$1, { variant: "outline", size: "sm", className: "text-red-600 hover:text-red-700", onClick: () => setConfirmOpen(true), disabled: isBusy, "aria-label": t('advancedCustomDomain.removeAriaLabel', { domain: row.custom_domain }), children: isHosted ? t('advancedCustomDomain.detach') : t('advancedCustomDomain.delete') })] })] }), records.length > 0 ? (jsxs(Table$1, { className: "table-fixed", children: [jsx(TableHeader$1, { children: jsxs(TableRow$1, { children: [jsx(TableHead, { className: "w-[90px]", children: t('advancedCustomDomain.tableType') }), jsx(TableHead, { className: "w-1/3", children: t('advancedCustomDomain.tableNameHost') }), jsx(TableHead, { children: t('advancedCustomDomain.tableValue') })] }) }), jsx(TableBody, { children: records.map((record, index) => (jsxs(TableRow$1, { children: [jsx(TableCell$1, { className: "text-sm", children: record.type }), jsx(TableCell$1, { children: jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm break-all", children: record.name }), jsx(Button$1, { type: "button", variant: "ghost", size: "icon", className: "h-6 w-6 shrink-0", onClick: () => handleCopy(record.name, `name-${index}`), "aria-label": t('advancedCustomDomain.copyNameHostAriaLabel', {
229728
+ domain: record.name,
229729
+ }), children: copiedKey === `name-${index}` ? (jsx(Check, { className: "h-4 w-4 text-blue-600", "aria-hidden": "true" })) : (jsx(Copy, { className: "h-4 w-4", "aria-hidden": "true" })) })] }) }), jsxs(TableCell$1, { children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm break-all", children: record.value }), jsx(Button$1, { type: "button", variant: "ghost", size: "icon", className: "h-6 w-6 shrink-0", onClick: () => handleCopy(record.value, `value-${index}`), "aria-label": t('advancedCustomDomain.copyValueAriaLabel'), children: copiedKey === `value-${index}` ? (jsx(Check, { className: "h-4 w-4 text-blue-600", "aria-hidden": "true" })) : (jsx(Copy, { className: "h-4 w-4", "aria-hidden": "true" })) })] }), record.reason && jsx("p", { className: "mt-1 text-xs text-[#646464]", children: record.reason })] })] }, `${record.type}-${record.name}-${record.value}`))) })] })) : (jsx("p", { className: "text-sm text-[#646464]", children: t('advancedCustomDomain.noRecordsYet') })), jsx(AlertDialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: jsxs(AlertDialogContent, { children: [jsxs(AlertDialogHeader, { children: [jsx(AlertDialogTitle, { children: t('advancedCustomDomain.confirmRemoveTitle') }), jsx(AlertDialogDescription, { children: isHosted
229730
+ ? t('advancedCustomDomain.confirmDetachBody', { domain: row.custom_domain })
229731
+ : t('advancedCustomDomain.confirmDeleteBody', { domain: row.custom_domain }) })] }), jsxs(AlertDialogFooter, { children: [jsx(AlertDialogCancel, { children: t('advancedCustomDomain.cancel') }), jsx(AlertDialogAction, { onClick: () => {
229732
+ setConfirmOpen(false);
229733
+ void onRemove(row);
229734
+ }, children: isHosted ? t('advancedCustomDomain.detach') : t('advancedCustomDomain.delete') })] })] }) })] }));
229735
+ };
229736
+
229270
229737
  const normalizeCustomDomains = (response) => {
229271
229738
  if (!response) {
229272
229739
  return [];
@@ -229285,141 +229752,196 @@ const normalizeCustomDomains = (response) => {
229285
229752
  }
229286
229753
  return [];
229287
229754
  };
229288
- const sanitizeDomain = (domain) => {
229289
- return domain
229290
- .trim()
229291
- .replace(/^https?:\/\//, '') // Remove http:// or https://
229292
- .replace(/^www\./, ''); // Remove www.
229755
+ const serverDetail = (error) => {
229756
+ const data = error === null || error === void 0 ? void 0 : error.data;
229757
+ if (typeof data === 'string') {
229758
+ return data;
229759
+ }
229760
+ const body = data;
229761
+ for (const value of [body === null || body === void 0 ? void 0 : body.error, body === null || body === void 0 ? void 0 : body.message, body === null || body === void 0 ? void 0 : body.detail]) {
229762
+ if (typeof value === 'string' && value.trim() !== '') {
229763
+ return value;
229764
+ }
229765
+ }
229766
+ // A field error — `{"domain": ["…"]}` — is how the backend refuses a malformed
229767
+ // name; its text is the first entry of the first such list.
229768
+ for (const value of Object.values(body !== null && body !== void 0 ? body : {})) {
229769
+ const first = Array.isArray(value) ? value[0] : undefined;
229770
+ if (typeof first === 'string' && first.trim() !== '') {
229771
+ return first;
229772
+ }
229773
+ }
229774
+ return undefined;
229293
229775
  };
229294
- const CustomDomainsContent = ({ platformKey, currentSPA, currentPlatformBaseDomain, }) => {
229776
+ const CustomDomainsContent = ({ platformKey, username, currentSPA, currentPlatformBaseDomain, }) => {
229777
+ var _a;
229295
229778
  const t = useT();
229296
229779
  const [isCollapsed, setIsCollapsed] = useState(true);
229297
229780
  const [isModalOpen, setIsModalOpen] = useState(false);
229298
- const [customDomainValue, setCustomDomainValue] = useState('');
229299
- const [deletingDomainId, setDeletingDomainId] = useState(null);
229300
- const [copiedField, setCopiedField] = useState(null);
229301
- const [isVerified, setIsVerified] = useState(null);
229302
- const [isVerifying, setIsVerifying] = useState(false);
229781
+ const [busyDomainId, setBusyDomainId] = useState(null);
229303
229782
  const { data, isLoading, isFetching, refetch } = useGetCustomDomainsQuery({
229304
229783
  params: { platform_key: platformKey },
229305
229784
  });
229785
+ // Only the caller's own deployed apps are listable, and only the Add dialog
229786
+ // needs them — so this stays idle until it opens.
229787
+ const { data: projectData, isFetching: isLoadingProjects } = useGetHostingProjectsQuery({ org: platformKey, username }, { skip: !isModalOpen || !username });
229306
229788
  const [createCustomDomain, { isLoading: isCreating }] = useCreateCustomDomainMutation();
229307
229789
  const [deleteCustomDomain] = useDeleteCustomDomainMutation();
229790
+ const [createHostingProjectDomain, { isLoading: isAttaching }] = useCreateHostingProjectDomainMutation();
229791
+ const [updateHostingDomain] = useUpdateHostingDomainMutation();
229792
+ const [deleteHostingDomain] = useDeleteHostingDomainMutation();
229308
229793
  const customDomains = useMemo(() => normalizeCustomDomains(data), [data]);
229309
- const sslValue = `ssl.${currentPlatformBaseDomain && currentPlatformBaseDomain.trim() !== '' ? currentPlatformBaseDomain : typeof window !== 'undefined' ? window.location.hostname.split('.').slice(-2).join('.') : 'iblai.app'}`;
229310
- // Get the current domain for the current SPA
229311
- const currentDomain = useMemo(() => {
229312
- if (!currentSPA)
229313
- return null;
229314
- return customDomains.find((domain) => { var _a; return (_a = domain.spa) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(currentSPA.toLowerCase()); });
229315
- }, [customDomains, currentSPA]);
229316
- const verifyCustomDomain = async (domain) => {
229317
- if (!(currentDomain === null || currentDomain === void 0 ? void 0 : currentDomain.registered_with_dns_pro)) {
229318
- return;
229319
- }
229320
- setIsVerifying(true);
229321
- try {
229322
- const endpoint = `https://dns.google/resolve?name=${domain}&type=CNAME`;
229323
- const res = await fetch(endpoint, { cache: 'no-store' });
229324
- const data = await res.json();
229325
- let verified = false;
229326
- if (data.Answer) {
229327
- // Check if any CNAME record points to sslValue
229328
- verified = data.Answer.some((a) => a.data.replace(/\.$/, '') === sslValue);
229329
- }
229330
- setIsVerified(verified);
229331
- }
229332
- catch (error) {
229333
- console.error('Failed to verify domain:', error);
229334
- setIsVerified(false);
229335
- }
229336
- finally {
229337
- setIsVerifying(false);
229338
- }
229339
- };
229340
- // Auto-check verification on domain load
229341
- useEffect(() => {
229342
- if (currentDomain === null || currentDomain === void 0 ? void 0 : currentDomain.custom_domain) {
229343
- verifyCustomDomain(currentDomain.custom_domain);
229344
- }
229345
- else {
229346
- setIsVerified(null);
229347
- }
229348
- }, [currentDomain === null || currentDomain === void 0 ? void 0 : currentDomain.custom_domain]);
229349
- const handleDeleteCustomDomain = async (domain_id) => {
229350
- try {
229351
- setDeletingDomainId(domain_id);
229352
- await deleteCustomDomain({
229353
- domain_id,
229354
- platform_key: platformKey,
229355
- }).unwrap();
229356
- await refetch();
229357
- toast.success(t('advancedCustomDomain.deleteSuccess'));
229358
- }
229359
- catch (error) {
229360
- console.error('Failed to delete custom domain:', error);
229361
- toast.error(t('advancedCustomDomain.deleteError'));
229362
- }
229363
- finally {
229364
- setDeletingDomainId(null);
229794
+ // A sign-in row's answer exists only in the browser, so the row reports it up
229795
+ // to here. Two things stop a child's effect writing parent state that
229796
+ // re-renders the child that fired it, for ever: this identity never changes,
229797
+ // and an unchanged status returns the SAME object so React bails out. Either
229798
+ // alone is enough — losing both hangs the process, so the cheap second one
229799
+ // stays. Adding a dependency below is exactly how the first gets lost.
229800
+ const [spaStatuses, setSpaStatuses] = useState({});
229801
+ const handleStatusChange = useCallback((id, status) => {
229802
+ setSpaStatuses((previous) => previous[id] === status ? previous : { ...previous, [id]: status });
229803
+ }, []);
229804
+ // Verified first. Two groups rather than a full ranking — nothing was asked
229805
+ // about the order of the rest, and Array#sort is stable, so the server's
229806
+ // order survives inside each group.
229807
+ const sortedDomains = useMemo(() => {
229808
+ const isVerified = (row) => (row.spa === VERCEL_SPA ? hostedDomainStatus(row) : spaStatuses[row.id]) === 'verified';
229809
+ return [...customDomains].sort((a, b) => Number(isVerified(b)) - Number(isVerified(a)));
229810
+ }, [customDomains, spaStatuses]);
229811
+ const sslValue = `ssl.${currentPlatformBaseDomain && currentPlatformBaseDomain.trim() !== ''
229812
+ ? currentPlatformBaseDomain
229813
+ : typeof window !== 'undefined'
229814
+ ? window.location.hostname.split('.').slice(-2).join('.')
229815
+ : 'iblai.app'}`;
229816
+ // A platform gets one sign-in domain per SPA, so the Add dialog offers that
229817
+ // kind only while this SPA has none. Deployed apps have no such limit.
229818
+ const canAddPlatformDomain = useMemo(() => Boolean(currentSPA) &&
229819
+ !customDomains.some((domain) => { var _a; return domain.spa !== VERCEL_SPA && ((_a = domain.spa) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(currentSPA.toLowerCase())); }), [customDomains, currentSPA]);
229820
+ /**
229821
+ * The status decides what the user should do next, so it gets its own
229822
+ * message. 409 shares 400's: both mean "not this domain, not here", and the
229823
+ * panel does not tell one organization that another is holding it.
229824
+ */
229825
+ const headlineForStatus = (status, fallback) => {
229826
+ switch (status) {
229827
+ case 400:
229828
+ case 409:
229829
+ return t('advancedCustomDomain.errorRefused');
229830
+ case 403:
229831
+ return t('advancedCustomDomain.errorForbidden');
229832
+ case 429:
229833
+ return t('advancedCustomDomain.errorRateLimited');
229834
+ case 502:
229835
+ return t('advancedCustomDomain.errorUpstream');
229836
+ case 503:
229837
+ return t('advancedCustomDomain.errorUnavailable');
229838
+ default:
229839
+ return fallback;
229365
229840
  }
229366
229841
  };
229367
- const handleResetForm = () => {
229368
- setCustomDomainValue('');
229842
+ const reportError = (error, fallback) => {
229843
+ const status = error === null || error === void 0 ? void 0 : error.status;
229844
+ // The server's own words go underneath the headline — except on 409, the
229845
+ // one status whose body names the organization holding the domain.
229846
+ const description = status === 409 ? undefined : serverDetail(error);
229847
+ toast.error(headlineForStatus(status, fallback), { description });
229369
229848
  };
229370
- const handleAddCustomDomain = async (event) => {
229371
- event.preventDefault();
229372
- if (!customDomainValue.trim()) {
229849
+ const handleAddPlatformDomain = async (domain) => {
229850
+ if (!domain) {
229373
229851
  toast.error(t('advancedCustomDomain.pleaseEnterDomain'));
229374
229852
  return;
229375
229853
  }
229376
- const sanitizedDomain = sanitizeDomain(customDomainValue);
229377
229854
  try {
229378
229855
  await createCustomDomain({
229379
229856
  requestBody: {
229380
229857
  platform_key: platformKey,
229381
- custom_domain: sanitizedDomain,
229858
+ custom_domain: domain,
229382
229859
  spa: (currentSPA.endsWith('ai') ? currentSPA : `${currentSPA}ai`),
229383
229860
  registered_with_dns_pro: true,
229384
229861
  },
229385
229862
  }).unwrap();
229386
229863
  await refetch();
229387
229864
  toast.success(t('advancedCustomDomain.createSuccess'));
229388
- handleResetForm();
229389
229865
  setIsModalOpen(false);
229390
- // Auto-verify after creation
229391
- setTimeout(() => {
229392
- verifyCustomDomain(sanitizedDomain);
229393
- }, 1000);
229394
229866
  }
229395
- catch (mutationError) {
229396
- console.error('Failed to create custom domain:', mutationError);
229397
- toast.error(t('advancedCustomDomain.createError'));
229867
+ catch (error) {
229868
+ reportError(error, t('advancedCustomDomain.createError'));
229398
229869
  }
229399
229870
  };
229400
- const handleCopyField = async (value, fieldType) => {
229871
+ const handleAddAppDomain = async (project, domain) => {
229401
229872
  try {
229402
- await navigator.clipboard.writeText(value);
229403
- setCopiedField(fieldType);
229404
- toast.success(t('advancedCustomDomain.copiedToClipboard'));
229405
- // Reset the icon after 5 seconds
229406
- setTimeout(() => {
229407
- setCopiedField(null);
229408
- }, 5000);
229873
+ // An empty domain is the "assign me a subdomain" path, which the backend
229874
+ // reads as the absent key — not as an empty string.
229875
+ await createHostingProjectDomain({
229876
+ org: platformKey,
229877
+ username,
229878
+ project,
229879
+ domain: domain || undefined,
229880
+ }).unwrap();
229881
+ await refetch();
229882
+ toast.success(t('advancedCustomDomain.createSuccess'));
229883
+ setIsModalOpen(false);
229409
229884
  }
229410
- catch (copyError) {
229411
- console.error('Failed to copy:', copyError);
229412
- toast.error(t('advancedCustomDomain.unableToCopy'));
229885
+ catch (error) {
229886
+ reportError(error, t('advancedCustomDomain.createError'));
229413
229887
  }
229414
229888
  };
229415
- return (jsxs("div", { className: "rounded-lg px-6 py-5 border border-gray-200 dark:border-gray-700", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex sm:items-center justify-between", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx("span", { className: "text-sm font-medium text-[#646464]", children: t('advancedCustomDomain.dnsConfiguration') }), isFetching && !isLoading && (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin text-blue-500", "aria-hidden": "true" }))] }), jsxs("div", { className: "flex items-center gap-2 self-end sm:self-auto", children: [!currentDomain && (jsxs(Dialog, { open: isModalOpen, onOpenChange: setIsModalOpen, children: [jsx(DialogTrigger, { asChild: true, children: jsxs(Button$1, { type: "button", variant: "secondary", size: "sm", className: "gap-1", children: [jsx(Plus, { className: "h-4 w-4", "aria-hidden": "true" }), t('advancedCustomDomain.add')] }) }), jsxs(DialogContent, { className: "sm:max-w-[425px]", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { children: t('advancedCustomDomain.dialogTitle') }) }), jsxs("form", { onSubmit: handleAddCustomDomain, className: "space-y-4", children: [jsxs("div", { className: "space-y-2", children: [jsx("div", { className: "bg-blue-50 border border-blue-200 rounded-md p-3", children: jsxs("div", { className: "flex items-center gap-2", children: [jsx("div", { className: "w-4 h-4 bg-blue-400 rounded-full flex items-center justify-center", children: jsx("span", { className: "text-white text-xs", children: "!" }) }), jsx("span", { className: "text-sm text-blue-800", children: t('advancedCustomDomain.verificationNecessary') })] }) }), jsxs("div", { className: "space-y-2", children: [jsx("label", { htmlFor: "custom-domain", className: "text-sm", children: t('advancedCustomDomain.customDomainLabel') }), jsx(Input, { id: "custom-domain", value: customDomainValue, onChange: (event) => setCustomDomainValue(event.target.value), placeholder: "example.com", className: "w-full", required: true })] })] }), jsxs("div", { className: "flex justify-end gap-2", children: [jsx(Button$1, { type: "button", variant: "outline", onClick: () => {
229416
- setIsModalOpen(false);
229417
- handleResetForm();
229418
- }, children: t('advancedCustomDomain.cancel') }), jsxs(Button$1, { className: "bg-gradient-to-r from-blue-500 to-blue-600 text-white hover:opacity-90", type: "submit", disabled: isCreating, children: [isCreating && jsx(LoaderCircle, { className: "h-4 w-4 animate-spin mr-2" }), t('advancedCustomDomain.save')] })] })] })] })] })), jsx("button", { onClick: () => setIsCollapsed((previous) => !previous), className: "p-1 rounded hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1", "aria-label": isCollapsed
229889
+ const handleReverify = async (row) => {
229890
+ setBusyDomainId(row.id);
229891
+ try {
229892
+ const result = await updateHostingDomain({
229893
+ org: platformKey,
229894
+ domainId: row.id,
229895
+ }).unwrap();
229896
+ await refetch();
229897
+ // The rule the badge is built from after the refetch: Vercel says verified
229898
+ // AND not misconfigured. `verified` alone is ownership (the TXT record); a
229899
+ // domain can hold that and still not point here, and the badge would then
229900
+ // say "required" while this toast said "serving".
229901
+ if ((result === null || result === void 0 ? void 0 : result.verified) && (result === null || result === void 0 ? void 0 : result.misconfigured) === false) {
229902
+ toast.success(t('advancedCustomDomain.verifySuccess'));
229903
+ }
229904
+ else {
229905
+ // Includes the reclaim the server refused — it answers 200, unverified,
229906
+ // and says which organization still serves it. Not relayed: from here
229907
+ // the domain is simply waiting on its records, same as any other.
229908
+ toast.message(t('advancedCustomDomain.verifyPending'));
229909
+ }
229910
+ }
229911
+ catch (error) {
229912
+ reportError(error, t('advancedCustomDomain.verifyError'));
229913
+ }
229914
+ finally {
229915
+ setBusyDomainId(null);
229916
+ }
229917
+ };
229918
+ const handleRemove = async (row) => {
229919
+ setBusyDomainId(row.id);
229920
+ try {
229921
+ // A hosted row has to go through the hosting route: deleting it here
229922
+ // would drop the record while the domain carried on serving the app.
229923
+ if (row.spa === VERCEL_SPA) {
229924
+ await deleteHostingDomain({ org: platformKey, domainId: row.id }).unwrap();
229925
+ }
229926
+ else {
229927
+ await deleteCustomDomain({ domain_id: row.id, platform_key: platformKey }).unwrap();
229928
+ }
229929
+ await refetch();
229930
+ toast.success(t('advancedCustomDomain.deleteSuccess'));
229931
+ }
229932
+ catch (error) {
229933
+ reportError(error, t('advancedCustomDomain.deleteError'));
229934
+ }
229935
+ finally {
229936
+ setBusyDomainId(null);
229937
+ }
229938
+ };
229939
+ return (jsxs("div", { className: "rounded-lg border border-gray-200 px-6 py-5 dark:border-gray-700", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex justify-between sm:items-center", children: [jsxs("div", { className: "flex items-center gap-3", children: [jsx("span", { className: "text-sm font-medium text-[#646464]", children: t('advancedCustomDomain.dnsConfiguration') }), isFetching && !isLoading && (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin text-blue-500", "aria-hidden": "true" }))] }), jsxs("div", { className: "flex items-center gap-2 self-end sm:self-auto", children: [jsxs(Button$1, { type: "button", variant: "secondary", size: "sm", className: "gap-1", onClick: () => {
229940
+ setIsCollapsed(false);
229941
+ setIsModalOpen(true);
229942
+ }, children: [jsx(Plus, { className: "h-4 w-4", "aria-hidden": "true" }), t('advancedCustomDomain.add')] }), jsx("button", { onClick: () => setIsCollapsed((previous) => !previous), className: "rounded p-1 hover:bg-gray-100 focus:ring-2 focus:ring-blue-500 focus:ring-offset-1 focus:outline-none dark:hover:bg-gray-800", "aria-label": isCollapsed
229419
229943
  ? t('advancedCustomDomain.expandAriaLabel')
229420
- : t('advancedCustomDomain.collapseAriaLabel'), type: "button", children: isCollapsed ? (jsx(ChevronDown, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" })) : (jsx(ChevronUp, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" })) })] })] }), !isCollapsed && (jsx("div", { className: "mt-4", children: isLoading ? (jsx("div", { className: "p-4 text-gray-500", children: t('advancedCustomDomain.loading') })) : currentDomain ? (jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between p-3 bg-gray-50 rounded-lg", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { children: currentDomain.custom_domain }), isVerifying ? (jsxs("span", { className: "px-2 py-1 text-xs bg-gray-100 text-gray-600 rounded flex items-center gap-1", children: [jsx(LoaderCircle, { className: "h-3 w-3 animate-spin" }), t('advancedCustomDomain.verifying')] })) : isVerified ? (jsx("span", { className: "px-2 py-1 text-xs bg-green-100 text-green-800 rounded", children: t('advancedCustomDomain.verified') })) : !currentDomain.registered_with_dns_pro ? (jsx("span", { className: "px-2 py-1 text-xs bg-yellow-100 text-yellow-800 rounded", children: t('advancedCustomDomain.unregistered') })) : isVerified === false ? (jsx("span", { className: "px-2 py-1 text-xs bg-yellow-100 text-yellow-800 rounded", children: t('advancedCustomDomain.notVerified') })) : null] }), jsxs("div", { className: "flex items-center gap-2", children: [!isVerified && isVerified !== null && currentDomain.registered_with_dns_pro && (jsx(Button$1, { variant: "outline", size: "sm", onClick: () => verifyCustomDomain(currentDomain.custom_domain), disabled: isVerifying, children: isVerifying ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" })) : (jsxs(Fragment$1, { children: [jsx(RefreshCw, { className: "h-4 w-4 mr-1" }), t('advancedCustomDomain.retry')] })) })), jsx(Button$1, { variant: "outline", size: "sm", className: "text-red-600 hover:text-red-700", onClick: () => handleDeleteCustomDomain(currentDomain.id), disabled: deletingDomainId === currentDomain.id, children: deletingDomainId === currentDomain.id ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" })) : (t('advancedCustomDomain.delete')) })] })] }), jsx("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-4", children: jsxs("div", { className: "flex items-start gap-2", children: [jsx("div", { className: "w-5 h-5 bg-blue-500 rounded-full flex items-center justify-center flex-shrink-0 mt-0.5", children: jsx("span", { className: "text-white text-xs", children: "i" }) }), jsxs("div", { className: "space-y-2", children: [jsx("h4", { className: "font-medium text-blue-900", children: t('advancedCustomDomain.domainVerificationHeading') }), jsx("p", { className: "text-sm text-blue-800", children: t('advancedCustomDomain.domainVerificationInstruction') })] })] }) }), jsxs("div", { className: "space-y-4", children: [jsx("div", { className: "flex items-center justify-between", children: jsx("h5", { children: t('advancedCustomDomain.domainRecords') }) }), jsx("div", { className: "", children: jsxs(Table$1, { children: [jsx(TableHeader$1, { children: jsxs(TableRow$1, { children: [jsx(TableHead, { className: "w-[100px]", children: t('advancedCustomDomain.tableType') }), jsx(TableHead, { children: t('advancedCustomDomain.tableNameHost') }), jsx(TableHead, { children: t('advancedCustomDomain.tableValue') }), jsx(TableHead, { className: "w-[100px]", children: t('advancedCustomDomain.tableStatus') })] }) }), jsx(TableBody, { children: jsxs(TableRow$1, { children: [jsx(TableCell$1, { className: "text-sm", children: "CNAME" }), jsx(TableCell$1, { children: jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm", children: currentDomain.custom_domain }), jsx(Button$1, { type: "button", variant: "ghost", size: "icon", className: "h-6 w-6 shrink-0", onClick: () => handleCopyField(currentDomain.custom_domain, 'name'), "aria-label": t('advancedCustomDomain.copyNameHostAriaLabel', {
229421
- domain: currentDomain.custom_domain,
229422
- }), children: copiedField === 'name' ? (jsx(Check, { className: "h-4 w-4 text-blue-600", "aria-hidden": "true" })) : (jsx(Copy, { className: "h-4 w-4", "aria-hidden": "true" })) })] }) }), jsx(TableCell$1, { children: jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "text-sm", children: sslValue }), jsx(Button$1, { type: "button", variant: "ghost", size: "icon", className: "h-6 w-6 shrink-0", onClick: () => handleCopyField(sslValue, 'value'), "aria-label": t('advancedCustomDomain.copyValueAriaLabel'), children: copiedField === 'value' ? (jsx(Check, { className: "h-4 w-4 text-blue-600", "aria-hidden": "true" })) : (jsx(Copy, { className: "h-4 w-4", "aria-hidden": "true" })) })] }) }), jsx(TableCell$1, { children: isVerifying ? (jsxs("span", { className: "px-2 py-1 text-xs bg-gray-100 text-gray-600 rounded flex items-center gap-1 w-fit", children: [jsx(LoaderCircle, { className: "h-3 w-3 animate-spin" }), t('advancedCustomDomain.verifying')] })) : isVerified ? (jsx("span", { className: "px-2 py-1 text-xs bg-green-100 text-green-800 rounded", children: t('advancedCustomDomain.verified') })) : !currentDomain.registered_with_dns_pro ? (jsx("span", { className: "px-2 py-1 text-xs bg-yellow-100 text-yellow-800 rounded", children: t('advancedCustomDomain.unregistered') })) : isVerified === false ? (jsxs(Button$1, { variant: "outline", size: "sm", onClick: () => verifyCustomDomain(currentDomain.custom_domain), disabled: isVerifying, className: "h-7 text-xs", children: [jsx(RefreshCw, { className: "h-3 w-3 mr-1" }), t('advancedCustomDomain.retry')] })) : null })] }) })] }) })] })] })) : (jsx("div", { className: "p-4 text-sm text-gray-500 text-center", children: t('advancedCustomDomain.noDomainConfigured') })) }))] }));
229944
+ : t('advancedCustomDomain.collapseAriaLabel'), type: "button", children: isCollapsed ? (jsx(ChevronDown, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" })) : (jsx(ChevronUp, { className: "h-5 w-5 text-gray-400", "aria-hidden": "true" })) })] })] }), !isCollapsed && (jsx("div", { className: "mt-4", children: isLoading ? (jsx("div", { className: "p-4 text-gray-500", children: t('advancedCustomDomain.loading') })) : customDomains.length > 0 ? (jsx("div", { className: "space-y-3", children: sortedDomains.map((row) => (jsx(DomainRow, { row: row, sslValue: sslValue, onReverify: handleReverify, onRemove: handleRemove, isBusy: busyDomainId === row.id, onStatusChange: handleStatusChange }, row.id))) })) : (jsx("div", { className: "p-4 text-center text-sm text-gray-500", children: t('advancedCustomDomain.noDomainConfigured') })) })), jsx(AddDomainDialog, { open: isModalOpen, onOpenChange: setIsModalOpen, canAddPlatformDomain: canAddPlatformDomain, projects: (_a = projectData === null || projectData === void 0 ? void 0 : projectData.projects) !== null && _a !== void 0 ? _a : [], isLoadingProjects: isLoadingProjects, isSubmitting: isCreating || isAttaching, onSubmitPlatformDomain: handleAddPlatformDomain, onSubmitAppDomain: handleAddAppDomain })] }));
229423
229945
  };
229424
229946
 
229425
229947
  const StudentMentorCreationContent = ({ platformKey, }) => {
@@ -231090,7 +231612,7 @@ function AdvancedTab({ platformKey, username, currentSPA, authURL, currentPlatfo
231090
231612
  await handleToggleSetting(metadataItem.slug, currentValue);
231091
231613
  }, disabled: isUpdatingTenantMetadata, "aria-label": `${metadataItem.label} ${currentValue ? t('advancedAdvanced.enabled') : t('advancedAdvanced.disabled')}`, className: "cursor-pointer data-[state=checked]:bg-blue-500" }), isUpdatingTenantMetadata && (jsx("div", { className: "w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" }))] })) })] }, metadataItem.slug));
231092
231614
  }) })] }, spa)));
231093
- })()), jsx(StartScreenContent, { platformKey: platformKey, currentSPA: currentSPA }), jsx(ContentViewWrapper, { currentSPA: currentSPA, spas: ['mentor'], children: jsx(ChatAreaWidth, { chatAreaSize: metadata === null || metadata === void 0 ? void 0 : metadata.chat_area_size, isUpdating: isUpdatingTenantMetadata, onUpdate: handleChatAreaSizeUpdate, onError: handleChatAreaSizeError }) }), jsx(AuthSpaCustomizationContent, { platformKey: platformKey, currentSPA: currentSPA }), jsx(AdvancedCssContent, { platformKey: platformKey, currentSPA: currentSPA || '' }), jsx(RecommendationSystemPromptsContent, { platformKey: platformKey, currentSPA: currentSPA }), jsx(StudentMentorCreationContent, { platformKey: platformKey }), jsx(ChatPrivacyContent, { platformKey: platformKey, username: username }), jsx(MemsearchConfigContent, { platformKey: platformKey, userId: username }), jsx(PlatformMembershipContent, { platformKey: platformKey, authURL: authURL }), jsx(CustomDomainsContent, { platformKey: platformKey, currentSPA: currentSPA || '', currentPlatformBaseDomain: currentPlatformBaseDomain || '' }), jsx(SmtpContent, { platformKey: platformKey }), (currentSPA === null || currentSPA === void 0 ? void 0 : currentSPA.includes('skills')) && (jsxs(Fragment$1, { children: [jsx(ProviderConfigContent, { platformKey: platformKey, username: username }), jsx(ExternalMappingContent, { platformKey: platformKey, username: username })] }))] }) }));
231615
+ })()), jsx(StartScreenContent, { platformKey: platformKey, currentSPA: currentSPA }), jsx(ContentViewWrapper, { currentSPA: currentSPA, spas: ['mentor'], children: jsx(ChatAreaWidth, { chatAreaSize: metadata === null || metadata === void 0 ? void 0 : metadata.chat_area_size, isUpdating: isUpdatingTenantMetadata, onUpdate: handleChatAreaSizeUpdate, onError: handleChatAreaSizeError }) }), jsx(AuthSpaCustomizationContent, { platformKey: platformKey, currentSPA: currentSPA }), jsx(AdvancedCssContent, { platformKey: platformKey, currentSPA: currentSPA || '' }), jsx(RecommendationSystemPromptsContent, { platformKey: platformKey, currentSPA: currentSPA }), jsx(StudentMentorCreationContent, { platformKey: platformKey }), jsx(ChatPrivacyContent, { platformKey: platformKey, username: username }), jsx(MemsearchConfigContent, { platformKey: platformKey, userId: username }), jsx(PlatformMembershipContent, { platformKey: platformKey, authURL: authURL }), jsx(CustomDomainsContent, { platformKey: platformKey, username: username, currentSPA: currentSPA || '', currentPlatformBaseDomain: currentPlatformBaseDomain || '' }), jsx(SmtpContent, { platformKey: platformKey }), (currentSPA === null || currentSPA === void 0 ? void 0 : currentSPA.includes('skills')) && (jsxs(Fragment$1, { children: [jsx(ProviderConfigContent, { platformKey: platformKey, username: username }), jsx(ExternalMappingContent, { platformKey: platformKey, username: username })] }))] }) }));
231094
231616
  }
231095
231617
 
231096
231618
  function StripeConnect({ platformKey }) {
@@ -231286,7 +231808,7 @@ function ItemSearchDropdown({ platformKey, onSelect, }) {
231286
231808
  }, children: [jsx("div", { className: "flex-1 min-w-0", children: jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100 block truncate", children: item.name }) }), jsx(Badge, { variant: "secondary", className: "text-xs shrink-0 capitalize", children: displayItemType(item.itemType) })] }, `${item.itemType}-${item.id}`)))) : isFetching ? (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-400", children: t('monetizationItemSearchDropdown.searching') })) : (jsx("div", { className: "px-3 py-4 text-center text-sm text-gray-400", children: t('monetizationItemSearchDropdown.noItemsFound') })) }))] }));
231287
231809
  }
231288
231810
 
231289
- const PAGE_SIZE$a = 8;
231811
+ const PAGE_SIZE$b = 8;
231290
231812
  function PaywalledItemsList({ platformKey, onSelectItem, onAddCustomItem, }) {
231291
231813
  const t = useT();
231292
231814
  const [page, setPage] = useState(1);
@@ -231294,7 +231816,7 @@ function PaywalledItemsList({ platformKey, onSelectItem, onAddCustomItem, }) {
231294
231816
  const { data: paywalls, isLoading } = useListPaywallsQuery({
231295
231817
  platform_key: platformKey,
231296
231818
  page,
231297
- page_size: PAGE_SIZE$a,
231819
+ page_size: PAGE_SIZE$b,
231298
231820
  ...(statusFilter !== 'all' && { is_enabled: statusFilter === 'active' }),
231299
231821
  }, { refetchOnMountOrArgChange: true });
231300
231822
  return (jsxs("div", { className: "space-y-4", children: [jsx(Card$1, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", children: [jsx("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 mb-3", children: t('monetizationPaywalledItemsList.configureItemForSale') }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(ItemSearchDropdown, { platformKey: platformKey, onSelect: (itemType, uniqueId, name) => onSelectItem(itemType, uniqueId, name) }), jsx(Button$1, { variant: "outline", size: "icon", onClick: onAddCustomItem, className: "shrink-0 cursor-pointer", title: t('monetizationPaywalledItemsList.addCustomItemTitle'), children: jsx(Plus, { className: "h-4 w-4" }) })] })] }) }), jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-medium text-gray-500", children: t('monetizationPaywalledItemsList.configuredItems') }), jsxs(Select$1, { value: statusFilter, onValueChange: (v) => {
@@ -231317,7 +231839,7 @@ function PaywalledItemsList({ platformKey, onSelectItem, onAddCustomItem, }) {
231317
231839
  : 'bg-gray-100 text-gray-500 border-gray-200 hover:bg-gray-100', children: pw.is_enabled
231318
231840
  ? t('monetizationPaywalledItemsList.statusActive')
231319
231841
  : t('monetizationPaywalledItemsList.statusDisabled') })] }) }, `${pw.item_type}-${pw.item_id}`));
231320
- }), jsx(AdvancedPagination, { variant: "footer", className: "mt-2 rounded-lg border", currentPage: page, totalPages: Math.ceil(paywalls.count / PAGE_SIZE$a), onPageChange: setPage, totalCount: paywalls.count, itemsPerPage: PAGE_SIZE$a, itemLabel: "items" })] })) : (jsx("p", { className: "text-sm text-gray-400 text-center py-6", children: statusFilter !== 'all'
231842
+ }), jsx(AdvancedPagination, { variant: "footer", className: "mt-2 rounded-lg border", currentPage: page, totalPages: Math.ceil(paywalls.count / PAGE_SIZE$b), onPageChange: setPage, totalCount: paywalls.count, itemsPerPage: PAGE_SIZE$b, itemLabel: "items" })] })) : (jsx("p", { className: "text-sm text-gray-400 text-center py-6", children: statusFilter !== 'all'
231321
231843
  ? t('monetizationPaywalledItemsList.noFilteredItemsFound', { status: statusFilter })
231322
231844
  : t('monetizationPaywalledItemsList.noItemsConfigured') }))] })] }));
231323
231845
  }
@@ -231668,7 +232190,7 @@ function MonetizationTab({ platformKey, authURL }) {
231668
232190
  }
231669
232191
 
231670
232192
  /** Matches the server-side cap on the global memories listing. */
231671
- const PAGE_SIZE$9 = 25;
232193
+ const PAGE_SIZE$a = 25;
231672
232194
  /**
231673
232195
  * Popup for managing one user's global memories. Reads them the way the
231674
232196
  * profile preview does — the caller in the path, the managed user identified
@@ -231689,10 +232211,10 @@ function UserMemoriesModal({ isOpen, onClose, tenantKey, adminUsername, user, })
231689
232211
  userId: adminUsername,
231690
232212
  // `user_id` must be the managed user's id (username) — the backend does
231691
232213
  // not resolve emails here, so passing one returns an empty list.
231692
- params: { page, page_size: PAGE_SIZE$9, user_id: user.username },
232214
+ params: { page, page_size: PAGE_SIZE$a, user_id: user.username },
231693
232215
  });
231694
232216
  const memories = (_a = memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.results) !== null && _a !== void 0 ? _a : [];
231695
- const totalPages = (memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.count) ? Math.ceil(memoriesData.count / PAGE_SIZE$9) : 0;
232217
+ const totalPages = (memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.count) ? Math.ceil(memoriesData.count / PAGE_SIZE$a) : 0;
231696
232218
  const isForbidden = !!error && error.status === 403;
231697
232219
  // The managed user's capture/personalization toggles, addressed through
231698
232220
  // their path the way every admin write here is. Hidden unless they load.
@@ -231748,7 +232270,7 @@ function UserMemoriesModal({ isOpen, onClose, tenantKey, adminUsername, user, })
231748
232270
  }), className: "cursor-pointer data-[state=checked]:bg-blue-500 flex-shrink-0" })] })] })), !isForbidden && (jsx("div", { className: "flex justify-end mb-4", children: jsxs(Button$1, { "data-testid": "user-memories-add", variant: "outline", size: "sm", onClick: () => setShowAdd(true), className: "text-xs", children: [jsx(Plus, { className: "h-3 w-3 mr-1" }), t('memoryAdminUserMemoriesModal.addMemoryButton')] }) })), isForbidden ? (jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children: t('memoryAdminUserMemoriesModal.forbidden') }) })) : error ? (jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children: t('memoryAdminUserMemoriesModal.failedToLoad') }) })) : (jsx(MemoriesList, { memories: memories, isLoading: isLoading, emptyText: t('memoryAdminUserMemoriesModal.noMemories'), deletingId: deletingId, onEdit: setEditingMemory, onDelete: handleDeleteMemory, totalPages: totalPages, currentPage: page, onPageChange: setPage })), jsx(AddMemoryDialog, { open: showAdd, onOpenChange: setShowAdd, org: tenantKey, username: user.username }), editingMemory && (jsx(EditMemoryDialog, { open: !!editingMemory, onOpenChange: (open) => !open && setEditingMemory(null), org: tenantKey, username: user.username, memory: editingMemory }))] }) }));
231749
232271
  }
231750
232272
 
231751
- const PAGE_SIZE$8 = 10;
232273
+ const PAGE_SIZE$9 = 10;
231752
232274
  const SEARCH_DEBOUNCE_MS = 300;
231753
232275
  /**
231754
232276
  * Tenant users table with server-side search. Opening a row shows that user's
@@ -231781,7 +232303,7 @@ function GlobalMemoriesSection({ tenantKey, username }) {
231781
232303
  platform_key: tenantKey,
231782
232304
  platform_org: tenantKey,
231783
232305
  page,
231784
- page_size: PAGE_SIZE$8,
232306
+ page_size: PAGE_SIZE$9,
231785
232307
  query: debouncedSearch,
231786
232308
  return_policies: 'false',
231787
232309
  });
@@ -231802,7 +232324,7 @@ function GlobalMemoriesSection({ tenantKey, username }) {
231802
232324
  email: user.email,
231803
232325
  }));
231804
232326
  }, [data]);
231805
- const totalPages = Math.ceil(((_a = data === null || data === void 0 ? void 0 : data.count) !== null && _a !== void 0 ? _a : 0) / PAGE_SIZE$8);
232327
+ const totalPages = Math.ceil(((_a = data === null || data === void 0 ? void 0 : data.count) !== null && _a !== void 0 ? _a : 0) / PAGE_SIZE$9);
231806
232328
  const isForbidden = !!error && error.status === 403;
231807
232329
  return (jsxs("div", { "data-testid": "memory-admin-global-section", children: [jsxs("div", { className: "relative mb-6 max-w-sm w-full sm:w-auto", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { "data-testid": "memory-admin-users-search", type: "text", value: searchQuery, onChange: (event) => setSearchQuery(event.target.value), placeholder: t('memoryAdminTab.searchUsersPlaceholder'), className: "pl-10 pr-10 focus:ring-blue-500 focus:border-blue-500 h-[35px]", "aria-label": t('memoryAdminTab.searchUsersAriaLabel') }), searchQuery.length > 0 && (searchQuery !== debouncedSearch || isFetching) && (jsx(LoaderCircle, { "data-testid": "user-search-spinner", className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400 animate-spin", "aria-hidden": "true" }))] }), isForbidden ? (jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children: t('memoryAdminTab.forbidden') }) })) : isLoading ? (jsx("div", { className: "flex justify-center items-center h-64", children: jsx(Spinner, {}) })) : (jsxs(Fragment$1, { children: [jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[28%]", children: t('memoryAdminTab.nameColumn') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[26%]", children: t('memoryAdminTab.usernameColumn') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[30%]", children: t('memoryAdminTab.emailColumn') }), jsx("th", { className: "px-6 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[16%]", children: t('memoryAdminTab.actionsColumn') })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [users.map((user) => (jsxs("tr", { "data-testid": `memory-admin-user-row-${user.username}`, children: [jsx("td", { className: "px-6 py-4 text-gray-900 dark:text-gray-100 max-w-0", children: jsx("div", { className: "truncate font-medium", children: user.name || '—' }) }), jsx("td", { className: "px-6 py-4 text-gray-600 dark:text-gray-300 max-w-0", children: jsx("div", { className: "truncate", children: user.username }) }), jsx("td", { className: "px-6 py-4 text-gray-600 dark:text-gray-300 max-w-0", children: jsx("div", { className: "truncate", children: user.email || '—' }) }), jsx("td", { className: "px-6 py-4", children: jsx("div", { className: "flex justify-end gap-2", children: jsx(Button$1, { "data-testid": `memory-admin-user-view-${user.username}`, variant: "ghost", size: "sm", "aria-label": t('memoryAdminTab.viewMemoriesAriaLabel', {
231808
232330
  name: user.email || user.username,
@@ -231824,7 +232346,7 @@ const BulkDeleteMemoryModal$1 = dynamic(() => Promise.resolve().then(function ()
231824
232346
  const ManageCategoriesModal$1 = dynamic(() => Promise.resolve().then(function () { return manageCategoriesModal; }).then((module) => ({
231825
232347
  default: module.ManageCategoriesModal,
231826
232348
  })), { ssr: false });
231827
- const PAGE_SIZE$7 = 20;
232349
+ const PAGE_SIZE$8 = 20;
231828
232350
  const SNAPSHOT_PAGE_SIZE = 1000;
231829
232351
  function ManageMemories({ tenantKey, username, mentorId }) {
231830
232352
  var _a, _b, _c, _d, _e;
@@ -231839,7 +232361,7 @@ function ManageMemories({ tenantKey, username, mentorId }) {
231839
232361
  setPage(1);
231840
232362
  }, [selectedLearner, dateRange, selectedCategorySlug]);
231841
232363
  const listParams = useMemo(() => {
231842
- const params = { page, page_size: PAGE_SIZE$7 };
232364
+ const params = { page, page_size: PAGE_SIZE$8 };
231843
232365
  if (selectedLearner)
231844
232366
  params.email = selectedLearner;
231845
232367
  if (selectedCategorySlug !== 'all')
@@ -231858,7 +232380,7 @@ function ManageMemories({ tenantKey, username, mentorId }) {
231858
232380
  }, {
231859
232381
  skip: !tenantKey || !username || !mentorId,
231860
232382
  });
231861
- const totalPages = Math.max(1, Math.ceil(((_a = listResponse === null || listResponse === void 0 ? void 0 : listResponse.count) !== null && _a !== void 0 ? _a : 0) / PAGE_SIZE$7));
232383
+ const totalPages = Math.max(1, Math.ceil(((_a = listResponse === null || listResponse === void 0 ? void 0 : listResponse.count) !== null && _a !== void 0 ? _a : 0) / PAGE_SIZE$8));
231862
232384
  const { data: adminCategories } = useGetMemoryCategoriesAdminQuery({
231863
232385
  org: tenantKey,
231864
232386
  mentorId,
@@ -232100,7 +232622,7 @@ function AgentMemoriesModal({ isOpen, onClose, tenantKey, username, agent, }) {
232100
232622
  return (jsx(Dialog, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: jsxs(DialogContent, { "data-testid": "agent-memories-modal", "aria-label": "agent-memories", className: "flex max-h-[90vh] w-[calc(100vw-2rem)] flex-col gap-0 overflow-hidden p-0 sm:max-w-4xl", children: [jsxs(DialogHeader, { className: "flex-shrink-0 border-b border-gray-200 px-6 py-4 pr-12", children: [jsx(DialogTitle, { className: "ibl-dialog-title", children: agent.name }), jsx(DialogDescription, { children: t('memoryAdminAgentMemoriesModal.description') })] }), jsx("div", { className: "min-h-0 flex-1 overflow-y-auto p-3 lg:p-4", children: jsx("div", { className: "space-y-8", children: jsx(ManageMemories, { tenantKey: tenantKey, username: username, mentorId: agent.unique_id }) }) })] }) }));
232101
232623
  }
232102
232624
 
232103
- const PAGE_SIZE$6 = 10;
232625
+ const PAGE_SIZE$7 = 10;
232104
232626
  /**
232105
232627
  * Agents table filtered by the same agent autocomplete the Billing tab's
232106
232628
  * Agent Limits section uses. Opening a row shows that agent's memories in a
@@ -232133,12 +232655,12 @@ function AgentMemoriesSection({ tenantKey, username }) {
232133
232655
  const { data, isLoading, isFetching, error } = useGetMentorsQuery({
232134
232656
  org: tenantKey,
232135
232657
  username,
232136
- limit: PAGE_SIZE$6,
232137
- offset: (page - 1) * PAGE_SIZE$6,
232658
+ limit: PAGE_SIZE$7,
232659
+ offset: (page - 1) * PAGE_SIZE$7,
232138
232660
  ...(agentFilter ? { uniqueId: agentFilter.value } : {}),
232139
232661
  });
232140
232662
  const agents = ((_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : []);
232141
- const totalPages = (data === null || data === void 0 ? void 0 : data.count) ? Math.ceil(data.count / PAGE_SIZE$6) : 0;
232663
+ const totalPages = (data === null || data === void 0 ? void 0 : data.count) ? Math.ceil(data.count / PAGE_SIZE$7) : 0;
232142
232664
  const isForbidden = !!error && error.status === 403;
232143
232665
  return (jsxs("div", { "data-testid": "memory-admin-agent-section", children: [jsx("div", { className: "mb-6 max-w-sm", children: jsx(SearchSelect, { labels: {
232144
232666
  // No field label — the users tab's search carries none either.
@@ -259491,173 +260013,6 @@ function TenantSwitcher({ currentTenantKey, tenants, visitingTenant, onTenantCha
259491
260013
  tenantList.map((tenant) => (jsx(SelectItem, { value: tenant === null || tenant === void 0 ? void 0 : tenant.key, children: (tenant === null || tenant === void 0 ? void 0 : tenant.name) || (tenant === null || tenant === void 0 ? void 0 : tenant.key) }, tenant === null || tenant === void 0 ? void 0 : tenant.key))) })] }))] }) }));
259492
260014
  }
259493
260015
 
259494
- var SLOTTABLE_IDENTIFIER = Symbol("radix.slottable");
259495
- // @__NO_SIDE_EFFECTS__
259496
- function createSlottable(ownerName) {
259497
- const Slottable2 = ({ children }) => {
259498
- return /* @__PURE__ */ jsx(Fragment$1, { children });
259499
- };
259500
- Slottable2.displayName = `${ownerName}.Slottable`;
259501
- Slottable2.__radixId = SLOTTABLE_IDENTIFIER;
259502
- return Slottable2;
259503
- }
259504
-
259505
- var ROOT_NAME = "AlertDialog";
259506
- var [createAlertDialogContext] = createContextScope$1(ROOT_NAME, [
259507
- createDialogScope
259508
- ]);
259509
- var useDialogScope = createDialogScope();
259510
- var AlertDialog$1 = (props) => {
259511
- const { __scopeAlertDialog, ...alertDialogProps } = props;
259512
- const dialogScope = useDialogScope(__scopeAlertDialog);
259513
- return /* @__PURE__ */ jsx(DialogPrimitive.Root, { ...dialogScope, ...alertDialogProps, modal: true });
259514
- };
259515
- AlertDialog$1.displayName = ROOT_NAME;
259516
- var TRIGGER_NAME$1 = "AlertDialogTrigger";
259517
- var AlertDialogTrigger = React.forwardRef(
259518
- (props, forwardedRef) => {
259519
- const { __scopeAlertDialog, ...triggerProps } = props;
259520
- const dialogScope = useDialogScope(__scopeAlertDialog);
259521
- return /* @__PURE__ */ jsx(DialogPrimitive.Trigger, { ...dialogScope, ...triggerProps, ref: forwardedRef });
259522
- }
259523
- );
259524
- AlertDialogTrigger.displayName = TRIGGER_NAME$1;
259525
- var PORTAL_NAME$1 = "AlertDialogPortal";
259526
- var AlertDialogPortal$1 = (props) => {
259527
- const { __scopeAlertDialog, ...portalProps } = props;
259528
- const dialogScope = useDialogScope(__scopeAlertDialog);
259529
- return /* @__PURE__ */ jsx(DialogPrimitive.Portal, { ...dialogScope, ...portalProps });
259530
- };
259531
- AlertDialogPortal$1.displayName = PORTAL_NAME$1;
259532
- var OVERLAY_NAME = "AlertDialogOverlay";
259533
- var AlertDialogOverlay$1 = React.forwardRef(
259534
- (props, forwardedRef) => {
259535
- const { __scopeAlertDialog, ...overlayProps } = props;
259536
- const dialogScope = useDialogScope(__scopeAlertDialog);
259537
- return /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { ...dialogScope, ...overlayProps, ref: forwardedRef });
259538
- }
259539
- );
259540
- AlertDialogOverlay$1.displayName = OVERLAY_NAME;
259541
- var CONTENT_NAME$2 = "AlertDialogContent";
259542
- var [AlertDialogContentProvider, useAlertDialogContentContext] = createAlertDialogContext(CONTENT_NAME$2);
259543
- var Slottable = createSlottable("AlertDialogContent");
259544
- var AlertDialogContent$1 = React.forwardRef(
259545
- (props, forwardedRef) => {
259546
- const { __scopeAlertDialog, children, ...contentProps } = props;
259547
- const dialogScope = useDialogScope(__scopeAlertDialog);
259548
- const contentRef = React.useRef(null);
259549
- const composedRefs = useComposedRefs$1(forwardedRef, contentRef);
259550
- const cancelRef = React.useRef(null);
259551
- return /* @__PURE__ */ jsx(
259552
- DialogPrimitive.WarningProvider,
259553
- {
259554
- contentName: CONTENT_NAME$2,
259555
- titleName: TITLE_NAME,
259556
- docsSlug: "alert-dialog",
259557
- children: /* @__PURE__ */ jsx(AlertDialogContentProvider, { scope: __scopeAlertDialog, cancelRef, children: /* @__PURE__ */ jsxs(
259558
- DialogPrimitive.Content,
259559
- {
259560
- role: "alertdialog",
259561
- ...dialogScope,
259562
- ...contentProps,
259563
- ref: composedRefs,
259564
- onOpenAutoFocus: composeEventHandlers$2(contentProps.onOpenAutoFocus, (event) => {
259565
- event.preventDefault();
259566
- cancelRef.current?.focus({ preventScroll: true });
259567
- }),
259568
- onPointerDownOutside: (event) => event.preventDefault(),
259569
- onInteractOutside: (event) => event.preventDefault(),
259570
- children: [
259571
- /* @__PURE__ */ jsx(Slottable, { children }),
259572
- /* @__PURE__ */ jsx(DescriptionWarning, { contentRef })
259573
- ]
259574
- }
259575
- ) })
259576
- }
259577
- );
259578
- }
259579
- );
259580
- AlertDialogContent$1.displayName = CONTENT_NAME$2;
259581
- var TITLE_NAME = "AlertDialogTitle";
259582
- var AlertDialogTitle$1 = React.forwardRef(
259583
- (props, forwardedRef) => {
259584
- const { __scopeAlertDialog, ...titleProps } = props;
259585
- const dialogScope = useDialogScope(__scopeAlertDialog);
259586
- return /* @__PURE__ */ jsx(DialogPrimitive.Title, { ...dialogScope, ...titleProps, ref: forwardedRef });
259587
- }
259588
- );
259589
- AlertDialogTitle$1.displayName = TITLE_NAME;
259590
- var DESCRIPTION_NAME = "AlertDialogDescription";
259591
- var AlertDialogDescription$1 = React.forwardRef((props, forwardedRef) => {
259592
- const { __scopeAlertDialog, ...descriptionProps } = props;
259593
- const dialogScope = useDialogScope(__scopeAlertDialog);
259594
- return /* @__PURE__ */ jsx(DialogPrimitive.Description, { ...dialogScope, ...descriptionProps, ref: forwardedRef });
259595
- });
259596
- AlertDialogDescription$1.displayName = DESCRIPTION_NAME;
259597
- var ACTION_NAME = "AlertDialogAction";
259598
- var AlertDialogAction$1 = React.forwardRef(
259599
- (props, forwardedRef) => {
259600
- const { __scopeAlertDialog, ...actionProps } = props;
259601
- const dialogScope = useDialogScope(__scopeAlertDialog);
259602
- return /* @__PURE__ */ jsx(DialogPrimitive.Close, { ...dialogScope, ...actionProps, ref: forwardedRef });
259603
- }
259604
- );
259605
- AlertDialogAction$1.displayName = ACTION_NAME;
259606
- var CANCEL_NAME = "AlertDialogCancel";
259607
- var AlertDialogCancel$1 = React.forwardRef(
259608
- (props, forwardedRef) => {
259609
- const { __scopeAlertDialog, ...cancelProps } = props;
259610
- const { cancelRef } = useAlertDialogContentContext(CANCEL_NAME, __scopeAlertDialog);
259611
- const dialogScope = useDialogScope(__scopeAlertDialog);
259612
- const ref = useComposedRefs$1(forwardedRef, cancelRef);
259613
- return /* @__PURE__ */ jsx(DialogPrimitive.Close, { ...dialogScope, ...cancelProps, ref });
259614
- }
259615
- );
259616
- AlertDialogCancel$1.displayName = CANCEL_NAME;
259617
- var DescriptionWarning = ({ contentRef }) => {
259618
- const MESSAGE = `\`${CONTENT_NAME$2}\` requires a description for the component to be accessible for screen reader users.
259619
-
259620
- You can add a description to the \`${CONTENT_NAME$2}\` by passing a \`${DESCRIPTION_NAME}\` component as a child, which also benefits sighted users by adding visible context to the dialog.
259621
-
259622
- Alternatively, you can use your own component as a description by assigning it an \`id\` and passing the same value to the \`aria-describedby\` prop in \`${CONTENT_NAME$2}\`. If the description is confusing or duplicative for sighted users, you can use the \`@radix-ui/react-visually-hidden\` primitive as a wrapper around your description component.
259623
-
259624
- For more information, see https://radix-ui.com/primitives/docs/components/alert-dialog`;
259625
- React.useEffect(() => {
259626
- const hasDescription = document.getElementById(
259627
- contentRef.current?.getAttribute("aria-describedby")
259628
- );
259629
- if (!hasDescription) console.warn(MESSAGE);
259630
- }, [MESSAGE, contentRef]);
259631
- return null;
259632
- };
259633
- var Root2$2 = AlertDialog$1;
259634
- var Portal2 = AlertDialogPortal$1;
259635
- var Overlay2 = AlertDialogOverlay$1;
259636
- var Content2$1 = AlertDialogContent$1;
259637
- var Action = AlertDialogAction$1;
259638
- var Cancel = AlertDialogCancel$1;
259639
- var Title2 = AlertDialogTitle$1;
259640
- var Description2 = AlertDialogDescription$1;
259641
-
259642
- const AlertDialog = Root2$2;
259643
- const AlertDialogPortal = Portal2;
259644
- const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => (jsx(Overlay2, { className: cn('data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80', className), ...props, ref: ref })));
259645
- AlertDialogOverlay.displayName = Overlay2.displayName;
259646
- const AlertDialogContent = React.forwardRef(({ className, ...props }, ref) => (jsxs(AlertDialogPortal, { children: [jsx(AlertDialogOverlay, {}), jsx(Content2$1, { ref: ref, className: cn('bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg', className), ...props })] })));
259647
- AlertDialogContent.displayName = Content2$1.displayName;
259648
- const AlertDialogHeader = ({ className, ...props }) => (jsx("div", { className: cn('flex flex-col space-y-2 text-center sm:text-left', className), ...props }));
259649
- AlertDialogHeader.displayName = 'AlertDialogHeader';
259650
- const AlertDialogFooter = ({ className, ...props }) => (jsx("div", { className: cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className), ...props }));
259651
- AlertDialogFooter.displayName = 'AlertDialogFooter';
259652
- const AlertDialogTitle = React.forwardRef(({ className, ...props }, ref) => (jsx(Title2, { ref: ref, className: cn('text-lg font-semibold', className), ...props })));
259653
- AlertDialogTitle.displayName = Title2.displayName;
259654
- const AlertDialogDescription = React.forwardRef(({ className, ...props }, ref) => (jsx(Description2, { ref: ref, className: cn('text-muted-foreground text-sm', className), ...props })));
259655
- AlertDialogDescription.displayName = Description2.displayName;
259656
- const AlertDialogAction = React.forwardRef(({ className, ...props }, ref) => (jsx(Action, { ref: ref, className: cn(buttonVariants(), className), ...props })));
259657
- AlertDialogAction.displayName = Action.displayName;
259658
- const AlertDialogCancel = React.forwardRef(({ className, ...props }, ref) => (jsx(Cancel, { ref: ref, className: cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', className), ...props })));
259659
- AlertDialogCancel.displayName = Cancel.displayName;
259660
-
259661
260016
  // Notification bodies are arbitrary (often email) HTML: long unbroken URLs and
259662
260017
  // fixed-width tables would otherwise bleed out of the panel. Break long words,
259663
260018
  // cap every descendant at the container width, and let anything that still
@@ -263055,7 +263410,7 @@ const AutoResizeTextarea = ({ allowEmptySubmit = false, value, onChange, onSubmi
263055
263410
  disabled, placeholder: placeholder, style: combinedStyle, className: `flex max-h-32 min-h-[36px] w-full resize-none rounded-2xl border-0 border-gray-200 bg-transparent px-4 py-2 pt-2 pb-1 text-base ring-offset-white placeholder:text-gray-400 focus:outline-none focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-800 dark:bg-gray-950 dark:ring-offset-gray-950 dark:placeholder:text-gray-400 ${className}`, ...props }));
263056
263411
  };
263057
263412
 
263058
- const PAGE_SIZE$5 = 10;
263413
+ const PAGE_SIZE$6 = 10;
263059
263414
  const MemoryMenu = ({ onClose, mentorId, tenantKey, username }) => {
263060
263415
  const t = useT();
263061
263416
  const [page, setPage] = useState(1);
@@ -263073,7 +263428,7 @@ const MemoryMenu = ({ onClose, mentorId, tenantKey, username }) => {
263073
263428
  mentorId,
263074
263429
  params: {
263075
263430
  page,
263076
- page_size: PAGE_SIZE$5,
263431
+ page_size: PAGE_SIZE$6,
263077
263432
  my_memory: true,
263078
263433
  },
263079
263434
  }, {
@@ -267025,7 +267380,7 @@ function DeleteItemConfirm({ isOpen, onClose, tenantKey, username, datasetName,
267025
267380
  : t('benchmarksDeleteItemConfirm.delete') })] })] }) }));
267026
267381
  }
267027
267382
 
267028
- const PAGE_SIZE$4 = 10;
267383
+ const PAGE_SIZE$5 = 10;
267029
267384
  function BenchmarkItemsModal({ isOpen, onClose, tenantKey, username, datasetName }) {
267030
267385
  var _a;
267031
267386
  const t = useT();
@@ -267037,17 +267392,17 @@ function BenchmarkItemsModal({ isOpen, onClose, tenantKey, username, datasetName
267037
267392
  userId: username,
267038
267393
  datasetName,
267039
267394
  page,
267040
- limit: PAGE_SIZE$4,
267395
+ limit: PAGE_SIZE$5,
267041
267396
  });
267042
267397
  const items = (_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : [];
267043
- const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$4);
267398
+ const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$5);
267044
267399
  return (jsx(Dialog, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: jsxs(DialogContent, { "aria-label": "benchmark-items", className: "w-full max-w-4xl max-h-[90vh] overflow-y-auto", children: [jsxs(DialogHeader, { children: [jsx(DialogTitle, { children: datasetName }), jsx(DialogDescription, { children: t('benchmarksBenchmarkItemsModal.description') })] }), jsx("div", { className: "flex justify-end mb-4", children: jsxs(Button$1, { onClick: () => setShowAdd(true), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", children: [jsx(Plus, { className: "h-4 w-4 mr-1" }), t('benchmarksBenchmarkItemsModal.addItems')] }) }), isLoading ? (jsx("div", { className: "flex justify-center items-center h-40", children: jsx(Spinner, {}) })) : (jsxs(Fragment$1, { children: [jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-4 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[45%]", children: t('benchmarksBenchmarkItemsModal.questionColumn') }), jsx("th", { className: "px-4 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[45%]", children: t('benchmarksBenchmarkItemsModal.answerColumn') }), jsx("th", { className: "px-4 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[10%]", children: t('benchmarksBenchmarkItemsModal.actionsColumn') })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [items.map((item) => {
267045
267400
  var _a;
267046
267401
  return (jsxs("tr", { className: "align-top", children: [jsx("td", { className: "px-4 py-3 text-gray-900 dark:text-gray-100", children: jsx("div", { className: "line-clamp-3 break-words", children: typeof item.input === 'string' ? item.input : JSON.stringify(item.input) }) }), jsx("td", { className: "px-4 py-3 text-gray-600 dark:text-gray-300", children: jsx("div", { className: "line-clamp-3 break-words", children: (_a = item.expected_output) !== null && _a !== void 0 ? _a : jsx("span", { className: "text-gray-400", children: "\u2014" }) }) }), jsx("td", { className: "px-4 py-3 text-right", children: jsx(Button$1, { variant: "ghost", size: "sm", "aria-label": t('benchmarksBenchmarkItemsModal.deleteItemAriaLabel'), onClick: () => setDeleteItemId(item.id), children: jsx(Trash2, { className: "h-4 w-4 text-red-500" }) }) })] }, item.id));
267047
267402
  }), items.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 3, className: "px-4 py-8 text-center text-gray-500 dark:text-gray-400", children: t('benchmarksBenchmarkItemsModal.empty') }) }))] })] }) }), totalPages > 1 && (jsx("div", { className: "mt-6", children: jsx(AdvancedPagination, { totalPages: totalPages, currentPage: page, onPageChange: setPage }) }))] })), jsx(AddItemsModal, { isOpen: showAdd, onClose: () => setShowAdd(false), tenantKey: tenantKey, username: username, datasetName: datasetName }), deleteItemId && (jsx(DeleteItemConfirm, { isOpen: !!deleteItemId, onClose: () => setDeleteItemId(null), tenantKey: tenantKey, username: username, datasetName: datasetName, itemId: deleteItemId }))] }) }));
267048
267403
  }
267049
267404
 
267050
- const PAGE_SIZE$3 = 10;
267405
+ const PAGE_SIZE$4 = 10;
267051
267406
  function BenchmarksTab({ tenantKey, username, }) {
267052
267407
  var _a;
267053
267408
  const t = useT();
@@ -267059,13 +267414,13 @@ function BenchmarksTab({ tenantKey, username, }) {
267059
267414
  org: tenantKey,
267060
267415
  userId: username,
267061
267416
  page,
267062
- limit: PAGE_SIZE$3,
267417
+ limit: PAGE_SIZE$4,
267063
267418
  });
267064
267419
  const benchmarks = (_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : [];
267065
267420
  const filtered = searchQuery.trim()
267066
267421
  ? benchmarks.filter((benchmark) => benchmark.name.toLowerCase().includes(searchQuery.toLowerCase()))
267067
267422
  : benchmarks;
267068
- const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$3);
267423
+ const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$4);
267069
267424
  return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex justify-between items-center gap-1 flex-wrap", children: [jsxs("div", { className: "relative mb-6 max-w-sm w-full sm:w-auto", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { type: "text", value: searchQuery, onChange: (event) => setSearchQuery(event.target.value), placeholder: t('benchmarksIndex.searchPlaceholder'), className: "pl-10 pr-10 focus:ring-blue-500 focus:border-blue-500 h-[35px]", "aria-label": t('benchmarksIndex.searchAriaLabel') })] }), jsx("div", { className: "mb-6", children: jsxs(Button$1, { className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", onClick: () => setShowCreate(true), children: [jsx(Plus, { className: "h-4 w-4 mr-1" }), t('benchmarksIndex.newBenchmark')] }) })] }), isLoading ? (jsx("div", { className: "flex justify-center items-center h-64", children: jsx(Spinner, {}) })) : (jsxs(Fragment$1, { children: [jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[28%]", children: t('benchmarksIndex.nameColumn') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[36%]", children: t('benchmarksIndex.descriptionColumn') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[20%]", children: t('benchmarksIndex.createdColumn') }), jsx("th", { className: "px-6 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[16%]", children: t('benchmarksIndex.actionsColumn') })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [filtered.map((benchmark) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 text-gray-900 dark:text-gray-100 max-w-0", children: jsx("div", { className: "truncate font-medium", children: benchmark.name }) }), jsx("td", { className: "px-6 py-4 text-gray-600 dark:text-gray-300 max-w-0", children: jsx("div", { className: "truncate", children: benchmark.description || '—' }) }), jsx("td", { className: "px-6 py-4 text-gray-600 dark:text-gray-300 whitespace-nowrap", children: benchmark.created_at
267070
267425
  ? formatDistanceToNow(new Date(benchmark.created_at), {
267071
267426
  addSuffix: true,
@@ -276659,7 +277014,7 @@ function isIblaiVoice(voice) {
276659
277014
  return voice.provider === 'iblai';
276660
277015
  }
276661
277016
 
276662
- const PAGE_SIZE$2 = 20;
277017
+ const PAGE_SIZE$3 = 20;
276663
277018
  function VoicePicker({ org, userId, provider, selectedVoiceId, onSelect, disabled, labels, }) {
276664
277019
  var _a, _b;
276665
277020
  const t = useT();
@@ -276679,13 +277034,13 @@ function VoicePicker({ org, userId, provider, selectedVoiceId, onSelect, disable
276679
277034
  userId,
276680
277035
  provider,
276681
277036
  page,
276682
- pageSize: PAGE_SIZE$2,
277037
+ pageSize: PAGE_SIZE$3,
276683
277038
  ...(debouncedSearch ? { search: debouncedSearch } : {}),
276684
277039
  }, { skip: !org || !userId });
276685
277040
  const paginated = data;
276686
277041
  const voices = (_a = paginated === null || paginated === void 0 ? void 0 : paginated.results) !== null && _a !== void 0 ? _a : [];
276687
277042
  const total = (_b = paginated === null || paginated === void 0 ? void 0 : paginated.count) !== null && _b !== void 0 ? _b : 0;
276688
- const totalPages = total > 0 ? Math.ceil(total / PAGE_SIZE$2) : 1;
277043
+ const totalPages = total > 0 ? Math.ceil(total / PAGE_SIZE$3) : 1;
276689
277044
  // Whenever a voice id is saved on the mentor settings, fetch it directly
276690
277045
  // so we can pin it at the top of the list. Otherwise the user can land
276691
277046
  // on a page that doesn't contain the selected voice and the selection
@@ -278264,7 +278619,7 @@ function GradeResultOverrideModal({ isOpen, onClose, result, tenantKey, mentorId
278264
278619
  return (jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: jsxs(DialogContent, { "aria-describedby": "grader-override-modal-description", "data-testid": "grader-override-modal", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "ibl-dialog-title", children: m.title }) }), isLoading || !detail ? (jsx("div", { className: "flex items-center justify-center py-8", "data-testid": "grader-override-loading", children: jsx(Spinner, {}) })) : (jsxs("div", { className: "space-y-4", id: "grader-override-modal-description", children: [jsxs("div", { className: "grid grid-cols-2 gap-2 rounded-lg border border-gray-200 bg-gray-50/60 p-3 text-sm", children: [jsx("span", { className: "text-gray-500", children: m.learnerLabel }), jsx("span", { className: "truncate text-gray-900", title: detail.student.email, children: detail.student.email }), jsx("span", { className: "text-gray-500", children: m.aiScoreLabel }), jsx("span", { className: "text-gray-900", children: formatPercent$1(detail.score) }), jsx("span", { className: "text-gray-500", children: m.currentOverrideLabel }), jsx("span", { className: "text-gray-900", "data-testid": "grader-override-current", children: hasExistingOverride ? `${detail.override_points} / ${totalPoints}` : m.noOverride })] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { htmlFor: "grader-override-points", children: m.pointsLabel }), jsx(Input, { id: "grader-override-points", type: "number", min: 0, max: maxPoints, step: "any", value: points, className: "w-28", onChange: (e) => setPoints(e.target.value) }), jsx("p", { className: "text-xs text-gray-500", children: m.pointsHelp.replace('{total}', String(maxPoints)) }), showErrors && !pointsValid && (jsx("p", { className: "text-xs text-red-500", children: m.pointsRange.replace('{total}', String(maxPoints)) }))] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { htmlFor: "grader-override-feedback", children: m.feedbackLabel }), jsx(Textarea, { id: "grader-override-feedback", value: feedback, placeholder: m.feedbackPlaceholder, rows: 3, onChange: (e) => setFeedback(e.target.value) })] }), hasExistingOverride && jsx("p", { className: "text-xs text-gray-500", children: m.clearHelp })] })), jsxs(DialogFooter, { className: "gap-3", children: [hasExistingOverride && (jsx(Button$1, { variant: "outline", className: "mr-auto text-red-600 hover:text-red-700", onClick: handleClear, disabled: isSaving || isLoading, "data-testid": "grader-override-clear", children: isClearing ? m.clearing : m.clear })), jsx(Button$1, { variant: "outline", onClick: onClose, children: m.cancel }), jsx(Button$1, { className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", onClick: handleSave, disabled: isSaving || isLoading, "data-testid": "grader-override-save", children: isSaving && !isClearing ? m.saving : m.save })] })] }) }));
278265
278620
  }
278266
278621
 
278267
- const PAGE_SIZE$1 = 10;
278622
+ const PAGE_SIZE$2 = 10;
278268
278623
  const STATUS_ALL = 'all';
278269
278624
  function formatPercent(score) {
278270
278625
  return `${Math.round(score * 100)}%`;
@@ -278306,10 +278661,10 @@ function ResultsSection({ labels, tenantKey, mentorId, username, canOverride, })
278306
278661
  graded_at_after: gradedAtAfter,
278307
278662
  graded_at_before: gradedAtBefore,
278308
278663
  page,
278309
- page_size: PAGE_SIZE$1,
278664
+ page_size: PAGE_SIZE$2,
278310
278665
  }, { skip: !tenantKey || !mentorId });
278311
278666
  const results = (_b = data === null || data === void 0 ? void 0 : data.results) !== null && _b !== void 0 ? _b : [];
278312
- const totalPages = Math.max(1, Math.ceil(((_c = data === null || data === void 0 ? void 0 : data.count) !== null && _c !== void 0 ? _c : 0) / PAGE_SIZE$1));
278667
+ const totalPages = Math.max(1, Math.ceil(((_c = data === null || data === void 0 ? void 0 : data.count) !== null && _c !== void 0 ? _c : 0) / PAGE_SIZE$2));
278313
278668
  const statusText = (value) => value ? labels.statusValues[value] : '—';
278314
278669
  return (jsxs("div", { className: "space-y-3", "data-testid": "grader-results-section", children: [jsxs("div", { children: [jsx("h4", { className: "text-sm font-medium text-gray-900", children: labels.sectionTitle }), jsx("p", { className: "text-xs text-gray-600", children: labels.description })] }), jsx("div", { className: "rounded-lg border p-4", children: jsxs("div", { className: "flex flex-col gap-3 lg:flex-row", children: [jsx("div", { className: "relative min-w-[200px] flex-1", children: jsxs(Popover, { children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", role: "combobox", "aria-label": labels.filters.searchUser, className: "w-full justify-between bg-transparent font-normal", "data-testid": "grader-results-user-filter", children: [selectedEmail || labels.filters.searchUser, jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), jsx(PopoverContent, { className: "w-full p-0", align: "start", portalled: false, children: jsxs(Command, { children: [jsx(CommandInput, { placeholder: labels.filters.searchUsersPlaceholder }), jsxs(CommandList, { children: [jsx(CommandEmpty, { children: labels.filters.noUsersFound }), jsxs(CommandGroup, { children: [jsxs(CommandItem, { value: "", onSelect: () => setSelectedEmail(''), children: [jsx(Check, { className: cn('mr-2 h-4 w-4', !selectedEmail ? 'opacity-100' : 'opacity-0') }), labels.filters.allUsers] }), learners.map((learner) => (jsxs(CommandItem, { value: learner.email, onSelect: () => setSelectedEmail(learner.email), children: [jsx(Check, { className: cn('mr-2 h-4 w-4', selectedEmail === learner.email ? 'opacity-100' : 'opacity-0') }), jsx("div", { className: "flex flex-col", children: jsx("span", { className: "font-medium text-gray-700", children: learner.email }) })] }, learner.email)))] })] })] }) })] }) }), jsxs(Select$1, { value: status, onValueChange: setStatus, children: [jsx(SelectTrigger, { className: "w-full lg:w-[160px]", "aria-label": labels.filters.statusLabel, "data-testid": "grader-results-status-filter", children: jsx(SelectValue, { placeholder: labels.filters.statusLabel }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: STATUS_ALL, children: labels.filters.allStatuses }), jsx(SelectItem, { value: "pending", children: labels.statusValues.pending }), jsx(SelectItem, { value: "published", children: labels.statusValues.published }), jsx(SelectItem, { value: "failed", children: labels.statusValues.failed })] })] }), jsxs(Popover, { children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", className: "flex w-full items-center gap-2 bg-transparent font-normal whitespace-nowrap lg:w-auto", "data-testid": "grader-results-date-filter", children: [jsx(Calendar$1, { className: "h-4 w-4" }), (dateRange === null || dateRange === void 0 ? void 0 : dateRange.from) && (dateRange === null || dateRange === void 0 ? void 0 : dateRange.to)
278315
278670
  ? `${format$1(dateRange.from, 'MMM dd')} - ${format$1(dateRange.to, 'MMM dd')}`
@@ -282322,6 +282677,7 @@ const AGENT_DISCLAIMERS_TAB_LABELS = {
282322
282677
  title: 'Disclaimers',
282323
282678
  description: 'Configure disclaimer settings for your agent.',
282324
282679
  },
282680
+ infoBox: "Show your users the fine print. Add notices — like 'This is an AI assistant' or a compliance statement — that appear in the chat so people know what to expect.",
282325
282681
  userAgreement: {
282326
282682
  title: 'User Agreement',
282327
282683
  tooltip: 'Controls User Agreement',
@@ -282343,6 +282699,7 @@ const AGENT_DISCLAIMERS_TAB_LABELS = {
282343
282699
  save: 'Save',
282344
282700
  saving: 'Saving...',
282345
282701
  cancel: 'Cancel',
282702
+ viewAgreements: 'View Agreements',
282346
282703
  },
282347
282704
  toasts: {
282348
282705
  advisorySuccess: 'Agent updated successfully',
@@ -282353,6 +282710,20 @@ const AGENT_DISCLAIMERS_TAB_LABELS = {
282353
282710
  userAgreementDisabled: 'User agreement disabled successfully',
282354
282711
  toggleError: 'Failed to update user agreement',
282355
282712
  },
282713
+ agreements: {
282714
+ title: 'Agreements',
282715
+ dialogDescription: "Users who have accepted this agent's User Agreement.",
282716
+ totalAgreements: (count) => `${count} Total Agreements`,
282717
+ summaryDescription: "Review the users who have accepted this agent's User Agreement. Each entry shows the user's name, email and when they agreed. Users who haven't accepted yet aren't listed. Search matches the exact username.",
282718
+ searchPlaceholder: 'Search by username',
282719
+ searchAriaLabel: 'Search agreements by username',
282720
+ columnUser: 'User',
282721
+ columnAgreedAt: 'Agreed at',
282722
+ empty: 'No agreements yet',
282723
+ emptyDescription: 'Users who accept the User Agreement will appear here with the time they agreed.',
282724
+ noMatches: 'No users match your search',
282725
+ noMatchesDescription: 'Search matches the exact username — try the full username.',
282726
+ },
282356
282727
  };
282357
282728
  function buildDisclaimersTabLabels(t) {
282358
282729
  return {
@@ -282360,6 +282731,7 @@ function buildDisclaimersTabLabels(t) {
282360
282731
  title: t('disclaimersTabLabels.header.title'),
282361
282732
  description: t('disclaimersTabLabels.header.description'),
282362
282733
  },
282734
+ infoBox: t('disclaimersTabLabels.infoBox'),
282363
282735
  userAgreement: {
282364
282736
  title: t('disclaimersTabLabels.userAgreement.title'),
282365
282737
  tooltip: t('disclaimersTabLabels.userAgreement.tooltip'),
@@ -282381,6 +282753,7 @@ function buildDisclaimersTabLabels(t) {
282381
282753
  save: t('disclaimersTabLabels.actions.save'),
282382
282754
  saving: t('disclaimersTabLabels.actions.saving'),
282383
282755
  cancel: t('disclaimersTabLabels.actions.cancel'),
282756
+ viewAgreements: t('disclaimersTabLabels.actions.viewAgreements'),
282384
282757
  },
282385
282758
  toasts: {
282386
282759
  advisorySuccess: t('disclaimersTabLabels.toasts.advisorySuccess'),
@@ -282391,6 +282764,20 @@ function buildDisclaimersTabLabels(t) {
282391
282764
  userAgreementDisabled: t('disclaimersTabLabels.toasts.userAgreementDisabled'),
282392
282765
  toggleError: t('disclaimersTabLabels.toasts.toggleError'),
282393
282766
  },
282767
+ agreements: {
282768
+ title: t('disclaimersTabLabels.agreements.title'),
282769
+ dialogDescription: t('disclaimersTabLabels.agreements.dialogDescription'),
282770
+ totalAgreements: (count) => t('disclaimersTabLabels.agreements.totalAgreements', { count }),
282771
+ summaryDescription: t('disclaimersTabLabels.agreements.summaryDescription'),
282772
+ searchPlaceholder: t('disclaimersTabLabels.agreements.searchPlaceholder'),
282773
+ searchAriaLabel: t('disclaimersTabLabels.agreements.searchAriaLabel'),
282774
+ columnUser: t('disclaimersTabLabels.agreements.columnUser'),
282775
+ columnAgreedAt: t('disclaimersTabLabels.agreements.columnAgreedAt'),
282776
+ empty: t('disclaimersTabLabels.agreements.empty'),
282777
+ emptyDescription: t('disclaimersTabLabels.agreements.emptyDescription'),
282778
+ noMatches: t('disclaimersTabLabels.agreements.noMatches'),
282779
+ noMatchesDescription: t('disclaimersTabLabels.agreements.noMatchesDescription'),
282780
+ },
282394
282781
  };
282395
282782
  }
282396
282783
  function resolveDisclaimersTabLabels(override, t) {
@@ -282400,18 +282787,23 @@ function resolveDisclaimersTabLabels(override, t) {
282400
282787
  return deepMerge(base, override);
282401
282788
  }
282402
282789
 
282790
+ /* istanbul ignore next -- @preserve dynamic import is not testable in unit tests */
282791
+ const AgreementsModal$1 = dynamic(() => Promise.resolve().then(function () { return agreementsModal; }).then((module) => ({
282792
+ default: module.AgreementsModal,
282793
+ })), { ssr: false });
282403
282794
  // ── Component ────────────────────────────────────────────────────────────
282404
282795
  const DEFAULT_FALLBACK_DISCLAIMER = '';
282405
282796
  function AgentDisclaimersTab({ labels: labelsProp, defaultDisclaimerContent = DEFAULT_FALLBACK_DISCLAIMER, renderContent, }) {
282406
282797
  var _a, _b, _c, _d, _e;
282407
282798
  const t = useT();
282408
282799
  const labels = React__default.useMemo(() => resolveDisclaimersTabLabels(labelsProp, t), [labelsProp, t]);
282409
- const { tenantKey, mentorId, username, rbacPermissions } = useAgentSettings();
282800
+ const { tenantKey, mentorId, username, enableRBAC, rbacPermissions } = useAgentSettings();
282410
282801
  const [editMentor, { isLoading: isEditMentorLoading }] = useEditMentorMutation();
282411
282802
  const [createDisclaimer, { isLoading: isCreateDisclaimerLoading }] = useCreateDisclaimerMutation();
282412
282803
  const [updateDisclaimer, { isLoading: isUpdateDisclaimerLoading }] = useUpdateDisclaimerMutation();
282413
282804
  const [isEditDisclaimerModalOpen, setIsEditDisclaimerModalOpen] = React__default.useState(false);
282414
282805
  const [isEditUserAgreementModalOpen, setIsEditUserAgreementModalOpen] = React__default.useState(false);
282806
+ const [isAgreementsModalOpen, setIsAgreementsModalOpen] = React__default.useState(false);
282415
282807
  const { data: mentorSettings } = useGetMentorSettingsQuery({
282416
282808
  mentor: mentorId,
282417
282809
  org: tenantKey,
@@ -282525,25 +282917,27 @@ function AgentDisclaimersTab({ labels: labelsProp, defaultDisclaimerContent = DE
282525
282917
  // match any entry and WithPermissions resolves hasPermission=false.
282526
282918
  // @ts-ignore mentor_id exists on MentorSettings
282527
282919
  const viewDisclaimersResource = `/mentors/${mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.mentor_id}/#view_disclaimers`;
282528
- return (jsxs(Fragment$1, { children: [jsx("div", { className: "flex h-[73px] flex-shrink-0 items-center border-b border-gray-200 bg-white p-4 lg:block", children: jsxs("div", { children: [jsx("h3", { className: "mb-1 text-base font-medium text-gray-900", children: labels.header.title }), jsx("p", { className: "text-xs text-gray-600", children: labels.header.description })] }) }), jsx("div", { className: "flex-1 space-y-6 overflow-y-auto p-3 lg:p-4", children: jsxs("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2", children: [jsx(WithPermissions, { rbacResource: viewDisclaimersResource, rbacPermissions: rbacPermissions !== null && rbacPermissions !== void 0 ? rbacPermissions : {}, children: ({ hasPermission }) => {
282529
- var _a;
282530
- return hasPermission && (jsx(UserAgreementCard, { content: (_a = userAgreement.content) !== null && _a !== void 0 ? _a : '', active: userAgreement.active, isDisabled: isUserAgreementDisabled, onToggle: toggleUserAgreement, onEditClick: () => setIsEditUserAgreementModalOpen(true), renderText: renderText, labels: labels }));
282531
- } }), jsx(WithFormPermissions, { name: "disclaimer",
282532
- // @ts-ignore permissions not in type of MentorSettingsPublic
282533
- permissions: (_c = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.permissions) === null || _c === void 0 ? void 0 : _c.field, children: ({ disabled }) => {
282534
- var _a, _b;
282535
- return (jsxs("div", { className: "overflow-hidden rounded-lg bg-gray-50", children: [jsx("div", { className: "flex items-center justify-between border-b border-gray-200 p-4", children: jsxs("div", { className: "flex items-center gap-2", children: [jsx("h3", { className: "text-sm font-medium text-gray-900", children: labels.advisory.title }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { "aria-label": t('tabsDisclaimersTab.advisoryMoreInfo', {
282536
- title: labels.advisory.title,
282537
- }), children: jsx(Info$3, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { className: "ibl-tooltip-content", children: jsx("p", { children: labels.advisory.tooltip }) })] }) })] }) }), jsxs("div", { className: "flex items-start gap-2 p-4", children: [jsx("div", { className: "mt-1 flex-shrink-0", children: "\uD83D\uDCDD" }), jsx("div", { className: "flex h-[180px] flex-1 flex-col", children: jsx("div", { className: "mb-4 flex-grow overflow-y-auto", tabIndex: 0, role: "region", "aria-label": t('tabsDisclaimersTab.advisoryContentRegion', {
282538
- title: labels.advisory.title,
282539
- }), children: renderText((_a = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.disclaimer) !== null && _a !== void 0 ? _a : '') }) })] }), jsxs("div", { className: "flex w-full gap-2 px-4 pb-4", children: [jsxs(Button$1, { variant: "outline", size: "sm", className: "h-8 flex-1 py-5", disabled: disabled, onClick: () => setIsEditDisclaimerModalOpen(true), children: [jsx(SquarePen, { className: "mr-2 h-4 w-4" }), labels.actions.edit] }), jsx(CopyButton
282540
- // @ts-ignore disclaimer not in type of MentorSettingsPublic
282541
- , {
282920
+ return (jsxs(Fragment$1, { children: [jsx("div", { className: "flex h-[73px] flex-shrink-0 items-center border-b border-gray-200 bg-white p-4 lg:block", children: jsxs("div", { children: [jsx("h3", { className: "mb-1 text-base font-medium text-gray-900", children: labels.header.title }), jsx("p", { className: "text-xs text-gray-600", children: labels.header.description })] }) }), jsxs("div", { className: "flex-1 space-y-6 overflow-y-auto p-3 lg:p-4", children: [jsx("div", { className: "rounded-md border border-gray-200 bg-gray-50 p-3 text-xs text-gray-600", "data-testid": "disclaimers-info-box", children: labels.infoBox }), jsx(WithPermissions, { rbacResource: viewDisclaimersResource, rbacPermissions: rbacPermissions !== null && rbacPermissions !== void 0 ? rbacPermissions : {}, children: ({ hasPermission }) => hasPermission &&
282921
+ userAgreementRecord &&
282922
+ userAgreement.active && (jsx("div", { className: "flex justify-end", children: jsxs(Button$1, { onClick: () => setIsAgreementsModalOpen(true), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", "data-testid": "view-agreements-button", children: [jsx(Users, { className: "mr-2 h-4 w-4" }), labels.actions.viewAgreements] }) })) }), jsxs("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2", children: [jsx(WithPermissions, { rbacResource: viewDisclaimersResource, rbacPermissions: rbacPermissions !== null && rbacPermissions !== void 0 ? rbacPermissions : {}, children: ({ hasPermission }) => {
282923
+ var _a;
282924
+ return hasPermission && (jsx(UserAgreementCard, { content: (_a = userAgreement.content) !== null && _a !== void 0 ? _a : '', active: userAgreement.active, isDisabled: isUserAgreementDisabled, onToggle: toggleUserAgreement, onEditClick: () => setIsEditUserAgreementModalOpen(true), renderText: renderText, labels: labels }));
282925
+ } }), jsx(WithFormPermissions, { name: "disclaimer",
282926
+ // @ts-ignore permissions not in type of MentorSettingsPublic
282927
+ permissions: (_c = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.permissions) === null || _c === void 0 ? void 0 : _c.field, enableRBAC: enableRBAC, children: ({ disabled }) => {
282928
+ var _a, _b;
282929
+ return (jsxs("div", { className: "overflow-hidden rounded-lg bg-gray-50", children: [jsx("div", { className: "flex items-center justify-between border-b border-gray-200 p-4", children: jsxs("div", { className: "flex items-center gap-2", children: [jsx("h3", { className: "text-sm font-medium text-gray-900", children: labels.advisory.title }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { "aria-label": t('tabsDisclaimersTab.advisoryMoreInfo', {
282930
+ title: labels.advisory.title,
282931
+ }), children: jsx(Info$3, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { className: "ibl-tooltip-content", children: jsx("p", { children: labels.advisory.tooltip }) })] }) })] }) }), jsxs("div", { className: "flex items-start gap-2 p-4", children: [jsx("div", { className: "mt-1 flex-shrink-0", children: "\uD83D\uDCDD" }), jsx("div", { className: "flex h-[180px] flex-1 flex-col", children: jsx("div", { className: "mb-4 flex-grow overflow-y-auto", tabIndex: 0, role: "region", "aria-label": t('tabsDisclaimersTab.advisoryContentRegion', {
282932
+ title: labels.advisory.title,
282933
+ }), children: renderText((_a = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.disclaimer) !== null && _a !== void 0 ? _a : '') }) })] }), jsxs("div", { className: "flex w-full gap-2 px-4 pb-4", children: [jsxs(Button$1, { variant: "outline", size: "sm", className: "h-8 flex-1 py-5", disabled: disabled, onClick: () => setIsEditDisclaimerModalOpen(true), children: [jsx(SquarePen, { className: "mr-2 h-4 w-4" }), labels.actions.edit] }), jsx(CopyButton
282542
282934
  // @ts-ignore disclaimer not in type of MentorSettingsPublic
282543
- text: (_b = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.disclaimer) !== null && _b !== void 0 ? _b : '' })] })] }));
282544
- } })] }) }), jsx(EditDisclaimerModal, { open: isEditDisclaimerModalOpen, onOpenChange: setIsEditDisclaimerModalOpen,
282935
+ , {
282936
+ // @ts-ignore disclaimer not in type of MentorSettingsPublic
282937
+ text: (_b = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.disclaimer) !== null && _b !== void 0 ? _b : '' })] })] }));
282938
+ } })] })] }), jsx(EditDisclaimerModal, { open: isEditDisclaimerModalOpen, onOpenChange: setIsEditDisclaimerModalOpen,
282545
282939
  // @ts-ignore disclaimer not in type of MentorSettingsPublic
282546
- disclaimer: (_d = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.disclaimer) !== null && _d !== void 0 ? _d : '', onSave: handleSaveDisclaimer, onCancel: () => setIsEditDisclaimerModalOpen(false), isSaving: isEditMentorLoading, labels: labels }), jsx(EditUserAgreementModal, { open: isEditUserAgreementModalOpen, onOpenChange: setIsEditUserAgreementModalOpen, content: (_e = userAgreement.content) !== null && _e !== void 0 ? _e : '', onSave: handleSaveUserAgreement, onCancel: () => setIsEditUserAgreementModalOpen(false), isSaving: isUserAgreementDisabled, labels: labels })] }));
282940
+ disclaimer: (_d = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.disclaimer) !== null && _d !== void 0 ? _d : '', onSave: handleSaveDisclaimer, onCancel: () => setIsEditDisclaimerModalOpen(false), isSaving: isEditMentorLoading, labels: labels }), jsx(EditUserAgreementModal, { open: isEditUserAgreementModalOpen, onOpenChange: setIsEditUserAgreementModalOpen, content: (_e = userAgreement.content) !== null && _e !== void 0 ? _e : '', onSave: handleSaveUserAgreement, onCancel: () => setIsEditUserAgreementModalOpen(false), isSaving: isUserAgreementDisabled, labels: labels }), userAgreementRecord && (jsx(AgreementsModal$1, { open: isAgreementsModalOpen, onOpenChange: setIsAgreementsModalOpen, org: tenantKey, userId: username, mentorId: mentorId, disclaimerId: userAgreementRecord.id, labels: labels }))] }));
282547
282941
  }
282548
282942
 
282549
282943
  const DEFAULT_MENTOR_ROLES = ['editor', 'chat'];
@@ -284231,7 +284625,7 @@ function resolveEvaluationTabLabels(override, t) {
284231
284625
  return deepMerge(base, override);
284232
284626
  }
284233
284627
 
284234
- const PAGE_SIZE = 10;
284628
+ const PAGE_SIZE$1 = 10;
284235
284629
  function StatusBadge({ status }) {
284236
284630
  const upper = status === null || status === void 0 ? void 0 : status.toUpperCase();
284237
284631
  const color = upper === 'COMPLETED'
@@ -284284,7 +284678,7 @@ function AgentEvaluationTabContent({ labels: labelsOverride, PaginationComponent
284284
284678
  userId: username,
284285
284679
  datasetName: selectedBenchmark,
284286
284680
  page,
284287
- limit: PAGE_SIZE,
284681
+ limit: PAGE_SIZE$1,
284288
284682
  }, { skip: !selectedBenchmark });
284289
284683
  // Runs are benchmark-scoped server-side, but a benchmark can be evaluated
284290
284684
  // against multiple agents. Filter client-side to the agent we're editing:
@@ -284300,7 +284694,7 @@ function AgentEvaluationTabContent({ labels: labelsOverride, PaginationComponent
284300
284694
  return runMentor === mentorId;
284301
284695
  return !!username && run.username === username;
284302
284696
  }), [allRuns, mentorId, username]);
284303
- const totalPages = evalTotalPages(runsData === null || runsData === void 0 ? void 0 : runsData.count, PAGE_SIZE);
284697
+ const totalPages = evalTotalPages(runsData === null || runsData === void 0 ? void 0 : runsData.count, PAGE_SIZE$1);
284304
284698
  const [fetchRunDetail] = useLazyGetEvalRunQuery();
284305
284699
  const handleCheckStatus = async (runName) => {
284306
284700
  setCheckingRun(runName);
@@ -290885,6 +291279,62 @@ var trainOrDeleteModal = /*#__PURE__*/Object.freeze({
290885
291279
  TrainOrDeleteModal: TrainOrDeleteModal
290886
291280
  });
290887
291281
 
291282
+ const PAGE_SIZE = 20;
291283
+ function AgreementsModal({ open, onOpenChange, ...bodyProps }) {
291284
+ return (jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: open && jsx(AgreementsBody, { ...bodyProps }) }));
291285
+ }
291286
+ function AgreementsBody({ org, userId, mentorId, disclaimerId, labels }) {
291287
+ var _a, _b;
291288
+ const t = labels.agreements;
291289
+ const [searchTerm, setSearchTerm] = React__default.useState('');
291290
+ const [debouncedSearchTerm] = a$3(searchTerm, 300);
291291
+ const [page, setPage] = React__default.useState(1);
291292
+ const [pageSearchTerm, setPageSearchTerm] = React__default.useState(debouncedSearchTerm);
291293
+ // A new search always starts from the first page. Adjusting during render
291294
+ // (not in an effect) means no render is committed -- and no request fired --
291295
+ // with the new term and the old page.
291296
+ if (pageSearchTerm !== debouncedSearchTerm) {
291297
+ setPageSearchTerm(debouncedSearchTerm);
291298
+ setPage(1);
291299
+ }
291300
+ const { data, isLoading, isFetching } = useGetDisclaimerAgreementsQuery({
291301
+ org,
291302
+ userId,
291303
+ params: {
291304
+ disclaimer: disclaimerId,
291305
+ mentor_id: mentorId,
291306
+ username: debouncedSearchTerm || undefined,
291307
+ page,
291308
+ page_size: PAGE_SIZE,
291309
+ },
291310
+ },
291311
+ // Other users' agreements land in other clients, so the cached list goes
291312
+ // stale without any invalidation here; always refetch on (re)open.
291313
+ { refetchOnMountOrArgChange: true });
291314
+ const agreements = (_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : [];
291315
+ const count = (_b = data === null || data === void 0 ? void 0 : data.count) !== null && _b !== void 0 ? _b : 0;
291316
+ const totalPages = Math.max(1, Math.ceil(count / PAGE_SIZE));
291317
+ // An empty list is either nobody agreed yet or a search miss.
291318
+ const emptyState = debouncedSearchTerm
291319
+ ? { Icon: Search, heading: t.noMatches, description: t.noMatchesDescription }
291320
+ : { Icon: Users, heading: t.empty, description: t.emptyDescription };
291321
+ return (jsxs(DialogContent, { className: "flex h-[90vh] max-w-6xl flex-col p-0", "data-testid": "disclaimer-agreements", children: [jsxs(DialogHeader, { className: "flex-shrink-0 border-b border-gray-200 px-6 pt-6 pb-4", children: [jsx(DialogTitle, { className: "text-xl font-semibold text-gray-900", children: t.title }), jsx(DialogDescription, { className: "sr-only", children: t.dialogDescription })] }), jsx("div", { className: "scrollbar-hide flex-1 overflow-y-auto p-4", children: jsxs("div", { className: "space-y-6", children: [jsxs("div", { className: "rounded-lg border p-4", "data-testid": "disclaimer-agreements-summary", children: [jsxs("div", { className: "mb-3 flex items-center gap-2", children: [jsx(Users, { className: "h-5 w-5 text-blue-600", "aria-hidden": "true" }), jsx("span", { className: "font-semibold text-gray-900", "data-testid": "disclaimer-agreements-count", children: t.totalAgreements(count) })] }), jsx("p", { className: "text-sm leading-relaxed text-gray-900", role: "note", "data-testid": "disclaimer-agreements-banner", children: t.summaryDescription })] }), jsx("div", { className: "rounded-lg border p-4", children: jsxs("div", { className: "relative", children: [jsx(Search, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 transform text-gray-500", "aria-hidden": "true" }), jsx(Input, { type: "search", value: searchTerm, onChange: (event) => setSearchTerm(event.target.value), placeholder: t.searchPlaceholder, "aria-label": t.searchAriaLabel, className: "w-full pl-9", "data-testid": "disclaimer-agreements-search" })] }) }), isLoading ? (jsx("div", { className: "space-y-2", "data-testid": "disclaimer-agreements-loading", "aria-busy": "true", children: [0, 1, 2].map((key) => (jsx("div", { className: "h-9 animate-pulse rounded bg-gray-200" }, key))) })) : agreements.length === 0 ? (jsxs("div", { className: "rounded-lg border border-dashed border-gray-200 bg-gray-50 p-6 text-center text-sm text-gray-600 md:p-10", "data-testid": "disclaimer-agreements-empty", children: [jsx(emptyState.Icon, { className: "mx-auto mb-2 h-8 w-8 text-blue-600", "aria-hidden": "true" }), jsx("p", { className: "font-medium text-gray-900", children: emptyState.heading }), jsx("p", { className: "mt-1 text-sm text-gray-600", children: emptyState.description })] })) : (jsx("div", { className: "overflow-hidden rounded-lg border border-gray-200 bg-white", children: jsxs(Table$1, { children: [jsx(TableHeader$1, { children: jsxs(TableRow$1, { children: [jsx(TableHead, { children: t.columnUser }), jsx(TableHead, { className: "w-0 whitespace-nowrap", children: t.columnAgreedAt })] }) }), jsx(TableBody, { children: agreements.map((agreement) => {
291322
+ const agreedAt = new Date(agreement.agreed_at);
291323
+ // Primary is the full name, falling back to the username.
291324
+ // Secondary is the email, falling back to the username only
291325
+ // when the primary is the name (never print it twice).
291326
+ const primary = agreement.user_full_name || agreement.user_id;
291327
+ const secondary = agreement.user_email ||
291328
+ (primary !== agreement.user_id ? agreement.user_id : null);
291329
+ return (jsxs(TableRow$1, { "data-testid": "disclaimer-agreement-row", "data-username": agreement.user_id, children: [jsxs(TableCell$1, { children: [jsx("div", { className: "font-medium text-gray-900", "data-testid": "disclaimer-agreement-user", children: primary }), secondary && jsx("div", { className: "text-xs text-gray-500", children: secondary })] }), jsx(TableCell$1, { className: "text-sm whitespace-nowrap text-gray-600", children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("span", { children: formatDistanceToNow(agreedAt, { addSuffix: true }) }) }), jsx(TooltipContent, { className: "ibl-tooltip-content", children: jsx("p", { children: format$1(agreedAt, "MMM dd, yyyy 'at' h:mm a") }) })] }) })] }, agreement.id));
291330
+ }) })] }) })), jsx(IblPagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage, disabled: isFetching })] }) })] }));
291331
+ }
291332
+
291333
+ var agreementsModal = /*#__PURE__*/Object.freeze({
291334
+ __proto__: null,
291335
+ AgreementsModal: AgreementsModal
291336
+ });
291337
+
290888
291338
  function ImagePreviewModal({ url, onClose }) {
290889
291339
  return (jsx("div", { className: "bg-opacity-75 fixed inset-0 z-50 flex items-center justify-center bg-black p-4", onClick: onClose, children: jsxs("div", { className: "relative flex h-full w-full items-center justify-center", children: [jsx("button", { className: "bg-opacity-50 hover:bg-opacity-70 absolute top-2 right-2 rounded-full bg-black p-1 text-white", onClick: (e) => {
290890
291340
  e.stopPropagation();