@iblai/iblai-js 2.5.1 → 2.5.6
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 +12521 -11250
- package/dist/web-containers/source/next/index.esm.js +1734 -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 +5 -5
|
@@ -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
|
}
|
|
@@ -258034,7 +258924,7 @@ function RetrievedDocumentsButton({ sessionId }) {
|
|
|
258034
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 }) })] }) })] }));
|
|
258035
258925
|
}
|
|
258036
258926
|
|
|
258037
|
-
const PAGE_SIZE$
|
|
258927
|
+
const PAGE_SIZE$9 = 10;
|
|
258038
258928
|
const MemoryMenu = ({ onClose, mentorId, tenantKey, username }) => {
|
|
258039
258929
|
const t = useT();
|
|
258040
258930
|
const [page, setPage] = useState(1);
|
|
@@ -258052,7 +258942,7 @@ const MemoryMenu = ({ onClose, mentorId, tenantKey, username }) => {
|
|
|
258052
258942
|
mentorId,
|
|
258053
258943
|
params: {
|
|
258054
258944
|
page,
|
|
258055
|
-
page_size: PAGE_SIZE$
|
|
258945
|
+
page_size: PAGE_SIZE$9,
|
|
258056
258946
|
my_memory: true,
|
|
258057
258947
|
},
|
|
258058
258948
|
}, {
|
|
@@ -261935,7 +262825,7 @@ function DeleteItemConfirm({ isOpen, onClose, tenantKey, username, datasetName,
|
|
|
261935
262825
|
: t('benchmarksDeleteItemConfirm.delete') })] })] }) }));
|
|
261936
262826
|
}
|
|
261937
262827
|
|
|
261938
|
-
const PAGE_SIZE$
|
|
262828
|
+
const PAGE_SIZE$8 = 10;
|
|
261939
262829
|
function BenchmarkItemsModal({ isOpen, onClose, tenantKey, username, datasetName }) {
|
|
261940
262830
|
var _a;
|
|
261941
262831
|
const t = useT();
|
|
@@ -261947,17 +262837,17 @@ function BenchmarkItemsModal({ isOpen, onClose, tenantKey, username, datasetName
|
|
|
261947
262837
|
userId: username,
|
|
261948
262838
|
datasetName,
|
|
261949
262839
|
page,
|
|
261950
|
-
limit: PAGE_SIZE$
|
|
262840
|
+
limit: PAGE_SIZE$8,
|
|
261951
262841
|
});
|
|
261952
262842
|
const items = (_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : [];
|
|
261953
|
-
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);
|
|
261954
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) => {
|
|
261955
262845
|
var _a;
|
|
261956
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));
|
|
261957
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 }))] }) }));
|
|
261958
262848
|
}
|
|
261959
262849
|
|
|
261960
|
-
const PAGE_SIZE$
|
|
262850
|
+
const PAGE_SIZE$7 = 10;
|
|
261961
262851
|
function BenchmarksTab({ tenantKey, username, }) {
|
|
261962
262852
|
var _a;
|
|
261963
262853
|
const t = useT();
|
|
@@ -261969,13 +262859,13 @@ function BenchmarksTab({ tenantKey, username, }) {
|
|
|
261969
262859
|
org: tenantKey,
|
|
261970
262860
|
userId: username,
|
|
261971
262861
|
page,
|
|
261972
|
-
limit: PAGE_SIZE$
|
|
262862
|
+
limit: PAGE_SIZE$7,
|
|
261973
262863
|
});
|
|
261974
262864
|
const benchmarks = (_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : [];
|
|
261975
262865
|
const filtered = searchQuery.trim()
|
|
261976
262866
|
? benchmarks.filter((benchmark) => benchmark.name.toLowerCase().includes(searchQuery.toLowerCase()))
|
|
261977
262867
|
: benchmarks;
|
|
261978
|
-
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);
|
|
261979
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
|
|
261980
262870
|
? formatDistanceToNow(new Date(benchmark.created_at), {
|
|
261981
262871
|
addSuffix: true,
|
|
@@ -261985,6 +262875,514 @@ function BenchmarksTab({ tenantKey, username, }) {
|
|
|
261985
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 }))] }));
|
|
261986
262876
|
}
|
|
261987
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
|
+
|
|
261988
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, }) {
|
|
261989
263387
|
var _a, _b, _c, _d;
|
|
261990
263388
|
const t = useT();
|
|
@@ -262001,6 +263399,7 @@ function Account({ tenant, tenants = [], username, onInviteClick, email, mainPla
|
|
|
262001
263399
|
...(showBenchmarks
|
|
262002
263400
|
? [{ id: 'datasets', label: t('profileAccount.tabBenchmarks'), icon: ListChecks }]
|
|
262003
263401
|
: []),
|
|
263402
|
+
{ id: 'memory', label: t('profileAccount.tabMemory'), icon: Brain },
|
|
262004
263403
|
{ id: 'advanced', label: t('profileAccount.tabAdvanced'), icon: Settings$1 },
|
|
262005
263404
|
];
|
|
262006
263405
|
const [activeTab, setActiveTab] = useState(targetTab);
|
|
@@ -262082,10 +263481,10 @@ function Account({ tenant, tenants = [], username, onInviteClick, email, mainPla
|
|
|
262082
263481
|
onTabChange === null || onTabChange === void 0 ? void 0 : onTabChange('billing');
|
|
262083
263482
|
}, className: `flex items-center gap-2 px-3 py-2 rounded-lg whitespace-nowrap text-sm transition-all ${activeTab === 'billing'
|
|
262084
263483
|
? 'bg-blue-50 text-blue-600 font-medium'
|
|
262085
|
-
: '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: {
|
|
262086
263485
|
overflowY: 'auto',
|
|
262087
263486
|
overflowX: 'hidden',
|
|
262088
|
-
}, 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, {})] }));
|
|
262089
263488
|
}
|
|
262090
263489
|
|
|
262091
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, }) {
|
|
@@ -268183,286 +269582,6 @@ function AgentToolsTab({ labels: labelsOverride }) {
|
|
|
268183
269582
|
}) })) }) })] }));
|
|
268184
269583
|
}
|
|
268185
269584
|
|
|
268186
|
-
const EditMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return editMemoryModal; }).then((module) => ({
|
|
268187
|
-
default: module.EditMemoryModal,
|
|
268188
|
-
})), { ssr: false });
|
|
268189
|
-
const AddMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return addMemoryModal; }).then((module) => ({
|
|
268190
|
-
default: module.AddMemoryModal,
|
|
268191
|
-
})), { ssr: false });
|
|
268192
|
-
const DeleteMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return deleteMemoryModal; }).then((module) => ({
|
|
268193
|
-
default: module.DeleteMemoryModal,
|
|
268194
|
-
})), { ssr: false });
|
|
268195
|
-
const BulkDeleteMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return bulkDeleteMemoryModal; }).then((module) => ({
|
|
268196
|
-
default: module.BulkDeleteMemoryModal,
|
|
268197
|
-
})), { ssr: false });
|
|
268198
|
-
const ManageCategoriesModal$1 = dynamic(() => Promise.resolve().then(function () { return manageCategoriesModal; }).then((module) => ({
|
|
268199
|
-
default: module.ManageCategoriesModal,
|
|
268200
|
-
})), { ssr: false });
|
|
268201
|
-
const PAGE_SIZE$3 = 20;
|
|
268202
|
-
const SNAPSHOT_PAGE_SIZE = 1000;
|
|
268203
|
-
function ManageMemories({ tenantKey, username, mentorId }) {
|
|
268204
|
-
var _a, _b, _c, _d, _e;
|
|
268205
|
-
const t = useT();
|
|
268206
|
-
const [selectedLearner, setSelectedLearner] = useState('');
|
|
268207
|
-
const [dateRange, setDateRange] = useState(undefined);
|
|
268208
|
-
const [selectedCategorySlug, setSelectedCategorySlug] = useState('all');
|
|
268209
|
-
const [page, setPage] = useState(1);
|
|
268210
|
-
// Reset to page 1 whenever any filter changes — otherwise we could land on a
|
|
268211
|
-
// page index that no longer exists in the new result set.
|
|
268212
|
-
useEffect(() => {
|
|
268213
|
-
setPage(1);
|
|
268214
|
-
}, [selectedLearner, dateRange, selectedCategorySlug]);
|
|
268215
|
-
const listParams = useMemo(() => {
|
|
268216
|
-
const params = { page, page_size: PAGE_SIZE$3 };
|
|
268217
|
-
if (selectedLearner)
|
|
268218
|
-
params.email = selectedLearner;
|
|
268219
|
-
if (selectedCategorySlug !== 'all')
|
|
268220
|
-
params.category = selectedCategorySlug;
|
|
268221
|
-
if (dateRange === null || dateRange === void 0 ? void 0 : dateRange.from)
|
|
268222
|
-
params.start_date = format$1(dateRange.from, 'yyyy-MM-dd');
|
|
268223
|
-
if (dateRange === null || dateRange === void 0 ? void 0 : dateRange.to)
|
|
268224
|
-
params.end_date = format$1(dateRange.to, 'yyyy-MM-dd');
|
|
268225
|
-
return params;
|
|
268226
|
-
}, [page, selectedLearner, selectedCategorySlug, dateRange]);
|
|
268227
|
-
const { data: listResponse, isLoading: isLoadingMemories } = useGetMentorMemoriesListQuery({
|
|
268228
|
-
org: tenantKey,
|
|
268229
|
-
userId: username !== null && username !== void 0 ? username : '',
|
|
268230
|
-
mentorId,
|
|
268231
|
-
params: listParams,
|
|
268232
|
-
}, {
|
|
268233
|
-
skip: !tenantKey || !username || !mentorId,
|
|
268234
|
-
});
|
|
268235
|
-
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));
|
|
268236
|
-
const { data: adminCategories } = useGetMemoryCategoriesAdminQuery({
|
|
268237
|
-
org: tenantKey,
|
|
268238
|
-
mentorId,
|
|
268239
|
-
}, {
|
|
268240
|
-
skip: !tenantKey || !mentorId,
|
|
268241
|
-
});
|
|
268242
|
-
const [deleteMentorMemory, { isLoading: isDeleting }] = useDeleteMentorMemoryMutation();
|
|
268243
|
-
const [updateMentorMemory, { isLoading: isEditing }] = useUpdateMentorMemoryMutation();
|
|
268244
|
-
const [createMentorMemory, { isLoading: isSaving }] = useCreateMentorMemoryMutation();
|
|
268245
|
-
// Flat list of memories on the current page, mapped into the local `Memory`
|
|
268246
|
-
// shape used by the rest of this component.
|
|
268247
|
-
const memories = useMemo(() => {
|
|
268248
|
-
if (!(listResponse === null || listResponse === void 0 ? void 0 : listResponse.results))
|
|
268249
|
-
return [];
|
|
268250
|
-
return listResponse.results.map((memory) => ({
|
|
268251
|
-
id: memory.id,
|
|
268252
|
-
content: memory.content,
|
|
268253
|
-
category: {
|
|
268254
|
-
id: memory.category.id,
|
|
268255
|
-
name: memory.category.name,
|
|
268256
|
-
slug: memory.category.slug,
|
|
268257
|
-
},
|
|
268258
|
-
email: memory.email,
|
|
268259
|
-
createdAt: memory.created_at,
|
|
268260
|
-
}));
|
|
268261
|
-
}, [listResponse]);
|
|
268262
|
-
// Unfiltered snapshot used to derive the learner dropdown and to source the
|
|
268263
|
-
// bulk-delete operation, which needs the full set of memories — not just the
|
|
268264
|
-
// current page.
|
|
268265
|
-
const { data: snapshotResponse } = useGetMentorMemoriesListQuery({
|
|
268266
|
-
org: tenantKey,
|
|
268267
|
-
userId: username !== null && username !== void 0 ? username : '',
|
|
268268
|
-
mentorId,
|
|
268269
|
-
params: { page: 1, page_size: SNAPSHOT_PAGE_SIZE },
|
|
268270
|
-
}, {
|
|
268271
|
-
skip: !tenantKey || !username || !mentorId,
|
|
268272
|
-
});
|
|
268273
|
-
const learners = useMemo(() => {
|
|
268274
|
-
if (!(snapshotResponse === null || snapshotResponse === void 0 ? void 0 : snapshotResponse.results))
|
|
268275
|
-
return [];
|
|
268276
|
-
const emailSet = new Set();
|
|
268277
|
-
snapshotResponse.results.forEach((m) => {
|
|
268278
|
-
if (m.email)
|
|
268279
|
-
emailSet.add(m.email);
|
|
268280
|
-
});
|
|
268281
|
-
return Array.from(emailSet).map((email) => ({ email }));
|
|
268282
|
-
}, [snapshotResponse]);
|
|
268283
|
-
const categories = useMemo(() => {
|
|
268284
|
-
if (adminCategories && adminCategories.length > 0) {
|
|
268285
|
-
return [
|
|
268286
|
-
{ id: 0, name: 'All', slug: 'all' },
|
|
268287
|
-
...adminCategories.map((cat) => ({
|
|
268288
|
-
id: cat.id,
|
|
268289
|
-
name: cat.name,
|
|
268290
|
-
slug: cat.slug,
|
|
268291
|
-
})),
|
|
268292
|
-
];
|
|
268293
|
-
}
|
|
268294
|
-
return [{ id: 0, name: 'All', slug: 'all' }];
|
|
268295
|
-
}, [adminCategories]);
|
|
268296
|
-
const [editingMemory, setEditingMemory] = useState(null);
|
|
268297
|
-
const [editContent, setEditContent] = useState('');
|
|
268298
|
-
const [editCategory, setEditCategory] = useState('');
|
|
268299
|
-
const [showDeleteConfirm, setShowDeleteConfirm] = useState(null);
|
|
268300
|
-
const [showAddMemory, setShowAddMemory] = useState(false);
|
|
268301
|
-
const [newMemoryContent, setNewMemoryContent] = useState('');
|
|
268302
|
-
const [newMemoryCategory, setNewMemoryCategory] = useState('');
|
|
268303
|
-
const [showMobileDropdown, setShowMobileDropdown] = useState(false);
|
|
268304
|
-
const [showBulkDeleteConfirm, setShowBulkDeleteConfirm] = useState(false);
|
|
268305
|
-
const [isBulkDeleting, setIsBulkDeleting] = useState(false);
|
|
268306
|
-
const [showManageCategories, setShowManageCategories] = useState(false);
|
|
268307
|
-
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');
|
|
268308
|
-
const VISIBLE_CATEGORY_LIMIT = 6;
|
|
268309
|
-
const visibleCategories = categories.slice(0, VISIBLE_CATEGORY_LIMIT);
|
|
268310
|
-
const overflowCategories = categories.slice(VISIBLE_CATEGORY_LIMIT);
|
|
268311
|
-
const overflowSelected = overflowCategories.find((c) => c.slug === selectedCategorySlug);
|
|
268312
|
-
// Category is filtered server-side via the `category` query param now, so
|
|
268313
|
-
// `memories` already contains only the relevant entries for the page.
|
|
268314
|
-
const filteredMemories = memories;
|
|
268315
|
-
const handleDeleteMemory = async (id) => {
|
|
268316
|
-
if (!tenantKey || !username)
|
|
268317
|
-
return;
|
|
268318
|
-
try {
|
|
268319
|
-
await deleteMentorMemory({
|
|
268320
|
-
org: tenantKey,
|
|
268321
|
-
userId: username,
|
|
268322
|
-
mentorId,
|
|
268323
|
-
memoryId: id,
|
|
268324
|
-
}).unwrap();
|
|
268325
|
-
setShowDeleteConfirm(null);
|
|
268326
|
-
toast.success(t('memoryTabManageMemories.memoryDeletedSuccessfully'));
|
|
268327
|
-
}
|
|
268328
|
-
catch (error) {
|
|
268329
|
-
console.error('Failed to delete memory:', error);
|
|
268330
|
-
toast.error(t('memoryTabManageMemories.failedToDeleteMemory'));
|
|
268331
|
-
}
|
|
268332
|
-
};
|
|
268333
|
-
const handleBulkDelete = async () => {
|
|
268334
|
-
var _a;
|
|
268335
|
-
if (!tenantKey || !username)
|
|
268336
|
-
return;
|
|
268337
|
-
setIsBulkDeleting(true);
|
|
268338
|
-
try {
|
|
268339
|
-
// Source bulk-delete from the unfiltered snapshot — `memories` only holds
|
|
268340
|
-
// the current page, while bulk delete must remove every entry in the
|
|
268341
|
-
// selected category.
|
|
268342
|
-
const memoriesToDelete = ((_a = snapshotResponse === null || snapshotResponse === void 0 ? void 0 : snapshotResponse.results) !== null && _a !== void 0 ? _a : []).filter((memory) => memory.category.slug === selectedCategorySlug);
|
|
268343
|
-
await Promise.all(memoriesToDelete.map((memory) => deleteMentorMemory({
|
|
268344
|
-
org: tenantKey,
|
|
268345
|
-
userId: username,
|
|
268346
|
-
mentorId,
|
|
268347
|
-
memoryId: memory.id,
|
|
268348
|
-
}).unwrap()));
|
|
268349
|
-
toast.success(t('memoryTabManageMemories.allCategoryMemoriesDeleted', { category: selectedCategoryName }));
|
|
268350
|
-
setShowBulkDeleteConfirm(false);
|
|
268351
|
-
}
|
|
268352
|
-
catch (error) {
|
|
268353
|
-
console.error('Failed to delete memories:', error);
|
|
268354
|
-
toast.error(t('memoryTabManageMemories.failedToDeleteMemories'));
|
|
268355
|
-
}
|
|
268356
|
-
finally {
|
|
268357
|
-
setIsBulkDeleting(false);
|
|
268358
|
-
}
|
|
268359
|
-
};
|
|
268360
|
-
const startEdit = (memory) => {
|
|
268361
|
-
setEditingMemory(memory);
|
|
268362
|
-
setEditContent(memory.content);
|
|
268363
|
-
setEditCategory(memory.category.name);
|
|
268364
|
-
};
|
|
268365
|
-
const saveEdit = async () => {
|
|
268366
|
-
if (!editingMemory || !tenantKey || !username)
|
|
268367
|
-
return;
|
|
268368
|
-
try {
|
|
268369
|
-
const selectedCat = categories.find((c) => c.name === editCategory);
|
|
268370
|
-
const categoryChanged = !!selectedCat && selectedCat.slug !== editingMemory.category.slug;
|
|
268371
|
-
await updateMentorMemory({
|
|
268372
|
-
org: tenantKey,
|
|
268373
|
-
userId: username,
|
|
268374
|
-
mentorId,
|
|
268375
|
-
memoryId: editingMemory.id,
|
|
268376
|
-
data: {
|
|
268377
|
-
content: editContent,
|
|
268378
|
-
...(categoryChanged ? { category_slug: selectedCat.slug } : {}),
|
|
268379
|
-
},
|
|
268380
|
-
}).unwrap();
|
|
268381
|
-
toast.success(t('memoryTabManageMemories.memoryUpdatedSuccessfully'));
|
|
268382
|
-
// Follow the entry to its new category tab so the user doesn't lose
|
|
268383
|
-
// sight of it. Skip when viewing "All" — the entry is still visible.
|
|
268384
|
-
if (categoryChanged && selectedCategorySlug !== 'all') {
|
|
268385
|
-
setSelectedCategorySlug(selectedCat.slug);
|
|
268386
|
-
}
|
|
268387
|
-
setEditingMemory(null);
|
|
268388
|
-
setEditContent('');
|
|
268389
|
-
setEditCategory('');
|
|
268390
|
-
}
|
|
268391
|
-
catch (error) {
|
|
268392
|
-
console.error('Failed to update memory:', error);
|
|
268393
|
-
toast.error(t('memoryTabManageMemories.failedToUpdateMemory'));
|
|
268394
|
-
}
|
|
268395
|
-
};
|
|
268396
|
-
const cancelEdit = () => {
|
|
268397
|
-
setEditingMemory(null);
|
|
268398
|
-
setEditContent('');
|
|
268399
|
-
setEditCategory('');
|
|
268400
|
-
};
|
|
268401
|
-
const startAddMemory = () => {
|
|
268402
|
-
setShowAddMemory(true);
|
|
268403
|
-
setNewMemoryCategory(selectedCategoryName);
|
|
268404
|
-
};
|
|
268405
|
-
const saveNewMemory = async () => {
|
|
268406
|
-
var _a;
|
|
268407
|
-
if (!newMemoryContent.trim() || !tenantKey || !username)
|
|
268408
|
-
return;
|
|
268409
|
-
try {
|
|
268410
|
-
const selectedCat = categories.find((c) => c.name === newMemoryCategory);
|
|
268411
|
-
const categorySlug = (_a = selectedCat === null || selectedCat === void 0 ? void 0 : selectedCat.slug) !== null && _a !== void 0 ? _a : selectedCategorySlug;
|
|
268412
|
-
await createMentorMemory({
|
|
268413
|
-
org: tenantKey,
|
|
268414
|
-
userId: username,
|
|
268415
|
-
mentorId,
|
|
268416
|
-
data: {
|
|
268417
|
-
category_slug: categorySlug === 'all' ? 'general' : categorySlug,
|
|
268418
|
-
content: newMemoryContent.trim(),
|
|
268419
|
-
},
|
|
268420
|
-
}).unwrap();
|
|
268421
|
-
setShowAddMemory(false);
|
|
268422
|
-
setNewMemoryContent('');
|
|
268423
|
-
setNewMemoryCategory('');
|
|
268424
|
-
if (selectedCat) {
|
|
268425
|
-
setSelectedCategorySlug(selectedCat.slug);
|
|
268426
|
-
}
|
|
268427
|
-
toast.success(t('memoryTabManageMemories.memoryCreatedSuccessfully'));
|
|
268428
|
-
}
|
|
268429
|
-
catch (error) {
|
|
268430
|
-
console.error('Failed to create memory:', error);
|
|
268431
|
-
toast.error(t('memoryTabManageMemories.failedToCreateMemory'));
|
|
268432
|
-
}
|
|
268433
|
-
};
|
|
268434
|
-
const cancelAddMemory = () => {
|
|
268435
|
-
setShowAddMemory(false);
|
|
268436
|
-
setNewMemoryContent('');
|
|
268437
|
-
setNewMemoryCategory('');
|
|
268438
|
-
};
|
|
268439
|
-
const categoryNames = categories.map((c) => c.name);
|
|
268440
|
-
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
|
|
268441
|
-
? ((_e = (_d = learners.find((learner) => learner.email === selectedLearner)) === null || _d === void 0 ? void 0 : _d.email) !== null && _e !== void 0 ? _e : selectedLearner)
|
|
268442
|
-
: 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: () => {
|
|
268443
|
-
setSelectedLearner('');
|
|
268444
|
-
}, 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: () => {
|
|
268445
|
-
setSelectedLearner(learner.email);
|
|
268446
|
-
}, 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)
|
|
268447
|
-
? `${format$1(dateRange.from, 'MMM dd')} - ${format$1(dateRange.to, 'MMM dd')}`
|
|
268448
|
-
: 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
|
|
268449
|
-
? 'text-[#38A1E5]'
|
|
268450
|
-
: '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: {
|
|
268451
|
-
width: `${overflowSelected.name.length * 0.55}em`,
|
|
268452
|
-
} }))] }) }), 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: () => {
|
|
268453
|
-
setSelectedCategorySlug(category.slug);
|
|
268454
|
-
setShowMobileDropdown(false);
|
|
268455
|
-
}, 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) => {
|
|
268456
|
-
const timeAgo = memory.createdAt
|
|
268457
|
-
? formatDistanceToNow(new Date(memory.createdAt), {
|
|
268458
|
-
addSuffix: true,
|
|
268459
|
-
})
|
|
268460
|
-
: '';
|
|
268461
|
-
const displayUser = memory.email || t('memoryTabManageMemories.unknown');
|
|
268462
|
-
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));
|
|
268463
|
-
})) }), 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 })] }));
|
|
268464
|
-
}
|
|
268465
|
-
|
|
268466
269585
|
const AGENT_MEMORY_TAB_LABELS = {
|
|
268467
269586
|
header: {
|
|
268468
269587
|
title: 'Memory',
|
|
@@ -270346,6 +271465,9 @@ function CopyButton({ text, disabled = false }) {
|
|
|
270346
271465
|
const systemPromptSchema$1 = z$2.object({
|
|
270347
271466
|
prompt: z$2.string().min(1, 'Prompt is required'),
|
|
270348
271467
|
});
|
|
271468
|
+
const emptyAllowedPromptSchema = z$2.object({
|
|
271469
|
+
prompt: z$2.string(),
|
|
271470
|
+
});
|
|
270349
271471
|
const nonSystemPromptSchema$1 = z$2.object({
|
|
270350
271472
|
category: z$2.string().min(1, 'Category is required'),
|
|
270351
271473
|
prompt: z$2.string().min(1, 'Prompt is required'),
|
|
@@ -270374,7 +271496,11 @@ function EditPromptModal$1({ isOpen, onClose, selectedPrompt, handleSave, isEdit
|
|
|
270374
271496
|
promptVisibility: selectedPrompt.promptVisibility,
|
|
270375
271497
|
},
|
|
270376
271498
|
validators: {
|
|
270377
|
-
onChange: selectedPrompt.isSystem
|
|
271499
|
+
onChange: selectedPrompt.isSystem
|
|
271500
|
+
? selectedPrompt.allowEmpty
|
|
271501
|
+
? emptyAllowedPromptSchema
|
|
271502
|
+
: systemPromptSchema$1
|
|
271503
|
+
: nonSystemPromptSchema$1,
|
|
270378
271504
|
},
|
|
270379
271505
|
onSubmit: ({ value }) => {
|
|
270380
271506
|
handleSave(selectedPrompt, value);
|
|
@@ -270395,8 +271521,8 @@ function EditPromptModal$1({ isOpen, onClose, selectedPrompt, handleSave, isEdit
|
|
|
270395
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) => {
|
|
270396
271522
|
const hasNoValue = field.state.value === '';
|
|
270397
271523
|
const isDirty = field.state.meta.isDirty;
|
|
270398
|
-
const hasNoValueAndIsDirty = hasNoValue && isDirty;
|
|
270399
|
-
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') }))] }));
|
|
270400
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
|
|
270401
271527
|
? t('promptsTabEditPromptModal.saving')
|
|
270402
271528
|
: t('promptsTabEditPromptModal.save') })) }) }) })] }) }) }));
|
|
@@ -270918,6 +272044,27 @@ const AGENT_VOICE_TAB_LABELS = {
|
|
|
270918
272044
|
previewAria: (voiceName, action) => `${action === 'play' ? 'Preview' : 'Stop'} ${voiceName} voice`,
|
|
270919
272045
|
saveButton: 'Save voice',
|
|
270920
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
|
+
},
|
|
270921
272068
|
},
|
|
270922
272069
|
callConfig: {
|
|
270923
272070
|
title: 'Voice call',
|
|
@@ -271018,6 +272165,27 @@ function buildVoiceTabLabels(t) {
|
|
|
271018
272165
|
: t('voiceTabLabels.mentorVoice.previewAria.stop', { voiceName }),
|
|
271019
272166
|
saveButton: t('voiceTabLabels.mentorVoice.saveButton'),
|
|
271020
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
|
+
},
|
|
271021
272189
|
},
|
|
271022
272190
|
callConfig: {
|
|
271023
272191
|
title: t('voiceTabLabels.callConfig.title'),
|
|
@@ -271557,10 +272725,29 @@ function FieldWrap({ label, tooltip, children }) {
|
|
|
271557
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] }));
|
|
271558
272726
|
}
|
|
271559
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
|
+
|
|
271560
272741
|
const SUB_TAB_VALUES = {
|
|
271561
272742
|
voice: 'voice',
|
|
271562
272743
|
callConfig: 'call-config',
|
|
271563
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;
|
|
271564
272751
|
/**
|
|
271565
272752
|
* Pull a voice **name** out of the mentor settings response, which can
|
|
271566
272753
|
* return a plain string, a numeric id, or a serialized object with a
|
|
@@ -271577,7 +272764,7 @@ function readVoiceName(value) {
|
|
|
271577
272764
|
return null;
|
|
271578
272765
|
}
|
|
271579
272766
|
function AgentVoiceTab({ labels: labelsOverride, defaultSubTab = 'voice', renderPromptContent, tenantKey: tenantKeyProp, mentorId: mentorIdProp, username: usernameProp, enableRBAC: enableRBACProp, }) {
|
|
271580
|
-
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;
|
|
271581
272768
|
const ctx = useAgentSettingsOptional();
|
|
271582
272769
|
const tenantKey = (_a = tenantKeyProp !== null && tenantKeyProp !== void 0 ? tenantKeyProp : ctx === null || ctx === void 0 ? void 0 : ctx.tenantKey) !== null && _a !== void 0 ? _a : '';
|
|
271583
272770
|
const mentorId = (_b = mentorIdProp !== null && mentorIdProp !== void 0 ? mentorIdProp : ctx === null || ctx === void 0 ? void 0 : ctx.mentorId) !== null && _b !== void 0 ? _b : '';
|
|
@@ -271611,15 +272798,19 @@ function AgentVoiceTab({ labels: labelsOverride, defaultSubTab = 'voice', render
|
|
|
271611
272798
|
provider: 'google',
|
|
271612
272799
|
name: savedGoogleName,
|
|
271613
272800
|
});
|
|
272801
|
+
const savedInstructions = typeof (mentorSettings === null || mentorSettings === void 0 ? void 0 : mentorSettings.voice_instructions) === 'string' ? mentorSettings.voice_instructions : '';
|
|
271614
272802
|
// Picked voices override the resolved server values once the user
|
|
271615
272803
|
// makes a choice. Null means "use what came from the server".
|
|
271616
272804
|
const [provider, setProvider] = React__default.useState(initialProvider);
|
|
271617
272805
|
const [pickedOpenaiVoice, setPickedOpenaiVoice] = React__default.useState(null);
|
|
271618
272806
|
const [pickedGoogleVoice, setPickedGoogleVoice] = React__default.useState(null);
|
|
272807
|
+
const [instructions, setInstructions] = React__default.useState(savedInstructions);
|
|
272808
|
+
const [selectedPrompt, setSelectedPrompt] = React__default.useState(null);
|
|
271619
272809
|
React__default.useEffect(() => {
|
|
271620
272810
|
setProvider(initialProvider);
|
|
271621
272811
|
setPickedOpenaiVoice(null);
|
|
271622
272812
|
setPickedGoogleVoice(null);
|
|
272813
|
+
setInstructions(savedInstructions);
|
|
271623
272814
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
271624
272815
|
}, [mentorId, rawMentorSettings]);
|
|
271625
272816
|
const effectiveOpenaiVoice = (_h = pickedOpenaiVoice !== null && pickedOpenaiVoice !== void 0 ? pickedOpenaiVoice : resolvedOpenaiVoice) !== null && _h !== void 0 ? _h : null;
|
|
@@ -271657,7 +272848,14 @@ function AgentVoiceTab({ labels: labelsOverride, defaultSubTab = 'voice', render
|
|
|
271657
272848
|
}
|
|
271658
272849
|
};
|
|
271659
272850
|
const isDisabled = isMentorSettingsLoading || isSavingMentor;
|
|
271660
|
-
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;
|
|
271661
272859
|
/**
|
|
271662
272860
|
* Provider chips. We reuse the OpenAI / Google logos already shipped in
|
|
271663
272861
|
* the host's static-root (see `getLLMProviderDetails` for the canonical
|
|
@@ -271696,6 +272894,12 @@ function AgentVoiceTab({ labels: labelsOverride, defaultSubTab = 'voice', render
|
|
|
271696
272894
|
if (provider === 'google' && pickedGoogleVoice) {
|
|
271697
272895
|
formData.google_voice = pickedGoogleVoice.id;
|
|
271698
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
|
+
}
|
|
271699
272903
|
await editMentor({
|
|
271700
272904
|
mentor: mentorId,
|
|
271701
272905
|
org: tenantKey,
|
|
@@ -271721,43 +272925,60 @@ function AgentVoiceTab({ labels: labelsOverride, defaultSubTab = 'voice', render
|
|
|
271721
272925
|
else if (provider === 'google')
|
|
271722
272926
|
setPickedGoogleVoice(voice);
|
|
271723
272927
|
};
|
|
271724
|
-
|
|
271725
|
-
|
|
271726
|
-
|
|
271727
|
-
|
|
271728
|
-
|
|
271729
|
-
|
|
271730
|
-
|
|
271731
|
-
|
|
271732
|
-
|
|
271733
|
-
|
|
271734
|
-
|
|
271735
|
-
|
|
271736
|
-
|
|
271737
|
-
|
|
271738
|
-
|
|
271739
|
-
|
|
271740
|
-
error
|
|
271741
|
-
|
|
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
|
+
} }) }))] })) })] }));
|
|
271742
272976
|
}
|
|
271743
272977
|
function FieldTooltip({ text }) {
|
|
271744
272978
|
const t = useT();
|
|
271745
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 }) })] }) }));
|
|
271746
272980
|
}
|
|
271747
272981
|
|
|
271748
|
-
/**
|
|
271749
|
-
* Display-only card for a single prompt. Mirrors the visual pattern
|
|
271750
|
-
* used by `AgentPromptsTab` (System Prompt / Proactive Prompt cards):
|
|
271751
|
-
* a header, a 📝-prefixed body, and Edit + Copy action buttons at the
|
|
271752
|
-
* bottom. "Edit" is wired by the parent (typically opens the shared
|
|
271753
|
-
* `EditPromptModal`); the new value is written back via the parent's
|
|
271754
|
-
* `onEdit` handler.
|
|
271755
|
-
*/
|
|
271756
|
-
function PromptCard$1({ label, placeholder, value, disabled, renderContent, onEdit, }) {
|
|
271757
|
-
const isEmpty = !value || value.trim() === '';
|
|
271758
|
-
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 })] })] }));
|
|
271759
|
-
}
|
|
271760
|
-
|
|
271761
272982
|
const AGENT_SCREENSHARE_TAB_LABELS = {
|
|
271762
272983
|
header: {
|
|
271763
272984
|
// Title is deliberately just "Screen" — the description below carries the
|
|
@@ -273589,7 +274810,7 @@ function resolveHumanSupportTabLabels(override, t) {
|
|
|
273589
274810
|
return deepMerge(base, override);
|
|
273590
274811
|
}
|
|
273591
274812
|
|
|
273592
|
-
const STATUS_BADGE_CLASSES = {
|
|
274813
|
+
const STATUS_BADGE_CLASSES$1 = {
|
|
273593
274814
|
open: 'border-green-200 bg-green-100 text-green-800 hover:bg-green-100',
|
|
273594
274815
|
in_progress: 'border-amber-200 bg-amber-100 text-amber-800 hover:bg-amber-100',
|
|
273595
274816
|
closed: 'border-gray-200 bg-gray-100 text-gray-700 hover:bg-gray-100',
|
|
@@ -273833,7 +275054,7 @@ function AgentHumanSupportTab({ PaginationComponent = IblPagination, labels: lab
|
|
|
273833
275054
|
};
|
|
273834
275055
|
const renderStatusBadge = (status) => {
|
|
273835
275056
|
const resolvedStatus = status !== null && status !== void 0 ? status : 'open';
|
|
273836
|
-
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] }));
|
|
273837
275058
|
};
|
|
273838
275059
|
const renderMessage = (message, ticket) => {
|
|
273839
275060
|
var _a;
|
|
@@ -273977,6 +275198,18 @@ const AGENT_LTI_TAB_LABELS = {
|
|
|
273977
275198
|
createButton: 'Create LTI Link',
|
|
273978
275199
|
empty: 'No LTI link yet for this agent.',
|
|
273979
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}`,
|
|
273980
275213
|
editAria: (name) => `Edit ${name}`,
|
|
273981
275214
|
copyTargetUri: 'Copy target link URI',
|
|
273982
275215
|
modal: {
|
|
@@ -274084,6 +275317,7 @@ const AGENT_LTI_TAB_LABELS = {
|
|
|
274084
275317
|
},
|
|
274085
275318
|
toasts: {
|
|
274086
275319
|
linkCreated: 'LTI link created successfully',
|
|
275320
|
+
linkCreationStarted: 'LTI link creation started — this can take a few minutes',
|
|
274087
275321
|
linkUpdated: 'LTI link updated successfully',
|
|
274088
275322
|
linkDeleted: 'LTI link deleted successfully',
|
|
274089
275323
|
linkError: 'Something went wrong with the LTI link',
|
|
@@ -274145,6 +275379,18 @@ function buildLtiTabLabels(t) {
|
|
|
274145
275379
|
createButton: t('ltiTabLabels.links.createButton'),
|
|
274146
275380
|
empty: t('ltiTabLabels.links.empty'),
|
|
274147
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 }),
|
|
274148
275394
|
editAria: (name) => t('ltiTabLabels.links.editAria', { name }),
|
|
274149
275395
|
copyTargetUri: t('ltiTabLabels.links.copyTargetUri'),
|
|
274150
275396
|
modal: {
|
|
@@ -274252,6 +275498,7 @@ function buildLtiTabLabels(t) {
|
|
|
274252
275498
|
},
|
|
274253
275499
|
toasts: {
|
|
274254
275500
|
linkCreated: t('ltiTabLabels.toasts.linkCreated'),
|
|
275501
|
+
linkCreationStarted: t('ltiTabLabels.toasts.linkCreationStarted'),
|
|
274255
275502
|
linkUpdated: t('ltiTabLabels.toasts.linkUpdated'),
|
|
274256
275503
|
linkDeleted: t('ltiTabLabels.toasts.linkDeleted'),
|
|
274257
275504
|
linkError: t('ltiTabLabels.toasts.linkError'),
|
|
@@ -274389,8 +275636,11 @@ function AgentLinkModal({ isOpen, onClose, platformKey, mentorId, mentorUniqueId
|
|
|
274389
275636
|
toast.success(labels.toasts.linkUpdated);
|
|
274390
275637
|
}
|
|
274391
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).
|
|
274392
275642
|
await createLtiMentor({ requestBody }).unwrap();
|
|
274393
|
-
toast.success(labels.toasts.
|
|
275643
|
+
toast.success(labels.toasts.linkCreationStarted);
|
|
274394
275644
|
// "Allow LTI" must be on for the link to work. Enable it automatically
|
|
274395
275645
|
// on create so the user doesn't have to toggle it in Settings as a
|
|
274396
275646
|
// separate step. Best-effort: a failure here doesn't fail the link.
|
|
@@ -274448,26 +275698,78 @@ function readTargetLinkUri(link) {
|
|
|
274448
275698
|
const config = link.mentor_config;
|
|
274449
275699
|
return (_a = config === null || config === void 0 ? void 0 : config.target_link_uri) !== null && _a !== void 0 ? _a : null;
|
|
274450
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
|
+
}
|
|
274451
275713
|
function AgentLinksSection({ identity, labels, }) {
|
|
274452
275714
|
const { platformKey, mentorId, mentorUniqueId, username, isLtiAccessible, isReady, isSettingsLoading } = identity;
|
|
274453
275715
|
const [showCreate, setShowCreate] = React__default.useState(false);
|
|
274454
275716
|
const [editingLink, setEditingLink] = React__default.useState(null);
|
|
274455
275717
|
const [page, setPage] = React__default.useState(1);
|
|
274456
|
-
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();
|
|
274457
275722
|
// The backend scopes the list to this agent via `mentor_id`; we still narrow
|
|
274458
|
-
// 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.
|
|
274459
275726
|
const links = React__default.useMemo(() => mentorUniqueId
|
|
274460
|
-
? 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; })
|
|
274461
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
|
+
};
|
|
274462
275756
|
const totalPages = getTotalPages(allLinks);
|
|
274463
275757
|
const busy = !isReady || isSettingsLoading || isLoading;
|
|
274464
275758
|
const canCreate = !busy && links.length === 0 && Boolean(mentorUniqueId);
|
|
274465
|
-
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) => {
|
|
274466
275760
|
const targetLinkUri = readTargetLinkUri(link);
|
|
274467
|
-
|
|
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) => {
|
|
274468
275770
|
event.stopPropagation();
|
|
274469
275771
|
setEditingLink(link);
|
|
274470
|
-
}, children: jsx(Pencil, { className: "h-4 w-4" }) }) })] }, link.id));
|
|
275772
|
+
}, children: jsx(Pencil, { className: "h-4 w-4" }) })) : null })] }, link.id));
|
|
274471
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 }))] }));
|
|
274472
275774
|
}
|
|
274473
275775
|
|
|
@@ -284927,18 +286229,6 @@ var addMemoryModal = /*#__PURE__*/Object.freeze({
|
|
|
284927
286229
|
AddMemoryModal: AddMemoryModal
|
|
284928
286230
|
});
|
|
284929
286231
|
|
|
284930
|
-
function DeleteMemoryModal({ open, onOpenChange, onConfirm, onCancel, isDeleting, }) {
|
|
284931
|
-
const t = useT();
|
|
284932
|
-
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
|
|
284933
|
-
? t('memoryTabDeleteMemoryModal.deleting')
|
|
284934
|
-
: t('memoryTabDeleteMemoryModal.delete') })] })] }) }));
|
|
284935
|
-
}
|
|
284936
|
-
|
|
284937
|
-
var deleteMemoryModal = /*#__PURE__*/Object.freeze({
|
|
284938
|
-
__proto__: null,
|
|
284939
|
-
DeleteMemoryModal: DeleteMemoryModal
|
|
284940
|
-
});
|
|
284941
|
-
|
|
284942
286232
|
function BulkDeleteMemoryModal({ open, onOpenChange, onConfirm, onCancel, isDeleting, selectedCategory, }) {
|
|
284943
286233
|
const isDeleteAll = selectedCategory === 'All';
|
|
284944
286234
|
const getConfirmationText = () => {
|