@iblai/iblai-js 2.5.0 → 2.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data-layer/playwright/index.d.ts +4 -2
- package/dist/data-layer/playwright/lti-tab-helpers.d.ts +36 -1
- package/dist/data-layer/playwright/memory-admin-helpers.d.ts +153 -0
- package/dist/data-layer/playwright/memory-test-helpers.d.ts +8 -7
- package/dist/data-layer/playwright/voice-tab-helpers.d.ts +32 -0
- package/dist/playwright/index.cjs +550 -26
- package/dist/playwright/index.cjs.map +1 -1
- package/dist/playwright/index.d.ts +231 -10
- package/dist/playwright/index.esm.js +521 -27
- package/dist/playwright/index.esm.js.map +1 -1
- package/dist/playwright/playwright/index.d.ts +4 -2
- package/dist/playwright/playwright/lti-tab-helpers.d.ts +36 -1
- package/dist/playwright/playwright/memory-admin-helpers.d.ts +153 -0
- package/dist/playwright/playwright/memory-test-helpers.d.ts +8 -7
- package/dist/playwright/playwright/voice-tab-helpers.d.ts +32 -0
- package/dist/security/playwright/index.d.ts +4 -2
- package/dist/security/playwright/lti-tab-helpers.d.ts +36 -1
- package/dist/security/playwright/memory-admin-helpers.d.ts +153 -0
- package/dist/security/playwright/memory-test-helpers.d.ts +8 -7
- package/dist/security/playwright/voice-tab-helpers.d.ts +32 -0
- package/dist/web-containers/playwright/index.d.ts +4 -2
- package/dist/web-containers/playwright/lti-tab-helpers.d.ts +36 -1
- package/dist/web-containers/playwright/memory-admin-helpers.d.ts +153 -0
- package/dist/web-containers/playwright/memory-test-helpers.d.ts +8 -7
- package/dist/web-containers/playwright/voice-tab-helpers.d.ts +32 -0
- package/dist/web-containers/source/index.esm.js +12524 -11248
- package/dist/web-containers/source/next/index.esm.js +1740 -444
- package/dist/web-utils/playwright/index.d.ts +4 -2
- package/dist/web-utils/playwright/lti-tab-helpers.d.ts +36 -1
- package/dist/web-utils/playwright/memory-admin-helpers.d.ts +153 -0
- package/dist/web-utils/playwright/memory-test-helpers.d.ts +8 -7
- package/dist/web-utils/playwright/voice-tab-helpers.d.ts +32 -0
- package/package.json +4 -4
|
@@ -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, useId as useId$2, useDebugValue, lazy, Suspense } from 'react';
|
|
4
4
|
import * as dataLayer from '@iblai/data-layer';
|
|
5
|
-
import { useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useGetLearnerDetailsQuery, useGetUserEnrolledCoursesQuery, useGetUserEnrolledProgramsQuery, useGetUserCatalogPathwaysQuery, useGetUsersAsAssertionsQuery, useGetUserEarnedSkillsQuery, useGetUserReportedSkillsQuery, useGetUserDesiredSkillsQuery, useCreateGlobalMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useGetAllMentorMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, useGetAccessibleUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacActionsDefinitionQuery, useGetRbacResourceDiscoveryQuery, useGetRbacResourceListQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useGetWatchedGroupsQuery, useCreateWatchedGroupMutation, useUpdateWatchedGroupMutation, useDeleteWatchedGroupMutation, useAddWatchedUserMutation, useRemoveWatchedUserMutation, useAddWatcherMutation, useUpdateWatcherMutation, useDeleteWatcherMutation, useGetWatchedUsersQuery, useGetWatchersQuery, WATCHER_NOTIFICATION_EVENTS, WATCHER_NOTIFICATION_EVENT_LABELS, useGetApplicationFormsQuery, useGetApplicationFormDetailQuery, useCreateApplicationFormMutation, useUpdateApplicationFormMutation, useGetApplicationAdminDetailQuery, useInviteApplicationCandidateMutation, useLazyGetApplicationAttachmentFileQuery, useCreateApplicationWaiverMutation, useDeleteApplicationWaiverMutation, useSubmitApplicationOverrideMutation, useUpdateApplicationPlacementMutation, useDeleteApplicationCourseAssignmentMutation, useCreateApplicationNoteMutation, useUpdateApplicationNoteMutation, useDeleteApplicationNoteMutation, useTransitionApplicationMutation, useLinkApplicationCandidateMutation, useCreateApplicationPlacementsMutation, useGetCustomMentorsQuery, useCreateApplicationCourseAssignmentsMutation, useGetApplicationBlocksQuery, useDeleteApplicationBlockMutation, useGetApplicationsPipelineStatsQuery, useGetApplicationsPipelineQuery, useDeleteApiKeyMutation, useGetApiKeyQuery, useGetApiKeyFieldPermissionsQuery, useUpdateApiKeyMutation, useGetApiKeysQuery, unwrapApiTokenList, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useGetAgentSpendCapQuery, useGetTenantSpendCapQuery, useListAgentUserSpendCapsQuery, useUpsertAgentSpendCapMutation, useDeleteAgentSpendCapMutation, useUpsertTenantSpendCapMutation, useDeleteTenantSpendCapMutation, useUpsertUserSpendCapMutation, useDeleteUserSpendCapMutation, useGetFinancialStatsQuery, useGetMentorsQuery, useListAgentSpendCapsQuery, useGetCreditTransactionsQuery, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, useGetCustomDomainsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useUpdateTenantMetadataMutation, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useGetMemsearchConfigQuery, useUpdateMemsearchConfigMutation, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useGetAiSearchMentorsQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useStarMentorMutation, useUnstarMentorMutation, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetAgentSkillResourcesQuery, useCreateAgentSkillResourceMutation, useUpdateAgentSkillResourceMutation, useUploadAgentSkillResourceAssetMutation, useDeleteAgentSkillResourceMutation, useGetMentorSkillAssignmentsQuery, useGetAgentSkillsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, filterSlashSkills, useGetMentorSkillAssignmentsInfiniteQuery, MENTOR_SKILL_ASSIGNMENTS_PAGE_SIZE, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useGetVectorDocumentsQuery, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useDeleteMentorMemoryMutation, useUpdateMentorMemoryMutation, useCreateMentorMemoryMutation, useLazyGetConnectedServiceAuthUrlQuery, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorSettingsQuery, useEditMentorMutation, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, LOGO_ENDPOINTS, useCreateEvalDatasetMutation, useAddEvalDatasetItemsMutation, useUploadEvalDatasetCsvMutation, useDeleteEvalDatasetItemMutation, useListEvalDatasetItemsQuery, evalTotalPages, useListEvalDatasetsQuery, useGetUserProjectsQuery, useCreateSessionIdMutation, useGetMentorCategoriesQuery, useGetTenantChatPrivacyConfigQuery as useGetTenantChatPrivacyConfigQuery$1, useGetCallConfigurationsQuery, useCreateCallConfigurationMutation, useUpdateCallConfigurationMutation, chatPrivacyApiSlice, useDeleteMentorMutation, useForkMentorMutation, useGetToolsQuery, useLazyGetMCPServersQuery, useOauthFindMutation, useLazyStartOAuthFlowQuery, useCreateMCPServerMutation, usePartialUpdateMCPServerMutation, useCreateMCPServerConnectionMutation, usePatchMCPServerConnectionMutation, useGetConnectedServicesQuery, useGetMCPServersQuery, useGetMCPServerConnectionsQuery, useUpdateMCPServerMutation, useDeleteMCPServerMutation, useEditMentorJsonMutation, useDisconnectServiceMutation, useGetPromptCategoriesQuery, PRIVACY_ACTIONS, PRIVACY_ENTITY_TYPES, useGetVoicesQuery, useGetVoiceQuery, isBaseAgentMentor, useGetGradeResultQuery, useOverrideGradeResultMutation, useGetChatHistoryFilterQuery, useListGradeResultsQuery, useGetMentorGraderConfigurationQuery, useListGraderCriteriaQuery, useCreateMentorGraderConfigurationMutation, useUpdateMentorGraderConfigurationMutation, useCreateGraderCriterionMutation, useUpdateGraderCriterionMutation, useDeleteGraderCriterionMutation, useGetSpendCapStatusQuery, useGetMentorPublicSettingsQuery, useGetChatHistoryQuery, useGetMentorSummariesQuery, useGetConversationMemoriesQuery, useGetSupportTicketsQuery, useGetSupportTicketMessagesQuery, useCreateSupportTicketMessageMutation, usePatchSupportTicketMutation, useCloseSupportTicketMutation, useCreateLtiMentorMutation, useUpdateLtiMentorMutation, useGetLtiMentorsQuery, useCreateLtiKeyMutation, useUpdateLtiKeyMutation, useDeleteLtiKeyMutation, useGetLtiKeysQuery, useCreateLtiToolMutation, useUpdateLtiToolMutation, useGetLtiToolsQuery, useGetPlatformInfoQuery, useCreatePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useCreateRedirectTokenMutation, useGetShareableLinkQuery, useCreateShareableLinkMutation, useUpdateShareableLinkMutation, useCreateDisclaimerMutation, useUpdateDisclaimerMutation, useGetDisclaimersQuery, useUpdateRbacMentorAccessMutation, useGetRbacMentorAccessListQuery, useStartEvalRunMutation, useEvaluateEvalRunMutation, useGetEvalRunQuery, useDeleteEvalScoreMutation, useListEvalRunJudgesQuery, useCreateEvalScoreMutation, useDeleteEvalRunMutation, useExportEvalRunMutation, useListEvalRunsQuery, useLazyGetEvalRunQuery, evaluationsApiSlice, EVALUATIONS_TAGS, useGetPersonnalizedMentorsQuery, useCreateCallCredentialsMutation, useGetGuidedPromptsQuery, useUpdateChatSessionSharedMutation, useUpdateMessageFeedbackMutation, useLazyGetPromptsSearchQuery, useLazyGetGuidedPromptsQuery, useGetPublicMentorsQuery, useGetPeriodicAgentsQuery, useGetPeriodicAgentLogsListQuery, useCreatePeriodicAgentMutation, useDeletePeriodicAgentMutation, useDeletePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useUpdateArtifactMutation, useLazyGetArtifactVersionQuery, useLazyListArtifactVersionsQuery, useSetCurrentVersionMutation, useListArtifactVersionsQuery, useLazyGetArtifactQuery, useLazyListArtifactsQuery, useEditSessionMutation } from '@iblai/data-layer';
|
|
5
|
+
import { useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useGetLearnerDetailsQuery, useGetUserEnrolledCoursesQuery, useGetUserEnrolledProgramsQuery, useGetUserCatalogPathwaysQuery, useGetUsersAsAssertionsQuery, useGetUserEarnedSkillsQuery, useGetUserReportedSkillsQuery, useGetUserDesiredSkillsQuery, useCreateGlobalMemoryMutation, useUpdateGlobalMemoryMutation, useUpdateMentorMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useGetAllMentorMemoriesQuery, useDeleteGlobalMemoryMutation, useDeleteMentorMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, useGetAccessibleUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacActionsDefinitionQuery, useGetRbacResourceDiscoveryQuery, useGetRbacResourceListQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useGetWatchedGroupsQuery, useCreateWatchedGroupMutation, useUpdateWatchedGroupMutation, useDeleteWatchedGroupMutation, useAddWatchedUserMutation, useRemoveWatchedUserMutation, useAddWatcherMutation, useUpdateWatcherMutation, useDeleteWatcherMutation, useGetWatchedUsersQuery, useGetWatchersQuery, WATCHER_NOTIFICATION_EVENTS, WATCHER_NOTIFICATION_EVENT_LABELS, useGetApplicationFormsQuery, useGetApplicationFormDetailQuery, useCreateApplicationFormMutation, useUpdateApplicationFormMutation, useGetApplicationAdminDetailQuery, useInviteApplicationCandidateMutation, useLazyGetApplicationAttachmentFileQuery, useCreateApplicationWaiverMutation, useDeleteApplicationWaiverMutation, useSubmitApplicationOverrideMutation, useUpdateApplicationPlacementMutation, useDeleteApplicationCourseAssignmentMutation, useCreateApplicationNoteMutation, useUpdateApplicationNoteMutation, useDeleteApplicationNoteMutation, useTransitionApplicationMutation, useLinkApplicationCandidateMutation, useCreateApplicationPlacementsMutation, useGetCustomMentorsQuery, useCreateApplicationCourseAssignmentsMutation, useGetApplicationBlocksQuery, useDeleteApplicationBlockMutation, useGetApplicationsPipelineStatsQuery, useGetApplicationsPipelineQuery, useGetTenantMetadataQuery, useGetMentorsQuery, useUpdateTenantMetadataMutation, useLazyGetTenantMetadataQuery, useDeleteApiKeyMutation, useGetApiKeyQuery, useGetApiKeyFieldPermissionsQuery, useUpdateApiKeyMutation, useGetApiKeysQuery, unwrapApiTokenList, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useGetAgentSpendCapQuery, useGetTenantSpendCapQuery, useListAgentUserSpendCapsQuery, useUpsertAgentSpendCapMutation, useDeleteAgentSpendCapMutation, useUpsertTenantSpendCapMutation, useDeleteTenantSpendCapMutation, useUpsertUserSpendCapMutation, useDeleteUserSpendCapMutation, useGetFinancialStatsQuery, 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, useGetAiSearchMentorsQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useStarMentorMutation, useUnstarMentorMutation, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetAgentSkillResourcesQuery, useCreateAgentSkillResourceMutation, useUpdateAgentSkillResourceMutation, useUploadAgentSkillResourceAssetMutation, useDeleteAgentSkillResourceMutation, useGetMentorSkillAssignmentsQuery, useGetAgentSkillsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, filterSlashSkills, useGetMentorSkillAssignmentsInfiniteQuery, MENTOR_SKILL_ASSIGNMENTS_PAGE_SIZE, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useGetVectorDocumentsQuery, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useCreateMentorMemoryMutation, useLazyGetConnectedServiceAuthUrlQuery, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorSettingsQuery, useEditMentorMutation, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, LOGO_ENDPOINTS, useCreateEvalDatasetMutation, useAddEvalDatasetItemsMutation, useUploadEvalDatasetCsvMutation, useDeleteEvalDatasetItemMutation, useListEvalDatasetItemsQuery, evalTotalPages, useListEvalDatasetsQuery, useGetUserProjectsQuery, useCreateSessionIdMutation, useGetMentorCategoriesQuery, useGetTenantChatPrivacyConfigQuery as useGetTenantChatPrivacyConfigQuery$1, useGetCallConfigurationsQuery, useCreateCallConfigurationMutation, useUpdateCallConfigurationMutation, chatPrivacyApiSlice, useDeleteMentorMutation, useForkMentorMutation, useGetToolsQuery, useLazyGetMCPServersQuery, useOauthFindMutation, useLazyStartOAuthFlowQuery, useCreateMCPServerMutation, usePartialUpdateMCPServerMutation, useCreateMCPServerConnectionMutation, usePatchMCPServerConnectionMutation, useGetConnectedServicesQuery, useGetMCPServersQuery, useGetMCPServerConnectionsQuery, useUpdateMCPServerMutation, useDeleteMCPServerMutation, useEditMentorJsonMutation, useDisconnectServiceMutation, useGetPromptCategoriesQuery, PRIVACY_ACTIONS, PRIVACY_ENTITY_TYPES, useGetVoicesQuery, useGetVoiceQuery, isBaseAgentMentor, useGetGradeResultQuery, useOverrideGradeResultMutation, useGetChatHistoryFilterQuery, useListGradeResultsQuery, useGetMentorGraderConfigurationQuery, useListGraderCriteriaQuery, useCreateMentorGraderConfigurationMutation, useUpdateMentorGraderConfigurationMutation, useCreateGraderCriterionMutation, useUpdateGraderCriterionMutation, useDeleteGraderCriterionMutation, 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, useDeletePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useUpdateArtifactMutation, useLazyGetArtifactVersionQuery, useLazyListArtifactVersionsQuery, useSetCurrentVersionMutation, useListArtifactVersionsQuery, useLazyGetArtifactQuery, useLazyListArtifactsQuery, useEditSessionMutation } from '@iblai/data-layer';
|
|
6
6
|
import { getInitials, useTenantMetadata, useCurrentTenant, selectRbacPermissions, isPureWatcher, WithPermissions, canWriteField, useStripeUpgrade, openExternalUrl, CHAT_AREA_SIZE, isAlphaNumeric32, checkRbacPermission, selectNumberOfActiveChatMessages, useUsername, selectStreaming, isLoggedIn, TOOLS, hasRemoteAiConfig, isSafariBrowser, useShowAttachment, useShowVoiceCall, useShowVoiceRecorder, useMentorSettings, selectShowingSharedChat, useShowFreeTrialDialog, useEmbedMode, chatInputSliceSelectors, useResponsive, useAccessingPublicRoute, useVisitingTenant, useModelFileUploadCapabilities, useChatFileUpload, useVoiceChat, selectAttachedFiles, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, removeFile, chatInputSliceActions, chatActions, WithFormPermissions, useTenantContext, TimeTracker, advancedTabsProperties, defaultSessionIds, pickWritableFields, ANONYMOUS_USERNAME as ANONYMOUS_USERNAME$3, redirectToAuthSpaJoinTenant, selectActiveTab, useAxdToken, useWelcomeMessage, markdownToPlainText, useCachedSessionId, use402ErrorCheck, selectTokenEnabled, selectToken, useServiceWorker, useUserAgreement, useAdvancedChat, sendMessageToParentWebsite, useMentorTools, useFileDragDrop, eventBus, RemoteEvents, selectEnableChatActionsPopup, advancedTabs, isInIframe, getAuthSpaJoinUrl, addMessage, clearFiles, MENTOR_VISIBILITY } from '@iblai/web-utils';
|
|
7
7
|
import { useDispatch, useSelector } from 'react-redux';
|
|
8
8
|
import { toast } from 'sonner';
|
|
@@ -99699,7 +99699,63 @@ var memoryMemoryTab$3 = {
|
|
|
99699
99699
|
noMemoriesYet: "No memories yet. The AI will start remembering information from your conversations, or you can add memories manually.",
|
|
99700
99700
|
noMemoriesYetPreview: "No memories yet. The AI has not recorded any information from this user's conversations.",
|
|
99701
99701
|
stateEnabled: "enabled",
|
|
99702
|
-
stateDisabled: "disabled"
|
|
99702
|
+
stateDisabled: "disabled",
|
|
99703
|
+
actionsMenuAriaLabel: "Memory actions: {excerpt}",
|
|
99704
|
+
editAction: "Edit",
|
|
99705
|
+
deleteAction: "Delete"
|
|
99706
|
+
};
|
|
99707
|
+
var memoryAdminTab$3 = {
|
|
99708
|
+
tabsAriaLabel: "Memory management sections",
|
|
99709
|
+
tabGlobalMemories: "Global",
|
|
99710
|
+
tabAgentMemories: "Agent",
|
|
99711
|
+
featureDisabled: "The memory feature is not enabled for this platform.",
|
|
99712
|
+
searchUsersPlaceholder: "Search Users",
|
|
99713
|
+
searchUsersAriaLabel: "Search Users",
|
|
99714
|
+
nameColumn: "Name",
|
|
99715
|
+
usernameColumn: "Username",
|
|
99716
|
+
emailColumn: "Email",
|
|
99717
|
+
agentColumn: "Agent",
|
|
99718
|
+
descriptionColumn: "Description",
|
|
99719
|
+
actionsColumn: "Actions",
|
|
99720
|
+
loading: "Loading...",
|
|
99721
|
+
noUsersFound: "No users found",
|
|
99722
|
+
noAgentsFound: "No agents found",
|
|
99723
|
+
forbidden: "You do not have permission to view this content.",
|
|
99724
|
+
viewMemoriesAriaLabel: "View memories for {name}",
|
|
99725
|
+
filter: {
|
|
99726
|
+
placeholder: "Search Agents…",
|
|
99727
|
+
typeToSearch: "Type at least 2 characters to search",
|
|
99728
|
+
searching: "Searching agents…",
|
|
99729
|
+
noResults: "No agents found",
|
|
99730
|
+
clear: "Clear Agent Filter"
|
|
99731
|
+
}
|
|
99732
|
+
};
|
|
99733
|
+
var memoryAdminUserMemoriesModal$3 = {
|
|
99734
|
+
title: "Global Memories",
|
|
99735
|
+
description: "View and manage this user's global memories.",
|
|
99736
|
+
addMemoryButton: "Add Memory",
|
|
99737
|
+
noMemories: "No memories saved for this user yet.",
|
|
99738
|
+
forbidden: "You do not have permission to view this user's memories.",
|
|
99739
|
+
failedToLoad: "Failed to load memories.",
|
|
99740
|
+
memoryDeleted: "Memory deleted",
|
|
99741
|
+
failedToDeleteMemory: "Failed to delete memory"
|
|
99742
|
+
};
|
|
99743
|
+
var memoryEditMemoryDialog$3 = {
|
|
99744
|
+
dialogTitle: "Edit Memory",
|
|
99745
|
+
dialogDescription: "Update the content of this memory",
|
|
99746
|
+
contentLabel: "Memory Content",
|
|
99747
|
+
validationMinLength: "Memory content must be at least 10 characters",
|
|
99748
|
+
inlineMinLength: "Must be at least 10 characters",
|
|
99749
|
+
toastUpdated: "Memory updated",
|
|
99750
|
+
toastDuplicate: "This memory already exists",
|
|
99751
|
+
toastForbidden: "You do not have permission to update this memory",
|
|
99752
|
+
toastFailed: "Failed to update memory",
|
|
99753
|
+
cancelButton: "Cancel",
|
|
99754
|
+
savingButton: "Saving...",
|
|
99755
|
+
saveButton: "Save Memory"
|
|
99756
|
+
};
|
|
99757
|
+
var memoryAdminAgentMemoriesModal$3 = {
|
|
99758
|
+
description: "View and manage memories saved for this agent."
|
|
99703
99759
|
};
|
|
99704
99760
|
var memoryTabAddMemoryModal$3 = {
|
|
99705
99761
|
addMemory: "Add Memory",
|
|
@@ -100287,7 +100343,9 @@ var profileAccount$3 = {
|
|
|
100287
100343
|
descSocial: "Connect and manage your social media accounts.",
|
|
100288
100344
|
descSecurity: "Update your security settings and password.",
|
|
100289
100345
|
tabBenchmarks: "Benchmarks",
|
|
100290
|
-
descBenchmarks: "Build benchmark suites of test inputs to evaluate agents."
|
|
100346
|
+
descBenchmarks: "Build benchmark suites of test inputs to evaluate agents.",
|
|
100347
|
+
tabMemory: "Memory",
|
|
100348
|
+
descMemory: "Manage user global memories and agent memories."
|
|
100291
100349
|
};
|
|
100292
100350
|
var profileAddCreditsModal$3 = {
|
|
100293
100351
|
title: "Add Credits",
|
|
@@ -100321,7 +100379,9 @@ var profileAdmin$3 = {
|
|
|
100321
100379
|
teamsDescription: "A team is a curated set of users that you can share with others — e.g., grant another user permission to view the team's analytics or send notifications to them.",
|
|
100322
100380
|
alertsDescription: "An alert pairs a team of watched users with one or more watchers who get notified when monitored events occur for a watched user. Each watcher subscribes to its own subset of events.",
|
|
100323
100381
|
applicationsTab: "Applications",
|
|
100324
|
-
applicationsTabDescription: "Review applications to your organization and edit the questions applicants answer when they apply."
|
|
100382
|
+
applicationsTabDescription: "Review applications to your organization and edit the questions applicants answer when they apply.",
|
|
100383
|
+
onboardingTab: "Onboarding",
|
|
100384
|
+
onboardingTabDescription: "Choose the agent every new member of this platform meets when they arrive, and how it introduces itself."
|
|
100325
100385
|
};
|
|
100326
100386
|
var profileAutoRechargeModal$3 = {
|
|
100327
100387
|
title: "Manage Usage",
|
|
@@ -101867,8 +101927,8 @@ var tabsTeamsaccesspanel$3 = {
|
|
|
101867
101927
|
errorDefault: "An error occurred while updating team access"
|
|
101868
101928
|
};
|
|
101869
101929
|
var tabsUserstab$3 = {
|
|
101870
|
-
searchPlaceholder: "Search
|
|
101871
|
-
searchAriaLabel: "Search
|
|
101930
|
+
searchPlaceholder: "Search Users",
|
|
101931
|
+
searchAriaLabel: "Search Users",
|
|
101872
101932
|
inviteButton: "Invite",
|
|
101873
101933
|
columnName: "Name",
|
|
101874
101934
|
columnEmail: "Email",
|
|
@@ -102135,7 +102195,28 @@ var voiceTabLabels$3 = {
|
|
|
102135
102195
|
stop: "Stop {voiceName} voice"
|
|
102136
102196
|
},
|
|
102137
102197
|
saveButton: "Save voice",
|
|
102138
|
-
savingButton: "Saving…"
|
|
102198
|
+
savingButton: "Saving…",
|
|
102199
|
+
instructions: {
|
|
102200
|
+
label: "Voice Instructions",
|
|
102201
|
+
tooltip: "Describe how the agent should sound when it speaks — tone, pace, emotion, accent, energy. This changes the delivery, not what it says. Example: \"Speak slowly in a warm, encouraging tone, like a patient tutor.\"",
|
|
102202
|
+
placeholder: "e.g. Speak slowly in a warm, encouraging tone, like a patient tutor.",
|
|
102203
|
+
helpText: "Works with OpenAI voices (sent as speech instructions) and Google voices (sent as a synthesis prompt); other voices ignore it. Leave blank for the provider's default delivery — instructions switch OpenAI to a pricier, instruction-capable speech model.",
|
|
102204
|
+
presetsLabel: "Examples",
|
|
102205
|
+
presets: {
|
|
102206
|
+
warm: {
|
|
102207
|
+
label: "Warm and encouraging",
|
|
102208
|
+
text: "Speak slowly in a warm, encouraging tone, like a patient tutor."
|
|
102209
|
+
},
|
|
102210
|
+
calm: {
|
|
102211
|
+
label: "Calm and measured",
|
|
102212
|
+
text: "Speak in a calm, measured voice with a steady, unhurried pace."
|
|
102213
|
+
},
|
|
102214
|
+
energetic: {
|
|
102215
|
+
label: "Energetic and upbeat",
|
|
102216
|
+
text: "Speak with upbeat energy and enthusiasm, keeping a lively pace."
|
|
102217
|
+
}
|
|
102218
|
+
}
|
|
102219
|
+
}
|
|
102139
102220
|
},
|
|
102140
102221
|
callConfig: {
|
|
102141
102222
|
title: "Voice call",
|
|
@@ -102385,6 +102466,18 @@ var ltiTabLabels$3 = {
|
|
|
102385
102466
|
createButton: "Create LTI Link",
|
|
102386
102467
|
empty: "No LTI link yet for this agent.",
|
|
102387
102468
|
targetUriColumn: "TARGET LINK URI",
|
|
102469
|
+
statusColumn: "STATUS",
|
|
102470
|
+
status: {
|
|
102471
|
+
pending: "Pending",
|
|
102472
|
+
building: "Building",
|
|
102473
|
+
ready: "Ready",
|
|
102474
|
+
failed: "Failed"
|
|
102475
|
+
},
|
|
102476
|
+
failedHint: "Something went wrong while creating this link. Retry deletes it and creates it again.",
|
|
102477
|
+
refresh: "Refresh",
|
|
102478
|
+
retry: "Retry",
|
|
102479
|
+
retrying: "Retrying…",
|
|
102480
|
+
retryAria: "Retry {name}",
|
|
102388
102481
|
editAria: "Edit {name}",
|
|
102389
102482
|
copyTargetUri: "Copy target link URI",
|
|
102390
102483
|
modal: {
|
|
@@ -102492,6 +102585,7 @@ var ltiTabLabels$3 = {
|
|
|
102492
102585
|
},
|
|
102493
102586
|
toasts: {
|
|
102494
102587
|
linkCreated: "LTI link created successfully",
|
|
102588
|
+
linkCreationStarted: "LTI link creation started — this can take a few minutes",
|
|
102495
102589
|
linkUpdated: "LTI link updated successfully",
|
|
102496
102590
|
linkDeleted: "LTI link deleted successfully",
|
|
102497
102591
|
linkError: "Something went wrong with the LTI link",
|
|
@@ -103298,6 +103392,41 @@ var analyticsUsePlatformAuditLabels$3 = {
|
|
|
103298
103392
|
actionDelete: "Delete",
|
|
103299
103393
|
actionAccess: "Access"
|
|
103300
103394
|
};
|
|
103395
|
+
var onboardingUserOnboarding$3 = {
|
|
103396
|
+
defaultTitle: "Tell us about yourself",
|
|
103397
|
+
"continue": "Continue",
|
|
103398
|
+
submit: "Submit",
|
|
103399
|
+
back: "Back",
|
|
103400
|
+
saving: "Saving...",
|
|
103401
|
+
selectAnOption: "Select an option",
|
|
103402
|
+
couldNotSaveAnswers: "Could not save your answers. Please try again.",
|
|
103403
|
+
agentStepTitle: "Meet your assistant",
|
|
103404
|
+
agentStepSubtitle: "Ask your assistant anything to get started.",
|
|
103405
|
+
agentUnavailable: "Your assistant cannot be loaded right now. You can finish onboarding and come back to it later.",
|
|
103406
|
+
noOnboardingTitle: "Nothing to set up yet",
|
|
103407
|
+
noOnboardingBody: "Your organization has not set up an onboarding experience. Nothing is required from you — head on in.",
|
|
103408
|
+
continueToApp: "Continue"
|
|
103409
|
+
};
|
|
103410
|
+
var profileOnboardingTab$3 = {
|
|
103411
|
+
editorTitle: "User onboarding agent",
|
|
103412
|
+
editorDescription: "The agent every new member of this platform meets when they arrive.",
|
|
103413
|
+
loadError: "Could not load the onboarding settings.",
|
|
103414
|
+
save: "Save changes",
|
|
103415
|
+
saving: "Saving...",
|
|
103416
|
+
savedToast: "Onboarding agent saved",
|
|
103417
|
+
saveFailedToast: "Could not save the onboarding agent",
|
|
103418
|
+
unsavedChanges: "Unsaved changes",
|
|
103419
|
+
agentLabel: "Agent",
|
|
103420
|
+
searchAgents: "Search agents",
|
|
103421
|
+
loadingAgents: "Loading agents...",
|
|
103422
|
+
noAgents: "No agents found.",
|
|
103423
|
+
clearAgent: "Clear the selected agent",
|
|
103424
|
+
agentTitleLabel: "Heading",
|
|
103425
|
+
agentTitlePlaceholder: "Meet your assistant",
|
|
103426
|
+
agentDescriptionLabel: "Sub-heading",
|
|
103427
|
+
agentDescriptionPlaceholder: "Ask your assistant anything to get started.",
|
|
103428
|
+
noAgentHint: "With no agent set, members skip onboarding entirely."
|
|
103429
|
+
};
|
|
103301
103430
|
var en = {
|
|
103302
103431
|
accessTabAddAccess: accessTabAddAccess$3,
|
|
103303
103432
|
accessTabLabels: accessTabLabels$3,
|
|
@@ -103425,6 +103554,10 @@ var en = {
|
|
|
103425
103554
|
mcpTabConnectorManagementContent: mcpTabConnectorManagementContent$3,
|
|
103426
103555
|
memoryAddMemoryDialog: memoryAddMemoryDialog$3,
|
|
103427
103556
|
memoryMemoryTab: memoryMemoryTab$3,
|
|
103557
|
+
memoryAdminTab: memoryAdminTab$3,
|
|
103558
|
+
memoryAdminUserMemoriesModal: memoryAdminUserMemoriesModal$3,
|
|
103559
|
+
memoryEditMemoryDialog: memoryEditMemoryDialog$3,
|
|
103560
|
+
memoryAdminAgentMemoriesModal: memoryAdminAgentMemoriesModal$3,
|
|
103428
103561
|
memoryTabAddMemoryModal: memoryTabAddMemoryModal$3,
|
|
103429
103562
|
memoryTabDeleteMemoryModal: memoryTabDeleteMemoryModal$3,
|
|
103430
103563
|
memoryTabEditMemoryModal: memoryTabEditMemoryModal$3,
|
|
@@ -103567,7 +103700,9 @@ var en = {
|
|
|
103567
103700
|
analyticsAnalyticsPlatformAuditLog: analyticsAnalyticsPlatformAuditLog$3,
|
|
103568
103701
|
analyticsPlatformAuditLogDetailSheet: analyticsPlatformAuditLogDetailSheet$3,
|
|
103569
103702
|
analyticsAuditLogJsonView: analyticsAuditLogJsonView$3,
|
|
103570
|
-
analyticsUsePlatformAuditLabels: analyticsUsePlatformAuditLabels$3
|
|
103703
|
+
analyticsUsePlatformAuditLabels: analyticsUsePlatformAuditLabels$3,
|
|
103704
|
+
onboardingUserOnboarding: onboardingUserOnboarding$3,
|
|
103705
|
+
profileOnboardingTab: profileOnboardingTab$3
|
|
103571
103706
|
};
|
|
103572
103707
|
|
|
103573
103708
|
var accessTabAddAccess$2 = {
|
|
@@ -106608,7 +106743,63 @@ var memoryMemoryTab$2 = {
|
|
|
106608
106743
|
noMemoriesYet: "Aucun souvenir pour l'instant. L'IA commencera à mémoriser des informations de vos conversations, ou vous pouvez ajouter des souvenirs manuellement.",
|
|
106609
106744
|
noMemoriesYetPreview: "Aucun souvenir pour l'instant. L'IA n'a enregistré aucune information des conversations de cet utilisateur.",
|
|
106610
106745
|
stateEnabled: "activée",
|
|
106611
|
-
stateDisabled: "désactivée"
|
|
106746
|
+
stateDisabled: "désactivée",
|
|
106747
|
+
actionsMenuAriaLabel: "Actions de la mémoire : {excerpt}",
|
|
106748
|
+
editAction: "Modifier",
|
|
106749
|
+
deleteAction: "Supprimer"
|
|
106750
|
+
};
|
|
106751
|
+
var memoryAdminTab$2 = {
|
|
106752
|
+
tabsAriaLabel: "Sections de gestion des mémoires",
|
|
106753
|
+
tabGlobalMemories: "Global",
|
|
106754
|
+
tabAgentMemories: "Agent",
|
|
106755
|
+
featureDisabled: "La fonctionnalité de mémoire n'est pas activée pour cette plateforme.",
|
|
106756
|
+
searchUsersPlaceholder: "Rechercher des utilisateurs",
|
|
106757
|
+
searchUsersAriaLabel: "Rechercher des utilisateurs",
|
|
106758
|
+
nameColumn: "Nom",
|
|
106759
|
+
usernameColumn: "Nom d'utilisateur",
|
|
106760
|
+
emailColumn: "E-mail",
|
|
106761
|
+
agentColumn: "Agent",
|
|
106762
|
+
descriptionColumn: "Description",
|
|
106763
|
+
actionsColumn: "Actions",
|
|
106764
|
+
loading: "Chargement...",
|
|
106765
|
+
noUsersFound: "Aucun utilisateur trouvé",
|
|
106766
|
+
noAgentsFound: "Aucun agent trouvé",
|
|
106767
|
+
forbidden: "Vous n'avez pas l'autorisation de voir ce contenu.",
|
|
106768
|
+
viewMemoriesAriaLabel: "Voir les mémoires de {name}",
|
|
106769
|
+
filter: {
|
|
106770
|
+
placeholder: "Rechercher des agents…",
|
|
106771
|
+
typeToSearch: "Saisissez au moins 2 caractères pour rechercher",
|
|
106772
|
+
searching: "Recherche d'agents…",
|
|
106773
|
+
noResults: "Aucun agent trouvé",
|
|
106774
|
+
clear: "Effacer le filtre d'agent"
|
|
106775
|
+
}
|
|
106776
|
+
};
|
|
106777
|
+
var memoryAdminUserMemoriesModal$2 = {
|
|
106778
|
+
title: "Mémoires globales",
|
|
106779
|
+
description: "Voir et gérer les mémoires globales de cet utilisateur.",
|
|
106780
|
+
addMemoryButton: "Ajouter une mémoire",
|
|
106781
|
+
noMemories: "Aucune mémoire enregistrée pour cet utilisateur pour l'instant.",
|
|
106782
|
+
forbidden: "Vous n'avez pas l'autorisation de voir les mémoires de cet utilisateur.",
|
|
106783
|
+
failedToLoad: "Échec du chargement des mémoires.",
|
|
106784
|
+
memoryDeleted: "Mémoire supprimée",
|
|
106785
|
+
failedToDeleteMemory: "Échec de la suppression de la mémoire"
|
|
106786
|
+
};
|
|
106787
|
+
var memoryEditMemoryDialog$2 = {
|
|
106788
|
+
dialogTitle: "Modifier la mémoire",
|
|
106789
|
+
dialogDescription: "Mettez à jour le contenu de cette mémoire",
|
|
106790
|
+
contentLabel: "Contenu de la mémoire",
|
|
106791
|
+
validationMinLength: "Le contenu de la mémoire doit comporter au moins 10 caractères",
|
|
106792
|
+
inlineMinLength: "Doit comporter au moins 10 caractères",
|
|
106793
|
+
toastUpdated: "Mémoire mise à jour",
|
|
106794
|
+
toastDuplicate: "Cette mémoire existe déjà",
|
|
106795
|
+
toastForbidden: "Vous n'avez pas l'autorisation de mettre à jour cette mémoire",
|
|
106796
|
+
toastFailed: "Échec de la mise à jour de la mémoire",
|
|
106797
|
+
cancelButton: "Annuler",
|
|
106798
|
+
savingButton: "Enregistrement...",
|
|
106799
|
+
saveButton: "Enregistrer la mémoire"
|
|
106800
|
+
};
|
|
106801
|
+
var memoryAdminAgentMemoriesModal$2 = {
|
|
106802
|
+
description: "Voir et gérer les mémoires enregistrées pour cet agent."
|
|
106612
106803
|
};
|
|
106613
106804
|
var memoryTabAddMemoryModal$2 = {
|
|
106614
106805
|
addMemory: "Ajouter un souvenir",
|
|
@@ -107196,7 +107387,9 @@ var profileAccount$2 = {
|
|
|
107196
107387
|
descSocial: "Connecter et gérer vos comptes de réseaux sociaux.",
|
|
107197
107388
|
descSecurity: "Mettre à jour vos paramètres de sécurité et votre mot de passe.",
|
|
107198
107389
|
tabBenchmarks: "Benchmarks",
|
|
107199
|
-
descBenchmarks: "Créez des suites de benchmarks d'entrées de test pour évaluer les agents."
|
|
107390
|
+
descBenchmarks: "Créez des suites de benchmarks d'entrées de test pour évaluer les agents.",
|
|
107391
|
+
tabMemory: "Mémoire",
|
|
107392
|
+
descMemory: "Gérez les mémoires globales des utilisateurs et les mémoires des agents."
|
|
107200
107393
|
};
|
|
107201
107394
|
var profileAddCreditsModal$2 = {
|
|
107202
107395
|
title: "Ajouter des crédits",
|
|
@@ -107230,7 +107423,9 @@ var profileAdmin$2 = {
|
|
|
107230
107423
|
teamsDescription: "Une équipe est un ensemble organisé d'utilisateurs que vous pouvez partager avec d'autres — par exemple, accorder à un autre utilisateur la permission de consulter les analyses de l'équipe ou de lui envoyer des notifications.",
|
|
107231
107424
|
alertsDescription: "Une alerte associe une équipe d'utilisateurs surveillés à un ou plusieurs observateurs qui sont notifiés lorsque des événements surveillés se produisent pour un utilisateur observé. Chaque observateur s'abonne à son propre sous-ensemble d'événements.",
|
|
107232
107425
|
applicationsTab: "Candidatures",
|
|
107233
|
-
applicationsTabDescription: "Consultez les candidatures à votre organisation et modifiez les questions auxquelles les candidats répondent lorsqu'ils postulent."
|
|
107426
|
+
applicationsTabDescription: "Consultez les candidatures à votre organisation et modifiez les questions auxquelles les candidats répondent lorsqu'ils postulent.",
|
|
107427
|
+
onboardingTab: "Intégration",
|
|
107428
|
+
onboardingTabDescription: "Choisissez l'agent que rencontre chaque nouveau membre de cette plateforme à son arrivée, ainsi que sa présentation."
|
|
107234
107429
|
};
|
|
107235
107430
|
var profileAutoRechargeModal$2 = {
|
|
107236
107431
|
title: "Gérer l'utilisation",
|
|
@@ -109044,7 +109239,28 @@ var voiceTabLabels$2 = {
|
|
|
109044
109239
|
stop: "Arrêter la voix {voiceName}"
|
|
109045
109240
|
},
|
|
109046
109241
|
saveButton: "Enregistrer la voix",
|
|
109047
|
-
savingButton: "Enregistrement…"
|
|
109242
|
+
savingButton: "Enregistrement…",
|
|
109243
|
+
instructions: {
|
|
109244
|
+
label: "Instructions vocales",
|
|
109245
|
+
tooltip: "Décrivez comment l'agent doit sonner lorsqu'il parle : ton, rythme, émotion, accent, énergie. Cela modifie la manière de le dire, pas le contenu. Exemple : « Parle lentement, d'un ton chaleureux et encourageant, comme un tuteur patient. »",
|
|
109246
|
+
placeholder: "p. ex. Parle lentement, d'un ton chaleureux et encourageant, comme un tuteur patient.",
|
|
109247
|
+
helpText: "Fonctionne avec les voix OpenAI (envoyé comme instructions de parole) et Google (comme prompt de synthèse) ; les autres voix l'ignorent. Laissez vide pour la diction par défaut du fournisseur — avec des instructions, OpenAI utilise un modèle vocal plus coûteux compatible avec les instructions.",
|
|
109248
|
+
presetsLabel: "Exemples",
|
|
109249
|
+
presets: {
|
|
109250
|
+
warm: {
|
|
109251
|
+
label: "Chaleureux et encourageant",
|
|
109252
|
+
text: "Parle lentement, d'un ton chaleureux et encourageant, comme un tuteur patient."
|
|
109253
|
+
},
|
|
109254
|
+
calm: {
|
|
109255
|
+
label: "Calme et posé",
|
|
109256
|
+
text: "Parle d'une voix calme et posée, à un rythme régulier et sans hâte."
|
|
109257
|
+
},
|
|
109258
|
+
energetic: {
|
|
109259
|
+
label: "Énergique et enjoué",
|
|
109260
|
+
text: "Parle avec énergie et enthousiasme, en gardant un rythme entraînant."
|
|
109261
|
+
}
|
|
109262
|
+
}
|
|
109263
|
+
}
|
|
109048
109264
|
},
|
|
109049
109265
|
callConfig: {
|
|
109050
109266
|
title: "Appel vocal",
|
|
@@ -109294,6 +109510,18 @@ var ltiTabLabels$2 = {
|
|
|
109294
109510
|
createButton: "Créer un lien LTI",
|
|
109295
109511
|
empty: "Aucun lien LTI pour cet agent pour le moment.",
|
|
109296
109512
|
targetUriColumn: "URI DU LIEN CIBLE",
|
|
109513
|
+
statusColumn: "STATUT",
|
|
109514
|
+
status: {
|
|
109515
|
+
pending: "En attente",
|
|
109516
|
+
building: "Création",
|
|
109517
|
+
ready: "Prêt",
|
|
109518
|
+
failed: "Échec"
|
|
109519
|
+
},
|
|
109520
|
+
failedHint: "Une erreur s'est produite lors de la création de ce lien. Réessayer le supprime et le recrée.",
|
|
109521
|
+
refresh: "Actualiser",
|
|
109522
|
+
retry: "Réessayer",
|
|
109523
|
+
retrying: "Nouvelle tentative…",
|
|
109524
|
+
retryAria: "Réessayer {name}",
|
|
109297
109525
|
editAria: "Modifier {name}",
|
|
109298
109526
|
copyTargetUri: "Copier l'URI du lien cible",
|
|
109299
109527
|
modal: {
|
|
@@ -109401,6 +109629,7 @@ var ltiTabLabels$2 = {
|
|
|
109401
109629
|
},
|
|
109402
109630
|
toasts: {
|
|
109403
109631
|
linkCreated: "Lien LTI créé avec succès",
|
|
109632
|
+
linkCreationStarted: "Création du lien LTI lancée — cela peut prendre quelques minutes",
|
|
109404
109633
|
linkUpdated: "Lien LTI mis à jour avec succès",
|
|
109405
109634
|
linkDeleted: "Lien LTI supprimé avec succès",
|
|
109406
109635
|
linkError: "Un problème est survenu avec le lien LTI",
|
|
@@ -110041,6 +110270,41 @@ var analyticsUsePlatformAuditLabels$2 = {
|
|
|
110041
110270
|
actionDelete: "Supprimer",
|
|
110042
110271
|
actionAccess: "Accéder"
|
|
110043
110272
|
};
|
|
110273
|
+
var onboardingUserOnboarding$2 = {
|
|
110274
|
+
defaultTitle: "Parlez-nous de vous",
|
|
110275
|
+
"continue": "Continuer",
|
|
110276
|
+
submit: "Envoyer",
|
|
110277
|
+
back: "Retour",
|
|
110278
|
+
saving: "Enregistrement...",
|
|
110279
|
+
selectAnOption: "Sélectionnez une option",
|
|
110280
|
+
couldNotSaveAnswers: "Impossible d'enregistrer vos réponses. Veuillez réessayer.",
|
|
110281
|
+
agentStepTitle: "Rencontrez votre assistant",
|
|
110282
|
+
agentStepSubtitle: "Posez toutes vos questions à votre assistant pour commencer.",
|
|
110283
|
+
agentUnavailable: "Votre assistant ne peut pas être chargé pour le moment. Vous pouvez terminer l'intégration et y revenir plus tard.",
|
|
110284
|
+
noOnboardingTitle: "Rien à configurer pour l'instant",
|
|
110285
|
+
noOnboardingBody: "Votre organisation n'a pas encore configuré de parcours d'intégration. Rien ne vous est demandé — vous pouvez continuer.",
|
|
110286
|
+
continueToApp: "Continuer"
|
|
110287
|
+
};
|
|
110288
|
+
var profileOnboardingTab$2 = {
|
|
110289
|
+
editorTitle: "Agent d'intégration des utilisateurs",
|
|
110290
|
+
editorDescription: "L'agent que rencontre chaque nouveau membre de cette plateforme à son arrivée.",
|
|
110291
|
+
loadError: "Impossible de charger les paramètres d'intégration.",
|
|
110292
|
+
save: "Enregistrer les modifications",
|
|
110293
|
+
saving: "Enregistrement...",
|
|
110294
|
+
savedToast: "Agent d'intégration enregistré",
|
|
110295
|
+
saveFailedToast: "Impossible d'enregistrer l'agent d'intégration",
|
|
110296
|
+
unsavedChanges: "Modifications non enregistrées",
|
|
110297
|
+
agentLabel: "Agent",
|
|
110298
|
+
searchAgents: "Rechercher des agents",
|
|
110299
|
+
loadingAgents: "Chargement des agents...",
|
|
110300
|
+
noAgents: "Aucun agent trouvé.",
|
|
110301
|
+
clearAgent: "Effacer l'agent sélectionné",
|
|
110302
|
+
agentTitleLabel: "Titre",
|
|
110303
|
+
agentTitlePlaceholder: "Rencontrez votre assistant",
|
|
110304
|
+
agentDescriptionLabel: "Sous-titre",
|
|
110305
|
+
agentDescriptionPlaceholder: "Posez toutes vos questions à votre assistant pour commencer.",
|
|
110306
|
+
noAgentHint: "Sans agent défini, les membres ignorent complètement l'intégration."
|
|
110307
|
+
};
|
|
110044
110308
|
var fr = {
|
|
110045
110309
|
accessTabAddAccess: accessTabAddAccess$2,
|
|
110046
110310
|
accessTabLabels: accessTabLabels$2,
|
|
@@ -110169,6 +110433,10 @@ var fr = {
|
|
|
110169
110433
|
mcpTabConnectorManagementContent: mcpTabConnectorManagementContent$2,
|
|
110170
110434
|
memoryAddMemoryDialog: memoryAddMemoryDialog$2,
|
|
110171
110435
|
memoryMemoryTab: memoryMemoryTab$2,
|
|
110436
|
+
memoryAdminTab: memoryAdminTab$2,
|
|
110437
|
+
memoryAdminUserMemoriesModal: memoryAdminUserMemoriesModal$2,
|
|
110438
|
+
memoryEditMemoryDialog: memoryEditMemoryDialog$2,
|
|
110439
|
+
memoryAdminAgentMemoriesModal: memoryAdminAgentMemoriesModal$2,
|
|
110172
110440
|
memoryTabAddMemoryModal: memoryTabAddMemoryModal$2,
|
|
110173
110441
|
memoryTabDeleteMemoryModal: memoryTabDeleteMemoryModal$2,
|
|
110174
110442
|
memoryTabEditMemoryModal: memoryTabEditMemoryModal$2,
|
|
@@ -110310,7 +110578,9 @@ var fr = {
|
|
|
110310
110578
|
analyticsAnalyticsPlatformAuditLog: analyticsAnalyticsPlatformAuditLog$2,
|
|
110311
110579
|
analyticsPlatformAuditLogDetailSheet: analyticsPlatformAuditLogDetailSheet$2,
|
|
110312
110580
|
analyticsAuditLogJsonView: analyticsAuditLogJsonView$2,
|
|
110313
|
-
analyticsUsePlatformAuditLabels: analyticsUsePlatformAuditLabels$2
|
|
110581
|
+
analyticsUsePlatformAuditLabels: analyticsUsePlatformAuditLabels$2,
|
|
110582
|
+
onboardingUserOnboarding: onboardingUserOnboarding$2,
|
|
110583
|
+
profileOnboardingTab: profileOnboardingTab$2
|
|
110314
110584
|
};
|
|
110315
110585
|
|
|
110316
110586
|
var accessTabAddAccess$1 = {
|
|
@@ -113351,7 +113621,63 @@ var memoryMemoryTab$1 = {
|
|
|
113351
113621
|
noMemoriesYet: "Aún no hay memorias. La IA comenzará a recordar información de sus conversaciones, o puede añadir memorias manualmente.",
|
|
113352
113622
|
noMemoriesYetPreview: "Aún no hay memorias. La IA no ha registrado información de las conversaciones de este usuario.",
|
|
113353
113623
|
stateEnabled: "habilitada",
|
|
113354
|
-
stateDisabled: "deshabilitada"
|
|
113624
|
+
stateDisabled: "deshabilitada",
|
|
113625
|
+
actionsMenuAriaLabel: "Acciones de memoria: {excerpt}",
|
|
113626
|
+
editAction: "Editar",
|
|
113627
|
+
deleteAction: "Eliminar"
|
|
113628
|
+
};
|
|
113629
|
+
var memoryAdminTab$1 = {
|
|
113630
|
+
tabsAriaLabel: "Secciones de gestión de memorias",
|
|
113631
|
+
tabGlobalMemories: "Global",
|
|
113632
|
+
tabAgentMemories: "Agente",
|
|
113633
|
+
featureDisabled: "La función de memoria no está habilitada para esta plataforma.",
|
|
113634
|
+
searchUsersPlaceholder: "Buscar usuarios",
|
|
113635
|
+
searchUsersAriaLabel: "Buscar usuarios",
|
|
113636
|
+
nameColumn: "Nombre",
|
|
113637
|
+
usernameColumn: "Nombre de usuario",
|
|
113638
|
+
emailColumn: "Correo electrónico",
|
|
113639
|
+
agentColumn: "Agente",
|
|
113640
|
+
descriptionColumn: "Descripción",
|
|
113641
|
+
actionsColumn: "Acciones",
|
|
113642
|
+
loading: "Cargando...",
|
|
113643
|
+
noUsersFound: "No se encontraron usuarios",
|
|
113644
|
+
noAgentsFound: "No se encontraron agentes",
|
|
113645
|
+
forbidden: "No tienes permiso para ver este contenido.",
|
|
113646
|
+
viewMemoriesAriaLabel: "Ver memorias de {name}",
|
|
113647
|
+
filter: {
|
|
113648
|
+
placeholder: "Buscar agentes…",
|
|
113649
|
+
typeToSearch: "Escribe al menos 2 caracteres para buscar",
|
|
113650
|
+
searching: "Buscando agentes…",
|
|
113651
|
+
noResults: "No se encontraron agentes",
|
|
113652
|
+
clear: "Quitar el filtro de agente"
|
|
113653
|
+
}
|
|
113654
|
+
};
|
|
113655
|
+
var memoryAdminUserMemoriesModal$1 = {
|
|
113656
|
+
title: "Memorias globales",
|
|
113657
|
+
description: "Ver y gestionar las memorias globales de este usuario.",
|
|
113658
|
+
addMemoryButton: "Agregar memoria",
|
|
113659
|
+
noMemories: "Este usuario aún no tiene memorias guardadas.",
|
|
113660
|
+
forbidden: "No tienes permiso para ver las memorias de este usuario.",
|
|
113661
|
+
failedToLoad: "Error al cargar las memorias.",
|
|
113662
|
+
memoryDeleted: "Memoria eliminada",
|
|
113663
|
+
failedToDeleteMemory: "Error al eliminar la memoria"
|
|
113664
|
+
};
|
|
113665
|
+
var memoryEditMemoryDialog$1 = {
|
|
113666
|
+
dialogTitle: "Editar memoria",
|
|
113667
|
+
dialogDescription: "Actualiza el contenido de esta memoria",
|
|
113668
|
+
contentLabel: "Contenido de la memoria",
|
|
113669
|
+
validationMinLength: "El contenido de la memoria debe tener al menos 10 caracteres",
|
|
113670
|
+
inlineMinLength: "Debe tener al menos 10 caracteres",
|
|
113671
|
+
toastUpdated: "Memoria actualizada",
|
|
113672
|
+
toastDuplicate: "Esta memoria ya existe",
|
|
113673
|
+
toastForbidden: "No tienes permiso para actualizar esta memoria",
|
|
113674
|
+
toastFailed: "Error al actualizar la memoria",
|
|
113675
|
+
cancelButton: "Cancelar",
|
|
113676
|
+
savingButton: "Guardando...",
|
|
113677
|
+
saveButton: "Guardar memoria"
|
|
113678
|
+
};
|
|
113679
|
+
var memoryAdminAgentMemoriesModal$1 = {
|
|
113680
|
+
description: "Ver y gestionar las memorias guardadas para este agente."
|
|
113355
113681
|
};
|
|
113356
113682
|
var memoryTabAddMemoryModal$1 = {
|
|
113357
113683
|
addMemory: "Agregar memoria",
|
|
@@ -113939,7 +114265,9 @@ var profileAccount$1 = {
|
|
|
113939
114265
|
descSocial: "Conectar y gestionar sus cuentas de redes sociales.",
|
|
113940
114266
|
descSecurity: "Actualizar su configuración de seguridad y contraseña.",
|
|
113941
114267
|
tabBenchmarks: "Benchmarks",
|
|
113942
|
-
descBenchmarks: "Cree suites de benchmarks con entradas de prueba para evaluar agentes."
|
|
114268
|
+
descBenchmarks: "Cree suites de benchmarks con entradas de prueba para evaluar agentes.",
|
|
114269
|
+
tabMemory: "Memoria",
|
|
114270
|
+
descMemory: "Gestiona las memorias globales de los usuarios y las memorias de los agentes."
|
|
113943
114271
|
};
|
|
113944
114272
|
var profileAddCreditsModal$1 = {
|
|
113945
114273
|
title: "Agregar créditos",
|
|
@@ -113973,7 +114301,9 @@ var profileAdmin$1 = {
|
|
|
113973
114301
|
teamsDescription: "Un equipo es un conjunto organizado de usuarios que puedes compartir con otros — por ejemplo, otorgar a otro usuario permiso para ver las analíticas del equipo o enviarles notificaciones.",
|
|
113974
114302
|
alertsDescription: "Una alerta empareja un equipo de usuarios vigilados con uno o más observadores que reciben notificaciones cuando ocurren eventos monitoreados para un usuario vigilado. Cada observador se suscribe a su propio subconjunto de eventos.",
|
|
113975
114303
|
applicationsTab: "Solicitudes",
|
|
113976
|
-
applicationsTabDescription: "Revise las solicitudes a su organización y edite las preguntas que responden los solicitantes cuando postulan."
|
|
114304
|
+
applicationsTabDescription: "Revise las solicitudes a su organización y edite las preguntas que responden los solicitantes cuando postulan.",
|
|
114305
|
+
onboardingTab: "Incorporación",
|
|
114306
|
+
onboardingTabDescription: "Elija el agente que conoce cada nuevo miembro de esta plataforma al llegar y cómo se presenta."
|
|
113977
114307
|
};
|
|
113978
114308
|
var profileAutoRechargeModal$1 = {
|
|
113979
114309
|
title: "Gestionar uso",
|
|
@@ -115787,7 +116117,28 @@ var voiceTabLabels$1 = {
|
|
|
115787
116117
|
stop: "Detener la voz {voiceName}"
|
|
115788
116118
|
},
|
|
115789
116119
|
saveButton: "Guardar voz",
|
|
115790
|
-
savingButton: "Guardando…"
|
|
116120
|
+
savingButton: "Guardando…",
|
|
116121
|
+
instructions: {
|
|
116122
|
+
label: "Instrucciones de voz",
|
|
116123
|
+
tooltip: "Describe cómo debe sonar el agente al hablar: tono, ritmo, emoción, acento, energía. Cambia la forma de decirlo, no lo que dice. Ejemplo: \"Habla despacio, con un tono cálido y alentador, como un tutor paciente.\"",
|
|
116124
|
+
placeholder: "p. ej., Habla despacio, con un tono cálido y alentador, como un tutor paciente.",
|
|
116125
|
+
helpText: "Funciona con las voces de OpenAI (se envía como instrucciones de habla) y de Google (como prompt de síntesis); las demás voces lo ignoran. Déjalo en blanco para usar la entrega predeterminada del proveedor: con instrucciones, OpenAI usa un modelo de voz más caro compatible con instrucciones.",
|
|
116126
|
+
presetsLabel: "Ejemplos",
|
|
116127
|
+
presets: {
|
|
116128
|
+
warm: {
|
|
116129
|
+
label: "Cálido y alentador",
|
|
116130
|
+
text: "Habla despacio, con un tono cálido y alentador, como un tutor paciente."
|
|
116131
|
+
},
|
|
116132
|
+
calm: {
|
|
116133
|
+
label: "Tranquilo y pausado",
|
|
116134
|
+
text: "Habla con voz tranquila y pausada, a un ritmo constante y sin prisa."
|
|
116135
|
+
},
|
|
116136
|
+
energetic: {
|
|
116137
|
+
label: "Enérgico y animado",
|
|
116138
|
+
text: "Habla con energía y entusiasmo, manteniendo un ritmo animado."
|
|
116139
|
+
}
|
|
116140
|
+
}
|
|
116141
|
+
}
|
|
115791
116142
|
},
|
|
115792
116143
|
callConfig: {
|
|
115793
116144
|
title: "Llamada de voz",
|
|
@@ -116037,6 +116388,18 @@ var ltiTabLabels$1 = {
|
|
|
116037
116388
|
createButton: "Crear enlace LTI",
|
|
116038
116389
|
empty: "Aún no hay ningún enlace LTI para este agente.",
|
|
116039
116390
|
targetUriColumn: "URI DE ENLACE DESTINO",
|
|
116391
|
+
statusColumn: "ESTADO",
|
|
116392
|
+
status: {
|
|
116393
|
+
pending: "Pendiente",
|
|
116394
|
+
building: "Creando",
|
|
116395
|
+
ready: "Listo",
|
|
116396
|
+
failed: "Fallido"
|
|
116397
|
+
},
|
|
116398
|
+
failedHint: "Algo salió mal al crear este enlace. Reintentar lo elimina y lo crea de nuevo.",
|
|
116399
|
+
refresh: "Actualizar",
|
|
116400
|
+
retry: "Reintentar",
|
|
116401
|
+
retrying: "Reintentando…",
|
|
116402
|
+
retryAria: "Reintentar {name}",
|
|
116040
116403
|
editAria: "Editar {name}",
|
|
116041
116404
|
copyTargetUri: "Copiar URI de enlace destino",
|
|
116042
116405
|
modal: {
|
|
@@ -116144,6 +116507,7 @@ var ltiTabLabels$1 = {
|
|
|
116144
116507
|
},
|
|
116145
116508
|
toasts: {
|
|
116146
116509
|
linkCreated: "Enlace LTI creado correctamente",
|
|
116510
|
+
linkCreationStarted: "Creación del enlace LTI iniciada — puede tardar unos minutos",
|
|
116147
116511
|
linkUpdated: "Enlace LTI actualizado correctamente",
|
|
116148
116512
|
linkDeleted: "Enlace LTI eliminado correctamente",
|
|
116149
116513
|
linkError: "Algo salió mal con el enlace LTI",
|
|
@@ -116784,6 +117148,41 @@ var analyticsUsePlatformAuditLabels$1 = {
|
|
|
116784
117148
|
actionDelete: "Eliminar",
|
|
116785
117149
|
actionAccess: "Acceder"
|
|
116786
117150
|
};
|
|
117151
|
+
var onboardingUserOnboarding$1 = {
|
|
117152
|
+
defaultTitle: "Cuéntenos sobre usted",
|
|
117153
|
+
"continue": "Continuar",
|
|
117154
|
+
submit: "Enviar",
|
|
117155
|
+
back: "Atrás",
|
|
117156
|
+
saving: "Guardando...",
|
|
117157
|
+
selectAnOption: "Seleccione una opción",
|
|
117158
|
+
couldNotSaveAnswers: "No se pudieron guardar sus respuestas. Inténtelo de nuevo.",
|
|
117159
|
+
agentStepTitle: "Conozca a su asistente",
|
|
117160
|
+
agentStepSubtitle: "Pregúntele lo que quiera a su asistente para empezar.",
|
|
117161
|
+
agentUnavailable: "Su asistente no se puede cargar en este momento. Puede terminar la incorporación y volver más tarde.",
|
|
117162
|
+
noOnboardingTitle: "Todavía no hay nada que configurar",
|
|
117163
|
+
noOnboardingBody: "Su organización aún no ha configurado una experiencia de incorporación. No se le pide nada — puede continuar.",
|
|
117164
|
+
continueToApp: "Continuar"
|
|
117165
|
+
};
|
|
117166
|
+
var profileOnboardingTab$1 = {
|
|
117167
|
+
editorTitle: "Agente de incorporación de usuarios",
|
|
117168
|
+
editorDescription: "El agente que conoce cada nuevo miembro de esta plataforma al llegar.",
|
|
117169
|
+
loadError: "No se pudo cargar la configuración de incorporación.",
|
|
117170
|
+
save: "Guardar cambios",
|
|
117171
|
+
saving: "Guardando...",
|
|
117172
|
+
savedToast: "Agente de incorporación guardado",
|
|
117173
|
+
saveFailedToast: "No se pudo guardar el agente de incorporación",
|
|
117174
|
+
unsavedChanges: "Cambios sin guardar",
|
|
117175
|
+
agentLabel: "Agente",
|
|
117176
|
+
searchAgents: "Buscar agentes",
|
|
117177
|
+
loadingAgents: "Cargando agentes...",
|
|
117178
|
+
noAgents: "No se encontraron agentes.",
|
|
117179
|
+
clearAgent: "Quitar el agente seleccionado",
|
|
117180
|
+
agentTitleLabel: "Encabezado",
|
|
117181
|
+
agentTitlePlaceholder: "Conozca a su asistente",
|
|
117182
|
+
agentDescriptionLabel: "Subtítulo",
|
|
117183
|
+
agentDescriptionPlaceholder: "Pregúntele lo que quiera a su asistente para empezar.",
|
|
117184
|
+
noAgentHint: "Sin un agente definido, los miembros omiten por completo la incorporación."
|
|
117185
|
+
};
|
|
116787
117186
|
var es = {
|
|
116788
117187
|
accessTabAddAccess: accessTabAddAccess$1,
|
|
116789
117188
|
accessTabLabels: accessTabLabels$1,
|
|
@@ -116912,6 +117311,10 @@ var es = {
|
|
|
116912
117311
|
mcpTabConnectorManagementContent: mcpTabConnectorManagementContent$1,
|
|
116913
117312
|
memoryAddMemoryDialog: memoryAddMemoryDialog$1,
|
|
116914
117313
|
memoryMemoryTab: memoryMemoryTab$1,
|
|
117314
|
+
memoryAdminTab: memoryAdminTab$1,
|
|
117315
|
+
memoryAdminUserMemoriesModal: memoryAdminUserMemoriesModal$1,
|
|
117316
|
+
memoryEditMemoryDialog: memoryEditMemoryDialog$1,
|
|
117317
|
+
memoryAdminAgentMemoriesModal: memoryAdminAgentMemoriesModal$1,
|
|
116915
117318
|
memoryTabAddMemoryModal: memoryTabAddMemoryModal$1,
|
|
116916
117319
|
memoryTabDeleteMemoryModal: memoryTabDeleteMemoryModal$1,
|
|
116917
117320
|
memoryTabEditMemoryModal: memoryTabEditMemoryModal$1,
|
|
@@ -117053,7 +117456,9 @@ var es = {
|
|
|
117053
117456
|
analyticsAnalyticsPlatformAuditLog: analyticsAnalyticsPlatformAuditLog$1,
|
|
117054
117457
|
analyticsPlatformAuditLogDetailSheet: analyticsPlatformAuditLogDetailSheet$1,
|
|
117055
117458
|
analyticsAuditLogJsonView: analyticsAuditLogJsonView$1,
|
|
117056
|
-
analyticsUsePlatformAuditLabels: analyticsUsePlatformAuditLabels$1
|
|
117459
|
+
analyticsUsePlatformAuditLabels: analyticsUsePlatformAuditLabels$1,
|
|
117460
|
+
onboardingUserOnboarding: onboardingUserOnboarding$1,
|
|
117461
|
+
profileOnboardingTab: profileOnboardingTab$1
|
|
117057
117462
|
};
|
|
117058
117463
|
|
|
117059
117464
|
var accessTabAddAccess = {
|
|
@@ -120094,7 +120499,63 @@ var memoryMemoryTab = {
|
|
|
120094
120499
|
noMemoriesYet: "暂无记忆。AI 将开始记住您对话中的信息,或者您也可以手动添加记忆。",
|
|
120095
120500
|
noMemoriesYetPreview: "暂无记忆。AI 尚未记录该用户对话中的任何信息。",
|
|
120096
120501
|
stateEnabled: "已启用",
|
|
120097
|
-
stateDisabled: "已禁用"
|
|
120502
|
+
stateDisabled: "已禁用",
|
|
120503
|
+
actionsMenuAriaLabel: "记忆操作:{excerpt}",
|
|
120504
|
+
editAction: "编辑",
|
|
120505
|
+
deleteAction: "删除"
|
|
120506
|
+
};
|
|
120507
|
+
var memoryAdminTab = {
|
|
120508
|
+
tabsAriaLabel: "记忆管理部分",
|
|
120509
|
+
tabGlobalMemories: "全局",
|
|
120510
|
+
tabAgentMemories: "智能体",
|
|
120511
|
+
featureDisabled: "此平台未启用记忆功能。",
|
|
120512
|
+
searchUsersPlaceholder: "搜索用户",
|
|
120513
|
+
searchUsersAriaLabel: "搜索用户",
|
|
120514
|
+
nameColumn: "姓名",
|
|
120515
|
+
usernameColumn: "用户名",
|
|
120516
|
+
emailColumn: "邮箱",
|
|
120517
|
+
agentColumn: "智能体",
|
|
120518
|
+
descriptionColumn: "描述",
|
|
120519
|
+
actionsColumn: "操作",
|
|
120520
|
+
loading: "加载中...",
|
|
120521
|
+
noUsersFound: "未找到用户",
|
|
120522
|
+
noAgentsFound: "未找到智能体",
|
|
120523
|
+
forbidden: "您没有权限查看此内容。",
|
|
120524
|
+
viewMemoriesAriaLabel: "查看 {name} 的记忆",
|
|
120525
|
+
filter: {
|
|
120526
|
+
placeholder: "搜索智能体…",
|
|
120527
|
+
typeToSearch: "请输入至少 2 个字符进行搜索",
|
|
120528
|
+
searching: "正在搜索智能体…",
|
|
120529
|
+
noResults: "未找到智能体",
|
|
120530
|
+
clear: "清除智能体筛选"
|
|
120531
|
+
}
|
|
120532
|
+
};
|
|
120533
|
+
var memoryAdminUserMemoriesModal = {
|
|
120534
|
+
title: "全局记忆",
|
|
120535
|
+
description: "查看和管理此用户的全局记忆。",
|
|
120536
|
+
addMemoryButton: "添加记忆",
|
|
120537
|
+
noMemories: "此用户尚未保存任何记忆。",
|
|
120538
|
+
forbidden: "您没有权限查看此用户的记忆。",
|
|
120539
|
+
failedToLoad: "加载记忆失败。",
|
|
120540
|
+
memoryDeleted: "记忆已删除",
|
|
120541
|
+
failedToDeleteMemory: "删除记忆失败"
|
|
120542
|
+
};
|
|
120543
|
+
var memoryEditMemoryDialog = {
|
|
120544
|
+
dialogTitle: "编辑记忆",
|
|
120545
|
+
dialogDescription: "更新此记忆的内容",
|
|
120546
|
+
contentLabel: "记忆内容",
|
|
120547
|
+
validationMinLength: "记忆内容至少需要 10 个字符",
|
|
120548
|
+
inlineMinLength: "至少需要 10 个字符",
|
|
120549
|
+
toastUpdated: "记忆已更新",
|
|
120550
|
+
toastDuplicate: "此记忆已存在",
|
|
120551
|
+
toastForbidden: "您没有权限更新此记忆",
|
|
120552
|
+
toastFailed: "更新记忆失败",
|
|
120553
|
+
cancelButton: "取消",
|
|
120554
|
+
savingButton: "保存中...",
|
|
120555
|
+
saveButton: "保存记忆"
|
|
120556
|
+
};
|
|
120557
|
+
var memoryAdminAgentMemoriesModal = {
|
|
120558
|
+
description: "查看和管理为此智能体保存的记忆。"
|
|
120098
120559
|
};
|
|
120099
120560
|
var memoryTabAddMemoryModal = {
|
|
120100
120561
|
addMemory: "添加记忆",
|
|
@@ -120682,7 +121143,9 @@ var profileAccount = {
|
|
|
120682
121143
|
descSocial: "连接和管理您的社交媒体账户。",
|
|
120683
121144
|
descSecurity: "更新您的安全设置和密码。",
|
|
120684
121145
|
tabBenchmarks: "基准测试",
|
|
120685
|
-
descBenchmarks: "构建包含测试输入的基准测试套件,以评估智能体。"
|
|
121146
|
+
descBenchmarks: "构建包含测试输入的基准测试套件,以评估智能体。",
|
|
121147
|
+
tabMemory: "记忆",
|
|
121148
|
+
descMemory: "管理用户的全局记忆和智能体记忆。"
|
|
120686
121149
|
};
|
|
120687
121150
|
var profileAddCreditsModal = {
|
|
120688
121151
|
title: "添加积分",
|
|
@@ -120716,7 +121179,9 @@ var profileAdmin = {
|
|
|
120716
121179
|
teamsDescription: "团队是一组精心筛选的用户,可与他人共享 — 例如,授予另一个用户查看团队分析数据或向其发送通知的权限。",
|
|
120717
121180
|
alertsDescription: "警报将一组被监控用户与一个或多个观察者配对,当被监控用户发生受监控事件时,观察者会收到通知。每位观察者可订阅自己感兴趣的事件子集。",
|
|
120718
121181
|
applicationsTab: "申请",
|
|
120719
|
-
applicationsTabDescription: "查看向贵组织提交的申请,并编辑申请人申请时回答的问题。"
|
|
121182
|
+
applicationsTabDescription: "查看向贵组织提交的申请,并编辑申请人申请时回答的问题。",
|
|
121183
|
+
onboardingTab: "引导",
|
|
121184
|
+
onboardingTabDescription: "选择本平台每位新成员进入时见到的智能体,以及它的介绍文案。"
|
|
120720
121185
|
};
|
|
120721
121186
|
var profileAutoRechargeModal = {
|
|
120722
121187
|
title: "管理用量",
|
|
@@ -122530,7 +122995,28 @@ var voiceTabLabels = {
|
|
|
122530
122995
|
stop: "停止 {voiceName} 声音"
|
|
122531
122996
|
},
|
|
122532
122997
|
saveButton: "保存声音",
|
|
122533
|
-
savingButton: "保存中…"
|
|
122998
|
+
savingButton: "保存中…",
|
|
122999
|
+
instructions: {
|
|
123000
|
+
label: "语音指令",
|
|
123001
|
+
tooltip: "描述智能体说话时应有的声音效果:语气、语速、情感、口音、活力。它只改变表达方式,不改变说话内容。示例:\"语速放慢,用温暖、鼓励的语气,像一位耐心的导师。\"",
|
|
123002
|
+
placeholder: "例如:语速放慢,用温暖、鼓励的语气,像一位耐心的导师。",
|
|
123003
|
+
helpText: "适用于 OpenAI 声音(作为语音指令发送)和 Google 声音(作为合成提示发送);其他声音会忽略它。留空则使用提供商的默认表达方式——填写指令后,OpenAI 会切换到价格更高、支持指令的语音模型。",
|
|
123004
|
+
presetsLabel: "示例",
|
|
123005
|
+
presets: {
|
|
123006
|
+
warm: {
|
|
123007
|
+
label: "温暖鼓励",
|
|
123008
|
+
text: "语速放慢,用温暖、鼓励的语气,像一位耐心的导师。"
|
|
123009
|
+
},
|
|
123010
|
+
calm: {
|
|
123011
|
+
label: "平静从容",
|
|
123012
|
+
text: "用平静、从容的声音说话,保持稳定、不急不缓的节奏。"
|
|
123013
|
+
},
|
|
123014
|
+
energetic: {
|
|
123015
|
+
label: "活力四射",
|
|
123016
|
+
text: "用饱满的活力和热情说话,保持轻快的节奏。"
|
|
123017
|
+
}
|
|
123018
|
+
}
|
|
123019
|
+
}
|
|
122534
123020
|
},
|
|
122535
123021
|
callConfig: {
|
|
122536
123022
|
title: "语音通话",
|
|
@@ -122780,6 +123266,18 @@ var ltiTabLabels = {
|
|
|
122780
123266
|
createButton: "创建 LTI 链接",
|
|
122781
123267
|
empty: "此智能体尚无 LTI 链接。",
|
|
122782
123268
|
targetUriColumn: "目标链接 URI",
|
|
123269
|
+
statusColumn: "状态",
|
|
123270
|
+
status: {
|
|
123271
|
+
pending: "等待中",
|
|
123272
|
+
building: "创建中",
|
|
123273
|
+
ready: "就绪",
|
|
123274
|
+
failed: "失败"
|
|
123275
|
+
},
|
|
123276
|
+
failedHint: "创建此链接时出错。重试将删除该链接并重新创建。",
|
|
123277
|
+
refresh: "刷新",
|
|
123278
|
+
retry: "重试",
|
|
123279
|
+
retrying: "正在重试…",
|
|
123280
|
+
retryAria: "重试 {name}",
|
|
122783
123281
|
editAria: "编辑 {name}",
|
|
122784
123282
|
copyTargetUri: "复制目标链接 URI",
|
|
122785
123283
|
modal: {
|
|
@@ -122887,6 +123385,7 @@ var ltiTabLabels = {
|
|
|
122887
123385
|
},
|
|
122888
123386
|
toasts: {
|
|
122889
123387
|
linkCreated: "LTI 链接创建成功",
|
|
123388
|
+
linkCreationStarted: "LTI 链接创建已开始 — 可能需要几分钟",
|
|
122890
123389
|
linkUpdated: "LTI 链接更新成功",
|
|
122891
123390
|
linkDeleted: "LTI 链接删除成功",
|
|
122892
123391
|
linkError: "LTI 链接出现问题",
|
|
@@ -123527,6 +124026,41 @@ var analyticsUsePlatformAuditLabels = {
|
|
|
123527
124026
|
actionDelete: "删除",
|
|
123528
124027
|
actionAccess: "访问"
|
|
123529
124028
|
};
|
|
124029
|
+
var onboardingUserOnboarding = {
|
|
124030
|
+
defaultTitle: "介绍一下您自己",
|
|
124031
|
+
"continue": "继续",
|
|
124032
|
+
submit: "提交",
|
|
124033
|
+
back: "返回",
|
|
124034
|
+
saving: "保存中…",
|
|
124035
|
+
selectAnOption: "请选择一项",
|
|
124036
|
+
couldNotSaveAnswers: "无法保存您的答案,请重试。",
|
|
124037
|
+
agentStepTitle: "认识您的助手",
|
|
124038
|
+
agentStepSubtitle: "有任何问题都可以问您的助手。",
|
|
124039
|
+
agentUnavailable: "目前无法加载您的助手。您可以先完成引导,稍后再回来查看。",
|
|
124040
|
+
noOnboardingTitle: "暂时没有需要设置的内容",
|
|
124041
|
+
noOnboardingBody: "您的组织尚未配置引导流程。您无需进行任何操作,可以直接进入。",
|
|
124042
|
+
continueToApp: "继续"
|
|
124043
|
+
};
|
|
124044
|
+
var profileOnboardingTab = {
|
|
124045
|
+
editorTitle: "用户引导智能体",
|
|
124046
|
+
editorDescription: "本平台每位新成员进入时见到的智能体。",
|
|
124047
|
+
loadError: "无法加载引导设置。",
|
|
124048
|
+
save: "保存更改",
|
|
124049
|
+
saving: "保存中…",
|
|
124050
|
+
savedToast: "引导智能体已保存",
|
|
124051
|
+
saveFailedToast: "无法保存引导智能体",
|
|
124052
|
+
unsavedChanges: "有未保存的更改",
|
|
124053
|
+
agentLabel: "智能体",
|
|
124054
|
+
searchAgents: "搜索智能体",
|
|
124055
|
+
loadingAgents: "正在加载智能体…",
|
|
124056
|
+
noAgents: "未找到智能体。",
|
|
124057
|
+
clearAgent: "清除所选智能体",
|
|
124058
|
+
agentTitleLabel: "标题",
|
|
124059
|
+
agentTitlePlaceholder: "认识您的助手",
|
|
124060
|
+
agentDescriptionLabel: "副标题",
|
|
124061
|
+
agentDescriptionPlaceholder: "有任何问题都可以问您的助手。",
|
|
124062
|
+
noAgentHint: "未设置智能体时,成员将完全跳过引导流程。"
|
|
124063
|
+
};
|
|
123530
124064
|
var zh = {
|
|
123531
124065
|
accessTabAddAccess: accessTabAddAccess,
|
|
123532
124066
|
accessTabLabels: accessTabLabels,
|
|
@@ -123655,6 +124189,10 @@ var zh = {
|
|
|
123655
124189
|
mcpTabConnectorManagementContent: mcpTabConnectorManagementContent,
|
|
123656
124190
|
memoryAddMemoryDialog: memoryAddMemoryDialog,
|
|
123657
124191
|
memoryMemoryTab: memoryMemoryTab,
|
|
124192
|
+
memoryAdminTab: memoryAdminTab,
|
|
124193
|
+
memoryAdminUserMemoriesModal: memoryAdminUserMemoriesModal,
|
|
124194
|
+
memoryEditMemoryDialog: memoryEditMemoryDialog,
|
|
124195
|
+
memoryAdminAgentMemoriesModal: memoryAdminAgentMemoriesModal,
|
|
123658
124196
|
memoryTabAddMemoryModal: memoryTabAddMemoryModal,
|
|
123659
124197
|
memoryTabDeleteMemoryModal: memoryTabDeleteMemoryModal,
|
|
123660
124198
|
memoryTabEditMemoryModal: memoryTabEditMemoryModal,
|
|
@@ -123796,7 +124334,9 @@ var zh = {
|
|
|
123796
124334
|
analyticsAnalyticsPlatformAuditLog: analyticsAnalyticsPlatformAuditLog,
|
|
123797
124335
|
analyticsPlatformAuditLogDetailSheet: analyticsPlatformAuditLogDetailSheet,
|
|
123798
124336
|
analyticsAuditLogJsonView: analyticsAuditLogJsonView,
|
|
123799
|
-
analyticsUsePlatformAuditLabels: analyticsUsePlatformAuditLabels
|
|
124337
|
+
analyticsUsePlatformAuditLabels: analyticsUsePlatformAuditLabels,
|
|
124338
|
+
onboardingUserOnboarding: onboardingUserOnboarding,
|
|
124339
|
+
profileOnboardingTab: profileOnboardingTab
|
|
123800
124340
|
};
|
|
123801
124341
|
|
|
123802
124342
|
/**
|
|
@@ -177681,7 +178221,7 @@ const buildGradeSummary = (edx) => {
|
|
|
177681
178221
|
function GradeBar({ currentPct, passingPct }) {
|
|
177682
178222
|
const clampedCurrent = Math.min(Math.max(currentPct, 0), 100);
|
|
177683
178223
|
const clampedPassing = Math.min(Math.max(passingPct, 0), 100);
|
|
177684
|
-
return (jsxs("div", { className: "pt-7 pb-4", children: [jsxs("div", { className: "relative", children: [jsx("div", { className: "absolute -top-7 -translate-x-1/2", style: { left:
|
|
178224
|
+
return (jsxs("div", { className: "pt-7 pb-4", children: [jsxs("div", { className: "relative", children: [jsx("div", { className: "absolute -top-7 -translate-x-1/2", style: { left: `calc(${clampedCurrent}% + 15px)` }, children: jsxs("span", { className: "whitespace-nowrap rounded border border-amber-300 bg-amber-50 px-1.5 py-0.5 text-xs font-semibold text-gray-700", children: [currentPct, "%"] }) }), jsxs("div", { className: "relative h-2 rounded-full bg-gray-200", children: [jsx("div", { className: "absolute left-0 top-0 h-2 rounded-full bg-amber-500", style: { width: `${clampedCurrent}%` } }), jsx("div", { className: "absolute top-1/2 h-3.5 w-3.5 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white bg-amber-500", style: { left: `${clampedPassing}%` } })] }), jsx("div", { className: "absolute top-3 -translate-x-1/2", style: { left: `${clampedPassing}%` }, children: jsxs("span", { className: "whitespace-nowrap rounded bg-amber-500 px-1.5 py-0.5 text-xs font-semibold text-white", children: [passingPct, "%"] }) })] }), jsxs("div", { className: "mt-10 flex justify-between text-xs text-gray-500", children: [jsx("span", { children: "Current grade" }), jsx("span", { children: "Passing grade" })] })] }));
|
|
177685
178225
|
}
|
|
177686
178226
|
function EnrolledUserProgressModal({ open, onOpenChange, username, userName, email, contentId, contentName, tenantKey, metric = 'course', }) {
|
|
177687
178227
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
@@ -177722,7 +178262,7 @@ function DetailRow({ label, children }) {
|
|
|
177722
178262
|
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 })] }));
|
|
177723
178263
|
}
|
|
177724
178264
|
|
|
177725
|
-
const PAGE_SIZE$
|
|
178265
|
+
const PAGE_SIZE$e = 8;
|
|
177726
178266
|
const CONTENT_TYPES = [
|
|
177727
178267
|
{ value: 'courses', labelKey: 'gradebookGradebookTab.typeCourses', icon: GraduationCap },
|
|
177728
178268
|
{ value: 'programs', labelKey: 'gradebookGradebookTab.typePrograms', icon: Layers },
|
|
@@ -177753,14 +178293,14 @@ function useGradebookData(type, org, username, page, search) {
|
|
|
177753
178293
|
username,
|
|
177754
178294
|
query: {
|
|
177755
178295
|
page,
|
|
177756
|
-
page_size: PAGE_SIZE$
|
|
178296
|
+
page_size: PAGE_SIZE$e,
|
|
177757
178297
|
platform_key: org,
|
|
177758
178298
|
...(trimmed ? { search: trimmed } : {}),
|
|
177759
178299
|
},
|
|
177760
178300
|
}, { skip: type !== 'courses', refetchOnMountOrArgChange: true });
|
|
177761
178301
|
const programsQ = useGetUserEnrolledProgramsQuery([{ username, platformKey: org }], { skip: type !== 'programs' });
|
|
177762
178302
|
const pathwaysQ = useGetUserCatalogPathwaysQuery({ username, platform_key: org }, { skip: type !== 'pathways' });
|
|
177763
|
-
const credentialsQ = useGetUsersAsAssertionsQuery({ platformKey: org, userId: username, page, pageSize: PAGE_SIZE$
|
|
178303
|
+
const credentialsQ = useGetUsersAsAssertionsQuery({ platformKey: org, userId: username, page, pageSize: PAGE_SIZE$e }, { skip: type !== 'credentials', refetchOnMountOrArgChange: true });
|
|
177764
178304
|
const earnedQ = useGetUserEarnedSkillsQuery([{ org, userId: username }], { skip: type !== 'skills' });
|
|
177765
178305
|
const reportedQ = useGetUserReportedSkillsQuery([{ username }], { skip: type !== 'skills' });
|
|
177766
178306
|
const desiredQ = useGetUserDesiredSkillsQuery([{ username }], { skip: type !== 'skills' });
|
|
@@ -177770,12 +178310,12 @@ function useGradebookData(type, org, username, page, search) {
|
|
|
177770
178310
|
const filtered = trimmed
|
|
177771
178311
|
? rows.filter((row) => row.name.toLowerCase().includes(trimmed.toLowerCase()))
|
|
177772
178312
|
: rows;
|
|
177773
|
-
const start = (page - 1) * PAGE_SIZE$
|
|
178313
|
+
const start = (page - 1) * PAGE_SIZE$e;
|
|
177774
178314
|
return {
|
|
177775
|
-
rows: filtered.slice(start, start + PAGE_SIZE$
|
|
178315
|
+
rows: filtered.slice(start, start + PAGE_SIZE$e),
|
|
177776
178316
|
total: filtered.length,
|
|
177777
178317
|
hasPrev: page > 1,
|
|
177778
|
-
hasNext: start + PAGE_SIZE$
|
|
178318
|
+
hasNext: start + PAGE_SIZE$e < filtered.length,
|
|
177779
178319
|
};
|
|
177780
178320
|
};
|
|
177781
178321
|
switch (type) {
|
|
@@ -177832,7 +178372,7 @@ function useGradebookData(type, org, username, page, search) {
|
|
|
177832
178372
|
rows,
|
|
177833
178373
|
total,
|
|
177834
178374
|
hasPrev: page > 1,
|
|
177835
|
-
hasNext: page * PAGE_SIZE$
|
|
178375
|
+
hasNext: page * PAGE_SIZE$e < total,
|
|
177836
178376
|
isLoading: credentialsQ.isLoading,
|
|
177837
178377
|
isFetching: credentialsQ.isFetching,
|
|
177838
178378
|
isError: credentialsQ.isError,
|
|
@@ -177989,6 +178529,75 @@ function AddMemoryDialog({ open, onOpenChange, org, username }) {
|
|
|
177989
178529
|
: t('memoryAddMemoryDialog.saveButton') })] })] }) }) }));
|
|
177990
178530
|
}
|
|
177991
178531
|
|
|
178532
|
+
/**
|
|
178533
|
+
* Counterpart to {@link AddMemoryDialog} for updating a memory's content. The
|
|
178534
|
+
* backend refreshes embeddings on update and answers 409 when the new content
|
|
178535
|
+
* duplicates another memory.
|
|
178536
|
+
*/
|
|
178537
|
+
function EditMemoryDialog({ open, onOpenChange, org, username, memory, mentorId, }) {
|
|
178538
|
+
const t = useT();
|
|
178539
|
+
const [content, setContent] = useState(memory.content);
|
|
178540
|
+
const [updateGlobalMemory, { isLoading: isSavingGlobal }] = useUpdateGlobalMemoryMutation();
|
|
178541
|
+
const [updateMentorMemory, { isLoading: isSavingMentor }] = useUpdateMentorMemoryMutation();
|
|
178542
|
+
const isLoading = isSavingGlobal || isSavingMentor;
|
|
178543
|
+
const handleSubmit = async (e) => {
|
|
178544
|
+
e.preventDefault();
|
|
178545
|
+
e.stopPropagation();
|
|
178546
|
+
if (content.trim().length < 10) {
|
|
178547
|
+
toast.error(t('memoryEditMemoryDialog.validationMinLength'));
|
|
178548
|
+
return;
|
|
178549
|
+
}
|
|
178550
|
+
try {
|
|
178551
|
+
if (mentorId) {
|
|
178552
|
+
await updateMentorMemory({
|
|
178553
|
+
org,
|
|
178554
|
+
userId: username,
|
|
178555
|
+
mentorId,
|
|
178556
|
+
memoryId: memory.id,
|
|
178557
|
+
data: { content: content.trim() },
|
|
178558
|
+
}).unwrap();
|
|
178559
|
+
}
|
|
178560
|
+
else {
|
|
178561
|
+
await updateGlobalMemory({
|
|
178562
|
+
org,
|
|
178563
|
+
userId: username,
|
|
178564
|
+
memoryId: memory.id,
|
|
178565
|
+
content: content.trim(),
|
|
178566
|
+
}).unwrap();
|
|
178567
|
+
}
|
|
178568
|
+
toast.success(t('memoryEditMemoryDialog.toastUpdated'));
|
|
178569
|
+
onOpenChange(false);
|
|
178570
|
+
}
|
|
178571
|
+
catch (error) {
|
|
178572
|
+
const status = error === null || error === void 0 ? void 0 : error.status;
|
|
178573
|
+
if (status === 409) {
|
|
178574
|
+
toast.error(t('memoryEditMemoryDialog.toastDuplicate'));
|
|
178575
|
+
}
|
|
178576
|
+
else if (status === 403) {
|
|
178577
|
+
toast.error(t('memoryEditMemoryDialog.toastForbidden'));
|
|
178578
|
+
}
|
|
178579
|
+
else {
|
|
178580
|
+
toast.error(t('memoryEditMemoryDialog.toastFailed'));
|
|
178581
|
+
}
|
|
178582
|
+
}
|
|
178583
|
+
};
|
|
178584
|
+
return (jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: jsx(DialogContent, { className: "p-0 overflow-hidden max-w-lg", children: jsxs("form", { onSubmit: handleSubmit, children: [jsx("div", { className: "flex items-center justify-between px-6 py-4 border-b", children: jsx(DialogTitle, { className: "text-lg font-semibold text-gray-900", children: t('memoryEditMemoryDialog.dialogTitle') }) }), jsx(DialogDescription, { className: "sr-only", children: t('memoryEditMemoryDialog.dialogDescription') }), jsx("div", { className: "p-6 space-y-4", children: jsxs("div", { className: "space-y-2", children: [jsx(Label$1, { htmlFor: "edit-memory-content", children: t('memoryEditMemoryDialog.contentLabel') }), jsx(Textarea, { id: "edit-memory-content", value: content, onChange: (e) => setContent(e.target.value), rows: 4, className: "w-full bg-gray-50 border-gray-200 focus:ring-blue-500 focus:border-blue-500 text-sm resize-none", disabled: isLoading }), content.length > 0 && content.trim().length < 10 && (jsx("p", { className: "text-sm text-red-500", children: t('memoryEditMemoryDialog.inlineMinLength') }))] }) }), jsxs("div", { className: "flex justify-end gap-3 border-t px-6 py-4", children: [jsx(Button$1, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isLoading, children: t('memoryEditMemoryDialog.cancelButton') }), jsx(Button$1, { className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", type: "submit", disabled: isLoading || content.trim().length < 10, children: isLoading
|
|
178585
|
+
? t('memoryEditMemoryDialog.savingButton')
|
|
178586
|
+
: t('memoryEditMemoryDialog.saveButton') })] })] }) }) }));
|
|
178587
|
+
}
|
|
178588
|
+
|
|
178589
|
+
function DeleteMemoryModal$1({ open, onOpenChange, onConfirm, onCancel, isDeleting, }) {
|
|
178590
|
+
const t = useT();
|
|
178591
|
+
return (jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: jsxs(DialogContent, { className: "mx-4 max-w-md sm:mx-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { children: t('memoryTabDeleteMemoryModal.title') }) }), jsx("p", { className: "text-muted-foreground text-sm", children: t('memoryTabDeleteMemoryModal.confirmMessage') }), jsxs("div", { className: "mt-4 flex justify-end gap-2", children: [jsx(Button$1, { variant: "outline", onClick: onCancel, children: t('memoryTabDeleteMemoryModal.cancel') }), jsx(Button$1, { className: "ibl-button-primary", onClick: onConfirm, disabled: isDeleting, children: isDeleting
|
|
178592
|
+
? t('memoryTabDeleteMemoryModal.deleting')
|
|
178593
|
+
: t('memoryTabDeleteMemoryModal.delete') })] })] }) }));
|
|
178594
|
+
}
|
|
178595
|
+
|
|
178596
|
+
var deleteMemoryModal = /*#__PURE__*/Object.freeze({
|
|
178597
|
+
__proto__: null,
|
|
178598
|
+
DeleteMemoryModal: DeleteMemoryModal$1
|
|
178599
|
+
});
|
|
178600
|
+
|
|
177992
178601
|
const Pagination = ({ className, ...props }) => {
|
|
177993
178602
|
const t = useT();
|
|
177994
178603
|
return (jsx("nav", { role: "navigation", "aria-label": t('uiPagination.paginationNavLabel'), className: cn('mx-auto flex w-full justify-center', className), ...props }));
|
|
@@ -178069,11 +178678,42 @@ const IblPagination = ({ currentPage, totalPages, onPageChange, disabled = false
|
|
|
178069
178678
|
}, "aria-disabled": currentPage === totalPages || disabled, className: cn('cursor-pointer', (currentPage === totalPages || disabled) && 'pointer-events-none opacity-50') }) })] }) }));
|
|
178070
178679
|
};
|
|
178071
178680
|
|
|
178681
|
+
/**
|
|
178682
|
+
* The one memory list UI — rows with source icon, content, date and auto
|
|
178683
|
+
* badge, a three-dots Edit/Delete menu, delete confirmation, and pagination.
|
|
178684
|
+
* Shared by the profile Memory tab and the tenant-settings memory popup so
|
|
178685
|
+
* the two stay identical.
|
|
178686
|
+
*/
|
|
178687
|
+
function MemoriesList({ memories, isLoading, emptyText, deletingId, onEdit, onDelete, totalPages, currentPage, onPageChange, }) {
|
|
178688
|
+
const t = useT();
|
|
178689
|
+
const [pendingDelete, setPendingDelete] = useState(null);
|
|
178690
|
+
const confirmDelete = async () => {
|
|
178691
|
+
if (!pendingDelete)
|
|
178692
|
+
return;
|
|
178693
|
+
try {
|
|
178694
|
+
await onDelete(pendingDelete);
|
|
178695
|
+
}
|
|
178696
|
+
catch (_a) {
|
|
178697
|
+
// Hosts surface their own failure toasts; the modal just closes.
|
|
178698
|
+
}
|
|
178699
|
+
finally {
|
|
178700
|
+
setPendingDelete(null);
|
|
178701
|
+
}
|
|
178702
|
+
};
|
|
178703
|
+
if (isLoading) {
|
|
178704
|
+
return (jsx("div", { className: "space-y-3", children: [1, 2, 3].map((i) => (jsx(Skeleton, { className: "h-16 w-full rounded-lg" }, i))) }));
|
|
178705
|
+
}
|
|
178706
|
+
return (jsxs(Fragment$1, { children: [memories.length ? (jsx("div", { className: "space-y-3", "data-testid": "memories-list", children: memories.map((memory) => (jsxs("div", { "data-testid": "memory-row", className: "group flex items-start gap-3 rounded-lg border px-4 py-3", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx("div", { className: "flex-shrink-0 mt-0.5", children: memory.is_auto_generated ? (jsx(Bot, { className: "h-4 w-4 text-blue-500", "aria-label": t('memoryMemoryTab.autoGeneratedMemoryAriaLabel') })) : (jsx(User, { className: "h-4 w-4 text-gray-400", "aria-label": t('memoryMemoryTab.manuallyAddedMemoryAriaLabel') })) }), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("p", { className: "text-sm text-gray-800 dark:text-gray-200", children: memory.content }), jsxs("p", { className: "text-xs text-gray-400 mt-1", children: [new Date(memory.created_at).toLocaleDateString(), memory.is_auto_generated && (jsx("span", { className: "ml-2 inline-flex items-center rounded-full bg-blue-50 px-1.5 py-0.5 text-[10px] font-medium text-blue-600", children: t('memoryMemoryTab.autoBadge') }))] })] }), deletingId === memory.id ? (jsx("div", { className: "mt-1 h-4 w-4 flex-shrink-0 animate-spin rounded-full border-2 border-gray-500 border-t-transparent" })) : (jsxs(DropdownMenu, { children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsx(Button$1, { variant: "ghost", size: "sm", className: "h-6 w-6 flex-shrink-0 p-0 text-gray-600 hover:text-gray-900", "aria-label": t('memoryMemoryTab.actionsMenuAriaLabel', {
|
|
178707
|
+
excerpt: memory.content.substring(0, 30),
|
|
178708
|
+
}), children: jsx(Ellipsis, { className: "h-4 w-4" }) }) }), jsxs(DropdownMenuContent, { align: "end", children: [jsxs(DropdownMenuItem, { onClick: () => onEdit(memory), children: [jsx(Pencil, { className: "mr-2 h-4 w-4" }), t('memoryMemoryTab.editAction')] }), jsxs(DropdownMenuItem, { className: "text-red-600 focus:text-red-700", onClick: () => setPendingDelete(memory), children: [jsx(Trash2, { className: "mr-2 h-4 w-4" }), t('memoryMemoryTab.deleteAction')] })] })] }))] }, `${'mentor_id' in memory ? memory.mentor_id : 'global'}-${memory.id}`))) })) : (jsx("div", { "data-testid": "memories-list-empty", 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: emptyText }) })), totalPages > 1 && (jsx(IblPagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: onPageChange, disabled: isLoading })), jsx(DeleteMemoryModal$1, { open: !!pendingDelete, onOpenChange: (open) => !open && setPendingDelete(null), onConfirm: confirmDelete, onCancel: () => setPendingDelete(null), isDeleting: !!pendingDelete && deletingId === pendingDelete.id })] }));
|
|
178709
|
+
}
|
|
178710
|
+
|
|
178072
178711
|
const MEMORIES_PAGE_SIZE = 25;
|
|
178073
178712
|
function MemoryTab({ org, username }) {
|
|
178074
178713
|
var _a, _b;
|
|
178075
178714
|
const t = useT();
|
|
178076
178715
|
const [isAddDialogOpen, setIsAddDialogOpen] = useState(false);
|
|
178716
|
+
const [editingMemory, setEditingMemory] = useState(null);
|
|
178077
178717
|
const [deletingId, setDeletingId] = useState(null);
|
|
178078
178718
|
const [currentPage, setCurrentPage] = useState(1);
|
|
178079
178719
|
// Viewing someone else's profile, which lists both of that user's memory
|
|
@@ -178085,11 +178725,13 @@ function MemoryTab({ org, username }) {
|
|
|
178085
178725
|
org,
|
|
178086
178726
|
userId: username,
|
|
178087
178727
|
}, { skip: isPreview });
|
|
178088
|
-
// User memory settings
|
|
178728
|
+
// User memory settings. In preview the path addresses the previewed user —
|
|
178729
|
+
// the backend resolves that for admin/RBAC callers, and the section simply
|
|
178730
|
+
// stays hidden when the settings come back forbidden.
|
|
178089
178731
|
const { data: settings, isLoading: isLoadingSettings } = useGetUserMemorySettingsQuery({
|
|
178090
178732
|
org,
|
|
178091
178733
|
userId: username,
|
|
178092
|
-
}
|
|
178734
|
+
});
|
|
178093
178735
|
const [updateSettings, { isLoading: isUpdatingSettings }] = useUpdateUserMemorySettingsMutation();
|
|
178094
178736
|
const memoriesParams = { page: currentPage, page_size: MEMORIES_PAGE_SIZE };
|
|
178095
178737
|
// Global memories. On your own profile this is the plain call — your username
|
|
@@ -178124,6 +178766,7 @@ function MemoryTab({ org, username }) {
|
|
|
178124
178766
|
return isPreview ? Math.max(globalPages, pageCount(mentorMemoriesData === null || mentorMemoriesData === void 0 ? void 0 : mentorMemoriesData.count)) : globalPages;
|
|
178125
178767
|
}, [isPreview, globalMemoriesData, mentorMemoriesData]);
|
|
178126
178768
|
const [deleteMemory] = useDeleteGlobalMemoryMutation();
|
|
178769
|
+
const [deleteMentorMemory] = useDeleteMentorMemoryMutation();
|
|
178127
178770
|
const handleToggleSetting = async (key, checked) => {
|
|
178128
178771
|
try {
|
|
178129
178772
|
await updateSettings({
|
|
@@ -178137,14 +178780,26 @@ function MemoryTab({ org, username }) {
|
|
|
178137
178780
|
toast.error(t('memoryMemoryTab.failedToUpdateMemorySetting'));
|
|
178138
178781
|
}
|
|
178139
178782
|
};
|
|
178140
|
-
const handleDeleteMemory = async (
|
|
178141
|
-
setDeletingId(
|
|
178783
|
+
const handleDeleteMemory = async (memory) => {
|
|
178784
|
+
setDeletingId(memory.id);
|
|
178142
178785
|
try {
|
|
178143
|
-
|
|
178144
|
-
|
|
178145
|
-
|
|
178146
|
-
|
|
178147
|
-
|
|
178786
|
+
if ('mentor_id' in memory) {
|
|
178787
|
+
// Agent memories are deleted the way the agent memory manager does it:
|
|
178788
|
+
// the caller in the path, authorization resolved server-side.
|
|
178789
|
+
await deleteMentorMemory({
|
|
178790
|
+
org,
|
|
178791
|
+
userId: currentUsername,
|
|
178792
|
+
mentorId: memory.mentor_id,
|
|
178793
|
+
memoryId: memory.id,
|
|
178794
|
+
}).unwrap();
|
|
178795
|
+
}
|
|
178796
|
+
else {
|
|
178797
|
+
await deleteMemory({
|
|
178798
|
+
org,
|
|
178799
|
+
userId: username,
|
|
178800
|
+
memoryId: memory.id,
|
|
178801
|
+
}).unwrap();
|
|
178802
|
+
}
|
|
178148
178803
|
toast.success(t('memoryMemoryTab.memoryDeleted'));
|
|
178149
178804
|
}
|
|
178150
178805
|
catch (_a) {
|
|
@@ -178161,7 +178816,7 @@ function MemoryTab({ org, username }) {
|
|
|
178161
178816
|
if (!isConfigError && memsearchStatus && !memsearchStatus.enable_memsearch) {
|
|
178162
178817
|
return (jsx("div", { className: "max-w-2xl", children: jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children: t('memoryMemoryTab.memoryFeatureDisabled') }) }) }));
|
|
178163
178818
|
}
|
|
178164
|
-
return (jsxs("div", { className: "space-y-8", children: [!isPreview && (jsxs("div", { className: "space-y-4", children: [
|
|
178819
|
+
return (jsxs("div", { className: "space-y-8", children: [(!isPreview || settings) && (jsxs("div", { className: "space-y-4", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children: t('memoryMemoryTab.sectionMemoryPersonalization') }), jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex-1 mr-4", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: t('memoryMemoryTab.autoCaptureLabelTitle') }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: t('memoryMemoryTab.autoCaptureLabelDesc') })] }), jsx(Switch, { checked: (_a = settings === null || settings === void 0 ? void 0 : settings.auto_capture_enabled) !== null && _a !== void 0 ? _a : false, onCheckedChange: (checked) => handleToggleSetting('auto_capture_enabled', checked), disabled: isUpdatingSettings, "aria-label": t('memoryMemoryTab.autoCaptureAriaLabel', {
|
|
178165
178820
|
state: (settings === null || settings === void 0 ? void 0 : settings.auto_capture_enabled)
|
|
178166
178821
|
? t('memoryMemoryTab.stateEnabled')
|
|
178167
178822
|
: t('memoryMemoryTab.stateDisabled'),
|
|
@@ -178171,11 +178826,16 @@ function MemoryTab({ org, username }) {
|
|
|
178171
178826
|
: t('memoryMemoryTab.stateDisabled'),
|
|
178172
178827
|
}), className: "cursor-pointer data-[state=checked]:bg-blue-500 flex-shrink-0" })] })] })), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children: isPreview
|
|
178173
178828
|
? t('memoryMemoryTab.sectionMyMemoriesPreview')
|
|
178174
|
-
: t('memoryMemoryTab.sectionMyMemories') }),
|
|
178175
|
-
|
|
178176
|
-
|
|
178177
|
-
|
|
178178
|
-
|
|
178829
|
+
: t('memoryMemoryTab.sectionMyMemories') }), jsxs(Button$1, { variant: "outline", size: "sm", onClick: () => setIsAddDialogOpen(true), className: "text-xs", children: [jsx(Plus, { className: "h-3 w-3 mr-1" }), t('memoryMemoryTab.addMemoryButton')] })] }), jsx(MemoriesList, { memories: memories, isLoading: isLoadingMemories, emptyText: isPreview
|
|
178830
|
+
? t('memoryMemoryTab.noMemoriesYetPreview')
|
|
178831
|
+
: t('memoryMemoryTab.noMemoriesYet'), deletingId: deletingId, onEdit: (memory) => setEditingMemory({
|
|
178832
|
+
id: memory.id,
|
|
178833
|
+
content: memory.content,
|
|
178834
|
+
...('mentor_id' in memory ? { mentorId: memory.mentor_id } : {}),
|
|
178835
|
+
}), onDelete: handleDeleteMemory, totalPages: totalPages, currentPage: currentPage, onPageChange: setCurrentPage })] }), jsx(AddMemoryDialog, { open: isAddDialogOpen, onOpenChange: setIsAddDialogOpen, org: org, username: username }), editingMemory && (jsx(EditMemoryDialog, { open: !!editingMemory, onOpenChange: (open) => !open && setEditingMemory(null), org: org,
|
|
178836
|
+
// Agent memories are written with the caller in the path (the way
|
|
178837
|
+
// the agent memory manager does); global memories with their owner.
|
|
178838
|
+
username: editingMemory.mentorId ? currentUsername : username, memory: editingMemory, mentorId: editingMemory.mentorId }))] }));
|
|
178179
178839
|
}
|
|
178180
178840
|
|
|
178181
178841
|
var _a$1;
|
|
@@ -180316,7 +180976,7 @@ const PopoverContent = React.forwardRef(({ className, align = 'center', sideOffs
|
|
|
180316
180976
|
});
|
|
180317
180977
|
PopoverContent.displayName = Content2$2.displayName;
|
|
180318
180978
|
|
|
180319
|
-
const PAGE_SIZE$
|
|
180979
|
+
const PAGE_SIZE$d = 10;
|
|
180320
180980
|
function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false, }) {
|
|
180321
180981
|
var _a, _b;
|
|
180322
180982
|
const t = useT();
|
|
@@ -180338,7 +180998,7 @@ function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false,
|
|
|
180338
180998
|
const isWatcher = isPureWatcher(rbacPermissions, currentTenant);
|
|
180339
180999
|
const { data: users, refetch: refetchPlatformUsers, isLoading: isLoadingPlatformUsers, } = usePlatformUsersQuery({
|
|
180340
181000
|
page,
|
|
180341
|
-
page_size: PAGE_SIZE$
|
|
181001
|
+
page_size: PAGE_SIZE$d,
|
|
180342
181002
|
platform_key: tenant,
|
|
180343
181003
|
platform_org: tenant,
|
|
180344
181004
|
query: debouncedSearchQuery,
|
|
@@ -180352,7 +181012,7 @@ function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false,
|
|
|
180352
181012
|
// TODO to use required_action: 'Ibl.Core/Users/read',
|
|
180353
181013
|
required_action: 'Ibl.Mentor/Memory/list',
|
|
180354
181014
|
page,
|
|
180355
|
-
page_size: PAGE_SIZE$
|
|
181015
|
+
page_size: PAGE_SIZE$d,
|
|
180356
181016
|
sort: 'name',
|
|
180357
181017
|
...(debouncedSearchQuery.includes('@')
|
|
180358
181018
|
? { email: debouncedSearchQuery }
|
|
@@ -180521,14 +181181,16 @@ function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false,
|
|
|
180521
181181
|
managed: user,
|
|
180522
181182
|
}));
|
|
180523
181183
|
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;
|
|
180524
|
-
const totalPages = Math.ceil(totalCount / PAGE_SIZE$
|
|
180525
|
-
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-
|
|
181184
|
+
const totalPages = Math.ceil(totalCount / PAGE_SIZE$d);
|
|
181185
|
+
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) => {
|
|
180526
181186
|
// Only set on the admin path — see {@link UserRow}.
|
|
180527
181187
|
const user = row.managed;
|
|
180528
|
-
return (jsxs("tr", { onClick: () => setSelectedUser(row), className: "cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors", children: [jsx("td", { "aria-label": 'user-management-
|
|
181188
|
+
return (jsxs("tr", { onClick: () => setSelectedUser(row), className: "cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors", children: [jsx("td", { "aria-label": 'user-management-email-column', className: "px-6 py-4 text-gray-900 dark:text-gray-100 text-sm max-w-0", children: jsx("button", { type: "button", onClick: (e) => {
|
|
180529
181189
|
e.stopPropagation();
|
|
180530
181190
|
setSelectedUser(row);
|
|
180531
|
-
}, className: "block max-w-full truncate text-left hover:text-blue-600 hover:underline focus:outline-none focus:text-blue-600", "aria-label": t('tabsUserstab.viewProfileAriaLabel', {
|
|
181191
|
+
}, className: "block max-w-full truncate text-left hover:text-blue-600 hover:underline focus:outline-none focus:text-blue-600", "aria-label": t('tabsUserstab.viewProfileAriaLabel', {
|
|
181192
|
+
name: row.name || row.email,
|
|
181193
|
+
}), children: row.email }) }), user && (jsxs(Fragment$1, { children: [jsx("td", { className: "px-6 py-4", onClick: (e) => e.stopPropagation(), children: jsxs(Select$1, { value: user.is_admin ? 'admin' : 'student', onValueChange: () => handleUserRoleChange(user), children: [jsx(SelectTrigger, { className: "w-full text-sm", children: jsx(SelectValue, {}) }), jsxs(SelectContent, { className: "text-sm", children: [jsx(SelectItem, { value: "admin", children: t('tabsUserstab.roleAdmin') }), jsx(SelectItem, { value: "student", children: t('tabsUserstab.roleUser') })] })] }) }), jsx("td", { className: "px-6 py-4", onClick: (e) => e.stopPropagation(), children: jsxs(Popover, { modal: true, open: openPolicyPopover === user.user_id, onOpenChange: (open) => setOpenPolicyPopover(open ? user.user_id : null), children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", role: "combobox", "aria-expanded": openPolicyPopover === user.user_id, "aria-label": t('tabsUserstab.selectPoliciesAriaLabel', {
|
|
180532
181194
|
name: user.name,
|
|
180533
181195
|
}), className: "w-full justify-between text-sm h-9 font-normal", disabled: updatingUserIds.has(user === null || user === void 0 ? void 0 : user.user_id), children: [jsx("span", { className: "truncate", children: user.is_admin
|
|
180534
181196
|
? t('tabsUserstab.allPoliciesSelected', {
|
|
@@ -180547,7 +181209,7 @@ function UsersTab({ tenant, onInviteClick, currentSpa, showGradebookTab = false,
|
|
|
180547
181209
|
})] }) })] }) }), 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', {
|
|
180548
181210
|
name: user.name,
|
|
180549
181211
|
}), className: "cursor-pointer data-[state=checked]:bg-blue-500 disabled:cursor-not-allowed disabled:opacity-50" }) })] }))] }, row.key));
|
|
180550
|
-
}), 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$
|
|
181212
|
+
}), 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) => {
|
|
180551
181213
|
if (!open)
|
|
180552
181214
|
setSelectedUser(null);
|
|
180553
181215
|
}, 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: {
|
|
@@ -181767,7 +182429,7 @@ function PoliciesTab({ tenant }) {
|
|
|
181767
182429
|
: 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 })] }));
|
|
181768
182430
|
}
|
|
181769
182431
|
|
|
181770
|
-
const PAGE_SIZE$
|
|
182432
|
+
const PAGE_SIZE$c = 10;
|
|
181771
182433
|
function normalizeEvents(events) {
|
|
181772
182434
|
if (!events)
|
|
181773
182435
|
return [];
|
|
@@ -181816,8 +182478,8 @@ function AlertsTab({ tenant }) {
|
|
|
181816
182478
|
const { data: watchedGroupsData, isLoading, isError, refetch, } = useGetWatchedGroupsQuery({
|
|
181817
182479
|
params: {
|
|
181818
182480
|
platform_key: tenant,
|
|
181819
|
-
limit: PAGE_SIZE$
|
|
181820
|
-
offset: (page - 1) * PAGE_SIZE$
|
|
182481
|
+
limit: PAGE_SIZE$c,
|
|
182482
|
+
offset: (page - 1) * PAGE_SIZE$c,
|
|
181821
182483
|
},
|
|
181822
182484
|
});
|
|
181823
182485
|
const groups = useMemo(() => {
|
|
@@ -181830,7 +182492,7 @@ function AlertsTab({ tenant }) {
|
|
|
181830
182492
|
return results;
|
|
181831
182493
|
}, [watchedGroupsData, debouncedSearchQuery]);
|
|
181832
182494
|
const totalPages = watchedGroupsData
|
|
181833
|
-
? Math.max(1, Math.ceil(watchedGroupsData.count / PAGE_SIZE$
|
|
182495
|
+
? Math.max(1, Math.ceil(watchedGroupsData.count / PAGE_SIZE$c))
|
|
181834
182496
|
: 0;
|
|
181835
182497
|
const handlePageChange = async (newPage) => {
|
|
181836
182498
|
setPage(newPage);
|
|
@@ -182139,7 +182801,7 @@ function AlertsTab({ tenant }) {
|
|
|
182139
182801
|
setDeletingGroupId(null);
|
|
182140
182802
|
}
|
|
182141
182803
|
}
|
|
182142
|
-
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$
|
|
182804
|
+
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', {
|
|
182143
182805
|
username: user.username,
|
|
182144
182806
|
}), 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) => {
|
|
182145
182807
|
setWatchedUserSearch(e.target.value);
|
|
@@ -183462,8 +184124,8 @@ function BlocksView({ platformKey, onBack, }) {
|
|
|
183462
184124
|
}
|
|
183463
184125
|
|
|
183464
184126
|
const FILTER_ORDER = ['all', ...APPLICATION_STATUSES];
|
|
183465
|
-
const PAGE_SIZE$
|
|
183466
|
-
const SEARCH_DEBOUNCE_MS = 300;
|
|
184127
|
+
const PAGE_SIZE$b = 20;
|
|
184128
|
+
const SEARCH_DEBOUNCE_MS$1 = 300;
|
|
183467
184129
|
/**
|
|
183468
184130
|
* The public application URL on the auth SPA for one form of a platform
|
|
183469
184131
|
* (`<auth-url>/applications/<platform-key>/<form-id>?redirect-to=<origin>`), or
|
|
@@ -183574,7 +184236,7 @@ function SubmissionsPipeline({ platformKey, form, onBack, onOpen, }) {
|
|
|
183574
184236
|
const timer = setTimeout(() => {
|
|
183575
184237
|
setDebouncedSearch(search.trim());
|
|
183576
184238
|
setDebouncedCandidateFilter(candidateFilter.trim());
|
|
183577
|
-
}, SEARCH_DEBOUNCE_MS);
|
|
184239
|
+
}, SEARCH_DEBOUNCE_MS$1);
|
|
183578
184240
|
return () => clearTimeout(timer);
|
|
183579
184241
|
}, [search, candidateFilter]);
|
|
183580
184242
|
// New filters restart paging.
|
|
@@ -183597,7 +184259,7 @@ function SubmissionsPipeline({ platformKey, form, onBack, onOpen, }) {
|
|
|
183597
184259
|
...(sort !== '-created' ? { sort } : {}),
|
|
183598
184260
|
...candidateParams,
|
|
183599
184261
|
page,
|
|
183600
|
-
page_size: PAGE_SIZE$
|
|
184262
|
+
page_size: PAGE_SIZE$b,
|
|
183601
184263
|
}, {
|
|
183602
184264
|
refetchOnMountOrArgChange: true,
|
|
183603
184265
|
});
|
|
@@ -183606,7 +184268,7 @@ function SubmissionsPipeline({ platformKey, form, onBack, onOpen, }) {
|
|
|
183606
184268
|
: [];
|
|
183607
184269
|
const rows = form ? allRows.filter((row) => row.form_id === form.id) : allRows;
|
|
183608
184270
|
const count = typeof (pipeline === null || pipeline === void 0 ? void 0 : pipeline.count) === 'number' ? pipeline.count : allRows.length;
|
|
183609
|
-
const totalPages = Math.max(1, Math.ceil(count / PAGE_SIZE$
|
|
184271
|
+
const totalPages = Math.max(1, Math.ceil(count / PAGE_SIZE$b));
|
|
183610
184272
|
const counts = statsCounts(stats);
|
|
183611
184273
|
const countFor = (key) => {
|
|
183612
184274
|
if (!stats)
|
|
@@ -183644,7 +184306,263 @@ function SubmissionsPipeline({ platformKey, form, onBack, onOpen, }) {
|
|
|
183644
184306
|
}) }) }), 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]
|
|
183645
184307
|
? t(STATUS_LABEL_KEYS[row.status])
|
|
183646
184308
|
: row.status }) })] }, row.id));
|
|
183647
|
-
})) })] }) }), 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$
|
|
184309
|
+
})) })] }) }), 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" })] }))] }));
|
|
184310
|
+
}
|
|
184311
|
+
|
|
184312
|
+
/**
|
|
184313
|
+
* Single-select searchable picker: a deb-ounce-agnostic input + absolute
|
|
184314
|
+
* results dropdown (the add-access pattern), collapsing to a removable chip
|
|
184315
|
+
* once something is picked. The caller owns the search term and the fetched
|
|
184316
|
+
* options so any query hook can back it.
|
|
184317
|
+
*/
|
|
184318
|
+
function SearchSelect({ labels, selected, onSelect, onClear, searchTerm, onSearchTermChange, options, isLoading, minChars = 2, labelClassName = 'text-xs font-medium text-gray-700', testId, }) {
|
|
184319
|
+
const [isOpen, setIsOpen] = React__default.useState(false);
|
|
184320
|
+
const blurTimeout = React__default.useRef(null);
|
|
184321
|
+
React__default.useEffect(() => () => {
|
|
184322
|
+
if (blurTimeout.current)
|
|
184323
|
+
clearTimeout(blurTimeout.current);
|
|
184324
|
+
}, []);
|
|
184325
|
+
if (selected) {
|
|
184326
|
+
return (jsxs("div", { className: "space-y-1.5", children: [labels.label && jsx(Label$1, { className: labelClassName, children: labels.label }), jsxs("div", { className: "flex items-center justify-between gap-2 rounded-md border border-gray-200 bg-gray-50 px-3 py-2", "data-testid": `${testId}-selected`, children: [jsxs("div", { className: "min-w-0", children: [jsx("p", { className: "truncate text-sm font-medium text-gray-900", children: selected.label }), selected.sublabel && (jsx("p", { className: "truncate text-xs text-gray-600", children: selected.sublabel }))] }), jsxs(Button$1, { type: "button", size: "icon", variant: "ghost", className: "h-6 w-6 flex-shrink-0 text-gray-500 hover:text-red-600", onClick: onClear, "data-testid": `${testId}-clear`, children: [jsx(X$2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), jsx("span", { className: "sr-only", children: labels.clear })] })] })] }));
|
|
184327
|
+
}
|
|
184328
|
+
return (jsxs("div", { className: "space-y-1.5", children: [labels.label && (jsx(Label$1, { className: labelClassName, htmlFor: `${testId}-input`, children: labels.label })), jsxs("div", { className: "relative", children: [jsx(Input, { id: `${testId}-input`, className: "focus-visible:border-blue-500 focus-visible:ring-1 focus-visible:ring-blue-500", "aria-label": labels.label || labels.placeholder, value: searchTerm, onChange: (e) => onSearchTermChange(e.target.value), onFocus: () => {
|
|
184329
|
+
if (blurTimeout.current)
|
|
184330
|
+
clearTimeout(blurTimeout.current);
|
|
184331
|
+
setIsOpen(true);
|
|
184332
|
+
}, onBlur: () => {
|
|
184333
|
+
blurTimeout.current = setTimeout(() => setIsOpen(false), 100);
|
|
184334
|
+
}, placeholder: labels.placeholder, autoComplete: "off", "aria-autocomplete": "list", "aria-expanded": isOpen, "data-testid": `${testId}-input` }), isOpen && (jsx("div", { className: "absolute top-full right-0 left-0 z-50 mt-1 max-h-64 overflow-y-auto rounded-md border border-gray-200 bg-white shadow-lg", "data-testid": `${testId}-results`, children: searchTerm.trim().length < minChars ? (jsx("div", { className: "px-3 py-2 text-sm text-gray-600", children: labels.typeToSearch })) : isLoading ? (jsxs("div", { className: "flex items-center gap-2 px-3 py-2 text-sm text-gray-600", children: [jsx(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin", "aria-hidden": "true" }), labels.searching] })) : options.length > 0 ? (options.map((option) => (jsxs("button", { type: "button", className: "flex w-full flex-col items-start gap-0.5 px-3 py-2 text-left hover:bg-gray-50", onMouseDown: (event) => event.preventDefault(), onClick: () => {
|
|
184335
|
+
onSelect(option);
|
|
184336
|
+
setIsOpen(false);
|
|
184337
|
+
}, "data-testid": `${testId}-option-${option.value}`, children: [jsx("span", { className: "text-sm font-medium text-gray-900", children: option.label }), option.sublabel && (jsx("span", { className: "text-xs text-gray-600", children: option.sublabel }))] }, option.value)))) : (jsx("div", { className: "px-3 py-2 text-sm text-gray-600", "data-testid": `${testId}-no-results`, children: labels.noResults })) }))] })] }));
|
|
184338
|
+
}
|
|
184339
|
+
|
|
184340
|
+
// The user-onboarding form contract: the schema an admin authors in the admin
|
|
184341
|
+
// panel, where both it and the learners' answers live (tenant metadata), and
|
|
184342
|
+
// the pure readers/writers both sides share. No React here so it stays unit
|
|
184343
|
+
// testable.
|
|
184344
|
+
//
|
|
184345
|
+
// Storage (tenant metadata, `PUT /api/core/orgs/<org>/metadata/`):
|
|
184346
|
+
// `user_onboarding_form` -> one {@link UserOnboardingForm}
|
|
184347
|
+
// `user_onboarding_submission` -> { [username]: {@link UserOnboardingSubmission} }
|
|
184348
|
+
//
|
|
184349
|
+
// The metadata endpoint replaces the whole metadata object, so every writer
|
|
184350
|
+
// here takes the current metadata and returns a merged copy.
|
|
184351
|
+
/** Tenant-metadata key holding the admin-authored onboarding form. */
|
|
184352
|
+
const USER_ONBOARDING_FORM_SLUG = 'user_onboarding_form';
|
|
184353
|
+
/** Bump when the persisted form/submission shape changes. */
|
|
184354
|
+
const USER_ONBOARDING_FORM_VERSION = 1;
|
|
184355
|
+
/** Metadata values reach us as objects or, on older writes, JSON strings. */
|
|
184356
|
+
function parseMetadataValue(raw) {
|
|
184357
|
+
if (typeof raw !== 'string')
|
|
184358
|
+
return raw;
|
|
184359
|
+
try {
|
|
184360
|
+
return JSON.parse(raw);
|
|
184361
|
+
}
|
|
184362
|
+
catch (_a) {
|
|
184363
|
+
return undefined;
|
|
184364
|
+
}
|
|
184365
|
+
}
|
|
184366
|
+
function isRecord(value) {
|
|
184367
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
184368
|
+
}
|
|
184369
|
+
/** A blank form for a platform that has never configured onboarding. */
|
|
184370
|
+
function emptyUserOnboardingForm(title = '') {
|
|
184371
|
+
return {
|
|
184372
|
+
version: USER_ONBOARDING_FORM_VERSION,
|
|
184373
|
+
enabled: false,
|
|
184374
|
+
title,
|
|
184375
|
+
sections: [],
|
|
184376
|
+
agent: null,
|
|
184377
|
+
};
|
|
184378
|
+
}
|
|
184379
|
+
/** Defensive read of a stored agent selection; null when unusable. */
|
|
184380
|
+
function coerceOnboardingAgent(raw) {
|
|
184381
|
+
var _a, _b;
|
|
184382
|
+
const value = parseMetadataValue(raw);
|
|
184383
|
+
if (!isRecord(value))
|
|
184384
|
+
return null;
|
|
184385
|
+
const id = (_b = (_a = value.mentor_unique_id) !== null && _a !== void 0 ? _a : value.unique_id) !== null && _b !== void 0 ? _b : value.mentor;
|
|
184386
|
+
if (typeof id !== 'string' || !id.trim())
|
|
184387
|
+
return null;
|
|
184388
|
+
return {
|
|
184389
|
+
mentor_unique_id: id,
|
|
184390
|
+
name: typeof value.name === 'string' ? value.name : undefined,
|
|
184391
|
+
title: typeof value.title === 'string' ? value.title : undefined,
|
|
184392
|
+
description: typeof value.description === 'string' ? value.description : undefined,
|
|
184393
|
+
};
|
|
184394
|
+
}
|
|
184395
|
+
/**
|
|
184396
|
+
* Defensive read of the stored form. Anything unrecognizable (missing key,
|
|
184397
|
+
* wrong type, unparseable string) reads as an empty, disabled form so both the
|
|
184398
|
+
* editor and the wizard always have something to work with.
|
|
184399
|
+
*/
|
|
184400
|
+
function coerceUserOnboardingForm(raw) {
|
|
184401
|
+
const value = parseMetadataValue(raw);
|
|
184402
|
+
if (!isRecord(value))
|
|
184403
|
+
return emptyUserOnboardingForm();
|
|
184404
|
+
const sections = Array.isArray(value.sections)
|
|
184405
|
+
? value.sections.filter((section) => isRecord(section) && Array.isArray(section.fields))
|
|
184406
|
+
: [];
|
|
184407
|
+
return {
|
|
184408
|
+
version: typeof value.version === 'number' ? value.version : USER_ONBOARDING_FORM_VERSION,
|
|
184409
|
+
enabled: value.enabled === true,
|
|
184410
|
+
title: typeof value.title === 'string' ? value.title : '',
|
|
184411
|
+
description: typeof value.description === 'string' ? value.description : undefined,
|
|
184412
|
+
sections,
|
|
184413
|
+
agent: coerceOnboardingAgent(value.agent),
|
|
184414
|
+
updated_at: typeof value.updated_at === 'string' ? value.updated_at : undefined,
|
|
184415
|
+
};
|
|
184416
|
+
}
|
|
184417
|
+
/** Read the onboarding form out of a tenant's metadata. */
|
|
184418
|
+
function readUserOnboardingForm(metadata) {
|
|
184419
|
+
return coerceUserOnboardingForm(metadata === null || metadata === void 0 ? void 0 : metadata[USER_ONBOARDING_FORM_SLUG]);
|
|
184420
|
+
}
|
|
184421
|
+
/**
|
|
184422
|
+
* Merge the form into the tenant metadata for a `PUT` (the endpoint replaces
|
|
184423
|
+
* the whole object, so untouched keys must ride along).
|
|
184424
|
+
*/
|
|
184425
|
+
function buildUserOnboardingFormMetadata(metadata, form, updatedAt) {
|
|
184426
|
+
var _a;
|
|
184427
|
+
return {
|
|
184428
|
+
...(metadata !== null && metadata !== void 0 ? metadata : {}),
|
|
184429
|
+
[USER_ONBOARDING_FORM_SLUG]: {
|
|
184430
|
+
...form,
|
|
184431
|
+
version: USER_ONBOARDING_FORM_VERSION,
|
|
184432
|
+
agent: (_a = form.agent) !== null && _a !== void 0 ? _a : null,
|
|
184433
|
+
updated_at: updatedAt,
|
|
184434
|
+
},
|
|
184435
|
+
};
|
|
184436
|
+
}
|
|
184437
|
+
|
|
184438
|
+
/**
|
|
184439
|
+
* Onboarding management: which agent every new member of the platform
|
|
184440
|
+
* meets, and how it is introduced (heading + sub-heading).
|
|
184441
|
+
*
|
|
184442
|
+
* The whole thing is one tenant-metadata key (`user_onboarding_form`), so
|
|
184443
|
+
* saving merges the choice in and PUTs the metadata back. The member-facing
|
|
184444
|
+
* side is `OnboardingWizard` with `isAdminOnboarding={false}`, which shows the
|
|
184445
|
+
* agent — and nothing at all when no agent is set, handing the user straight
|
|
184446
|
+
* back to the app.
|
|
184447
|
+
*/
|
|
184448
|
+
function OnboardingTab({ platformKey, username, }) {
|
|
184449
|
+
var _a, _b, _c;
|
|
184450
|
+
const t = useT();
|
|
184451
|
+
const { data, isLoading, error } = useGetTenantMetadataQuery([{ org: platformKey }], {
|
|
184452
|
+
skip: !platformKey,
|
|
184453
|
+
refetchOnMountOrArgChange: true,
|
|
184454
|
+
});
|
|
184455
|
+
const metadata = data === null || data === void 0 ? void 0 : data.metadata;
|
|
184456
|
+
const resolvedUsername = React.useMemo(() => {
|
|
184457
|
+
var _a;
|
|
184458
|
+
if (username)
|
|
184459
|
+
return username;
|
|
184460
|
+
try {
|
|
184461
|
+
return (_a = getUserName$1()) !== null && _a !== void 0 ? _a : '';
|
|
184462
|
+
}
|
|
184463
|
+
catch (_b) {
|
|
184464
|
+
return '';
|
|
184465
|
+
}
|
|
184466
|
+
}, [username]);
|
|
184467
|
+
const [agent, setAgent] = React.useState(null);
|
|
184468
|
+
const [dirty, setDirty] = React.useState(false);
|
|
184469
|
+
// Seed from the saved metadata, and re-seed when a refetch brings a newer
|
|
184470
|
+
// saved version.
|
|
184471
|
+
const saved = readUserOnboardingForm(metadata);
|
|
184472
|
+
const savedAt = saved.updated_at;
|
|
184473
|
+
React.useEffect(() => {
|
|
184474
|
+
var _a;
|
|
184475
|
+
if (!metadata)
|
|
184476
|
+
return;
|
|
184477
|
+
setAgent((_a = readUserOnboardingForm(metadata).agent) !== null && _a !== void 0 ? _a : null);
|
|
184478
|
+
setDirty(false);
|
|
184479
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
184480
|
+
}, [!!metadata, savedAt]);
|
|
184481
|
+
const update = (next) => {
|
|
184482
|
+
setAgent(next);
|
|
184483
|
+
setDirty(true);
|
|
184484
|
+
};
|
|
184485
|
+
// Agent search — the endpoint filters server-side, so only the term is local.
|
|
184486
|
+
const [searchTerm, setSearchTerm] = React.useState('');
|
|
184487
|
+
const [debouncedTerm, setDebouncedTerm] = React.useState('');
|
|
184488
|
+
React.useEffect(() => {
|
|
184489
|
+
const timer = setTimeout(() => setDebouncedTerm(searchTerm.trim()), 300);
|
|
184490
|
+
return () => clearTimeout(timer);
|
|
184491
|
+
}, [searchTerm]);
|
|
184492
|
+
const { data: mentorsData, isFetching: isSearching } = useGetMentorsQuery({
|
|
184493
|
+
org: platformKey,
|
|
184494
|
+
username: resolvedUsername,
|
|
184495
|
+
limit: 20,
|
|
184496
|
+
...(debouncedTerm ? { query: debouncedTerm } : {}),
|
|
184497
|
+
}, { skip: !platformKey || !resolvedUsername });
|
|
184498
|
+
const options = ((_a = mentorsData === null || mentorsData === void 0 ? void 0 : mentorsData.results) !== null && _a !== void 0 ? _a : [])
|
|
184499
|
+
.filter((mentor) => !!mentor.unique_id)
|
|
184500
|
+
.map((mentor) => ({
|
|
184501
|
+
value: mentor.unique_id,
|
|
184502
|
+
label: mentor.name || mentor.unique_id,
|
|
184503
|
+
sublabel: mentor.description || undefined,
|
|
184504
|
+
}));
|
|
184505
|
+
const [updateTenantMetadata, { isLoading: saving }] = useUpdateTenantMetadataMutation();
|
|
184506
|
+
const [fetchTenantMetadata] = useLazyGetTenantMetadataQuery();
|
|
184507
|
+
/**
|
|
184508
|
+
* Save onto the tenant metadata. The endpoint replaces the whole metadata
|
|
184509
|
+
* object, so the newest copy is re-read immediately before merging rather
|
|
184510
|
+
* than trusting the one loaded on mount.
|
|
184511
|
+
*/
|
|
184512
|
+
const handleSave = async () => {
|
|
184513
|
+
var _a;
|
|
184514
|
+
try {
|
|
184515
|
+
let latest = metadata;
|
|
184516
|
+
try {
|
|
184517
|
+
const fresh = (await fetchTenantMetadata([{ org: platformKey }]).unwrap());
|
|
184518
|
+
latest = (_a = fresh === null || fresh === void 0 ? void 0 : fresh.metadata) !== null && _a !== void 0 ? _a : latest;
|
|
184519
|
+
}
|
|
184520
|
+
catch (_b) {
|
|
184521
|
+
// Fall back to the copy loaded on mount.
|
|
184522
|
+
}
|
|
184523
|
+
await updateTenantMetadata([
|
|
184524
|
+
{
|
|
184525
|
+
org: platformKey,
|
|
184526
|
+
// @ts-expect-error requestBody is not part of the useUpdateTenantMetadataMutation Query Definition
|
|
184527
|
+
requestBody: {
|
|
184528
|
+
metadata: buildUserOnboardingFormMetadata(latest, {
|
|
184529
|
+
...emptyUserOnboardingForm(),
|
|
184530
|
+
// An agent IS the onboarding here: picking one turns the flow
|
|
184531
|
+
// on, clearing it turns the flow off.
|
|
184532
|
+
enabled: !!agent,
|
|
184533
|
+
agent,
|
|
184534
|
+
}, new Date().toISOString()),
|
|
184535
|
+
},
|
|
184536
|
+
},
|
|
184537
|
+
]).unwrap();
|
|
184538
|
+
setDirty(false);
|
|
184539
|
+
toast.success(t('profileOnboardingTab.savedToast'));
|
|
184540
|
+
}
|
|
184541
|
+
catch (_c) {
|
|
184542
|
+
toast.error(t('profileOnboardingTab.saveFailedToast'));
|
|
184543
|
+
}
|
|
184544
|
+
};
|
|
184545
|
+
if (isLoading) {
|
|
184546
|
+
return (jsxs("div", { className: "space-y-4 pt-4", children: [jsx(Skeleton, { className: "h-8 w-56" }), jsx(Skeleton, { className: "h-40 w-full" })] }));
|
|
184547
|
+
}
|
|
184548
|
+
if (error) {
|
|
184549
|
+
return jsx("p", { className: "pt-4 text-sm text-red-600", children: t('profileOnboardingTab.loadError') });
|
|
184550
|
+
}
|
|
184551
|
+
return (jsxs("div", { className: "space-y-5 pt-4", children: [jsxs("div", { className: "space-y-4 rounded-xl border border-gray-200 bg-white p-5 shadow-sm dark:border-gray-700 dark:bg-gray-900", children: [jsx(SearchSelect, { testId: "onboarding-agent", labels: {
|
|
184552
|
+
label: t('profileOnboardingTab.agentLabel'),
|
|
184553
|
+
placeholder: t('profileOnboardingTab.searchAgents'),
|
|
184554
|
+
typeToSearch: t('profileOnboardingTab.searchAgents'),
|
|
184555
|
+
searching: t('profileOnboardingTab.loadingAgents'),
|
|
184556
|
+
noResults: t('profileOnboardingTab.noAgents'),
|
|
184557
|
+
clear: t('profileOnboardingTab.clearAgent'),
|
|
184558
|
+
},
|
|
184559
|
+
// Focusing shows the platform's agents straight away; typing filters.
|
|
184560
|
+
minChars: 0,
|
|
184561
|
+
// The picker's own compact label would sit a size below the Heading
|
|
184562
|
+
// and Sub-heading fields beside it; match them instead.
|
|
184563
|
+
labelClassName: "text-sm font-medium", selected: agent
|
|
184564
|
+
? { value: agent.mentor_unique_id, label: agent.name || agent.mentor_unique_id }
|
|
184565
|
+
: null, onSelect: (option) => update({ ...(agent !== null && agent !== void 0 ? agent : {}), mentor_unique_id: option.value, name: option.label }), onClear: () => update(null), searchTerm: searchTerm, onSearchTermChange: setSearchTerm, options: options, isLoading: isSearching }), agent && (jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { htmlFor: "onboarding-agent-title", children: t('profileOnboardingTab.agentTitleLabel') }), jsx(Input, { id: "onboarding-agent-title", value: (_b = agent.title) !== null && _b !== void 0 ? _b : '', placeholder: t('profileOnboardingTab.agentTitlePlaceholder'), onChange: (event) => update({ ...agent, title: event.target.value }) })] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { htmlFor: "onboarding-agent-description", children: t('profileOnboardingTab.agentDescriptionLabel') }), jsx(Input, { id: "onboarding-agent-description", value: (_c = agent.description) !== null && _c !== void 0 ? _c : '', placeholder: t('profileOnboardingTab.agentDescriptionPlaceholder'), onChange: (event) => update({ ...agent, description: event.target.value }) })] })] })), !agent && jsx("p", { className: "text-xs text-gray-400", children: t('profileOnboardingTab.noAgentHint') })] }), jsxs("div", { className: "flex flex-wrap items-center justify-end gap-3", children: [dirty && (jsx("span", { className: "text-xs text-amber-600", children: t('profileOnboardingTab.unsavedChanges') })), jsx(Button$1, { onClick: handleSave, disabled: saving, className: "bg-gradient-to-r from-blue-600 to-blue-400 text-white hover:opacity-90", children: saving ? t('profileOnboardingTab.saving') : t('profileOnboardingTab.save') })] })] }));
|
|
183648
184566
|
}
|
|
183649
184567
|
|
|
183650
184568
|
const TabDescription = ({ icon, title, children }) => {
|
|
@@ -183654,7 +184572,7 @@ const TabDescription = ({ icon, title, children }) => {
|
|
|
183654
184572
|
};
|
|
183655
184573
|
const Admin = ({ tenant, onInviteClick, hasUserTabPermission = false, hasGroupsTabPermission = false, hasRolesTabPermission = false, hasPoliciesTabPermission = false, hasTeamsTabPermission = false, hasAlertsTabPermission = false, hasInviteUserPermission = false, hasCreateTeamPermission = false, onLoadGroupPermissions, rbacPermissions = {}, enableRbac = false, showGradebookTab = false, currentSpa, authSpaUrl, }) => {
|
|
183656
184574
|
const t = useT();
|
|
183657
|
-
return (jsx("div", { className: "border border-gray-200 rounded-lg p-6", children: jsxs(Tabs, { defaultValue: "users", "aria-label": t('profileAdmin.rbacManagementTabsAriaLabel'), children: [jsxs(TabsList, { "aria-label": t('profileAdmin.managementTabsAriaLabel'), className: "max-w-full overflow-x-auto justify-start px-1", children: [hasUserTabPermission && (jsx(TabsTrigger, { value: "users", children: t('profileAdmin.usersTab') })), hasGroupsTabPermission && (jsx(TabsTrigger, { value: "groups", children: t('profileAdmin.groupsTab') })), hasRolesTabPermission && (jsx(TabsTrigger, { value: "roles", children: t('profileAdmin.rolesTab') })), hasPoliciesTabPermission && (jsx(TabsTrigger, { value: "policies", children: t('profileAdmin.policiesTab') })), hasTeamsTabPermission && (jsx(TabsTrigger, { value: "teams", children: t('profileAdmin.teamsTab') })), hasAlertsTabPermission && (jsx(TabsTrigger, { value: "alerts", children: t('profileAdmin.alertsTab') })), jsx(TabsTrigger, { value: "applications", children: t('profileAdmin.applicationsTab') })] }), hasUserTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "users", children: [jsx(TabDescription, { icon: jsx(Users, { className: "w-5 h-5" }), title: t('profileAdmin.usersTab'), children: t('profileAdmin.usersDescription') }), jsx(UsersTab, { tenant: tenant, onInviteClick: onInviteClick, currentSpa: currentSpa, showGradebookTab: showGradebookTab })] })), hasGroupsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "groups", children: [jsx(TabDescription, { icon: jsx(UsersRound, { className: "w-5 h-5" }), title: t('profileAdmin.groupsTab'), children: t('profileAdmin.groupsDescription') }), jsx(GroupsTab, { tenant: tenant })] })), hasRolesTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "roles", children: [jsx(TabDescription, { icon: jsx(UserCog, { className: "w-5 h-5" }), title: t('profileAdmin.rolesTab'), children: t('profileAdmin.rolesDescription') }), jsx(RolesTab, { tenant: tenant })] })), hasPoliciesTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "policies", children: [jsx(TabDescription, { icon: jsx(ScrollText, { className: "w-5 h-5" }), title: t('profileAdmin.policiesTab'), children: t('profileAdmin.policiesDescription') }), jsx(PoliciesTab, { tenant: tenant })] })), hasTeamsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "teams", children: [jsx(TabDescription, { icon: jsx(Shield, { className: "w-5 h-5" }), title: t('profileAdmin.teamsTab'), children: t('profileAdmin.teamsDescription') }), jsx(GroupsTab, { tenant: tenant, isTeam: true, onInviteClick: onInviteClick, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac })] })), hasAlertsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "alerts", children: [jsx(TabDescription, { icon: jsx(BellRing, { className: "w-5 h-5" }), title: t('profileAdmin.alertsTab'), children: t('profileAdmin.alertsDescription') }), jsx(AlertsTab, { tenant: tenant })] })), jsxs(TabsContent, { className: "mt-4", value: "applications", children: [jsx(TabDescription, { icon: jsx(ClipboardList, { className: "w-5 h-5" }), title: t('profileAdmin.applicationsTab'), children: t('profileAdmin.applicationsTabDescription') }), jsx(ApplicationsTab, { platformKey: tenant, authSpaUrl: authSpaUrl })] })] }) }));
|
|
184575
|
+
return (jsx("div", { className: "border border-gray-200 rounded-lg p-6", children: jsxs(Tabs, { defaultValue: "users", "aria-label": t('profileAdmin.rbacManagementTabsAriaLabel'), children: [jsxs(TabsList, { "aria-label": t('profileAdmin.managementTabsAriaLabel'), className: "max-w-full overflow-x-auto justify-start px-1", children: [hasUserTabPermission && (jsx(TabsTrigger, { value: "users", children: t('profileAdmin.usersTab') })), hasGroupsTabPermission && (jsx(TabsTrigger, { value: "groups", children: t('profileAdmin.groupsTab') })), hasRolesTabPermission && (jsx(TabsTrigger, { value: "roles", children: t('profileAdmin.rolesTab') })), hasPoliciesTabPermission && (jsx(TabsTrigger, { value: "policies", children: t('profileAdmin.policiesTab') })), hasTeamsTabPermission && (jsx(TabsTrigger, { value: "teams", children: t('profileAdmin.teamsTab') })), hasAlertsTabPermission && (jsx(TabsTrigger, { value: "alerts", children: t('profileAdmin.alertsTab') })), jsx(TabsTrigger, { value: "applications", children: t('profileAdmin.applicationsTab') }), jsx(TabsTrigger, { value: "onboarding", children: t('profileAdmin.onboardingTab') })] }), hasUserTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "users", children: [jsx(TabDescription, { icon: jsx(Users, { className: "w-5 h-5" }), title: t('profileAdmin.usersTab'), children: t('profileAdmin.usersDescription') }), jsx(UsersTab, { tenant: tenant, onInviteClick: onInviteClick, currentSpa: currentSpa, showGradebookTab: showGradebookTab })] })), hasGroupsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "groups", children: [jsx(TabDescription, { icon: jsx(UsersRound, { className: "w-5 h-5" }), title: t('profileAdmin.groupsTab'), children: t('profileAdmin.groupsDescription') }), jsx(GroupsTab, { tenant: tenant })] })), hasRolesTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "roles", children: [jsx(TabDescription, { icon: jsx(UserCog, { className: "w-5 h-5" }), title: t('profileAdmin.rolesTab'), children: t('profileAdmin.rolesDescription') }), jsx(RolesTab, { tenant: tenant })] })), hasPoliciesTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "policies", children: [jsx(TabDescription, { icon: jsx(ScrollText, { className: "w-5 h-5" }), title: t('profileAdmin.policiesTab'), children: t('profileAdmin.policiesDescription') }), jsx(PoliciesTab, { tenant: tenant })] })), hasTeamsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "teams", children: [jsx(TabDescription, { icon: jsx(Shield, { className: "w-5 h-5" }), title: t('profileAdmin.teamsTab'), children: t('profileAdmin.teamsDescription') }), jsx(GroupsTab, { tenant: tenant, isTeam: true, onInviteClick: onInviteClick, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac })] })), hasAlertsTabPermission && (jsxs(TabsContent, { className: "mt-4", value: "alerts", children: [jsx(TabDescription, { icon: jsx(BellRing, { className: "w-5 h-5" }), title: t('profileAdmin.alertsTab'), children: t('profileAdmin.alertsDescription') }), jsx(AlertsTab, { tenant: tenant })] })), jsxs(TabsContent, { className: "mt-4", value: "applications", children: [jsx(TabDescription, { icon: jsx(ClipboardList, { className: "w-5 h-5" }), title: t('profileAdmin.applicationsTab'), children: t('profileAdmin.applicationsTabDescription') }), jsx(ApplicationsTab, { platformKey: tenant, authSpaUrl: authSpaUrl })] }), jsxs(TabsContent, { className: "mt-4", value: "onboarding", children: [jsx(TabDescription, { icon: jsx(UserPlus, { className: "w-5 h-5" }), title: t('profileAdmin.onboardingTab'), children: t('profileAdmin.onboardingTabDescription') }), jsx(OnboardingTab, { platformKey: tenant })] })] }) }));
|
|
183658
184576
|
};
|
|
183659
184577
|
|
|
183660
184578
|
function DeleteApiModal$1({ isOpen, onClose, apiKey, tenantKey }) {
|
|
@@ -190002,34 +190920,6 @@ TableCell$1.displayName = "TableCell";
|
|
|
190002
190920
|
const TableCaption = React.forwardRef(({ className, ...props }, ref) => (jsx("caption", { ref: ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props })));
|
|
190003
190921
|
TableCaption.displayName = "TableCaption";
|
|
190004
190922
|
|
|
190005
|
-
/**
|
|
190006
|
-
* Single-select searchable picker: a deb-ounce-agnostic input + absolute
|
|
190007
|
-
* results dropdown (the add-access pattern), collapsing to a removable chip
|
|
190008
|
-
* once something is picked. The caller owns the search term and the fetched
|
|
190009
|
-
* options so any query hook can back it.
|
|
190010
|
-
*/
|
|
190011
|
-
function SearchSelect({ labels, selected, onSelect, onClear, searchTerm, onSearchTermChange, options, isLoading, minChars = 2, testId, }) {
|
|
190012
|
-
const [isOpen, setIsOpen] = React__default.useState(false);
|
|
190013
|
-
const blurTimeout = React__default.useRef(null);
|
|
190014
|
-
React__default.useEffect(() => () => {
|
|
190015
|
-
if (blurTimeout.current)
|
|
190016
|
-
clearTimeout(blurTimeout.current);
|
|
190017
|
-
}, []);
|
|
190018
|
-
if (selected) {
|
|
190019
|
-
return (jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { className: "text-xs font-medium text-gray-700", children: labels.label }), jsxs("div", { className: "flex items-center justify-between gap-2 rounded-md border border-gray-200 bg-gray-50 px-3 py-2", "data-testid": `${testId}-selected`, children: [jsxs("div", { className: "min-w-0", children: [jsx("p", { className: "truncate text-sm font-medium text-gray-900", children: selected.label }), selected.sublabel && (jsx("p", { className: "truncate text-xs text-gray-600", children: selected.sublabel }))] }), jsxs(Button$1, { type: "button", size: "icon", variant: "ghost", className: "h-6 w-6 flex-shrink-0 text-gray-500 hover:text-red-600", onClick: onClear, "data-testid": `${testId}-clear`, children: [jsx(X$2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }), jsx("span", { className: "sr-only", children: labels.clear })] })] })] }));
|
|
190020
|
-
}
|
|
190021
|
-
return (jsxs("div", { className: "space-y-1.5", children: [jsx(Label$1, { className: "text-xs font-medium text-gray-700", htmlFor: `${testId}-input`, children: labels.label }), jsxs("div", { className: "relative", children: [jsx(Input, { id: `${testId}-input`, className: "focus-visible:border-blue-500 focus-visible:ring-1 focus-visible:ring-blue-500", value: searchTerm, onChange: (e) => onSearchTermChange(e.target.value), onFocus: () => {
|
|
190022
|
-
if (blurTimeout.current)
|
|
190023
|
-
clearTimeout(blurTimeout.current);
|
|
190024
|
-
setIsOpen(true);
|
|
190025
|
-
}, onBlur: () => {
|
|
190026
|
-
blurTimeout.current = setTimeout(() => setIsOpen(false), 100);
|
|
190027
|
-
}, placeholder: labels.placeholder, autoComplete: "off", "aria-autocomplete": "list", "aria-expanded": isOpen, "data-testid": `${testId}-input` }), isOpen && (jsx("div", { className: "absolute top-full right-0 left-0 z-50 mt-1 max-h-64 overflow-y-auto rounded-md border border-gray-200 bg-white shadow-lg", "data-testid": `${testId}-results`, children: searchTerm.trim().length < minChars ? (jsx("div", { className: "px-3 py-2 text-sm text-gray-600", children: labels.typeToSearch })) : isLoading ? (jsxs("div", { className: "flex items-center gap-2 px-3 py-2 text-sm text-gray-600", children: [jsx(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin", "aria-hidden": "true" }), labels.searching] })) : options.length > 0 ? (options.map((option) => (jsxs("button", { type: "button", className: "flex w-full flex-col items-start gap-0.5 px-3 py-2 text-left hover:bg-gray-50", onMouseDown: (event) => event.preventDefault(), onClick: () => {
|
|
190028
|
-
onSelect(option);
|
|
190029
|
-
setIsOpen(false);
|
|
190030
|
-
}, "data-testid": `${testId}-option-${option.value}`, children: [jsx("span", { className: "text-sm font-medium text-gray-900", children: option.label }), option.sublabel && (jsx("span", { className: "text-xs text-gray-600", children: option.sublabel }))] }, option.value)))) : (jsx("div", { className: "px-3 py-2 text-sm text-gray-600", "data-testid": `${testId}-no-results`, children: labels.noResults })) }))] })] }));
|
|
190031
|
-
}
|
|
190032
|
-
|
|
190033
190923
|
/**
|
|
190034
190924
|
* The shared `Profile` viewer in a dialog — the same modal the tenant
|
|
190035
190925
|
* Management tab opens when a user row is clicked. Controlled variant for
|
|
@@ -192836,7 +193726,7 @@ function ItemSearchDropdown({ platformKey, onSelect, }) {
|
|
|
192836
193726
|
}, 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') })) }))] }));
|
|
192837
193727
|
}
|
|
192838
193728
|
|
|
192839
|
-
const PAGE_SIZE$
|
|
193729
|
+
const PAGE_SIZE$a = 8;
|
|
192840
193730
|
function PaywalledItemsList({ platformKey, onSelectItem, onAddCustomItem, }) {
|
|
192841
193731
|
const t = useT();
|
|
192842
193732
|
const [page, setPage] = useState(1);
|
|
@@ -192844,7 +193734,7 @@ function PaywalledItemsList({ platformKey, onSelectItem, onAddCustomItem, }) {
|
|
|
192844
193734
|
const { data: paywalls, isLoading } = useListPaywallsQuery({
|
|
192845
193735
|
platform_key: platformKey,
|
|
192846
193736
|
page,
|
|
192847
|
-
page_size: PAGE_SIZE$
|
|
193737
|
+
page_size: PAGE_SIZE$a,
|
|
192848
193738
|
...(statusFilter !== 'all' && { is_enabled: statusFilter === 'active' }),
|
|
192849
193739
|
}, { refetchOnMountOrArgChange: true });
|
|
192850
193740
|
return (jsxs("div", { className: "space-y-4", children: [jsx(Card, { className: "shadow-sm border", style: { borderColor: 'oklch(.922 0 0)' }, children: jsxs(CardContent, { className: "p-4", children: [jsx("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 mb-3", children: t('monetizationPaywalledItemsList.configureItemForSale') }), jsxs("div", { className: "flex items-center gap-2", children: [jsx(ItemSearchDropdown, { platformKey: platformKey, onSelect: (itemType, uniqueId, name) => onSelectItem(itemType, uniqueId, name) }), jsx(Button$1, { variant: "outline", size: "icon", onClick: onAddCustomItem, className: "shrink-0 cursor-pointer", title: t('monetizationPaywalledItemsList.addCustomItemTitle'), children: jsx(Plus, { className: "h-4 w-4" }) })] })] }) }), jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-medium text-gray-500", children: t('monetizationPaywalledItemsList.configuredItems') }), jsxs(Select$1, { value: statusFilter, onValueChange: (v) => {
|
|
@@ -192867,7 +193757,7 @@ function PaywalledItemsList({ platformKey, onSelectItem, onAddCustomItem, }) {
|
|
|
192867
193757
|
: 'bg-gray-100 text-gray-500 border-gray-200 hover:bg-gray-100', children: pw.is_enabled
|
|
192868
193758
|
? t('monetizationPaywalledItemsList.statusActive')
|
|
192869
193759
|
: t('monetizationPaywalledItemsList.statusDisabled') })] }) }, `${pw.item_type}-${pw.item_id}`));
|
|
192870
|
-
}), jsx(AdvancedPagination, { variant: "footer", className: "mt-2 rounded-lg border", currentPage: page, totalPages: Math.ceil(paywalls.count / PAGE_SIZE$
|
|
193760
|
+
}), 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'
|
|
192871
193761
|
? t('monetizationPaywalledItemsList.noFilteredItemsFound', { status: statusFilter })
|
|
192872
193762
|
: t('monetizationPaywalledItemsList.noItemsConfigured') }))] })] }));
|
|
192873
193763
|
}
|
|
@@ -220700,6 +221590,12 @@ AlertDialogAction.displayName = Action.displayName;
|
|
|
220700
221590
|
const AlertDialogCancel = React.forwardRef(({ className, ...props }, ref) => (jsx(Cancel, { ref: ref, className: cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', className), ...props })));
|
|
220701
221591
|
AlertDialogCancel.displayName = Cancel.displayName;
|
|
220702
221592
|
|
|
221593
|
+
// Notification bodies are arbitrary (often email) HTML: long unbroken URLs and
|
|
221594
|
+
// fixed-width tables would otherwise bleed out of the panel. Break long words,
|
|
221595
|
+
// cap every descendant at the container width, and let anything that still
|
|
221596
|
+
// cannot shrink scroll inside the body instead of stretching the layout.
|
|
221597
|
+
cn('prose prose-sm max-w-none text-gray-700', 'overflow-x-auto break-words [overflow-wrap:anywhere]', '[&_*]:max-w-full', '[&_a]:break-all', '[&_img]:h-auto', '[&_pre]:overflow-x-auto [&_pre]:whitespace-pre-wrap', '[&_code]:whitespace-pre-wrap');
|
|
221598
|
+
|
|
220703
221599
|
const THEMES = { light: '', dark: '.dark' };
|
|
220704
221600
|
const ChartContext = React.createContext(null);
|
|
220705
221601
|
function useChart() {
|
|
@@ -258028,7 +258924,7 @@ function RetrievedDocumentsButton({ sessionId }) {
|
|
|
258028
258924
|
return (jsxs(Fragment$1, { children: [jsxs(Button$1, { variant: "outline", size: "sm", className: "flex items-center gap-2 border-gray-200 bg-white text-gray-700 hover:bg-gray-50", onClick: () => setIsOpen(true), children: [jsx(FileText, { className: "h-4 w-4 text-blue-600" }), jsx("span", { children: t('retrievedDocumentsButton.title') })] }), jsx(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: jsxs(DialogContent, { className: "flex max-h-[80vh] flex-col gap-0 p-0 sm:max-w-[425px] md:max-w-[600px]", children: [jsx(DialogHeader, { className: "border-b px-4 py-2", children: jsxs(DialogTitle, { className: "flex items-center gap-2 text-base font-medium text-[#646464]", children: [jsx(FileText, { className: "h-5 w-5 text-blue-600" }), t('retrievedDocumentsButton.title')] }) }), jsx("div", { className: "flex-1 overflow-hidden", children: jsx(DocumentSidebar, { isModal: true, sessionId: sessionId }) })] }) })] }));
|
|
258029
258925
|
}
|
|
258030
258926
|
|
|
258031
|
-
const PAGE_SIZE$
|
|
258927
|
+
const PAGE_SIZE$9 = 10;
|
|
258032
258928
|
const MemoryMenu = ({ onClose, mentorId, tenantKey, username }) => {
|
|
258033
258929
|
const t = useT();
|
|
258034
258930
|
const [page, setPage] = useState(1);
|
|
@@ -258046,7 +258942,7 @@ const MemoryMenu = ({ onClose, mentorId, tenantKey, username }) => {
|
|
|
258046
258942
|
mentorId,
|
|
258047
258943
|
params: {
|
|
258048
258944
|
page,
|
|
258049
|
-
page_size: PAGE_SIZE$
|
|
258945
|
+
page_size: PAGE_SIZE$9,
|
|
258050
258946
|
my_memory: true,
|
|
258051
258947
|
},
|
|
258052
258948
|
}, {
|
|
@@ -261929,7 +262825,7 @@ function DeleteItemConfirm({ isOpen, onClose, tenantKey, username, datasetName,
|
|
|
261929
262825
|
: t('benchmarksDeleteItemConfirm.delete') })] })] }) }));
|
|
261930
262826
|
}
|
|
261931
262827
|
|
|
261932
|
-
const PAGE_SIZE$
|
|
262828
|
+
const PAGE_SIZE$8 = 10;
|
|
261933
262829
|
function BenchmarkItemsModal({ isOpen, onClose, tenantKey, username, datasetName }) {
|
|
261934
262830
|
var _a;
|
|
261935
262831
|
const t = useT();
|
|
@@ -261941,17 +262837,17 @@ function BenchmarkItemsModal({ isOpen, onClose, tenantKey, username, datasetName
|
|
|
261941
262837
|
userId: username,
|
|
261942
262838
|
datasetName,
|
|
261943
262839
|
page,
|
|
261944
|
-
limit: PAGE_SIZE$
|
|
262840
|
+
limit: PAGE_SIZE$8,
|
|
261945
262841
|
});
|
|
261946
262842
|
const items = (_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : [];
|
|
261947
|
-
const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$
|
|
262843
|
+
const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$8);
|
|
261948
262844
|
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) => {
|
|
261949
262845
|
var _a;
|
|
261950
262846
|
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));
|
|
261951
262847
|
}), 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 }))] }) }));
|
|
261952
262848
|
}
|
|
261953
262849
|
|
|
261954
|
-
const PAGE_SIZE$
|
|
262850
|
+
const PAGE_SIZE$7 = 10;
|
|
261955
262851
|
function BenchmarksTab({ tenantKey, username, }) {
|
|
261956
262852
|
var _a;
|
|
261957
262853
|
const t = useT();
|
|
@@ -261963,13 +262859,13 @@ function BenchmarksTab({ tenantKey, username, }) {
|
|
|
261963
262859
|
org: tenantKey,
|
|
261964
262860
|
userId: username,
|
|
261965
262861
|
page,
|
|
261966
|
-
limit: PAGE_SIZE$
|
|
262862
|
+
limit: PAGE_SIZE$7,
|
|
261967
262863
|
});
|
|
261968
262864
|
const benchmarks = (_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : [];
|
|
261969
262865
|
const filtered = searchQuery.trim()
|
|
261970
262866
|
? benchmarks.filter((benchmark) => benchmark.name.toLowerCase().includes(searchQuery.toLowerCase()))
|
|
261971
262867
|
: benchmarks;
|
|
261972
|
-
const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$
|
|
262868
|
+
const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$7);
|
|
261973
262869
|
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
|
|
261974
262870
|
? formatDistanceToNow(new Date(benchmark.created_at), {
|
|
261975
262871
|
addSuffix: true,
|
|
@@ -261979,6 +262875,514 @@ function BenchmarksTab({ tenantKey, username, }) {
|
|
|
261979
262875
|
}), onClick: () => setViewBenchmark(benchmark.name), children: jsx(Eye, { className: "h-4 w-4" }) }) }) })] }, benchmark.name))), filtered.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 4, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: isFetching ? t('benchmarksIndex.loading') : t('benchmarksIndex.empty') }) }))] })] }) }), totalPages > 1 && (jsx("div", { className: "mt-6", children: jsx(AdvancedPagination, { totalPages: totalPages, currentPage: page, onPageChange: setPage }) }))] })), jsx(CreateBenchmarkModal, { isOpen: showCreate, onClose: () => setShowCreate(false), tenantKey: tenantKey, username: username }), viewBenchmark && (jsx(BenchmarkItemsModal, { isOpen: !!viewBenchmark, onClose: () => setViewBenchmark(null), tenantKey: tenantKey, username: username, datasetName: viewBenchmark }))] }));
|
|
261980
262876
|
}
|
|
261981
262877
|
|
|
262878
|
+
/** Matches the server-side cap on the global memories listing. */
|
|
262879
|
+
const PAGE_SIZE$6 = 25;
|
|
262880
|
+
/**
|
|
262881
|
+
* Popup for managing one user's global memories. Reads them the way the
|
|
262882
|
+
* profile preview does — the caller in the path, the managed user identified
|
|
262883
|
+
* by their id (username) in `user_id` — while writes address the managed
|
|
262884
|
+
* user's path directly, which the backend resolves for admin/RBAC callers.
|
|
262885
|
+
* The list itself is the same {@link MemoriesList} the profile Memory tab
|
|
262886
|
+
* renders.
|
|
262887
|
+
*/
|
|
262888
|
+
function UserMemoriesModal({ isOpen, onClose, tenantKey, adminUsername, user, }) {
|
|
262889
|
+
var _a, _b, _c;
|
|
262890
|
+
const t = useT();
|
|
262891
|
+
const [page, setPage] = useState(1);
|
|
262892
|
+
const [showAdd, setShowAdd] = useState(false);
|
|
262893
|
+
const [editingMemory, setEditingMemory] = useState(null);
|
|
262894
|
+
const [deletingId, setDeletingId] = useState(null);
|
|
262895
|
+
const { data: memoriesData, isLoading, error, } = useGetGlobalMemoriesQuery({
|
|
262896
|
+
org: tenantKey,
|
|
262897
|
+
userId: adminUsername,
|
|
262898
|
+
// `user_id` must be the managed user's id (username) — the backend does
|
|
262899
|
+
// not resolve emails here, so passing one returns an empty list.
|
|
262900
|
+
params: { page, page_size: PAGE_SIZE$6, user_id: user.username },
|
|
262901
|
+
});
|
|
262902
|
+
const memories = (_a = memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.results) !== null && _a !== void 0 ? _a : [];
|
|
262903
|
+
const totalPages = (memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.count) ? Math.ceil(memoriesData.count / PAGE_SIZE$6) : 0;
|
|
262904
|
+
const isForbidden = !!error && error.status === 403;
|
|
262905
|
+
// The managed user's capture/personalization toggles, addressed through
|
|
262906
|
+
// their path the way every admin write here is. Hidden unless they load.
|
|
262907
|
+
const { data: settings } = useGetUserMemorySettingsQuery({
|
|
262908
|
+
org: tenantKey,
|
|
262909
|
+
userId: user.username,
|
|
262910
|
+
});
|
|
262911
|
+
const [updateSettings, { isLoading: isUpdatingSettings }] = useUpdateUserMemorySettingsMutation();
|
|
262912
|
+
const handleToggleSetting = async (key, checked) => {
|
|
262913
|
+
try {
|
|
262914
|
+
await updateSettings({
|
|
262915
|
+
org: tenantKey,
|
|
262916
|
+
userId: user.username,
|
|
262917
|
+
settings: { [key]: checked },
|
|
262918
|
+
}).unwrap();
|
|
262919
|
+
toast.success(t('memoryMemoryTab.memorySettingUpdated'));
|
|
262920
|
+
}
|
|
262921
|
+
catch (_a) {
|
|
262922
|
+
toast.error(t('memoryMemoryTab.failedToUpdateMemorySetting'));
|
|
262923
|
+
}
|
|
262924
|
+
};
|
|
262925
|
+
const [deleteMemory] = useDeleteGlobalMemoryMutation();
|
|
262926
|
+
const handleDeleteMemory = async (memory) => {
|
|
262927
|
+
setDeletingId(memory.id);
|
|
262928
|
+
try {
|
|
262929
|
+
await deleteMemory({
|
|
262930
|
+
org: tenantKey,
|
|
262931
|
+
userId: user.username,
|
|
262932
|
+
memoryId: memory.id,
|
|
262933
|
+
}).unwrap();
|
|
262934
|
+
toast.success(t('memoryAdminUserMemoriesModal.memoryDeleted'));
|
|
262935
|
+
}
|
|
262936
|
+
catch (deleteError) {
|
|
262937
|
+
if ((deleteError === null || deleteError === void 0 ? void 0 : deleteError.status) === 403) {
|
|
262938
|
+
toast.error(t('memoryAdminTab.forbidden'));
|
|
262939
|
+
}
|
|
262940
|
+
else {
|
|
262941
|
+
toast.error(t('memoryAdminUserMemoriesModal.failedToDeleteMemory'));
|
|
262942
|
+
}
|
|
262943
|
+
}
|
|
262944
|
+
finally {
|
|
262945
|
+
setDeletingId(null);
|
|
262946
|
+
}
|
|
262947
|
+
};
|
|
262948
|
+
return (jsx(Dialog, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: jsxs(DialogContent, { "data-testid": "user-memories-modal", "aria-label": "user-global-memories", className: "w-full max-w-3xl max-h-[90vh] overflow-y-auto", children: [jsxs(DialogHeader, { children: [jsxs(DialogTitle, { children: [t('memoryAdminUserMemoriesModal.title'), " \u2014 ", user.email || user.username] }), jsx(DialogDescription, { children: t('memoryAdminUserMemoriesModal.description') })] }), settings && (jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex-1 mr-4", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: t('memoryMemoryTab.autoCaptureLabelTitle') }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: t('memoryMemoryTab.autoCaptureLabelDesc') })] }), jsx(Switch, { checked: (_b = settings.auto_capture_enabled) !== null && _b !== void 0 ? _b : false, onCheckedChange: (checked) => handleToggleSetting('auto_capture_enabled', checked), disabled: isUpdatingSettings, "aria-label": t('memoryMemoryTab.autoCaptureAriaLabel', {
|
|
262949
|
+
state: settings.auto_capture_enabled
|
|
262950
|
+
? t('memoryMemoryTab.stateEnabled')
|
|
262951
|
+
: t('memoryMemoryTab.stateDisabled'),
|
|
262952
|
+
}), className: "cursor-pointer data-[state=checked]:bg-blue-500 flex-shrink-0" })] }), jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex-1 mr-4", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: t('memoryMemoryTab.useMemoryLabelTitle') }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: t('memoryMemoryTab.useMemoryLabelDesc') })] }), jsx(Switch, { checked: (_c = settings.use_memory_in_responses) !== null && _c !== void 0 ? _c : false, onCheckedChange: (checked) => handleToggleSetting('use_memory_in_responses', checked), disabled: isUpdatingSettings, "aria-label": t('memoryMemoryTab.useMemoryAriaLabel', {
|
|
262953
|
+
state: settings.use_memory_in_responses
|
|
262954
|
+
? t('memoryMemoryTab.stateEnabled')
|
|
262955
|
+
: t('memoryMemoryTab.stateDisabled'),
|
|
262956
|
+
}), 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 }))] }) }));
|
|
262957
|
+
}
|
|
262958
|
+
|
|
262959
|
+
const PAGE_SIZE$5 = 10;
|
|
262960
|
+
const SEARCH_DEBOUNCE_MS = 300;
|
|
262961
|
+
/**
|
|
262962
|
+
* Tenant users table with server-side search. Opening a row shows that user's
|
|
262963
|
+
* global memories in a popup where the admin can manage them.
|
|
262964
|
+
*/
|
|
262965
|
+
function GlobalMemoriesSection({ tenantKey, username }) {
|
|
262966
|
+
var _a;
|
|
262967
|
+
const t = useT();
|
|
262968
|
+
const [page, setPage] = useState(1);
|
|
262969
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
262970
|
+
const [debouncedSearch, setDebouncedSearch] = useState(searchQuery);
|
|
262971
|
+
const [selectedUser, setSelectedUser] = useState(null);
|
|
262972
|
+
// Same debounce contract as the Management tab's user search: terms shorter
|
|
262973
|
+
// than three characters search as empty. Bailing out on an unchanged value
|
|
262974
|
+
// keeps the mount-time timer from resetting a page the user already turned.
|
|
262975
|
+
useEffect(() => {
|
|
262976
|
+
const handler = setTimeout(() => {
|
|
262977
|
+
setDebouncedSearch((previous) => {
|
|
262978
|
+
const next = searchQuery.length > 2 ? searchQuery : '';
|
|
262979
|
+
return previous === next ? previous : next;
|
|
262980
|
+
});
|
|
262981
|
+
}, SEARCH_DEBOUNCE_MS);
|
|
262982
|
+
return () => clearTimeout(handler);
|
|
262983
|
+
}, [searchQuery]);
|
|
262984
|
+
// A new search term invalidates the current page index.
|
|
262985
|
+
useEffect(() => {
|
|
262986
|
+
setPage(1);
|
|
262987
|
+
}, [debouncedSearch]);
|
|
262988
|
+
const { data, isLoading, isFetching, error } = usePlatformUsersQuery({
|
|
262989
|
+
platform_key: tenantKey,
|
|
262990
|
+
platform_org: tenantKey,
|
|
262991
|
+
page,
|
|
262992
|
+
page_size: PAGE_SIZE$5,
|
|
262993
|
+
query: debouncedSearch,
|
|
262994
|
+
return_policies: 'false',
|
|
262995
|
+
});
|
|
262996
|
+
const users = useMemo(() => {
|
|
262997
|
+
var _a;
|
|
262998
|
+
// `results` is a bare array unless policies were requested, in which case
|
|
262999
|
+
// the users sit under `results.data`.
|
|
263000
|
+
const results = data === null || data === void 0 ? void 0 : data.results;
|
|
263001
|
+
const platformUsers = Array.isArray(results)
|
|
263002
|
+
? results
|
|
263003
|
+
: ((_a = results === null || results === void 0 ? void 0 : results.data) !== null && _a !== void 0 ? _a : []);
|
|
263004
|
+
// A user without a username cannot be addressed by the memory endpoints.
|
|
263005
|
+
return platformUsers
|
|
263006
|
+
.filter((user) => !!user.username)
|
|
263007
|
+
.map((user) => ({
|
|
263008
|
+
username: user.username,
|
|
263009
|
+
name: user.name,
|
|
263010
|
+
email: user.email,
|
|
263011
|
+
}));
|
|
263012
|
+
}, [data]);
|
|
263013
|
+
const totalPages = Math.ceil(((_a = data === null || data === void 0 ? void 0 : data.count) !== null && _a !== void 0 ? _a : 0) / PAGE_SIZE$5);
|
|
263014
|
+
const isForbidden = !!error && error.status === 403;
|
|
263015
|
+
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', {
|
|
263016
|
+
name: user.email || user.username,
|
|
263017
|
+
}), onClick: () => setSelectedUser(user), children: jsx(Eye, { className: "h-4 w-4" }) }) }) })] }, user.username))), users.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 4, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: isFetching ? t('memoryAdminTab.loading') : t('memoryAdminTab.noUsersFound') }) }))] })] }) }), totalPages > 1 && (jsx("div", { className: "mt-6", children: jsx(IblPagination, { totalPages: totalPages, currentPage: page, onPageChange: setPage, disabled: isFetching }) }))] })), selectedUser && (jsx(UserMemoriesModal, { isOpen: !!selectedUser, onClose: () => setSelectedUser(null), tenantKey: tenantKey, adminUsername: username, user: selectedUser }))] }));
|
|
263018
|
+
}
|
|
263019
|
+
|
|
263020
|
+
const EditMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return editMemoryModal; }).then((module) => ({
|
|
263021
|
+
default: module.EditMemoryModal,
|
|
263022
|
+
})), { ssr: false });
|
|
263023
|
+
const AddMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return addMemoryModal; }).then((module) => ({
|
|
263024
|
+
default: module.AddMemoryModal,
|
|
263025
|
+
})), { ssr: false });
|
|
263026
|
+
const DeleteMemoryModal = dynamic(() => Promise.resolve().then(function () { return deleteMemoryModal; }).then((module) => ({
|
|
263027
|
+
default: module.DeleteMemoryModal,
|
|
263028
|
+
})), { ssr: false });
|
|
263029
|
+
const BulkDeleteMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return bulkDeleteMemoryModal; }).then((module) => ({
|
|
263030
|
+
default: module.BulkDeleteMemoryModal,
|
|
263031
|
+
})), { ssr: false });
|
|
263032
|
+
const ManageCategoriesModal$1 = dynamic(() => Promise.resolve().then(function () { return manageCategoriesModal; }).then((module) => ({
|
|
263033
|
+
default: module.ManageCategoriesModal,
|
|
263034
|
+
})), { ssr: false });
|
|
263035
|
+
const PAGE_SIZE$4 = 20;
|
|
263036
|
+
const SNAPSHOT_PAGE_SIZE = 1000;
|
|
263037
|
+
function ManageMemories({ tenantKey, username, mentorId }) {
|
|
263038
|
+
var _a, _b, _c, _d, _e;
|
|
263039
|
+
const t = useT();
|
|
263040
|
+
const [selectedLearner, setSelectedLearner] = useState('');
|
|
263041
|
+
const [dateRange, setDateRange] = useState(undefined);
|
|
263042
|
+
const [selectedCategorySlug, setSelectedCategorySlug] = useState('all');
|
|
263043
|
+
const [page, setPage] = useState(1);
|
|
263044
|
+
// Reset to page 1 whenever any filter changes — otherwise we could land on a
|
|
263045
|
+
// page index that no longer exists in the new result set.
|
|
263046
|
+
useEffect(() => {
|
|
263047
|
+
setPage(1);
|
|
263048
|
+
}, [selectedLearner, dateRange, selectedCategorySlug]);
|
|
263049
|
+
const listParams = useMemo(() => {
|
|
263050
|
+
const params = { page, page_size: PAGE_SIZE$4 };
|
|
263051
|
+
if (selectedLearner)
|
|
263052
|
+
params.email = selectedLearner;
|
|
263053
|
+
if (selectedCategorySlug !== 'all')
|
|
263054
|
+
params.category = selectedCategorySlug;
|
|
263055
|
+
if (dateRange === null || dateRange === void 0 ? void 0 : dateRange.from)
|
|
263056
|
+
params.start_date = format$1(dateRange.from, 'yyyy-MM-dd');
|
|
263057
|
+
if (dateRange === null || dateRange === void 0 ? void 0 : dateRange.to)
|
|
263058
|
+
params.end_date = format$1(dateRange.to, 'yyyy-MM-dd');
|
|
263059
|
+
return params;
|
|
263060
|
+
}, [page, selectedLearner, selectedCategorySlug, dateRange]);
|
|
263061
|
+
const { data: listResponse, isLoading: isLoadingMemories } = useGetMentorMemoriesListQuery({
|
|
263062
|
+
org: tenantKey,
|
|
263063
|
+
userId: username !== null && username !== void 0 ? username : '',
|
|
263064
|
+
mentorId,
|
|
263065
|
+
params: listParams,
|
|
263066
|
+
}, {
|
|
263067
|
+
skip: !tenantKey || !username || !mentorId,
|
|
263068
|
+
});
|
|
263069
|
+
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$4));
|
|
263070
|
+
const { data: adminCategories } = useGetMemoryCategoriesAdminQuery({
|
|
263071
|
+
org: tenantKey,
|
|
263072
|
+
mentorId,
|
|
263073
|
+
}, {
|
|
263074
|
+
skip: !tenantKey || !mentorId,
|
|
263075
|
+
});
|
|
263076
|
+
const [deleteMentorMemory, { isLoading: isDeleting }] = useDeleteMentorMemoryMutation();
|
|
263077
|
+
const [updateMentorMemory, { isLoading: isEditing }] = useUpdateMentorMemoryMutation();
|
|
263078
|
+
const [createMentorMemory, { isLoading: isSaving }] = useCreateMentorMemoryMutation();
|
|
263079
|
+
// Flat list of memories on the current page, mapped into the local `Memory`
|
|
263080
|
+
// shape used by the rest of this component.
|
|
263081
|
+
const memories = useMemo(() => {
|
|
263082
|
+
if (!(listResponse === null || listResponse === void 0 ? void 0 : listResponse.results))
|
|
263083
|
+
return [];
|
|
263084
|
+
return listResponse.results.map((memory) => ({
|
|
263085
|
+
id: memory.id,
|
|
263086
|
+
content: memory.content,
|
|
263087
|
+
category: {
|
|
263088
|
+
id: memory.category.id,
|
|
263089
|
+
name: memory.category.name,
|
|
263090
|
+
slug: memory.category.slug,
|
|
263091
|
+
},
|
|
263092
|
+
email: memory.email,
|
|
263093
|
+
createdAt: memory.created_at,
|
|
263094
|
+
}));
|
|
263095
|
+
}, [listResponse]);
|
|
263096
|
+
// Unfiltered snapshot used to derive the learner dropdown and to source the
|
|
263097
|
+
// bulk-delete operation, which needs the full set of memories — not just the
|
|
263098
|
+
// current page.
|
|
263099
|
+
const { data: snapshotResponse } = useGetMentorMemoriesListQuery({
|
|
263100
|
+
org: tenantKey,
|
|
263101
|
+
userId: username !== null && username !== void 0 ? username : '',
|
|
263102
|
+
mentorId,
|
|
263103
|
+
params: { page: 1, page_size: SNAPSHOT_PAGE_SIZE },
|
|
263104
|
+
}, {
|
|
263105
|
+
skip: !tenantKey || !username || !mentorId,
|
|
263106
|
+
});
|
|
263107
|
+
const learners = useMemo(() => {
|
|
263108
|
+
if (!(snapshotResponse === null || snapshotResponse === void 0 ? void 0 : snapshotResponse.results))
|
|
263109
|
+
return [];
|
|
263110
|
+
const emailSet = new Set();
|
|
263111
|
+
snapshotResponse.results.forEach((m) => {
|
|
263112
|
+
if (m.email)
|
|
263113
|
+
emailSet.add(m.email);
|
|
263114
|
+
});
|
|
263115
|
+
return Array.from(emailSet).map((email) => ({ email }));
|
|
263116
|
+
}, [snapshotResponse]);
|
|
263117
|
+
const categories = useMemo(() => {
|
|
263118
|
+
if (adminCategories && adminCategories.length > 0) {
|
|
263119
|
+
return [
|
|
263120
|
+
{ id: 0, name: 'All', slug: 'all' },
|
|
263121
|
+
...adminCategories.map((cat) => ({
|
|
263122
|
+
id: cat.id,
|
|
263123
|
+
name: cat.name,
|
|
263124
|
+
slug: cat.slug,
|
|
263125
|
+
})),
|
|
263126
|
+
];
|
|
263127
|
+
}
|
|
263128
|
+
return [{ id: 0, name: 'All', slug: 'all' }];
|
|
263129
|
+
}, [adminCategories]);
|
|
263130
|
+
const [editingMemory, setEditingMemory] = useState(null);
|
|
263131
|
+
const [editContent, setEditContent] = useState('');
|
|
263132
|
+
const [editCategory, setEditCategory] = useState('');
|
|
263133
|
+
const [showDeleteConfirm, setShowDeleteConfirm] = useState(null);
|
|
263134
|
+
const [showAddMemory, setShowAddMemory] = useState(false);
|
|
263135
|
+
const [newMemoryContent, setNewMemoryContent] = useState('');
|
|
263136
|
+
const [newMemoryCategory, setNewMemoryCategory] = useState('');
|
|
263137
|
+
const [showMobileDropdown, setShowMobileDropdown] = useState(false);
|
|
263138
|
+
const [showBulkDeleteConfirm, setShowBulkDeleteConfirm] = useState(false);
|
|
263139
|
+
const [isBulkDeleting, setIsBulkDeleting] = useState(false);
|
|
263140
|
+
const [showManageCategories, setShowManageCategories] = useState(false);
|
|
263141
|
+
const selectedCategoryName = (_c = (_b = categories.find((c) => c.slug === selectedCategorySlug)) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : t('memoryTabManageMemories.all');
|
|
263142
|
+
const VISIBLE_CATEGORY_LIMIT = 6;
|
|
263143
|
+
const visibleCategories = categories.slice(0, VISIBLE_CATEGORY_LIMIT);
|
|
263144
|
+
const overflowCategories = categories.slice(VISIBLE_CATEGORY_LIMIT);
|
|
263145
|
+
const overflowSelected = overflowCategories.find((c) => c.slug === selectedCategorySlug);
|
|
263146
|
+
// Category is filtered server-side via the `category` query param now, so
|
|
263147
|
+
// `memories` already contains only the relevant entries for the page.
|
|
263148
|
+
const filteredMemories = memories;
|
|
263149
|
+
const handleDeleteMemory = async (id) => {
|
|
263150
|
+
if (!tenantKey || !username)
|
|
263151
|
+
return;
|
|
263152
|
+
try {
|
|
263153
|
+
await deleteMentorMemory({
|
|
263154
|
+
org: tenantKey,
|
|
263155
|
+
userId: username,
|
|
263156
|
+
mentorId,
|
|
263157
|
+
memoryId: id,
|
|
263158
|
+
}).unwrap();
|
|
263159
|
+
setShowDeleteConfirm(null);
|
|
263160
|
+
toast.success(t('memoryTabManageMemories.memoryDeletedSuccessfully'));
|
|
263161
|
+
}
|
|
263162
|
+
catch (error) {
|
|
263163
|
+
console.error('Failed to delete memory:', error);
|
|
263164
|
+
toast.error(t('memoryTabManageMemories.failedToDeleteMemory'));
|
|
263165
|
+
}
|
|
263166
|
+
};
|
|
263167
|
+
const handleBulkDelete = async () => {
|
|
263168
|
+
var _a;
|
|
263169
|
+
if (!tenantKey || !username)
|
|
263170
|
+
return;
|
|
263171
|
+
setIsBulkDeleting(true);
|
|
263172
|
+
try {
|
|
263173
|
+
// Source bulk-delete from the unfiltered snapshot — `memories` only holds
|
|
263174
|
+
// the current page, while bulk delete must remove every entry in the
|
|
263175
|
+
// selected category.
|
|
263176
|
+
const memoriesToDelete = ((_a = snapshotResponse === null || snapshotResponse === void 0 ? void 0 : snapshotResponse.results) !== null && _a !== void 0 ? _a : []).filter((memory) => memory.category.slug === selectedCategorySlug);
|
|
263177
|
+
await Promise.all(memoriesToDelete.map((memory) => deleteMentorMemory({
|
|
263178
|
+
org: tenantKey,
|
|
263179
|
+
userId: username,
|
|
263180
|
+
mentorId,
|
|
263181
|
+
memoryId: memory.id,
|
|
263182
|
+
}).unwrap()));
|
|
263183
|
+
toast.success(t('memoryTabManageMemories.allCategoryMemoriesDeleted', { category: selectedCategoryName }));
|
|
263184
|
+
setShowBulkDeleteConfirm(false);
|
|
263185
|
+
}
|
|
263186
|
+
catch (error) {
|
|
263187
|
+
console.error('Failed to delete memories:', error);
|
|
263188
|
+
toast.error(t('memoryTabManageMemories.failedToDeleteMemories'));
|
|
263189
|
+
}
|
|
263190
|
+
finally {
|
|
263191
|
+
setIsBulkDeleting(false);
|
|
263192
|
+
}
|
|
263193
|
+
};
|
|
263194
|
+
const startEdit = (memory) => {
|
|
263195
|
+
setEditingMemory(memory);
|
|
263196
|
+
setEditContent(memory.content);
|
|
263197
|
+
setEditCategory(memory.category.name);
|
|
263198
|
+
};
|
|
263199
|
+
const saveEdit = async () => {
|
|
263200
|
+
if (!editingMemory || !tenantKey || !username)
|
|
263201
|
+
return;
|
|
263202
|
+
try {
|
|
263203
|
+
const selectedCat = categories.find((c) => c.name === editCategory);
|
|
263204
|
+
const categoryChanged = !!selectedCat && selectedCat.slug !== editingMemory.category.slug;
|
|
263205
|
+
await updateMentorMemory({
|
|
263206
|
+
org: tenantKey,
|
|
263207
|
+
userId: username,
|
|
263208
|
+
mentorId,
|
|
263209
|
+
memoryId: editingMemory.id,
|
|
263210
|
+
data: {
|
|
263211
|
+
content: editContent,
|
|
263212
|
+
...(categoryChanged ? { category_slug: selectedCat.slug } : {}),
|
|
263213
|
+
},
|
|
263214
|
+
}).unwrap();
|
|
263215
|
+
toast.success(t('memoryTabManageMemories.memoryUpdatedSuccessfully'));
|
|
263216
|
+
// Follow the entry to its new category tab so the user doesn't lose
|
|
263217
|
+
// sight of it. Skip when viewing "All" — the entry is still visible.
|
|
263218
|
+
if (categoryChanged && selectedCategorySlug !== 'all') {
|
|
263219
|
+
setSelectedCategorySlug(selectedCat.slug);
|
|
263220
|
+
}
|
|
263221
|
+
setEditingMemory(null);
|
|
263222
|
+
setEditContent('');
|
|
263223
|
+
setEditCategory('');
|
|
263224
|
+
}
|
|
263225
|
+
catch (error) {
|
|
263226
|
+
console.error('Failed to update memory:', error);
|
|
263227
|
+
toast.error(t('memoryTabManageMemories.failedToUpdateMemory'));
|
|
263228
|
+
}
|
|
263229
|
+
};
|
|
263230
|
+
const cancelEdit = () => {
|
|
263231
|
+
setEditingMemory(null);
|
|
263232
|
+
setEditContent('');
|
|
263233
|
+
setEditCategory('');
|
|
263234
|
+
};
|
|
263235
|
+
const startAddMemory = () => {
|
|
263236
|
+
setShowAddMemory(true);
|
|
263237
|
+
setNewMemoryCategory(selectedCategoryName);
|
|
263238
|
+
};
|
|
263239
|
+
const saveNewMemory = async () => {
|
|
263240
|
+
var _a;
|
|
263241
|
+
if (!newMemoryContent.trim() || !tenantKey || !username)
|
|
263242
|
+
return;
|
|
263243
|
+
try {
|
|
263244
|
+
const selectedCat = categories.find((c) => c.name === newMemoryCategory);
|
|
263245
|
+
const categorySlug = (_a = selectedCat === null || selectedCat === void 0 ? void 0 : selectedCat.slug) !== null && _a !== void 0 ? _a : selectedCategorySlug;
|
|
263246
|
+
await createMentorMemory({
|
|
263247
|
+
org: tenantKey,
|
|
263248
|
+
userId: username,
|
|
263249
|
+
mentorId,
|
|
263250
|
+
data: {
|
|
263251
|
+
category_slug: categorySlug === 'all' ? 'general' : categorySlug,
|
|
263252
|
+
content: newMemoryContent.trim(),
|
|
263253
|
+
},
|
|
263254
|
+
}).unwrap();
|
|
263255
|
+
setShowAddMemory(false);
|
|
263256
|
+
setNewMemoryContent('');
|
|
263257
|
+
setNewMemoryCategory('');
|
|
263258
|
+
if (selectedCat) {
|
|
263259
|
+
setSelectedCategorySlug(selectedCat.slug);
|
|
263260
|
+
}
|
|
263261
|
+
toast.success(t('memoryTabManageMemories.memoryCreatedSuccessfully'));
|
|
263262
|
+
}
|
|
263263
|
+
catch (error) {
|
|
263264
|
+
console.error('Failed to create memory:', error);
|
|
263265
|
+
toast.error(t('memoryTabManageMemories.failedToCreateMemory'));
|
|
263266
|
+
}
|
|
263267
|
+
};
|
|
263268
|
+
const cancelAddMemory = () => {
|
|
263269
|
+
setShowAddMemory(false);
|
|
263270
|
+
setNewMemoryContent('');
|
|
263271
|
+
setNewMemoryCategory('');
|
|
263272
|
+
};
|
|
263273
|
+
const categoryNames = categories.map((c) => c.name);
|
|
263274
|
+
return (jsxs(Fragment$1, { children: [jsxs("div", { className: "space-y-6", children: [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": t('memoryTabManageMemories.searchForUser'), className: "w-full justify-between bg-transparent font-normal", children: [selectedLearner
|
|
263275
|
+
? ((_e = (_d = learners.find((learner) => learner.email === selectedLearner)) === null || _d === void 0 ? void 0 : _d.email) !== null && _e !== void 0 ? _e : selectedLearner)
|
|
263276
|
+
: t('memoryTabManageMemories.searchForUser'), jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), jsx(PopoverContent, { className: "w-full p-0", align: "start", children: jsxs(Command, { children: [jsx(CommandInput, { placeholder: t('memoryTabManageMemories.searchUsersPlaceholder') }), jsxs(CommandList, { children: [jsx(CommandEmpty, { children: t('memoryTabManageMemories.noUsersFound') }), jsxs(CommandGroup, { children: [jsxs(CommandItem, { value: "", onSelect: () => {
|
|
263277
|
+
setSelectedLearner('');
|
|
263278
|
+
}, children: [jsx(Check, { className: cn('mr-2 h-4 w-4', !selectedLearner ? 'opacity-100' : 'opacity-0') }), t('memoryTabManageMemories.allUsers')] }), learners.map((learner) => (jsxs(CommandItem, { value: learner.email, onSelect: () => {
|
|
263279
|
+
setSelectedLearner(learner.email);
|
|
263280
|
+
}, children: [jsx(Check, { className: cn('mr-2 h-4 w-4', selectedLearner === 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(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", 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)
|
|
263281
|
+
? `${format$1(dateRange.from, 'MMM dd')} - ${format$1(dateRange.to, 'MMM dd')}`
|
|
263282
|
+
: t('memoryTabManageMemories.pickDateRange')] }) }), jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: jsx(Calendar, { mode: "range", selected: dateRange, onSelect: setDateRange, numberOfMonths: 2, initialFocus: true }) })] })] }) }), jsx("div", { children: jsxs("div", { className: "flex items-center justify-between gap-4", children: [jsxs("div", { className: "scrollbar-none hidden flex-1 items-center space-x-8 overflow-x-auto sm:flex", children: [visibleCategories.map((category) => (jsxs("button", { onClick: () => setSelectedCategorySlug(category.slug), className: `relative px-1 py-2 text-sm font-medium whitespace-nowrap transition-colors ${selectedCategorySlug === category.slug
|
|
263283
|
+
? 'text-[#38A1E5]'
|
|
263284
|
+
: 'text-gray-600 hover:text-gray-900'}`, children: [category.name, selectedCategorySlug === category.slug && (jsx("div", { className: "absolute bottom-0 left-1/2 h-0.5 -translate-x-1/2 transform bg-[#38A1E5] transition-all duration-200", style: { width: `${category.name.length * 0.55}em` } }))] }, category.slug))), overflowCategories.length > 0 && (jsxs(DropdownMenu, { children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs("button", { className: cn('relative flex items-center gap-1 px-1 py-2 text-sm font-medium whitespace-nowrap transition-colors', overflowSelected ? 'text-[#38A1E5]' : 'text-gray-600 hover:text-gray-900'), "aria-label": t('memoryTabManageMemories.moreCategories'), children: [overflowSelected ? overflowSelected.name : t('memoryTabManageMemories.more'), jsx(ChevronDown, { className: "h-3.5 w-3.5" }), overflowSelected && (jsx("div", { className: "absolute bottom-0 left-0 h-0.5 bg-[#38A1E5] transition-all duration-200", style: {
|
|
263285
|
+
width: `${overflowSelected.name.length * 0.55}em`,
|
|
263286
|
+
} }))] }) }), jsx(DropdownMenuContent, { align: "end", children: overflowCategories.map((category) => (jsx(DropdownMenuItem, { onClick: () => setSelectedCategorySlug(category.slug), className: selectedCategorySlug === category.slug ? 'bg-gray-100' : '', children: category.name }, category.slug))) })] }))] }), jsx("div", { className: "w-full py-2 sm:hidden", children: jsxs(DropdownMenu, { open: showMobileDropdown, onOpenChange: setShowMobileDropdown, children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", className: "w-full justify-between bg-transparent", children: [selectedCategoryName, jsx(ChevronDown, { className: "h-4 w-4" })] }) }), jsx(DropdownMenuContent, { className: "w-full", children: categories.map((category) => (jsx(DropdownMenuItem, { onClick: () => {
|
|
263287
|
+
setSelectedCategorySlug(category.slug);
|
|
263288
|
+
setShowMobileDropdown(false);
|
|
263289
|
+
}, className: selectedCategorySlug === category.slug ? 'bg-gray-100' : '', children: category.name }, category.slug))) })] }) }), jsxs(Button$1, { onClick: () => setShowManageCategories(true), size: "sm", variant: "outline", className: "shrink-0", "aria-label": t('memoryTabManageMemories.manageCategories'), children: [jsx(Tags, { className: "h-4 w-4 sm:mr-2" }), jsx("span", { className: "hidden sm:inline", children: t('memoryTabManageMemories.categories') })] }), jsxs(Button$1, { onClick: startAddMemory, size: "sm", className: "ibl-button-primary shrink-0", children: [jsx(Plus, { className: "mr-1 h-4 w-4 sm:mr-2" }), jsx("span", { className: "hidden sm:inline", children: t('memoryTabManageMemories.addMemory') }), jsx("span", { className: "sm:hidden", children: t('memoryTabManageMemories.add') })] })] }) }), jsx("div", { className: "space-y-3 px-1 sm:px-0", children: isLoadingMemories ? (jsx("div", { className: "py-8 text-center text-gray-600", children: jsx("p", { children: t('memoryTabManageMemories.loadingMemories') }) })) : (filteredMemories.map((memory) => {
|
|
263290
|
+
const timeAgo = memory.createdAt
|
|
263291
|
+
? formatDistanceToNow(new Date(memory.createdAt), {
|
|
263292
|
+
addSuffix: true,
|
|
263293
|
+
})
|
|
263294
|
+
: '';
|
|
263295
|
+
const displayUser = memory.email || t('memoryTabManageMemories.unknown');
|
|
263296
|
+
return (jsxs("div", { className: "flex items-start gap-3 rounded-lg border border-gray-200 bg-white p-3", children: [jsxs("div", { className: "flex-1", children: [(timeAgo || displayUser) && (jsxs("div", { className: "mb-2 flex items-center justify-between", children: [timeAgo && jsx("span", { className: "text-sm text-gray-600", children: timeAgo }), displayUser && (jsx("span", { className: "max-w-[100px] truncate text-sm text-gray-900 sm:max-w-[200px]", children: displayUser }))] })), jsx("div", { className: "text-sm leading-relaxed text-gray-900", children: memory.content })] }), jsxs(DropdownMenu, { children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsx(Button$1, { variant: "ghost", size: "sm", className: "h-6 w-6 flex-shrink-0 p-0 text-gray-600 hover:text-gray-900", children: jsx(Ellipsis, { className: "h-4 w-4" }) }) }), jsxs(DropdownMenuContent, { align: "end", children: [jsx(DropdownMenuItem, { onClick: () => startEdit(memory), children: t('memoryTabManageMemories.edit') }), jsx(DropdownMenuItem, { onClick: () => setShowDeleteConfirm(memory.id), children: t('memoryTabManageMemories.delete') })] })] })] }, memory.id));
|
|
263297
|
+
})) }), filteredMemories.length > 0 && selectedCategorySlug !== 'all' && (jsx("div", { className: "flex justify-end", children: jsx(Button$1, { variant: "outline", onClick: () => setShowBulkDeleteConfirm(true), children: t('memoryTabManageMemories.deleteAll') }) })), filteredMemories.length === 0 && !isLoadingMemories && (jsx("div", { className: "py-8 text-center text-gray-600", children: jsx("p", { children: t('memoryTabManageMemories.noSavedMemories') }) })), totalPages > 1 && (jsx("div", { className: "flex justify-center pt-2", children: jsx(IblPagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage, disabled: isLoadingMemories }) }))] }), jsx(EditMemoryModal$1, { open: !!editingMemory, onOpenChange: (open) => !open && cancelEdit(), editContent: editContent, editCategory: editCategory, onContentChange: setEditContent, onCategoryChange: setEditCategory, onSave: saveEdit, onCancel: cancelEdit, categories: categoryNames, isSaving: isEditing }), jsx(AddMemoryModal$1, { open: showAddMemory, onOpenChange: (open) => !open && cancelAddMemory(), newMemoryContent: newMemoryContent, newMemoryCategory: newMemoryCategory, onContentChange: setNewMemoryContent, onCategoryChange: setNewMemoryCategory, onSave: saveNewMemory, onCancel: cancelAddMemory, categories: categoryNames, isSaving: isSaving }), jsx(DeleteMemoryModal, { open: !!showDeleteConfirm, onOpenChange: (open) => !open && setShowDeleteConfirm(null), onConfirm: () => showDeleteConfirm !== null && handleDeleteMemory(showDeleteConfirm), onCancel: () => setShowDeleteConfirm(null), isDeleting: isDeleting }), jsx(ManageCategoriesModal$1, { open: showManageCategories, onOpenChange: setShowManageCategories, tenantKey: tenantKey, mentorId: mentorId }), jsx(BulkDeleteMemoryModal$1, { open: showBulkDeleteConfirm, onOpenChange: setShowBulkDeleteConfirm, onConfirm: handleBulkDelete, onCancel: () => setShowBulkDeleteConfirm(false), isDeleting: isBulkDeleting, selectedCategory: selectedCategoryName })] }));
|
|
263298
|
+
}
|
|
263299
|
+
|
|
263300
|
+
/**
|
|
263301
|
+
* Popup hosting the same memory manager the agent settings modal renders —
|
|
263302
|
+
* learner/category/date filters and full CRUD included — for one agent.
|
|
263303
|
+
* Laid out like the Billing tab's agent-limits popup: a fixed divider header
|
|
263304
|
+
* and a body that scrolls vertically while the content fits the width.
|
|
263305
|
+
*/
|
|
263306
|
+
function AgentMemoriesModal({ isOpen, onClose, tenantKey, username, agent, }) {
|
|
263307
|
+
const t = useT();
|
|
263308
|
+
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 }) }) })] }) }));
|
|
263309
|
+
}
|
|
263310
|
+
|
|
263311
|
+
const PAGE_SIZE$3 = 10;
|
|
263312
|
+
/**
|
|
263313
|
+
* Agents table filtered by the same agent autocomplete the Billing tab's
|
|
263314
|
+
* Agent Limits section uses. Opening a row shows that agent's memories in a
|
|
263315
|
+
* popup hosting the same manager the agent settings modal uses.
|
|
263316
|
+
*/
|
|
263317
|
+
function AgentMemoriesSection({ tenantKey, username }) {
|
|
263318
|
+
var _a;
|
|
263319
|
+
const t = useT();
|
|
263320
|
+
const [page, setPage] = useState(1);
|
|
263321
|
+
const [agentFilter, setAgentFilter] = useState(null);
|
|
263322
|
+
const [agentSearch, setAgentSearch] = useState('');
|
|
263323
|
+
const [debouncedAgentSearch] = a$3(agentSearch, 300);
|
|
263324
|
+
const [selectedAgent, setSelectedAgent] = useState(null);
|
|
263325
|
+
// A new filter invalidates the current page index.
|
|
263326
|
+
useEffect(() => {
|
|
263327
|
+
setPage(1);
|
|
263328
|
+
}, [agentFilter]);
|
|
263329
|
+
// Autocomplete options for the filter, fetched once two characters are in.
|
|
263330
|
+
const shouldSearchAgents = Boolean(tenantKey && debouncedAgentSearch.trim().length >= 2);
|
|
263331
|
+
const { data: searchResponse, isFetching: isSearchingAgents } = useGetMentorsQuery({ org: tenantKey, username, limit: 20, query: debouncedAgentSearch.trim() }, { skip: !shouldSearchAgents });
|
|
263332
|
+
const agentOptions = useMemo(() => {
|
|
263333
|
+
var _a;
|
|
263334
|
+
return ((_a = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.results) !== null && _a !== void 0 ? _a : [])
|
|
263335
|
+
.filter((mentor) => Boolean(mentor.unique_id))
|
|
263336
|
+
.map((mentor) => ({
|
|
263337
|
+
value: mentor.unique_id,
|
|
263338
|
+
label: mentor.name || mentor.unique_id,
|
|
263339
|
+
}));
|
|
263340
|
+
}, [searchResponse]);
|
|
263341
|
+
const { data, isLoading, isFetching, error } = useGetMentorsQuery({
|
|
263342
|
+
org: tenantKey,
|
|
263343
|
+
username,
|
|
263344
|
+
limit: PAGE_SIZE$3,
|
|
263345
|
+
offset: (page - 1) * PAGE_SIZE$3,
|
|
263346
|
+
...(agentFilter ? { uniqueId: agentFilter.value } : {}),
|
|
263347
|
+
});
|
|
263348
|
+
const agents = ((_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : []);
|
|
263349
|
+
const totalPages = (data === null || data === void 0 ? void 0 : data.count) ? Math.ceil(data.count / PAGE_SIZE$3) : 0;
|
|
263350
|
+
const isForbidden = !!error && error.status === 403;
|
|
263351
|
+
return (jsxs("div", { "data-testid": "memory-admin-agent-section", children: [jsx("div", { className: "mb-6 max-w-sm", children: jsx(SearchSelect, { labels: {
|
|
263352
|
+
// No field label — the users tab's search carries none either.
|
|
263353
|
+
label: '',
|
|
263354
|
+
placeholder: t('memoryAdminTab.filter.placeholder'),
|
|
263355
|
+
typeToSearch: t('memoryAdminTab.filter.typeToSearch'),
|
|
263356
|
+
searching: t('memoryAdminTab.filter.searching'),
|
|
263357
|
+
noResults: t('memoryAdminTab.filter.noResults'),
|
|
263358
|
+
clear: t('memoryAdminTab.filter.clear'),
|
|
263359
|
+
}, selected: agentFilter, onSelect: (option) => {
|
|
263360
|
+
setAgentFilter(option);
|
|
263361
|
+
setAgentSearch('');
|
|
263362
|
+
}, onClear: () => setAgentFilter(null), searchTerm: agentSearch, onSearchTermChange: setAgentSearch, options: agentOptions, isLoading: isSearchingAgents, testId: "agent-memories-filter" }) }), 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-[32%]", children: t('memoryAdminTab.agentColumn') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[52%]", children: t('memoryAdminTab.descriptionColumn') }), 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: [agents.map((agent) => (jsxs("tr", { "data-testid": `memory-admin-agent-row-${agent.unique_id}`, 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: agent.name }) }), jsx("td", { className: "px-6 py-4 text-gray-600 dark:text-gray-300 max-w-0", children: jsx("div", { className: "truncate", children: agent.description || '—' }) }), jsx("td", { className: "px-6 py-4", children: jsx("div", { className: "flex justify-end gap-2", children: jsx(Button$1, { "data-testid": `memory-admin-agent-view-${agent.unique_id}`, variant: "ghost", size: "sm", "aria-label": t('memoryAdminTab.viewMemoriesAriaLabel', {
|
|
263363
|
+
name: agent.name,
|
|
263364
|
+
}), onClick: () => setSelectedAgent(agent), children: jsx(Eye, { className: "h-4 w-4" }) }) }) })] }, agent.unique_id))), agents.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 3, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: isFetching ? t('memoryAdminTab.loading') : t('memoryAdminTab.noAgentsFound') }) }))] })] }) }), totalPages > 1 && (jsx("div", { className: "mt-6", children: jsx(IblPagination, { totalPages: totalPages, currentPage: page, onPageChange: setPage, disabled: isFetching }) }))] })), selectedAgent && (jsx(AgentMemoriesModal, { isOpen: !!selectedAgent, onClose: () => setSelectedAgent(null), tenantKey: tenantKey, username: username, agent: selectedAgent }))] }));
|
|
263365
|
+
}
|
|
263366
|
+
|
|
263367
|
+
/**
|
|
263368
|
+
* Tenant-settings Memory tab. Lets admins/RBAC-granted users manage other
|
|
263369
|
+
* users' global memories and per-agent memories from one place, mirroring the
|
|
263370
|
+
* Billing tab's sub-tab layout.
|
|
263371
|
+
*/
|
|
263372
|
+
function MemoryAdminTab({ tenantKey, username }) {
|
|
263373
|
+
const t = useT();
|
|
263374
|
+
// Same platform gate the profile memory tab applies: when memsearch is off
|
|
263375
|
+
// for the tenant there is nothing to manage.
|
|
263376
|
+
const { data: memsearchStatus, isLoading, isError, } = useGetMemsearchStatusQuery({ org: tenantKey, userId: username });
|
|
263377
|
+
if (isLoading) {
|
|
263378
|
+
return (jsxs("div", { className: "space-y-6", children: [jsx(Skeleton, { className: "h-10 w-full max-w-sm rounded-lg" }), jsx(Skeleton, { className: "h-40 w-full rounded-lg" })] }));
|
|
263379
|
+
}
|
|
263380
|
+
if (!isError && memsearchStatus && !memsearchStatus.enable_memsearch) {
|
|
263381
|
+
return (jsx("div", { className: "max-w-2xl", children: jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children: t('memoryAdminTab.featureDisabled') }) }) }));
|
|
263382
|
+
}
|
|
263383
|
+
return (jsxs(Tabs, { defaultValue: "global-memories", "aria-label": t('memoryAdminTab.tabsAriaLabel'), children: [jsxs(TabsList, { "aria-label": t('memoryAdminTab.tabsAriaLabel'), className: "max-w-full overflow-x-auto justify-start px-1", children: [jsx(TabsTrigger, { "data-testid": "memory-admin-sub-tab-global", value: "global-memories", children: t('memoryAdminTab.tabGlobalMemories') }), jsx(TabsTrigger, { "data-testid": "memory-admin-sub-tab-agent", value: "agent-memories", children: t('memoryAdminTab.tabAgentMemories') })] }), jsx(TabsContent, { className: "mt-4", value: "global-memories", children: jsx(GlobalMemoriesSection, { tenantKey: tenantKey, username: username }) }), jsx(TabsContent, { className: "mt-4", value: "agent-memories", children: jsx(AgentMemoriesSection, { tenantKey: tenantKey, username: username }) })] }));
|
|
263384
|
+
}
|
|
263385
|
+
|
|
261982
263386
|
function Account({ tenant, tenants = [], username, onInviteClick, email, mainPlatformKey, userActiveApp = null, showPlatformName = false, isAdmin = false, targetTab = 'basic', currentPlan: _currentPlan = '', currentSPA = '', authURL, onTenantUpdate, currentPlatformBaseDomain = '', enableRbac = false, showBenchmarks = false, rbacPermissions = {}, onLoadGroupPermissions, onTabChange, defaultSupportPhone = '', enableSupportPhone, showGradebookTab = false, }) {
|
|
261983
263387
|
var _a, _b, _c, _d;
|
|
261984
263388
|
const t = useT();
|
|
@@ -261995,6 +263399,7 @@ function Account({ tenant, tenants = [], username, onInviteClick, email, mainPla
|
|
|
261995
263399
|
...(showBenchmarks
|
|
261996
263400
|
? [{ id: 'datasets', label: t('profileAccount.tabBenchmarks'), icon: ListChecks }]
|
|
261997
263401
|
: []),
|
|
263402
|
+
{ id: 'memory', label: t('profileAccount.tabMemory'), icon: Brain },
|
|
261998
263403
|
{ id: 'advanced', label: t('profileAccount.tabAdvanced'), icon: Settings$1 },
|
|
261999
263404
|
];
|
|
262000
263405
|
const [activeTab, setActiveTab] = useState(targetTab);
|
|
@@ -262076,10 +263481,10 @@ function Account({ tenant, tenants = [], username, onInviteClick, email, mainPla
|
|
|
262076
263481
|
onTabChange === null || onTabChange === void 0 ? void 0 : onTabChange('billing');
|
|
262077
263482
|
}, className: `flex items-center gap-2 px-3 py-2 rounded-lg whitespace-nowrap text-sm transition-all ${activeTab === 'billing'
|
|
262078
263483
|
? 'bg-blue-50 text-blue-600 font-medium'
|
|
262079
|
-
: 'text-gray-600 hover:bg-gray-50'}`, children: [jsx(CreditCard, { className: "h-4 w-4" }), jsx("span", { className: "hidden sm:inline", children: t('profileAccount.tabBilling') }), jsx("span", { className: "sm:hidden", children: t('profileAccount.tabBilling') })] }, 'billing'))] }) }) }), jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", style: { height: '100%' }, children: [jsxs("div", { className: "hidden lg:block flex-shrink-0 p-6 border-b border-gray-200 bg-white dark:bg-gray-900", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: (_b = (_a = TABS.find((t) => t.id === activeTab)) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : (activeTab === 'billing' ? t('profileAccount.tabBilling') : activeTab) }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'management' && t('profileAccount.descManagement'), activeTab === 'organization' && t('profileAccount.descOrganization'), activeTab === 'integrations' && t('profileAccount.descIntegrations'), activeTab === 'billing' && t('profileAccount.descBilling'), activeTab === 'monetization' && t('profileAccount.descMonetization'), activeTab === 'datasets' && t('profileAccount.descBenchmarks'), activeTab === 'advanced' && t('profileAccount.descAdvanced')] })] }), jsxs("div", { className: "flex-1 p-6 space-y-6", style: {
|
|
263484
|
+
: 'text-gray-600 hover:bg-gray-50'}`, children: [jsx(CreditCard, { className: "h-4 w-4" }), jsx("span", { className: "hidden sm:inline", children: t('profileAccount.tabBilling') }), jsx("span", { className: "sm:hidden", children: t('profileAccount.tabBilling') })] }, 'billing'))] }) }) }), jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", style: { height: '100%' }, children: [jsxs("div", { className: "hidden lg:block flex-shrink-0 p-6 border-b border-gray-200 bg-white dark:bg-gray-900", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: (_b = (_a = TABS.find((t) => t.id === activeTab)) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : (activeTab === 'billing' ? t('profileAccount.tabBilling') : activeTab) }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'management' && t('profileAccount.descManagement'), activeTab === 'organization' && t('profileAccount.descOrganization'), activeTab === 'integrations' && t('profileAccount.descIntegrations'), activeTab === 'billing' && t('profileAccount.descBilling'), activeTab === 'monetization' && t('profileAccount.descMonetization'), activeTab === 'datasets' && t('profileAccount.descBenchmarks'), activeTab === 'memory' && t('profileAccount.descMemory'), activeTab === 'advanced' && t('profileAccount.descAdvanced')] })] }), jsxs("div", { className: "flex-1 p-6 space-y-6", style: {
|
|
262080
263485
|
overflowY: 'auto',
|
|
262081
263486
|
overflowX: 'hidden',
|
|
262082
|
-
}, children: [jsxs("div", { className: "lg:hidden mb-6", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: (_d = (_c = TABS.find((t) => t.id === activeTab)) === null || _c === void 0 ? void 0 : _c.label) !== null && _d !== void 0 ? _d : (activeTab === 'billing' ? t('profileAccount.tabBilling') : activeTab) }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'billing' && t('profileAccount.descBilling'), activeTab === 'basic' && t('profileAccount.descBasic'), activeTab === 'social' && t('profileAccount.descSocial'), activeTab === 'security' && t('profileAccount.descSecurity'), activeTab === 'management' && t('profileAccount.descManagement'), activeTab === 'organization' && t('profileAccount.descOrganization'), activeTab === 'monetization' && t('profileAccount.descMonetization'), activeTab === 'datasets' && t('profileAccount.descBenchmarks'), activeTab === 'advanced' && t('profileAccount.descAdvanced')] })] }), activeTab === 'management' && hasManagementPermissions && (jsx(Admin, { authSpaUrl: authURL, onInviteClick: onInviteClick, tenant: tenant, currentSpa: currentSPA, hasUserTabPermission: hasUserTabPermission, hasGroupsTabPermission: hasGroupsTabPermission, hasPoliciesTabPermission: hasPoliciesTabPermission, hasRolesTabPermission: hasRolesTabPermission, hasTeamsTabPermission: hasTeamsTabPermission, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, hasAlertsTabPermission: hasAlertsTabPermission, rbacPermissions: rbacPermissions, enableRbac: enableRbac, showGradebookTab: showGradebookTab })), activeTab === 'organization' && (jsx(OrganizationTab, { platformKey: tenant, tenant: tenants.find((ten) => ten.key === tenant), onTenantUpdate: onTenantUpdate, setOrganizationLogoFromOutside: setOrganizationLogo, defaultSupportPhone: defaultSupportPhone, enableSupportPhone: enableSupportPhone })), activeTab === 'integrations' && (jsx(IntegrationsTab, { tenantKey: tenant, username: username })), activeTab === 'billing' && (jsx(BillingTab, { tenant: tenant, userActiveApp: userActiveApp, username: username, currentUserEmail: email, mainPlatformKey: mainPlatformKey })), activeTab === 'monetization' && (jsx(MonetizationTab, { platformKey: tenant, authURL: authURL })), activeTab === 'datasets' && showBenchmarks && (jsx(BenchmarksTab, { tenantKey: tenant, username: username })), activeTab === 'advanced' && (jsx(AdvancedTab, { platformKey: tenant, currentSPA: currentSPA, username: username, authURL: authURL, currentPlatformBaseDomain: currentPlatformBaseDomain }))] })] }), jsx(ToastProvider, {})] }));
|
|
263487
|
+
}, children: [jsxs("div", { className: "lg:hidden mb-6", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2", children: (_d = (_c = TABS.find((t) => t.id === activeTab)) === null || _c === void 0 ? void 0 : _c.label) !== null && _d !== void 0 ? _d : (activeTab === 'billing' ? t('profileAccount.tabBilling') : activeTab) }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'billing' && t('profileAccount.descBilling'), activeTab === 'basic' && t('profileAccount.descBasic'), activeTab === 'social' && t('profileAccount.descSocial'), activeTab === 'security' && t('profileAccount.descSecurity'), activeTab === 'management' && t('profileAccount.descManagement'), activeTab === 'organization' && t('profileAccount.descOrganization'), activeTab === 'monetization' && t('profileAccount.descMonetization'), activeTab === 'datasets' && t('profileAccount.descBenchmarks'), activeTab === 'memory' && t('profileAccount.descMemory'), activeTab === 'advanced' && t('profileAccount.descAdvanced')] })] }), activeTab === 'management' && hasManagementPermissions && (jsx(Admin, { authSpaUrl: authURL, onInviteClick: onInviteClick, tenant: tenant, currentSpa: currentSPA, hasUserTabPermission: hasUserTabPermission, hasGroupsTabPermission: hasGroupsTabPermission, hasPoliciesTabPermission: hasPoliciesTabPermission, hasRolesTabPermission: hasRolesTabPermission, hasTeamsTabPermission: hasTeamsTabPermission, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, hasAlertsTabPermission: hasAlertsTabPermission, rbacPermissions: rbacPermissions, enableRbac: enableRbac, showGradebookTab: showGradebookTab })), activeTab === 'organization' && (jsx(OrganizationTab, { platformKey: tenant, tenant: tenants.find((ten) => ten.key === tenant), onTenantUpdate: onTenantUpdate, setOrganizationLogoFromOutside: setOrganizationLogo, defaultSupportPhone: defaultSupportPhone, enableSupportPhone: enableSupportPhone })), activeTab === 'integrations' && (jsx(IntegrationsTab, { tenantKey: tenant, username: username })), activeTab === 'billing' && (jsx(BillingTab, { tenant: tenant, userActiveApp: userActiveApp, username: username, currentUserEmail: email, mainPlatformKey: mainPlatformKey })), activeTab === 'monetization' && (jsx(MonetizationTab, { platformKey: tenant, authURL: authURL })), activeTab === 'datasets' && showBenchmarks && (jsx(BenchmarksTab, { tenantKey: tenant, username: username })), activeTab === 'memory' && jsx(MemoryAdminTab, { tenantKey: tenant, username: username }), activeTab === 'advanced' && (jsx(AdvancedTab, { platformKey: tenant, currentSPA: currentSPA, username: username, authURL: authURL, currentPlatformBaseDomain: currentPlatformBaseDomain }))] })] }), jsx(ToastProvider, {})] }));
|
|
262083
263488
|
}
|
|
262084
263489
|
|
|
262085
263490
|
function UserProfileModal({ isOpen, onClose, params, email, mainPlatformKey, showMentorAIDisplayCheckbox = false, showLeaderboardDisplayCheckbox = false, showGradebookTab = false, showUsernameField = false, showPlatformName = false, useGravatarPicFallback = true, enableCatalogInvite = false, targetTab = 'basic', currentPlan = '', currentSPA = '', userActiveApp = null, authURL, tenants = [], onTenantUpdate, currentPlatformBaseDomain = '', rbacPermissions = {}, enableRbac = false, onLoadGroupPermissions, onTabChange, defaultSupportPhone = '', onBillingTabRequest, onAccountDeleted, enableMemoryTab = false, showBenchmarks = false, localLLMProps, enableSupportPhone, }) {
|
|
@@ -268177,286 +269582,6 @@ function AgentToolsTab({ labels: labelsOverride }) {
|
|
|
268177
269582
|
}) })) }) })] }));
|
|
268178
269583
|
}
|
|
268179
269584
|
|
|
268180
|
-
const EditMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return editMemoryModal; }).then((module) => ({
|
|
268181
|
-
default: module.EditMemoryModal,
|
|
268182
|
-
})), { ssr: false });
|
|
268183
|
-
const AddMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return addMemoryModal; }).then((module) => ({
|
|
268184
|
-
default: module.AddMemoryModal,
|
|
268185
|
-
})), { ssr: false });
|
|
268186
|
-
const DeleteMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return deleteMemoryModal; }).then((module) => ({
|
|
268187
|
-
default: module.DeleteMemoryModal,
|
|
268188
|
-
})), { ssr: false });
|
|
268189
|
-
const BulkDeleteMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return bulkDeleteMemoryModal; }).then((module) => ({
|
|
268190
|
-
default: module.BulkDeleteMemoryModal,
|
|
268191
|
-
})), { ssr: false });
|
|
268192
|
-
const ManageCategoriesModal$1 = dynamic(() => Promise.resolve().then(function () { return manageCategoriesModal; }).then((module) => ({
|
|
268193
|
-
default: module.ManageCategoriesModal,
|
|
268194
|
-
})), { ssr: false });
|
|
268195
|
-
const PAGE_SIZE$3 = 20;
|
|
268196
|
-
const SNAPSHOT_PAGE_SIZE = 1000;
|
|
268197
|
-
function ManageMemories({ tenantKey, username, mentorId }) {
|
|
268198
|
-
var _a, _b, _c, _d, _e;
|
|
268199
|
-
const t = useT();
|
|
268200
|
-
const [selectedLearner, setSelectedLearner] = useState('');
|
|
268201
|
-
const [dateRange, setDateRange] = useState(undefined);
|
|
268202
|
-
const [selectedCategorySlug, setSelectedCategorySlug] = useState('all');
|
|
268203
|
-
const [page, setPage] = useState(1);
|
|
268204
|
-
// Reset to page 1 whenever any filter changes — otherwise we could land on a
|
|
268205
|
-
// page index that no longer exists in the new result set.
|
|
268206
|
-
useEffect(() => {
|
|
268207
|
-
setPage(1);
|
|
268208
|
-
}, [selectedLearner, dateRange, selectedCategorySlug]);
|
|
268209
|
-
const listParams = useMemo(() => {
|
|
268210
|
-
const params = { page, page_size: PAGE_SIZE$3 };
|
|
268211
|
-
if (selectedLearner)
|
|
268212
|
-
params.email = selectedLearner;
|
|
268213
|
-
if (selectedCategorySlug !== 'all')
|
|
268214
|
-
params.category = selectedCategorySlug;
|
|
268215
|
-
if (dateRange === null || dateRange === void 0 ? void 0 : dateRange.from)
|
|
268216
|
-
params.start_date = format$1(dateRange.from, 'yyyy-MM-dd');
|
|
268217
|
-
if (dateRange === null || dateRange === void 0 ? void 0 : dateRange.to)
|
|
268218
|
-
params.end_date = format$1(dateRange.to, 'yyyy-MM-dd');
|
|
268219
|
-
return params;
|
|
268220
|
-
}, [page, selectedLearner, selectedCategorySlug, dateRange]);
|
|
268221
|
-
const { data: listResponse, isLoading: isLoadingMemories } = useGetMentorMemoriesListQuery({
|
|
268222
|
-
org: tenantKey,
|
|
268223
|
-
userId: username !== null && username !== void 0 ? username : '',
|
|
268224
|
-
mentorId,
|
|
268225
|
-
params: listParams,
|
|
268226
|
-
}, {
|
|
268227
|
-
skip: !tenantKey || !username || !mentorId,
|
|
268228
|
-
});
|
|
268229
|
-
const totalPages = Math.max(1, Math.ceil(((_a = listResponse === null || listResponse === void 0 ? void 0 : listResponse.count) !== null && _a !== void 0 ? _a : 0) / PAGE_SIZE$3));
|
|
268230
|
-
const { data: adminCategories } = useGetMemoryCategoriesAdminQuery({
|
|
268231
|
-
org: tenantKey,
|
|
268232
|
-
mentorId,
|
|
268233
|
-
}, {
|
|
268234
|
-
skip: !tenantKey || !mentorId,
|
|
268235
|
-
});
|
|
268236
|
-
const [deleteMentorMemory, { isLoading: isDeleting }] = useDeleteMentorMemoryMutation();
|
|
268237
|
-
const [updateMentorMemory, { isLoading: isEditing }] = useUpdateMentorMemoryMutation();
|
|
268238
|
-
const [createMentorMemory, { isLoading: isSaving }] = useCreateMentorMemoryMutation();
|
|
268239
|
-
// Flat list of memories on the current page, mapped into the local `Memory`
|
|
268240
|
-
// shape used by the rest of this component.
|
|
268241
|
-
const memories = useMemo(() => {
|
|
268242
|
-
if (!(listResponse === null || listResponse === void 0 ? void 0 : listResponse.results))
|
|
268243
|
-
return [];
|
|
268244
|
-
return listResponse.results.map((memory) => ({
|
|
268245
|
-
id: memory.id,
|
|
268246
|
-
content: memory.content,
|
|
268247
|
-
category: {
|
|
268248
|
-
id: memory.category.id,
|
|
268249
|
-
name: memory.category.name,
|
|
268250
|
-
slug: memory.category.slug,
|
|
268251
|
-
},
|
|
268252
|
-
email: memory.email,
|
|
268253
|
-
createdAt: memory.created_at,
|
|
268254
|
-
}));
|
|
268255
|
-
}, [listResponse]);
|
|
268256
|
-
// Unfiltered snapshot used to derive the learner dropdown and to source the
|
|
268257
|
-
// bulk-delete operation, which needs the full set of memories — not just the
|
|
268258
|
-
// current page.
|
|
268259
|
-
const { data: snapshotResponse } = useGetMentorMemoriesListQuery({
|
|
268260
|
-
org: tenantKey,
|
|
268261
|
-
userId: username !== null && username !== void 0 ? username : '',
|
|
268262
|
-
mentorId,
|
|
268263
|
-
params: { page: 1, page_size: SNAPSHOT_PAGE_SIZE },
|
|
268264
|
-
}, {
|
|
268265
|
-
skip: !tenantKey || !username || !mentorId,
|
|
268266
|
-
});
|
|
268267
|
-
const learners = useMemo(() => {
|
|
268268
|
-
if (!(snapshotResponse === null || snapshotResponse === void 0 ? void 0 : snapshotResponse.results))
|
|
268269
|
-
return [];
|
|
268270
|
-
const emailSet = new Set();
|
|
268271
|
-
snapshotResponse.results.forEach((m) => {
|
|
268272
|
-
if (m.email)
|
|
268273
|
-
emailSet.add(m.email);
|
|
268274
|
-
});
|
|
268275
|
-
return Array.from(emailSet).map((email) => ({ email }));
|
|
268276
|
-
}, [snapshotResponse]);
|
|
268277
|
-
const categories = useMemo(() => {
|
|
268278
|
-
if (adminCategories && adminCategories.length > 0) {
|
|
268279
|
-
return [
|
|
268280
|
-
{ id: 0, name: 'All', slug: 'all' },
|
|
268281
|
-
...adminCategories.map((cat) => ({
|
|
268282
|
-
id: cat.id,
|
|
268283
|
-
name: cat.name,
|
|
268284
|
-
slug: cat.slug,
|
|
268285
|
-
})),
|
|
268286
|
-
];
|
|
268287
|
-
}
|
|
268288
|
-
return [{ id: 0, name: 'All', slug: 'all' }];
|
|
268289
|
-
}, [adminCategories]);
|
|
268290
|
-
const [editingMemory, setEditingMemory] = useState(null);
|
|
268291
|
-
const [editContent, setEditContent] = useState('');
|
|
268292
|
-
const [editCategory, setEditCategory] = useState('');
|
|
268293
|
-
const [showDeleteConfirm, setShowDeleteConfirm] = useState(null);
|
|
268294
|
-
const [showAddMemory, setShowAddMemory] = useState(false);
|
|
268295
|
-
const [newMemoryContent, setNewMemoryContent] = useState('');
|
|
268296
|
-
const [newMemoryCategory, setNewMemoryCategory] = useState('');
|
|
268297
|
-
const [showMobileDropdown, setShowMobileDropdown] = useState(false);
|
|
268298
|
-
const [showBulkDeleteConfirm, setShowBulkDeleteConfirm] = useState(false);
|
|
268299
|
-
const [isBulkDeleting, setIsBulkDeleting] = useState(false);
|
|
268300
|
-
const [showManageCategories, setShowManageCategories] = useState(false);
|
|
268301
|
-
const selectedCategoryName = (_c = (_b = categories.find((c) => c.slug === selectedCategorySlug)) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : t('memoryTabManageMemories.all');
|
|
268302
|
-
const VISIBLE_CATEGORY_LIMIT = 6;
|
|
268303
|
-
const visibleCategories = categories.slice(0, VISIBLE_CATEGORY_LIMIT);
|
|
268304
|
-
const overflowCategories = categories.slice(VISIBLE_CATEGORY_LIMIT);
|
|
268305
|
-
const overflowSelected = overflowCategories.find((c) => c.slug === selectedCategorySlug);
|
|
268306
|
-
// Category is filtered server-side via the `category` query param now, so
|
|
268307
|
-
// `memories` already contains only the relevant entries for the page.
|
|
268308
|
-
const filteredMemories = memories;
|
|
268309
|
-
const handleDeleteMemory = async (id) => {
|
|
268310
|
-
if (!tenantKey || !username)
|
|
268311
|
-
return;
|
|
268312
|
-
try {
|
|
268313
|
-
await deleteMentorMemory({
|
|
268314
|
-
org: tenantKey,
|
|
268315
|
-
userId: username,
|
|
268316
|
-
mentorId,
|
|
268317
|
-
memoryId: id,
|
|
268318
|
-
}).unwrap();
|
|
268319
|
-
setShowDeleteConfirm(null);
|
|
268320
|
-
toast.success(t('memoryTabManageMemories.memoryDeletedSuccessfully'));
|
|
268321
|
-
}
|
|
268322
|
-
catch (error) {
|
|
268323
|
-
console.error('Failed to delete memory:', error);
|
|
268324
|
-
toast.error(t('memoryTabManageMemories.failedToDeleteMemory'));
|
|
268325
|
-
}
|
|
268326
|
-
};
|
|
268327
|
-
const handleBulkDelete = async () => {
|
|
268328
|
-
var _a;
|
|
268329
|
-
if (!tenantKey || !username)
|
|
268330
|
-
return;
|
|
268331
|
-
setIsBulkDeleting(true);
|
|
268332
|
-
try {
|
|
268333
|
-
// Source bulk-delete from the unfiltered snapshot — `memories` only holds
|
|
268334
|
-
// the current page, while bulk delete must remove every entry in the
|
|
268335
|
-
// selected category.
|
|
268336
|
-
const memoriesToDelete = ((_a = snapshotResponse === null || snapshotResponse === void 0 ? void 0 : snapshotResponse.results) !== null && _a !== void 0 ? _a : []).filter((memory) => memory.category.slug === selectedCategorySlug);
|
|
268337
|
-
await Promise.all(memoriesToDelete.map((memory) => deleteMentorMemory({
|
|
268338
|
-
org: tenantKey,
|
|
268339
|
-
userId: username,
|
|
268340
|
-
mentorId,
|
|
268341
|
-
memoryId: memory.id,
|
|
268342
|
-
}).unwrap()));
|
|
268343
|
-
toast.success(t('memoryTabManageMemories.allCategoryMemoriesDeleted', { category: selectedCategoryName }));
|
|
268344
|
-
setShowBulkDeleteConfirm(false);
|
|
268345
|
-
}
|
|
268346
|
-
catch (error) {
|
|
268347
|
-
console.error('Failed to delete memories:', error);
|
|
268348
|
-
toast.error(t('memoryTabManageMemories.failedToDeleteMemories'));
|
|
268349
|
-
}
|
|
268350
|
-
finally {
|
|
268351
|
-
setIsBulkDeleting(false);
|
|
268352
|
-
}
|
|
268353
|
-
};
|
|
268354
|
-
const startEdit = (memory) => {
|
|
268355
|
-
setEditingMemory(memory);
|
|
268356
|
-
setEditContent(memory.content);
|
|
268357
|
-
setEditCategory(memory.category.name);
|
|
268358
|
-
};
|
|
268359
|
-
const saveEdit = async () => {
|
|
268360
|
-
if (!editingMemory || !tenantKey || !username)
|
|
268361
|
-
return;
|
|
268362
|
-
try {
|
|
268363
|
-
const selectedCat = categories.find((c) => c.name === editCategory);
|
|
268364
|
-
const categoryChanged = !!selectedCat && selectedCat.slug !== editingMemory.category.slug;
|
|
268365
|
-
await updateMentorMemory({
|
|
268366
|
-
org: tenantKey,
|
|
268367
|
-
userId: username,
|
|
268368
|
-
mentorId,
|
|
268369
|
-
memoryId: editingMemory.id,
|
|
268370
|
-
data: {
|
|
268371
|
-
content: editContent,
|
|
268372
|
-
...(categoryChanged ? { category_slug: selectedCat.slug } : {}),
|
|
268373
|
-
},
|
|
268374
|
-
}).unwrap();
|
|
268375
|
-
toast.success(t('memoryTabManageMemories.memoryUpdatedSuccessfully'));
|
|
268376
|
-
// Follow the entry to its new category tab so the user doesn't lose
|
|
268377
|
-
// sight of it. Skip when viewing "All" — the entry is still visible.
|
|
268378
|
-
if (categoryChanged && selectedCategorySlug !== 'all') {
|
|
268379
|
-
setSelectedCategorySlug(selectedCat.slug);
|
|
268380
|
-
}
|
|
268381
|
-
setEditingMemory(null);
|
|
268382
|
-
setEditContent('');
|
|
268383
|
-
setEditCategory('');
|
|
268384
|
-
}
|
|
268385
|
-
catch (error) {
|
|
268386
|
-
console.error('Failed to update memory:', error);
|
|
268387
|
-
toast.error(t('memoryTabManageMemories.failedToUpdateMemory'));
|
|
268388
|
-
}
|
|
268389
|
-
};
|
|
268390
|
-
const cancelEdit = () => {
|
|
268391
|
-
setEditingMemory(null);
|
|
268392
|
-
setEditContent('');
|
|
268393
|
-
setEditCategory('');
|
|
268394
|
-
};
|
|
268395
|
-
const startAddMemory = () => {
|
|
268396
|
-
setShowAddMemory(true);
|
|
268397
|
-
setNewMemoryCategory(selectedCategoryName);
|
|
268398
|
-
};
|
|
268399
|
-
const saveNewMemory = async () => {
|
|
268400
|
-
var _a;
|
|
268401
|
-
if (!newMemoryContent.trim() || !tenantKey || !username)
|
|
268402
|
-
return;
|
|
268403
|
-
try {
|
|
268404
|
-
const selectedCat = categories.find((c) => c.name === newMemoryCategory);
|
|
268405
|
-
const categorySlug = (_a = selectedCat === null || selectedCat === void 0 ? void 0 : selectedCat.slug) !== null && _a !== void 0 ? _a : selectedCategorySlug;
|
|
268406
|
-
await createMentorMemory({
|
|
268407
|
-
org: tenantKey,
|
|
268408
|
-
userId: username,
|
|
268409
|
-
mentorId,
|
|
268410
|
-
data: {
|
|
268411
|
-
category_slug: categorySlug === 'all' ? 'general' : categorySlug,
|
|
268412
|
-
content: newMemoryContent.trim(),
|
|
268413
|
-
},
|
|
268414
|
-
}).unwrap();
|
|
268415
|
-
setShowAddMemory(false);
|
|
268416
|
-
setNewMemoryContent('');
|
|
268417
|
-
setNewMemoryCategory('');
|
|
268418
|
-
if (selectedCat) {
|
|
268419
|
-
setSelectedCategorySlug(selectedCat.slug);
|
|
268420
|
-
}
|
|
268421
|
-
toast.success(t('memoryTabManageMemories.memoryCreatedSuccessfully'));
|
|
268422
|
-
}
|
|
268423
|
-
catch (error) {
|
|
268424
|
-
console.error('Failed to create memory:', error);
|
|
268425
|
-
toast.error(t('memoryTabManageMemories.failedToCreateMemory'));
|
|
268426
|
-
}
|
|
268427
|
-
};
|
|
268428
|
-
const cancelAddMemory = () => {
|
|
268429
|
-
setShowAddMemory(false);
|
|
268430
|
-
setNewMemoryContent('');
|
|
268431
|
-
setNewMemoryCategory('');
|
|
268432
|
-
};
|
|
268433
|
-
const categoryNames = categories.map((c) => c.name);
|
|
268434
|
-
return (jsxs(Fragment$1, { children: [jsxs("div", { className: "space-y-6", children: [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": t('memoryTabManageMemories.searchForUser'), className: "w-full justify-between bg-transparent font-normal", children: [selectedLearner
|
|
268435
|
-
? ((_e = (_d = learners.find((learner) => learner.email === selectedLearner)) === null || _d === void 0 ? void 0 : _d.email) !== null && _e !== void 0 ? _e : selectedLearner)
|
|
268436
|
-
: t('memoryTabManageMemories.searchForUser'), jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), jsx(PopoverContent, { className: "w-full p-0", align: "start", children: jsxs(Command, { children: [jsx(CommandInput, { placeholder: t('memoryTabManageMemories.searchUsersPlaceholder') }), jsxs(CommandList, { children: [jsx(CommandEmpty, { children: t('memoryTabManageMemories.noUsersFound') }), jsxs(CommandGroup, { children: [jsxs(CommandItem, { value: "", onSelect: () => {
|
|
268437
|
-
setSelectedLearner('');
|
|
268438
|
-
}, children: [jsx(Check, { className: cn('mr-2 h-4 w-4', !selectedLearner ? 'opacity-100' : 'opacity-0') }), t('memoryTabManageMemories.allUsers')] }), learners.map((learner) => (jsxs(CommandItem, { value: learner.email, onSelect: () => {
|
|
268439
|
-
setSelectedLearner(learner.email);
|
|
268440
|
-
}, children: [jsx(Check, { className: cn('mr-2 h-4 w-4', selectedLearner === 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(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", 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)
|
|
268441
|
-
? `${format$1(dateRange.from, 'MMM dd')} - ${format$1(dateRange.to, 'MMM dd')}`
|
|
268442
|
-
: t('memoryTabManageMemories.pickDateRange')] }) }), jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: jsx(Calendar, { mode: "range", selected: dateRange, onSelect: setDateRange, numberOfMonths: 2, initialFocus: true }) })] })] }) }), jsx("div", { children: jsxs("div", { className: "flex items-center justify-between gap-4", children: [jsxs("div", { className: "scrollbar-none hidden flex-1 items-center space-x-8 overflow-x-auto sm:flex", children: [visibleCategories.map((category) => (jsxs("button", { onClick: () => setSelectedCategorySlug(category.slug), className: `relative px-1 py-2 text-sm font-medium whitespace-nowrap transition-colors ${selectedCategorySlug === category.slug
|
|
268443
|
-
? 'text-[#38A1E5]'
|
|
268444
|
-
: 'text-gray-600 hover:text-gray-900'}`, children: [category.name, selectedCategorySlug === category.slug && (jsx("div", { className: "absolute bottom-0 left-1/2 h-0.5 -translate-x-1/2 transform bg-[#38A1E5] transition-all duration-200", style: { width: `${category.name.length * 0.55}em` } }))] }, category.slug))), overflowCategories.length > 0 && (jsxs(DropdownMenu, { children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs("button", { className: cn('relative flex items-center gap-1 px-1 py-2 text-sm font-medium whitespace-nowrap transition-colors', overflowSelected ? 'text-[#38A1E5]' : 'text-gray-600 hover:text-gray-900'), "aria-label": t('memoryTabManageMemories.moreCategories'), children: [overflowSelected ? overflowSelected.name : t('memoryTabManageMemories.more'), jsx(ChevronDown, { className: "h-3.5 w-3.5" }), overflowSelected && (jsx("div", { className: "absolute bottom-0 left-0 h-0.5 bg-[#38A1E5] transition-all duration-200", style: {
|
|
268445
|
-
width: `${overflowSelected.name.length * 0.55}em`,
|
|
268446
|
-
} }))] }) }), jsx(DropdownMenuContent, { align: "end", children: overflowCategories.map((category) => (jsx(DropdownMenuItem, { onClick: () => setSelectedCategorySlug(category.slug), className: selectedCategorySlug === category.slug ? 'bg-gray-100' : '', children: category.name }, category.slug))) })] }))] }), jsx("div", { className: "w-full py-2 sm:hidden", children: jsxs(DropdownMenu, { open: showMobileDropdown, onOpenChange: setShowMobileDropdown, children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", className: "w-full justify-between bg-transparent", children: [selectedCategoryName, jsx(ChevronDown, { className: "h-4 w-4" })] }) }), jsx(DropdownMenuContent, { className: "w-full", children: categories.map((category) => (jsx(DropdownMenuItem, { onClick: () => {
|
|
268447
|
-
setSelectedCategorySlug(category.slug);
|
|
268448
|
-
setShowMobileDropdown(false);
|
|
268449
|
-
}, className: selectedCategorySlug === category.slug ? 'bg-gray-100' : '', children: category.name }, category.slug))) })] }) }), jsxs(Button$1, { onClick: () => setShowManageCategories(true), size: "sm", variant: "outline", className: "shrink-0", "aria-label": t('memoryTabManageMemories.manageCategories'), children: [jsx(Tags, { className: "h-4 w-4 sm:mr-2" }), jsx("span", { className: "hidden sm:inline", children: t('memoryTabManageMemories.categories') })] }), jsxs(Button$1, { onClick: startAddMemory, size: "sm", className: "ibl-button-primary shrink-0", children: [jsx(Plus, { className: "mr-1 h-4 w-4 sm:mr-2" }), jsx("span", { className: "hidden sm:inline", children: t('memoryTabManageMemories.addMemory') }), jsx("span", { className: "sm:hidden", children: t('memoryTabManageMemories.add') })] })] }) }), jsx("div", { className: "space-y-3 px-1 sm:px-0", children: isLoadingMemories ? (jsx("div", { className: "py-8 text-center text-gray-600", children: jsx("p", { children: t('memoryTabManageMemories.loadingMemories') }) })) : (filteredMemories.map((memory) => {
|
|
268450
|
-
const timeAgo = memory.createdAt
|
|
268451
|
-
? formatDistanceToNow(new Date(memory.createdAt), {
|
|
268452
|
-
addSuffix: true,
|
|
268453
|
-
})
|
|
268454
|
-
: '';
|
|
268455
|
-
const displayUser = memory.email || t('memoryTabManageMemories.unknown');
|
|
268456
|
-
return (jsxs("div", { className: "flex items-start gap-3 rounded-lg border border-gray-200 bg-white p-3", children: [jsxs("div", { className: "flex-1", children: [(timeAgo || displayUser) && (jsxs("div", { className: "mb-2 flex items-center justify-between", children: [timeAgo && jsx("span", { className: "text-sm text-gray-600", children: timeAgo }), displayUser && (jsx("span", { className: "max-w-[100px] truncate text-sm text-gray-900 sm:max-w-[200px]", children: displayUser }))] })), jsx("div", { className: "text-sm leading-relaxed text-gray-900", children: memory.content })] }), jsxs(DropdownMenu, { children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsx(Button$1, { variant: "ghost", size: "sm", className: "h-6 w-6 flex-shrink-0 p-0 text-gray-600 hover:text-gray-900", children: jsx(Ellipsis, { className: "h-4 w-4" }) }) }), jsxs(DropdownMenuContent, { align: "end", children: [jsx(DropdownMenuItem, { onClick: () => startEdit(memory), children: t('memoryTabManageMemories.edit') }), jsx(DropdownMenuItem, { onClick: () => setShowDeleteConfirm(memory.id), children: t('memoryTabManageMemories.delete') })] })] })] }, memory.id));
|
|
268457
|
-
})) }), filteredMemories.length > 0 && selectedCategorySlug !== 'all' && (jsx("div", { className: "flex justify-end", children: jsx(Button$1, { variant: "outline", onClick: () => setShowBulkDeleteConfirm(true), children: t('memoryTabManageMemories.deleteAll') }) })), filteredMemories.length === 0 && !isLoadingMemories && (jsx("div", { className: "py-8 text-center text-gray-600", children: jsx("p", { children: t('memoryTabManageMemories.noSavedMemories') }) })), totalPages > 1 && (jsx("div", { className: "flex justify-center pt-2", children: jsx(IblPagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage, disabled: isLoadingMemories }) }))] }), jsx(EditMemoryModal$1, { open: !!editingMemory, onOpenChange: (open) => !open && cancelEdit(), editContent: editContent, editCategory: editCategory, onContentChange: setEditContent, onCategoryChange: setEditCategory, onSave: saveEdit, onCancel: cancelEdit, categories: categoryNames, isSaving: isEditing }), jsx(AddMemoryModal$1, { open: showAddMemory, onOpenChange: (open) => !open && cancelAddMemory(), newMemoryContent: newMemoryContent, newMemoryCategory: newMemoryCategory, onContentChange: setNewMemoryContent, onCategoryChange: setNewMemoryCategory, onSave: saveNewMemory, onCancel: cancelAddMemory, categories: categoryNames, isSaving: isSaving }), jsx(DeleteMemoryModal$1, { open: !!showDeleteConfirm, onOpenChange: (open) => !open && setShowDeleteConfirm(null), onConfirm: () => showDeleteConfirm !== null && handleDeleteMemory(showDeleteConfirm), onCancel: () => setShowDeleteConfirm(null), isDeleting: isDeleting }), jsx(ManageCategoriesModal$1, { open: showManageCategories, onOpenChange: setShowManageCategories, tenantKey: tenantKey, mentorId: mentorId }), jsx(BulkDeleteMemoryModal$1, { open: showBulkDeleteConfirm, onOpenChange: setShowBulkDeleteConfirm, onConfirm: handleBulkDelete, onCancel: () => setShowBulkDeleteConfirm(false), isDeleting: isBulkDeleting, selectedCategory: selectedCategoryName })] }));
|
|
268458
|
-
}
|
|
268459
|
-
|
|
268460
269585
|
const AGENT_MEMORY_TAB_LABELS = {
|
|
268461
269586
|
header: {
|
|
268462
269587
|
title: 'Memory',
|
|
@@ -270340,6 +271465,9 @@ function CopyButton({ text, disabled = false }) {
|
|
|
270340
271465
|
const systemPromptSchema$1 = z$2.object({
|
|
270341
271466
|
prompt: z$2.string().min(1, 'Prompt is required'),
|
|
270342
271467
|
});
|
|
271468
|
+
const emptyAllowedPromptSchema = z$2.object({
|
|
271469
|
+
prompt: z$2.string(),
|
|
271470
|
+
});
|
|
270343
271471
|
const nonSystemPromptSchema$1 = z$2.object({
|
|
270344
271472
|
category: z$2.string().min(1, 'Category is required'),
|
|
270345
271473
|
prompt: z$2.string().min(1, 'Prompt is required'),
|
|
@@ -270368,7 +271496,11 @@ function EditPromptModal$1({ isOpen, onClose, selectedPrompt, handleSave, isEdit
|
|
|
270368
271496
|
promptVisibility: selectedPrompt.promptVisibility,
|
|
270369
271497
|
},
|
|
270370
271498
|
validators: {
|
|
270371
|
-
onChange: selectedPrompt.isSystem
|
|
271499
|
+
onChange: selectedPrompt.isSystem
|
|
271500
|
+
? selectedPrompt.allowEmpty
|
|
271501
|
+
? emptyAllowedPromptSchema
|
|
271502
|
+
: systemPromptSchema$1
|
|
271503
|
+
: nonSystemPromptSchema$1,
|
|
270372
271504
|
},
|
|
270373
271505
|
onSubmit: ({ value }) => {
|
|
270374
271506
|
handleSave(selectedPrompt, value);
|
|
@@ -270389,8 +271521,8 @@ function EditPromptModal$1({ isOpen, onClose, selectedPrompt, handleSave, isEdit
|
|
|
270389
271521
|
}, children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "text-start text-base font-semibold text-[#646464]", children: t('promptsTabEditPromptModal.editTitle', { label: selectedPrompt.label }) }) }), jsxs("div", { className: "mt-7 grid gap-4", children: [!selectedPrompt.isSystem && (jsx(form.Field, { name: "category", children: (field) => (jsxs("div", { className: "space-y-2", children: [jsx(Label$1, { className: "flex items-center text-sm font-medium text-[#646464]", children: t('promptsTabEditPromptModal.category') }), jsxs(Select$1, { disabled: isDisabled, value: field.state.value, onValueChange: field.handleChange, children: [jsx(SelectTrigger, { className: "py-6", "aria-label": t('promptsTabEditPromptModal.selectCategory'), children: jsx(SelectValue, { placeholder: t('promptsTabEditPromptModal.selectCategory') }) }), jsx(SelectContent, { children: promptCategories === null || promptCategories === void 0 ? void 0 : promptCategories.map((category) => (jsx(SelectItem, { value: category.name, children: category.name }, category.id))) })] })] })) })), !selectedPrompt.isSystem && (jsx(form.Field, { name: "promptVisibility", children: (field) => (jsxs("div", { className: "space-y-2", children: [jsx(Label$1, { className: "flex items-center text-sm font-medium text-[#646464]", children: t('promptsTabEditPromptModal.visibility') }), jsxs(Select$1, { disabled: isDisabled, value: field.state.value, onValueChange: (value) => field.handleChange(value), children: [jsx(SelectTrigger, { className: "py-6", "aria-label": t('promptsTabEditPromptModal.selectVisibility'), children: jsx(SelectValue, { placeholder: t('promptsTabEditPromptModal.selectVisibility') }) }), jsx(SelectContent, { children: (visibilityOptions !== null && visibilityOptions !== void 0 ? visibilityOptions : []).map((option) => (jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] })] })) })), jsx(form.Field, { name: "prompt", children: (field) => {
|
|
270390
271522
|
const hasNoValue = field.state.value === '';
|
|
270391
271523
|
const isDirty = field.state.meta.isDirty;
|
|
270392
|
-
const hasNoValueAndIsDirty = hasNoValue && isDirty;
|
|
270393
|
-
return (jsxs("div", { className: "space-y-2 overflow-hidden", children: [jsx(Label$1, { htmlFor: "prompt-textarea", className: "flex items-center text-sm font-medium text-[#646464]", children: selectedPrompt.label }), jsx(RichTextEditor, { value: field.state.value, onChange: field.handleChange, disabled: isDisabled }), hasNoValueAndIsDirty && (jsx("p", { className: "text-xs text-red-500", children: t('promptsTabEditPromptModal.promptRequired') }))] }));
|
|
271524
|
+
const hasNoValueAndIsDirty = hasNoValue && isDirty && !selectedPrompt.allowEmpty;
|
|
271525
|
+
return (jsxs("div", { className: "space-y-2 overflow-hidden", children: [!selectedPrompt.hideEditorLabel && (jsx(Label$1, { htmlFor: "prompt-textarea", className: "flex items-center text-sm font-medium text-[#646464]", children: selectedPrompt.label })), jsx(RichTextEditor, { value: field.state.value, onChange: field.handleChange, disabled: isDisabled }), hasNoValueAndIsDirty && (jsx("p", { className: "text-xs text-red-500", children: t('promptsTabEditPromptModal.promptRequired') }))] }));
|
|
270394
271526
|
} })] }), jsx(DialogFooter, { children: jsx("div", { className: "flex justify-end gap-2 pt-4", children: jsx(form.Subscribe, { selector: (state) => ({ isFormValue: state.canSubmit }), children: ({ isFormValue }) => (jsx(Button$1, { type: "submit", className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", disabled: isDisabled || !isFormValue, children: isEditing
|
|
270395
271527
|
? t('promptsTabEditPromptModal.saving')
|
|
270396
271528
|
: t('promptsTabEditPromptModal.save') })) }) }) })] }) }) }));
|
|
@@ -270912,6 +272044,27 @@ const AGENT_VOICE_TAB_LABELS = {
|
|
|
270912
272044
|
previewAria: (voiceName, action) => `${action === 'play' ? 'Preview' : 'Stop'} ${voiceName} voice`,
|
|
270913
272045
|
saveButton: 'Save voice',
|
|
270914
272046
|
savingButton: 'Saving…',
|
|
272047
|
+
instructions: {
|
|
272048
|
+
label: 'Voice Instructions',
|
|
272049
|
+
tooltip: 'Describe how the agent should sound when it speaks — tone, pace, emotion, accent, energy. This changes the delivery, not what it says. Example: "Speak slowly in a warm, encouraging tone, like a patient tutor."',
|
|
272050
|
+
placeholder: 'e.g. Speak slowly in a warm, encouraging tone, like a patient tutor.',
|
|
272051
|
+
helpText: "Works with OpenAI voices (sent as speech instructions) and Google voices (sent as a synthesis prompt); other voices ignore it. Leave blank for the provider's default delivery — instructions switch OpenAI to a pricier, instruction-capable speech model.",
|
|
272052
|
+
presetsLabel: 'Examples',
|
|
272053
|
+
presets: {
|
|
272054
|
+
warm: {
|
|
272055
|
+
label: 'Warm and encouraging',
|
|
272056
|
+
text: 'Speak slowly in a warm, encouraging tone, like a patient tutor.',
|
|
272057
|
+
},
|
|
272058
|
+
calm: {
|
|
272059
|
+
label: 'Calm and measured',
|
|
272060
|
+
text: 'Speak in a calm, measured voice with a steady, unhurried pace.',
|
|
272061
|
+
},
|
|
272062
|
+
energetic: {
|
|
272063
|
+
label: 'Energetic and upbeat',
|
|
272064
|
+
text: 'Speak with upbeat energy and enthusiasm, keeping a lively pace.',
|
|
272065
|
+
},
|
|
272066
|
+
},
|
|
272067
|
+
},
|
|
270915
272068
|
},
|
|
270916
272069
|
callConfig: {
|
|
270917
272070
|
title: 'Voice call',
|
|
@@ -271012,6 +272165,27 @@ function buildVoiceTabLabels(t) {
|
|
|
271012
272165
|
: t('voiceTabLabels.mentorVoice.previewAria.stop', { voiceName }),
|
|
271013
272166
|
saveButton: t('voiceTabLabels.mentorVoice.saveButton'),
|
|
271014
272167
|
savingButton: t('voiceTabLabels.mentorVoice.savingButton'),
|
|
272168
|
+
instructions: {
|
|
272169
|
+
label: t('voiceTabLabels.mentorVoice.instructions.label'),
|
|
272170
|
+
tooltip: t('voiceTabLabels.mentorVoice.instructions.tooltip'),
|
|
272171
|
+
placeholder: t('voiceTabLabels.mentorVoice.instructions.placeholder'),
|
|
272172
|
+
helpText: t('voiceTabLabels.mentorVoice.instructions.helpText'),
|
|
272173
|
+
presetsLabel: t('voiceTabLabels.mentorVoice.instructions.presetsLabel'),
|
|
272174
|
+
presets: {
|
|
272175
|
+
warm: {
|
|
272176
|
+
label: t('voiceTabLabels.mentorVoice.instructions.presets.warm.label'),
|
|
272177
|
+
text: t('voiceTabLabels.mentorVoice.instructions.presets.warm.text'),
|
|
272178
|
+
},
|
|
272179
|
+
calm: {
|
|
272180
|
+
label: t('voiceTabLabels.mentorVoice.instructions.presets.calm.label'),
|
|
272181
|
+
text: t('voiceTabLabels.mentorVoice.instructions.presets.calm.text'),
|
|
272182
|
+
},
|
|
272183
|
+
energetic: {
|
|
272184
|
+
label: t('voiceTabLabels.mentorVoice.instructions.presets.energetic.label'),
|
|
272185
|
+
text: t('voiceTabLabels.mentorVoice.instructions.presets.energetic.text'),
|
|
272186
|
+
},
|
|
272187
|
+
},
|
|
272188
|
+
},
|
|
271015
272189
|
},
|
|
271016
272190
|
callConfig: {
|
|
271017
272191
|
title: t('voiceTabLabels.callConfig.title'),
|
|
@@ -271551,10 +272725,29 @@ function FieldWrap({ label, tooltip, children }) {
|
|
|
271551
272725
|
return (jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx(Label$1, { className: "text-sm font-medium text-[#646464]", children: label }), tooltip && (jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { type: "button", "aria-label": t('voiceTabCallConfigSection.moreInfoAbout', { label }), children: jsx(Info$3, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { side: "top", align: "start", sideOffset: 6, collisionPadding: 16, className: "ibl-tooltip-content z-50 max-w-[300px]", children: jsx("p", { className: "text-xs leading-relaxed whitespace-normal", children: tooltip }) })] }) }))] }), children] }));
|
|
271552
272726
|
}
|
|
271553
272727
|
|
|
272728
|
+
/**
|
|
272729
|
+
* Display-only card for a single prompt. Mirrors the visual pattern
|
|
272730
|
+
* used by `AgentPromptsTab` (System Prompt / Proactive Prompt cards):
|
|
272731
|
+
* a header, a 📝-prefixed body, and Edit + Copy action buttons at the
|
|
272732
|
+
* bottom. "Edit" is wired by the parent (typically opens the shared
|
|
272733
|
+
* `EditPromptModal`); the new value is written back via the parent's
|
|
272734
|
+
* `onEdit` handler.
|
|
272735
|
+
*/
|
|
272736
|
+
function PromptCard$1({ label, placeholder, value, disabled, renderContent, onEdit, testId = 'screensharing-prompt-card', headerExtra, }) {
|
|
272737
|
+
const isEmpty = !value || value.trim() === '';
|
|
272738
|
+
return (jsxs("div", { className: "overflow-hidden rounded-lg bg-gray-50", "data-testid": testId, children: [jsx("div", { className: "flex items-center justify-between border-b border-gray-200 p-[1.12rem]", children: jsxs("div", { className: "flex items-center gap-2", children: [jsx("h3", { className: "text-sm font-medium text-gray-900", children: label }), headerExtra] }) }), jsxs("div", { className: "flex items-start gap-2 p-4", children: [jsx("div", { className: "mt-1 flex-shrink-0", "aria-hidden": "true", 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": `${label} content`, children: isEmpty ? (jsx("p", { className: "text-sm text-gray-400 italic", children: placeholder })) : (renderContent(value)) }) })] }), 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: onEdit, "aria-label": `Edit ${label}`, children: [jsx(SquarePen, { className: "mr-2 h-4 w-4" }), "Edit"] }), jsx(CopyButton, { text: value, disabled: disabled })] })] }));
|
|
272739
|
+
}
|
|
272740
|
+
|
|
271554
272741
|
const SUB_TAB_VALUES = {
|
|
271555
272742
|
voice: 'voice',
|
|
271556
272743
|
callConfig: 'call-config',
|
|
271557
272744
|
};
|
|
272745
|
+
/**
|
|
272746
|
+
* Soft cap for the voice-instructions textarea. The backend column is an
|
|
272747
|
+
* unbounded TextField — this is purely a UI guardrail (TTS style prompts
|
|
272748
|
+
* gain nothing from being longer than this).
|
|
272749
|
+
*/
|
|
272750
|
+
const VOICE_INSTRUCTIONS_MAX = 1000;
|
|
271558
272751
|
/**
|
|
271559
272752
|
* Pull a voice **name** out of the mentor settings response, which can
|
|
271560
272753
|
* return a plain string, a numeric id, or a serialized object with a
|
|
@@ -271571,7 +272764,7 @@ function readVoiceName(value) {
|
|
|
271571
272764
|
return null;
|
|
271572
272765
|
}
|
|
271573
272766
|
function AgentVoiceTab({ labels: labelsOverride, defaultSubTab = 'voice', renderPromptContent, tenantKey: tenantKeyProp, mentorId: mentorIdProp, username: usernameProp, enableRBAC: enableRBACProp, }) {
|
|
271574
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
272767
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
271575
272768
|
const ctx = useAgentSettingsOptional();
|
|
271576
272769
|
const tenantKey = (_a = tenantKeyProp !== null && tenantKeyProp !== void 0 ? tenantKeyProp : ctx === null || ctx === void 0 ? void 0 : ctx.tenantKey) !== null && _a !== void 0 ? _a : '';
|
|
271577
272770
|
const mentorId = (_b = mentorIdProp !== null && mentorIdProp !== void 0 ? mentorIdProp : ctx === null || ctx === void 0 ? void 0 : ctx.mentorId) !== null && _b !== void 0 ? _b : '';
|
|
@@ -271605,15 +272798,19 @@ function AgentVoiceTab({ labels: labelsOverride, defaultSubTab = 'voice', render
|
|
|
271605
272798
|
provider: 'google',
|
|
271606
272799
|
name: savedGoogleName,
|
|
271607
272800
|
});
|
|
272801
|
+
const savedInstructions = typeof (mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.voice_instructions) === 'string' ? mentorSettings.voice_instructions : '';
|
|
271608
272802
|
// Picked voices override the resolved server values once the user
|
|
271609
272803
|
// makes a choice. Null means "use what came from the server".
|
|
271610
272804
|
const [provider, setProvider] = React__default.useState(initialProvider);
|
|
271611
272805
|
const [pickedOpenaiVoice, setPickedOpenaiVoice] = React__default.useState(null);
|
|
271612
272806
|
const [pickedGoogleVoice, setPickedGoogleVoice] = React__default.useState(null);
|
|
272807
|
+
const [instructions, setInstructions] = React__default.useState(savedInstructions);
|
|
272808
|
+
const [selectedPrompt, setSelectedPrompt] = React__default.useState(null);
|
|
271613
272809
|
React__default.useEffect(() => {
|
|
271614
272810
|
setProvider(initialProvider);
|
|
271615
272811
|
setPickedOpenaiVoice(null);
|
|
271616
272812
|
setPickedGoogleVoice(null);
|
|
272813
|
+
setInstructions(savedInstructions);
|
|
271617
272814
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
271618
272815
|
}, [mentorId, rawMentorSettings]);
|
|
271619
272816
|
const effectiveOpenaiVoice = (_h = pickedOpenaiVoice !== null && pickedOpenaiVoice !== void 0 ? pickedOpenaiVoice : resolvedOpenaiVoice) !== null && _h !== void 0 ? _h : null;
|
|
@@ -271651,7 +272848,14 @@ function AgentVoiceTab({ labels: labelsOverride, defaultSubTab = 'voice', render
|
|
|
271651
272848
|
}
|
|
271652
272849
|
};
|
|
271653
272850
|
const isDisabled = isMentorSettingsLoading || isSavingMentor;
|
|
271654
|
-
const
|
|
272851
|
+
const instructionsDirty = instructions !== savedInstructions;
|
|
272852
|
+
// Soft cap only — the modal editor doesn't enforce a max length, so we
|
|
272853
|
+
// block Save instead of truncating what the user wrote.
|
|
272854
|
+
const instructionsOverCap = instructions.length > VOICE_INSTRUCTIONS_MAX;
|
|
272855
|
+
const isDirty = provider !== initialProvider ||
|
|
272856
|
+
pickedOpenaiVoice != null ||
|
|
272857
|
+
pickedGoogleVoice != null ||
|
|
272858
|
+
instructionsDirty;
|
|
271655
272859
|
/**
|
|
271656
272860
|
* Provider chips. We reuse the OpenAI / Google logos already shipped in
|
|
271657
272861
|
* the host's static-root (see `getLLMProviderDetails` for the canonical
|
|
@@ -271690,6 +272894,12 @@ function AgentVoiceTab({ labels: labelsOverride, defaultSubTab = 'voice', render
|
|
|
271690
272894
|
if (provider === 'google' && pickedGoogleVoice) {
|
|
271691
272895
|
formData.google_voice = pickedGoogleVoice.id;
|
|
271692
272896
|
}
|
|
272897
|
+
// Same "absent = keep" contract: only send voice_instructions when
|
|
272898
|
+
// the user actually edited it. Clearing sends "" (never null) —
|
|
272899
|
+
// that's what resets the stored value server-side.
|
|
272900
|
+
if (instructionsDirty) {
|
|
272901
|
+
formData.voice_instructions = instructions;
|
|
272902
|
+
}
|
|
271693
272903
|
await editMentor({
|
|
271694
272904
|
mentor: mentorId,
|
|
271695
272905
|
org: tenantKey,
|
|
@@ -271715,43 +272925,60 @@ function AgentVoiceTab({ labels: labelsOverride, defaultSubTab = 'voice', render
|
|
|
271715
272925
|
else if (provider === 'google')
|
|
271716
272926
|
setPickedGoogleVoice(voice);
|
|
271717
272927
|
};
|
|
271718
|
-
|
|
271719
|
-
|
|
271720
|
-
|
|
271721
|
-
|
|
271722
|
-
|
|
271723
|
-
|
|
271724
|
-
|
|
271725
|
-
|
|
271726
|
-
|
|
271727
|
-
|
|
271728
|
-
|
|
271729
|
-
|
|
271730
|
-
|
|
271731
|
-
|
|
271732
|
-
|
|
271733
|
-
|
|
271734
|
-
error
|
|
271735
|
-
|
|
272928
|
+
// Mirrors `AgentScreenShareTab`: hosts can render prompt content as
|
|
272929
|
+
// Markdown via `renderPromptContent`; plain text otherwise.
|
|
272930
|
+
const renderInstructionsContent = (text) => {
|
|
272931
|
+
if (renderPromptContent)
|
|
272932
|
+
return renderPromptContent(text);
|
|
272933
|
+
return jsx("p", { className: "text-sm whitespace-pre-wrap text-gray-700", children: text });
|
|
272934
|
+
};
|
|
272935
|
+
return (jsxs(Fragment$1, { children: [jsx("div", { className: "flex h-[73px] flex-shrink-0 items-center border-b border-gray-200 bg-white p-4 lg:block", children: jsxs("div", { children: [jsx("h3", { className: "mb-1 text-base font-medium text-gray-900", children: labels.header.title }), jsx("p", { className: "text-xs text-gray-600", children: labels.header.description })] }) }), jsx("div", { className: "flex-1 space-y-4 p-3 lg:p-4", style: { overflowY: 'auto', overflowX: 'hidden' }, "data-testid": "voice-tab-body", children: isMentorSettingsLoading ? (jsx("div", { className: "flex items-center justify-center py-12", "data-testid": "voice-tab-loading", children: jsx(Spinner, {}) })) : (jsxs(CapabilityGate, { title: labels.capability.title, description: labels.capability.description, offHint: labels.capability.offHint, enabled: voiceCallEnabled, onToggle: handleToggleVoiceCall, disabled: isDisabled || isTogglingVoiceCall, ariaLabel: labels.capability.title, toggleTestId: "voice-capability-toggle", children: [jsxs(Tabs, { defaultValue: SUB_TAB_VALUES[defaultSubTab], className: "w-full", children: [jsxs(TabsList, { "aria-label": labels.header.title, "data-testid": "voice-sub-tabs", children: [jsx(TabsTrigger, { value: SUB_TAB_VALUES.voice, "data-testid": "voice-sub-tab-voice", children: labels.subTabs.voice }), jsx(TabsTrigger, { value: SUB_TAB_VALUES.callConfig, "data-testid": "voice-sub-tab-call-config", children: labels.subTabs.callConfig })] }), jsxs(TabsContent, { value: SUB_TAB_VALUES.voice, className: "space-y-4", children: [jsx("p", { className: "text-xs text-gray-600", children: labels.mentorVoice.description }), jsx(WithFormPermissions, { name: "voice_provider",
|
|
272936
|
+
// @ts-expect-error permissions.field is opaque
|
|
272937
|
+
permissions: (_l = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.permissions) === null || _l === void 0 ? void 0 : _l.field, enableRBAC: enableRBAC, children: ({ disabled }) => (jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx(Label$1, { className: "text-sm font-medium text-[#646464]", children: labels.mentorVoice.providerLabel }), jsx(FieldTooltip, { text: labels.mentorVoice.providerTooltip })] }), jsx("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-3", role: "radiogroup", "aria-label": labels.mentorVoice.providerLabel, children: providerOptions.map((option) => {
|
|
272938
|
+
const isSelected = provider === option.value;
|
|
272939
|
+
const isDisabledOption = isDisabled || disabled;
|
|
272940
|
+
return (jsxs("button", { type: "button", role: "radio", "aria-checked": isSelected, "aria-label": option.label, disabled: isDisabledOption, "data-testid": `voice-provider-${option.value}`, "data-voice-provider": option.value, onClick: () => setProvider(option.value), className: cn('flex flex-col items-start gap-2 rounded-lg border-2 p-3 text-left transition-all hover:shadow-sm', isSelected
|
|
272941
|
+
? 'border-blue-500 bg-blue-50/40'
|
|
272942
|
+
: 'border-gray-200 bg-white hover:border-gray-300', isDisabledOption && 'cursor-not-allowed opacity-60'), children: [jsxs("div", { className: "flex items-center gap-2", children: [jsx("span", { className: "flex h-6 w-6 flex-shrink-0 items-center justify-center", children: option.logo.type === 'image' ? (jsx(Image$4, { src: option.logo.src, alt: option.logo.alt, width: 24, height: 24, className: "h-6 w-6 object-contain" })) : (jsx(option.logo.Icon, { className: "h-5 w-5 text-blue-600", "aria-hidden": "true" })) }), jsx("span", { className: "text-sm font-medium text-gray-900", children: option.label })] }), jsx("p", { className: "text-xs text-gray-500", children: option.description })] }, option.value));
|
|
272943
|
+
}) })] })) }), (provider === 'openai' || provider === 'google') && (jsx(WithFormPermissions, { name: provider === 'openai' ? 'openai_voice' : 'google_voice',
|
|
272944
|
+
// @ts-expect-error permissions.field is opaque
|
|
272945
|
+
permissions: (_m = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.permissions) === null || _m === void 0 ? void 0 : _m.field, enableRBAC: enableRBAC, children: ({ disabled }) => (jsxs("div", { className: "space-y-2", children: [jsx(Label$1, { className: "text-sm font-medium text-[#646464]", children: t('tabsVoiceTab.voiceLabel') }), jsx(VoicePickerTrigger, { org: tenantKey, userId: username, provider: provider, selectedVoice: selectedVoice, onSelect: onSelectVoice, disabled: isDisabled || disabled, labels: labels.mentorVoice, modalTitle: t('tabsVoiceTab.selectVoiceModalTitle', {
|
|
272946
|
+
voiceType: labels.mentorVoice.voicePickerLabel[provider],
|
|
272947
|
+
}), modalDescription: t('tabsVoiceTab.selectVoiceModalDescription'), testId: "mentor-voice-trigger" })] })) })), (provider === 'openai' || provider === 'google') && (jsx(WithFormPermissions, { name: "voice_instructions",
|
|
272948
|
+
// @ts-expect-error permissions.field is opaque
|
|
272949
|
+
permissions: (_o = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.permissions) === null || _o === void 0 ? void 0 : _o.field, enableRBAC: enableRBAC, children: ({ disabled }) => {
|
|
272950
|
+
const isFieldDisabled = isDisabled || disabled;
|
|
272951
|
+
const presetKeys = ['warm', 'calm', 'energetic'];
|
|
272952
|
+
return (jsxs("div", { className: "space-y-2", children: [jsx(PromptCard$1, { label: labels.mentorVoice.instructions.label, placeholder: labels.mentorVoice.instructions.placeholder, value: instructions, disabled: isFieldDisabled, renderContent: renderInstructionsContent, testId: "voice-instructions-card", headerExtra: jsx(FieldTooltip, { text: labels.mentorVoice.instructions.tooltip }), onEdit: () => setSelectedPrompt({
|
|
272953
|
+
label: labels.mentorVoice.instructions.label,
|
|
272954
|
+
isSystem: true,
|
|
272955
|
+
name: 'voice_instructions',
|
|
272956
|
+
prompt: instructions,
|
|
272957
|
+
allowEmpty: true,
|
|
272958
|
+
hideEditorLabel: true,
|
|
272959
|
+
}) }), jsxs("div", { className: "flex items-start justify-between gap-3", children: [jsx("p", { id: "voice-instructions-help", className: "text-xs text-gray-500", children: labels.mentorVoice.instructions.helpText }), jsxs("span", { id: "voice-instructions-counter", "aria-live": "polite", "data-testid": "voice-instructions-counter", className: cn('flex-shrink-0 text-xs text-gray-400', instructionsOverCap && 'text-red-500'), children: [instructions.length, "/", VOICE_INSTRUCTIONS_MAX] })] }), jsxs("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": labels.mentorVoice.instructions.presetsLabel, children: [jsxs("span", { className: "text-xs text-gray-500", children: [labels.mentorVoice.instructions.presetsLabel, ":"] }), presetKeys.map((key) => (jsx("button", { type: "button", disabled: isFieldDisabled, "data-testid": `voice-instructions-preset-${key}`, onClick: () => setInstructions(labels.mentorVoice.instructions.presets[key].text), className: cn('inline-flex items-center rounded-full border border-gray-300 bg-white px-3 py-1 text-xs text-gray-700 transition-colors hover:bg-gray-50', isFieldDisabled && 'cursor-not-allowed opacity-50'), children: labels.mentorVoice.instructions.presets[key].label }, key)))] })] }));
|
|
272960
|
+
} })), jsx("div", { className: "flex items-center justify-end border-t border-gray-100 pt-3", children: jsx(Button$1, { type: "button", onClick: handleSaveVoice, disabled: isDisabled || !isDirty || instructionsOverCap, "data-testid": "voice-save-button", className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", children: isSavingMentor
|
|
272961
|
+
? labels.mentorVoice.savingButton
|
|
272962
|
+
: labels.mentorVoice.saveButton }) })] }), jsxs(TabsContent, { value: SUB_TAB_VALUES.callConfig, className: "space-y-4", children: [jsx("p", { className: "text-xs text-gray-600", children: labels.callConfig.description }), mentorId && username && tenantKey && (jsx(CallConfigSection, { org: tenantKey, userId: username, mentorId: mentorId, isDisabled: isDisabled, labels: labels.callConfig, voicePickerLabels: labels.mentorVoice, initialConfig: (_p = mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.call_configuration) !== null && _p !== void 0 ? _p : null, renderPromptContent: renderPromptContent, toastLabels: {
|
|
272963
|
+
saved: labels.toasts.callConfigSaved,
|
|
272964
|
+
error: labels.toasts.callConfigError,
|
|
272965
|
+
} }))] })] }), selectedPrompt && (
|
|
272966
|
+
// `EditPromptModal` calls strict `useAgentSettings()`. The host
|
|
272967
|
+
// may not have wrapped this tab in `<AgentSettingsProvider>`
|
|
272968
|
+
// (older integrations pass identity via props), so re-provide
|
|
272969
|
+
// whatever we resolved — same pattern as `AgentScreenShareTab`.
|
|
272970
|
+
jsx(AgentSettingsProvider, { tenantKey: tenantKey, mentorId: mentorId, username: username, enableRBAC: enableRBAC, rbacPermissions: ctx === null || ctx === void 0 ? void 0 : ctx.rbacPermissions, executeGatedAction: ctx === null || ctx === void 0 ? void 0 : ctx.executeGatedAction, visibilityOptions: ctx === null || ctx === void 0 ? void 0 : ctx.visibilityOptions, children: jsx(EditPromptModal$1, { isOpen: true, onClose: () => setSelectedPrompt(null), selectedPrompt: selectedPrompt, isEditing: isSavingMentor, handleSave: (prompt, values) => {
|
|
272971
|
+
if (prompt.name === 'voice_instructions') {
|
|
272972
|
+
setInstructions(values.prompt);
|
|
272973
|
+
}
|
|
272974
|
+
setSelectedPrompt(null);
|
|
272975
|
+
} }) }))] })) })] }));
|
|
271736
272976
|
}
|
|
271737
272977
|
function FieldTooltip({ text }) {
|
|
271738
272978
|
const t = useT();
|
|
271739
272979
|
return (jsx(TooltipProvider, { delayDuration: 200, children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { type: "button", "aria-label": t('tabsVoiceTab.fieldTooltipMoreInfo'), children: jsx(Info$3, { className: "h-4 w-4 text-gray-400" }) }), jsx(TooltipContent, { side: "top", align: "start", sideOffset: 6, collisionPadding: 16, className: "ibl-tooltip-content z-50 max-w-[300px]", children: jsx("p", { className: "text-xs leading-relaxed whitespace-normal", children: text }) })] }) }));
|
|
271740
272980
|
}
|
|
271741
272981
|
|
|
271742
|
-
/**
|
|
271743
|
-
* Display-only card for a single prompt. Mirrors the visual pattern
|
|
271744
|
-
* used by `AgentPromptsTab` (System Prompt / Proactive Prompt cards):
|
|
271745
|
-
* a header, a 📝-prefixed body, and Edit + Copy action buttons at the
|
|
271746
|
-
* bottom. "Edit" is wired by the parent (typically opens the shared
|
|
271747
|
-
* `EditPromptModal`); the new value is written back via the parent's
|
|
271748
|
-
* `onEdit` handler.
|
|
271749
|
-
*/
|
|
271750
|
-
function PromptCard$1({ label, placeholder, value, disabled, renderContent, onEdit, }) {
|
|
271751
|
-
const isEmpty = !value || value.trim() === '';
|
|
271752
|
-
return (jsxs("div", { className: "overflow-hidden rounded-lg bg-gray-50", "data-testid": "screensharing-prompt-card", children: [jsx("div", { className: "flex items-center justify-between border-b border-gray-200 p-[1.12rem]", children: jsx("div", { className: "flex items-center gap-2", children: jsx("h3", { className: "text-sm font-medium text-gray-900", children: label }) }) }), jsxs("div", { className: "flex items-start gap-2 p-4", children: [jsx("div", { className: "mt-1 flex-shrink-0", "aria-hidden": "true", 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": `${label} content`, children: isEmpty ? (jsx("p", { className: "text-sm text-gray-400 italic", children: placeholder })) : (renderContent(value)) }) })] }), 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: onEdit, "aria-label": `Edit ${label}`, children: [jsx(SquarePen, { className: "mr-2 h-4 w-4" }), "Edit"] }), jsx(CopyButton, { text: value, disabled: disabled })] })] }));
|
|
271753
|
-
}
|
|
271754
|
-
|
|
271755
272982
|
const AGENT_SCREENSHARE_TAB_LABELS = {
|
|
271756
272983
|
header: {
|
|
271757
272984
|
// Title is deliberately just "Screen" — the description below carries the
|
|
@@ -273583,7 +274810,7 @@ function resolveHumanSupportTabLabels(override, t) {
|
|
|
273583
274810
|
return deepMerge(base, override);
|
|
273584
274811
|
}
|
|
273585
274812
|
|
|
273586
|
-
const STATUS_BADGE_CLASSES = {
|
|
274813
|
+
const STATUS_BADGE_CLASSES$1 = {
|
|
273587
274814
|
open: 'border-green-200 bg-green-100 text-green-800 hover:bg-green-100',
|
|
273588
274815
|
in_progress: 'border-amber-200 bg-amber-100 text-amber-800 hover:bg-amber-100',
|
|
273589
274816
|
closed: 'border-gray-200 bg-gray-100 text-gray-700 hover:bg-gray-100',
|
|
@@ -273827,7 +275054,7 @@ function AgentHumanSupportTab({ PaginationComponent = IblPagination, labels: lab
|
|
|
273827
275054
|
};
|
|
273828
275055
|
const renderStatusBadge = (status) => {
|
|
273829
275056
|
const resolvedStatus = status !== null && status !== void 0 ? status : 'open';
|
|
273830
|
-
return (jsx(Badge, { variant: "outline", className: cn('whitespace-nowrap', STATUS_BADGE_CLASSES[resolvedStatus]), children: statusLabels[resolvedStatus] }));
|
|
275057
|
+
return (jsx(Badge, { variant: "outline", className: cn('whitespace-nowrap', STATUS_BADGE_CLASSES$1[resolvedStatus]), children: statusLabels[resolvedStatus] }));
|
|
273831
275058
|
};
|
|
273832
275059
|
const renderMessage = (message, ticket) => {
|
|
273833
275060
|
var _a;
|
|
@@ -273971,6 +275198,18 @@ const AGENT_LTI_TAB_LABELS = {
|
|
|
273971
275198
|
createButton: 'Create LTI Link',
|
|
273972
275199
|
empty: 'No LTI link yet for this agent.',
|
|
273973
275200
|
targetUriColumn: 'TARGET LINK URI',
|
|
275201
|
+
statusColumn: 'STATUS',
|
|
275202
|
+
status: {
|
|
275203
|
+
pending: 'Pending',
|
|
275204
|
+
building: 'Building',
|
|
275205
|
+
ready: 'Ready',
|
|
275206
|
+
failed: 'Failed',
|
|
275207
|
+
},
|
|
275208
|
+
failedHint: 'Something went wrong while creating this link. Retry deletes it and creates it again.',
|
|
275209
|
+
refresh: 'Refresh',
|
|
275210
|
+
retry: 'Retry',
|
|
275211
|
+
retrying: 'Retrying…',
|
|
275212
|
+
retryAria: (name) => `Retry ${name}`,
|
|
273974
275213
|
editAria: (name) => `Edit ${name}`,
|
|
273975
275214
|
copyTargetUri: 'Copy target link URI',
|
|
273976
275215
|
modal: {
|
|
@@ -274078,6 +275317,7 @@ const AGENT_LTI_TAB_LABELS = {
|
|
|
274078
275317
|
},
|
|
274079
275318
|
toasts: {
|
|
274080
275319
|
linkCreated: 'LTI link created successfully',
|
|
275320
|
+
linkCreationStarted: 'LTI link creation started — this can take a few minutes',
|
|
274081
275321
|
linkUpdated: 'LTI link updated successfully',
|
|
274082
275322
|
linkDeleted: 'LTI link deleted successfully',
|
|
274083
275323
|
linkError: 'Something went wrong with the LTI link',
|
|
@@ -274139,6 +275379,18 @@ function buildLtiTabLabels(t) {
|
|
|
274139
275379
|
createButton: t('ltiTabLabels.links.createButton'),
|
|
274140
275380
|
empty: t('ltiTabLabels.links.empty'),
|
|
274141
275381
|
targetUriColumn: t('ltiTabLabels.links.targetUriColumn'),
|
|
275382
|
+
statusColumn: t('ltiTabLabels.links.statusColumn'),
|
|
275383
|
+
status: {
|
|
275384
|
+
pending: t('ltiTabLabels.links.status.pending'),
|
|
275385
|
+
building: t('ltiTabLabels.links.status.building'),
|
|
275386
|
+
ready: t('ltiTabLabels.links.status.ready'),
|
|
275387
|
+
failed: t('ltiTabLabels.links.status.failed'),
|
|
275388
|
+
},
|
|
275389
|
+
failedHint: t('ltiTabLabels.links.failedHint'),
|
|
275390
|
+
refresh: t('ltiTabLabels.links.refresh'),
|
|
275391
|
+
retry: t('ltiTabLabels.links.retry'),
|
|
275392
|
+
retrying: t('ltiTabLabels.links.retrying'),
|
|
275393
|
+
retryAria: (name) => t('ltiTabLabels.links.retryAria', { name }),
|
|
274142
275394
|
editAria: (name) => t('ltiTabLabels.links.editAria', { name }),
|
|
274143
275395
|
copyTargetUri: t('ltiTabLabels.links.copyTargetUri'),
|
|
274144
275396
|
modal: {
|
|
@@ -274246,6 +275498,7 @@ function buildLtiTabLabels(t) {
|
|
|
274246
275498
|
},
|
|
274247
275499
|
toasts: {
|
|
274248
275500
|
linkCreated: t('ltiTabLabels.toasts.linkCreated'),
|
|
275501
|
+
linkCreationStarted: t('ltiTabLabels.toasts.linkCreationStarted'),
|
|
274249
275502
|
linkUpdated: t('ltiTabLabels.toasts.linkUpdated'),
|
|
274250
275503
|
linkDeleted: t('ltiTabLabels.toasts.linkDeleted'),
|
|
274251
275504
|
linkError: t('ltiTabLabels.toasts.linkError'),
|
|
@@ -274383,8 +275636,11 @@ function AgentLinkModal({ isOpen, onClose, platformKey, mentorId, mentorUniqueId
|
|
|
274383
275636
|
toast.success(labels.toasts.linkUpdated);
|
|
274384
275637
|
}
|
|
274385
275638
|
else {
|
|
275639
|
+
// The data layer sends `async_create: true`, so the backend answers
|
|
275640
|
+
// 202 and builds the link in the background — the Links table polls
|
|
275641
|
+
// the detail endpoint and reports when it's ready (or failed).
|
|
274386
275642
|
await createLtiMentor({ requestBody }).unwrap();
|
|
274387
|
-
toast.success(labels.toasts.
|
|
275643
|
+
toast.success(labels.toasts.linkCreationStarted);
|
|
274388
275644
|
// "Allow LTI" must be on for the link to work. Enable it automatically
|
|
274389
275645
|
// on create so the user doesn't have to toggle it in Settings as a
|
|
274390
275646
|
// separate step. Best-effort: a failure here doesn't fail the link.
|
|
@@ -274442,26 +275698,78 @@ function readTargetLinkUri(link) {
|
|
|
274442
275698
|
const config = link.mentor_config;
|
|
274443
275699
|
return (_a = config === null || config === void 0 ? void 0 : config.target_link_uri) !== null && _a !== void 0 ? _a : null;
|
|
274444
275700
|
}
|
|
275701
|
+
function isInProgress(status) {
|
|
275702
|
+
return status === 'pending' || status === 'building';
|
|
275703
|
+
}
|
|
275704
|
+
const STATUS_BADGE_CLASSES = {
|
|
275705
|
+
pending: 'bg-amber-50 text-amber-700 border-amber-200',
|
|
275706
|
+
building: 'bg-amber-50 text-amber-700 border-amber-200',
|
|
275707
|
+
ready: 'bg-green-50 text-green-700 border-green-200',
|
|
275708
|
+
failed: 'bg-red-50 text-red-700 border-red-200',
|
|
275709
|
+
};
|
|
275710
|
+
function StatusBadge$2({ status, labels, }) {
|
|
275711
|
+
return (jsxs("span", { "data-testid": "lti-link-status", "data-status": status, title: status === 'failed' ? labels.links.failedHint : undefined, className: `inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium ${STATUS_BADGE_CLASSES[status]}`, children: [isInProgress(status) && jsx(LoaderCircle, { className: "h-3 w-3 animate-spin", "aria-hidden": "true" }), labels.links.status[status]] }));
|
|
275712
|
+
}
|
|
274445
275713
|
function AgentLinksSection({ identity, labels, }) {
|
|
274446
275714
|
const { platformKey, mentorId, mentorUniqueId, username, isLtiAccessible, isReady, isSettingsLoading } = identity;
|
|
274447
275715
|
const [showCreate, setShowCreate] = React__default.useState(false);
|
|
274448
275716
|
const [editingLink, setEditingLink] = React__default.useState(null);
|
|
274449
275717
|
const [page, setPage] = React__default.useState(1);
|
|
274450
|
-
const
|
|
275718
|
+
const [retryingId, setRetryingId] = React__default.useState(null);
|
|
275719
|
+
const { data: allLinks, isLoading, isFetching, refetch, } = useGetLtiMentorsQuery({ platformKey, mentorId: mentorUniqueId, page, pageSize: LTI_PAGE_SIZE }, { skip: !isReady });
|
|
275720
|
+
const [createLtiMentor] = useCreateLtiMentorMutation();
|
|
275721
|
+
const [deleteLtiMentor] = useDeleteLtiMentorMutation();
|
|
274451
275722
|
// The backend scopes the list to this agent via `mentor_id`; we still narrow
|
|
274452
|
-
// client-side by the unique_id as a defensive safety net.
|
|
275723
|
+
// client-side by the unique_id as a defensive safety net. An in-flight async
|
|
275724
|
+
// build may not have its `mentor_config.mentor` populated yet, so only drop
|
|
275725
|
+
// rows that carry a mentor and it's a different one.
|
|
274453
275726
|
const links = React__default.useMemo(() => mentorUniqueId
|
|
274454
|
-
? toArray(allLinks).filter((link) => { var _a; return ((_a = link.mentor_config) === null || _a === void 0 ? void 0 : _a.mentor) === mentorUniqueId; })
|
|
275727
|
+
? toArray(allLinks).filter((link) => { var _a; return !((_a = link.mentor_config) === null || _a === void 0 ? void 0 : _a.mentor) || link.mentor_config.mentor === mentorUniqueId; })
|
|
274455
275728
|
: [], [allLinks, mentorUniqueId]);
|
|
275729
|
+
// Async create: the celery build finishes out of band, so offer a manual
|
|
275730
|
+
// Refresh while any link is still pending/building.
|
|
275731
|
+
const hasLinkInProgress = links.some((link) => isInProgress(link.status));
|
|
275732
|
+
// Retry a failed build: delete the failed entity, then re-post the original
|
|
275733
|
+
// payload (name + mentor + platform_key) as a fresh async create.
|
|
275734
|
+
const handleRetry = async (link) => {
|
|
275735
|
+
var _a, _b;
|
|
275736
|
+
setRetryingId(link.id);
|
|
275737
|
+
try {
|
|
275738
|
+
await deleteLtiMentor({ id: String(link.id), platformKey }).unwrap();
|
|
275739
|
+
await createLtiMentor({
|
|
275740
|
+
requestBody: {
|
|
275741
|
+
name: link.name,
|
|
275742
|
+
mentor_config: { mentor: (_b = (_a = link.mentor_config) === null || _a === void 0 ? void 0 : _a.mentor) !== null && _b !== void 0 ? _b : mentorUniqueId },
|
|
275743
|
+
platform_key: platformKey,
|
|
275744
|
+
},
|
|
275745
|
+
}).unwrap();
|
|
275746
|
+
toast.success(labels.toasts.linkCreationStarted);
|
|
275747
|
+
}
|
|
275748
|
+
catch (error) {
|
|
275749
|
+
console.error(JSON.stringify({ tenant: platformKey, error }));
|
|
275750
|
+
toast.error(getApiErrorMessage(error, labels.toasts.linkError));
|
|
275751
|
+
}
|
|
275752
|
+
finally {
|
|
275753
|
+
setRetryingId(null);
|
|
275754
|
+
}
|
|
275755
|
+
};
|
|
274456
275756
|
const totalPages = getTotalPages(allLinks);
|
|
274457
275757
|
const busy = !isReady || isSettingsLoading || isLoading;
|
|
274458
275758
|
const canCreate = !busy && links.length === 0 && Boolean(mentorUniqueId);
|
|
274459
|
-
return (jsxs("div", { className: "space-y-4", "data-testid": "lti-links-section", children: [jsxs("div", { className: "flex flex-col items-start justify-between gap-3 sm:flex-row sm:items-center", children: [jsx("p", { className: "text-xs text-gray-600", children: labels.links.description }), canCreate && (jsxs(Button$1, { onClick: () => setShowCreate(true), size: "sm", "data-testid": "lti-link-create-button", className: "cursor-pointer whitespace-nowrap bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", children: [jsx(Plus, { className: "h-4 w-4" }), labels.links.createButton] }))] }), busy ? (jsx("div", { className: "flex w-full items-center justify-center py-10", children: jsx(Spinner, {}) })) : links.length === 0 ? (jsxs("div", { className: "flex flex-col items-center justify-center gap-3 rounded-md border border-dashed border-gray-200 py-12 text-center", "data-testid": "lti-links-empty", children: [jsx(Link2, { className: "h-8 w-8 text-gray-300", "aria-hidden": "true" }), jsx("p", { className: "text-sm text-[#646464]", children: labels.links.empty })] })) : (jsxs("div", { className: "overflow-hidden rounded-md border", children: [jsx("div", { className: "overflow-x-auto", children: jsxs(Table$1, { className: "min-w-full", children: [jsx(TableHeader$1, { children: jsxs(TableRow$1, { className: "bg-muted/50 border-b", children: [jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: labels.common.nameColumn }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: labels.links.targetUriColumn }), jsx(TableHead, { className: "p-3 text-right text-sm whitespace-nowrap text-[#646464]", children: labels.common.actionsColumn })] }) }), jsx(TableBody, { children: links.map((link) => {
|
|
275759
|
+
return (jsxs("div", { className: "space-y-4", "data-testid": "lti-links-section", children: [jsxs("div", { className: "flex flex-col items-start justify-between gap-3 sm:flex-row sm:items-center", children: [jsx("p", { className: "text-xs text-gray-600", children: labels.links.description }), hasLinkInProgress && (jsxs(Button$1, { type: "button", variant: "outline", size: "sm", "data-testid": "lti-links-refresh-button", disabled: isFetching, onClick: () => refetch(), className: "cursor-pointer whitespace-nowrap", children: [jsx(RefreshCw, { className: `h-4 w-4 ${isFetching ? 'animate-spin' : ''}` }), labels.links.refresh] })), canCreate && (jsxs(Button$1, { onClick: () => setShowCreate(true), size: "sm", "data-testid": "lti-link-create-button", className: "cursor-pointer whitespace-nowrap bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", children: [jsx(Plus, { className: "h-4 w-4" }), labels.links.createButton] }))] }), busy ? (jsx("div", { className: "flex w-full items-center justify-center py-10", children: jsx(Spinner, {}) })) : links.length === 0 ? (jsxs("div", { className: "flex flex-col items-center justify-center gap-3 rounded-md border border-dashed border-gray-200 py-12 text-center", "data-testid": "lti-links-empty", children: [jsx(Link2, { className: "h-8 w-8 text-gray-300", "aria-hidden": "true" }), jsx("p", { className: "text-sm text-[#646464]", children: labels.links.empty })] })) : (jsxs("div", { className: "overflow-hidden rounded-md border", children: [jsx("div", { className: "overflow-x-auto", children: jsxs(Table$1, { className: "min-w-full", children: [jsx(TableHeader$1, { children: jsxs(TableRow$1, { className: "bg-muted/50 border-b", children: [jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: labels.common.nameColumn }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: labels.links.targetUriColumn }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: labels.links.statusColumn }), jsx(TableHead, { className: "p-3 text-right text-sm whitespace-nowrap text-[#646464]", children: labels.common.actionsColumn })] }) }), jsx(TableBody, { children: links.map((link) => {
|
|
274460
275760
|
const targetLinkUri = readTargetLinkUri(link);
|
|
274461
|
-
|
|
275761
|
+
const inProgress = isInProgress(link.status);
|
|
275762
|
+
const failed = link.status === 'failed';
|
|
275763
|
+
// A finished (or legacy pre-async) link is the only editable state.
|
|
275764
|
+
const editable = !inProgress && !failed;
|
|
275765
|
+
const isRetrying = retryingId === link.id;
|
|
275766
|
+
return (jsxs(TableRow$1, { "data-testid": "lti-link-row", className: `border-b last:border-0 hover:bg-muted/40 ${editable ? 'cursor-pointer' : ''}`, onClick: editable ? () => setEditingLink(link) : undefined, children: [jsx(TableCell$1, { className: "p-3 text-sm font-medium text-gray-900", children: link.name }), jsx(TableCell$1, { className: "p-3 text-sm text-[#646464]", children: targetLinkUri ? (jsxs("div", { className: "flex items-center gap-2", onClick: (event) => event.stopPropagation(), children: [jsx("span", { className: "max-w-[260px] truncate font-mono text-xs", title: targetLinkUri, children: targetLinkUri }), jsx(CopyIconButton, { text: targetLinkUri, label: labels.links.copyTargetUri, copiedLabel: labels.common.copied })] })) : ('—') }), jsx(TableCell$1, { className: "p-3 text-sm", children: link.status ? jsx(StatusBadge$2, { status: link.status, labels: labels }) : '—' }), jsx(TableCell$1, { className: "p-3 text-right", children: failed ? (jsxs(Button$1, { type: "button", variant: "outline", size: "sm", "data-testid": "lti-link-retry-button", "aria-label": labels.links.retryAria(link.name), disabled: isRetrying, onClick: (event) => {
|
|
275767
|
+
event.stopPropagation();
|
|
275768
|
+
handleRetry(link);
|
|
275769
|
+
}, children: [jsx(RotateCcw, { className: "h-4 w-4" }), isRetrying ? labels.links.retrying : labels.links.retry] })) : editable ? (jsx(Button$1, { type: "button", variant: "outline", size: "icon", "aria-label": labels.links.editAria(link.name), onClick: (event) => {
|
|
274462
275770
|
event.stopPropagation();
|
|
274463
275771
|
setEditingLink(link);
|
|
274464
|
-
}, children: jsx(Pencil, { className: "h-4 w-4" }) }) })] }, link.id));
|
|
275772
|
+
}, children: jsx(Pencil, { className: "h-4 w-4" }) })) : null })] }, link.id));
|
|
274465
275773
|
}) })] }) }), isFetching && (jsx("p", { className: "px-3 py-2 text-xs text-gray-400", children: labels.common.refreshing }))] })), jsx(IblPagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage, disabled: busy }), showCreate && (jsx(AgentLinkModal, { isOpen: showCreate, onClose: () => setShowCreate(false), platformKey: platformKey, mentorId: mentorId, mentorUniqueId: mentorUniqueId, username: username, isLtiAccessible: isLtiAccessible, labels: labels })), editingLink && (jsx(AgentLinkModal, { isOpen: Boolean(editingLink), onClose: () => setEditingLink(null), platformKey: platformKey, mentorId: mentorId, mentorUniqueId: mentorUniqueId, username: username, isLtiAccessible: isLtiAccessible, link: editingLink, labels: labels }))] }));
|
|
274466
275774
|
}
|
|
274467
275775
|
|
|
@@ -284921,18 +286229,6 @@ var addMemoryModal = /*#__PURE__*/Object.freeze({
|
|
|
284921
286229
|
AddMemoryModal: AddMemoryModal
|
|
284922
286230
|
});
|
|
284923
286231
|
|
|
284924
|
-
function DeleteMemoryModal({ open, onOpenChange, onConfirm, onCancel, isDeleting, }) {
|
|
284925
|
-
const t = useT();
|
|
284926
|
-
return (jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: jsxs(DialogContent, { className: "mx-4 max-w-md sm:mx-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { children: t('memoryTabDeleteMemoryModal.title') }) }), jsx("p", { className: "text-muted-foreground text-sm", children: t('memoryTabDeleteMemoryModal.confirmMessage') }), jsxs("div", { className: "mt-4 flex justify-end gap-2", children: [jsx(Button$1, { variant: "outline", onClick: onCancel, children: t('memoryTabDeleteMemoryModal.cancel') }), jsx(Button$1, { className: "ibl-button-primary", onClick: onConfirm, disabled: isDeleting, children: isDeleting
|
|
284927
|
-
? t('memoryTabDeleteMemoryModal.deleting')
|
|
284928
|
-
: t('memoryTabDeleteMemoryModal.delete') })] })] }) }));
|
|
284929
|
-
}
|
|
284930
|
-
|
|
284931
|
-
var deleteMemoryModal = /*#__PURE__*/Object.freeze({
|
|
284932
|
-
__proto__: null,
|
|
284933
|
-
DeleteMemoryModal: DeleteMemoryModal
|
|
284934
|
-
});
|
|
284935
|
-
|
|
284936
286232
|
function BulkDeleteMemoryModal({ open, onOpenChange, onConfirm, onCancel, isDeleting, selectedCategory, }) {
|
|
284937
286233
|
const isDeleteAll = selectedCategory === 'All';
|
|
284938
286234
|
const getConfirmationText = () => {
|