@iblai/iblai-js 2.9.4 → 2.9.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.
|
@@ -2,8 +2,8 @@ import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import React__default, { useState, useEffect, forwardRef, createElement as createElement$3, useLayoutEffect, createContext, useContext, useMemo, useReducer, useRef, useImperativeHandle, useCallback, isValidElement, Children, PureComponent, cloneElement, Component as Component$1, useId as useId$2, useDebugValue, lazy, Suspense } from 'react';
|
|
4
4
|
import * as dataLayer from '@iblai/data-layer';
|
|
5
|
-
import { useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useGetLearnerDetailsQuery, useGetUserEnrolledCoursesQuery, useGetUserEnrolledProgramsQuery, useGetUserCatalogPathwaysQuery, useGetUsersAsAssertionsQuery, useGetUserEarnedSkillsQuery, useGetUserReportedSkillsQuery, useGetUserDesiredSkillsQuery, useCreateGlobalMemoryMutation, useUpdateGlobalMemoryMutation, useUpdateMentorMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useGetAllMentorMemoriesQuery, useDeleteGlobalMemoryMutation, useDeleteMentorMemoryMutation, useGetAiSearchMentorsQuery, useStarMentorMutation, useUnstarMentorMutation, useGetUserChatHistoryReportsQuery, USER_CHAT_HISTORY_REPORT_ACTIVE_STATES, useCreateUserChatHistoryReportMutation, useLazyGetDownloadReportFromURLQuery, useGetUserChatHistoryReportStatusQuery, userChatHistoryApiSlice, USER_CHAT_HISTORY_QUERY_KEYS, useGetUserChatHistoryQuery, useGetUserChatHistoryFilterQuery, useGetMentorsQuery, useGetUserChatHistorySessionQuery, 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, 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, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, 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
|
-
import { removeAuthItem, setAuthItem,
|
|
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, useGetAiSearchMentorsQuery, useStarMentorMutation, useUnstarMentorMutation, useGetUserChatHistoryReportsQuery, USER_CHAT_HISTORY_REPORT_ACTIVE_STATES, useCreateUserChatHistoryReportMutation, useLazyGetDownloadReportFromURLQuery, useGetUserChatHistoryReportStatusQuery, userChatHistoryApiSlice, USER_CHAT_HISTORY_QUERY_KEYS, useGetUserChatHistoryQuery, useGetUserChatHistoryFilterQuery, useGetMentorsQuery, useGetUserChatHistorySessionQuery, 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, 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, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useCreateMentorMemoryMutation, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetAgentSkillResourcesQuery, useCreateAgentSkillResourceMutation, useUpdateAgentSkillResourceMutation, useUploadAgentSkillResourceAssetMutation, useDeleteAgentSkillResourceMutation, useGetMentorSkillAssignmentsQuery, useGetAgentSkillsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, filterSlashSkills, useGetMentorSkillAssignmentsInfiniteQuery, MENTOR_SKILL_ASSIGNMENTS_PAGE_SIZE, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useGetVectorDocumentsQuery, useLazyGetConnectedServiceAuthUrlQuery, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorSettingsQuery, useEditMentorMutation, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, LOGO_ENDPOINTS, useCreateEvalDatasetMutation, useAddEvalDatasetItemsMutation, useUploadEvalDatasetCsvMutation, useDeleteEvalDatasetItemMutation, useListEvalDatasetItemsQuery, evalTotalPages, useListEvalDatasetsQuery, useGetUserProjectsQuery, useCreateSessionIdMutation, useGetMentorCategoriesQuery, useGetTenantChatPrivacyConfigQuery as useGetTenantChatPrivacyConfigQuery$1, useGetCallConfigurationsQuery, useCreateCallConfigurationMutation, useUpdateCallConfigurationMutation, chatPrivacyApiSlice, useDeleteMentorMutation, useForkMentorMutation, useGetToolsQuery, useLazyGetMCPServersQuery, useOauthFindMutation, useLazyStartOAuthFlowQuery, useCreateMCPServerMutation, usePartialUpdateMCPServerMutation, useCreateMCPServerConnectionMutation, usePatchMCPServerConnectionMutation, useGetConnectedServicesQuery, useGetMCPServersQuery, useGetMCPServerConnectionsQuery, useUpdateMCPServerMutation, useDeleteMCPServerMutation, useEditMentorJsonMutation, useDisconnectServiceMutation, useGetPromptCategoriesQuery, PRIVACY_ACTIONS, PRIVACY_ENTITY_TYPES, useGetVoicesQuery, useGetVoiceQuery, isBaseAgentMentor, useGetGradeResultQuery, useOverrideGradeResultMutation, useGetChatHistoryFilterQuery, useListGradeResultsQuery, useGetMentorGraderConfigurationQuery, useListGraderCriteriaQuery, useCreateMentorGraderConfigurationMutation, useUpdateMentorGraderConfigurationMutation, useCreateGraderCriterionMutation, useUpdateGraderCriterionMutation, useDeleteGraderCriterionMutation, useGetSpendCapStatusQuery, useGetMentorPublicSettingsQuery, useGetChatHistoryQuery, useGetMentorSummariesQuery, useGetConversationMemoriesQuery, useGetSupportTicketsQuery, useGetSupportTicketMessagesQuery, useCreateSupportTicketMessageMutation, usePatchSupportTicketMutation, useCloseSupportTicketMutation, useCreateLtiMentorMutation, useUpdateLtiMentorMutation, useGetLtiMentorsQuery, useDeleteLtiMentorMutation, useCreateLtiKeyMutation, useUpdateLtiKeyMutation, useDeleteLtiKeyMutation, useGetLtiKeysQuery, useCreateLtiToolMutation, useUpdateLtiToolMutation, useGetLtiToolsQuery, useGetPlatformInfoQuery, useCreatePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useCreateRedirectTokenMutation, useGetShareableLinkQuery, useCreateShareableLinkMutation, useUpdateShareableLinkMutation, useCreateDisclaimerMutation, useUpdateDisclaimerMutation, useGetDisclaimersQuery, useUpdateRbacMentorAccessMutation, useGetRbacMentorAccessListQuery, useStartEvalRunMutation, useEvaluateEvalRunMutation, useGetEvalRunQuery, useDeleteEvalScoreMutation, useListEvalRunJudgesQuery, useCreateEvalScoreMutation, useDeleteEvalRunMutation, useExportEvalRunMutation, useListEvalRunsQuery, useLazyGetEvalRunQuery, evaluationsApiSlice, EVALUATIONS_TAGS, useGetPersonnalizedMentorsQuery, useCreateCallCredentialsMutation, useGetGuidedPromptsQuery, useUpdateChatSessionSharedMutation, useUpdateMessageFeedbackMutation, useLazyGetPromptsSearchQuery, useLazyGetGuidedPromptsQuery, useGetPublicMentorsQuery, useGetPeriodicAgentsQuery, useGetPeriodicAgentLogsListQuery, useCreatePeriodicAgentMutation, useDeletePeriodicAgentMutation, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useDeletePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation, useUpdateArtifactMutation, useLazyGetArtifactVersionQuery, useLazyListArtifactVersionsQuery, useSetCurrentVersionMutation, useListArtifactVersionsQuery, useLazyGetArtifactQuery, useLazyListArtifactsQuery, useEditSessionMutation } from '@iblai/data-layer';
|
|
6
|
+
import { removeAuthItem, setAuthItem, selectRbacPermissions, useCurrentTenant, canViewOtherUsersChatHistory, getInitials, useTenantMetadata, 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, use401TokenRefresh, selectTokenEnabled, selectToken, useServiceWorker, useUserAgreement, useAdvancedChat, sendMessageToParentWebsite, useMentorTools, useFileDragDrop, eventBus, RemoteEvents, selectEnableChatActionsPopup, advancedTabs, isInIframe, getAuthSpaJoinUrl, addMessage, clearFiles, MENTOR_VISIBILITY } from '@iblai/web-utils';
|
|
7
7
|
import { useDispatch, useSelector } from 'react-redux';
|
|
8
8
|
import { toast } from 'sonner';
|
|
9
9
|
import { useSearchParams, useParams, useRouter, usePathname } from 'next/navigation';
|
|
@@ -16,8 +16,8 @@ import { RemoveScroll } from 'react-remove-scroll';
|
|
|
16
16
|
import { skipToken } from '@reduxjs/toolkit/query';
|
|
17
17
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
18
18
|
import { createDialogScope } from '@radix-ui/react-dialog';
|
|
19
|
-
import { MentorVisibilityEnum, TransportEnum, PromptVisibilityEnum } from '@iblai/iblai-api';
|
|
20
19
|
import dynamic from 'next/dynamic';
|
|
20
|
+
import { MentorVisibilityEnum, TransportEnum, PromptVisibilityEnum } from '@iblai/iblai-api';
|
|
21
21
|
import Script from 'next/script';
|
|
22
22
|
import { useRouter as useRouter$1 } from 'next/router';
|
|
23
23
|
import { Room, RoomEvent, ConnectionState, VideoPresets, Track, ParticipantEvent } from 'livekit-client';
|
|
@@ -97448,6 +97448,7 @@ var chatHistoryChatHistoryTab$3 = {
|
|
|
97448
97448
|
exportFailed: "Failed to export chat history. Please try again.",
|
|
97449
97449
|
downloadFailed: "Failed to download report.",
|
|
97450
97450
|
loadFailed: "Failed to load history.",
|
|
97451
|
+
forbidden: "You don't have permission to view this user's history.",
|
|
97451
97452
|
noConversations: "No conversations found",
|
|
97452
97453
|
noMessages: "No messages in this conversation.",
|
|
97453
97454
|
conversation: "Conversation",
|
|
@@ -97468,6 +97469,7 @@ var chatHistoryReportHistory$3 = {
|
|
|
97468
97469
|
download: "Download",
|
|
97469
97470
|
allAgents: "All agents",
|
|
97470
97471
|
allTime: "All time",
|
|
97472
|
+
createdBy: "by {owner}",
|
|
97471
97473
|
agentsCount: "{count, plural, one {# agent} other {# agents}}",
|
|
97472
97474
|
statePending: "Pending",
|
|
97473
97475
|
stateProcessing: "Processing",
|
|
@@ -104469,6 +104471,7 @@ var chatHistoryChatHistoryTab$2 = {
|
|
|
104469
104471
|
exportFailed: "Échec de l'exportation de l'historique. Veuillez réessayer.",
|
|
104470
104472
|
downloadFailed: "Échec du téléchargement du rapport.",
|
|
104471
104473
|
loadFailed: "Échec du chargement de l'historique.",
|
|
104474
|
+
forbidden: "Vous n'avez pas la permission de voir l'historique de cet utilisateur.",
|
|
104472
104475
|
noConversations: "Aucune conversation trouvée",
|
|
104473
104476
|
noMessages: "Aucun message dans cette conversation.",
|
|
104474
104477
|
conversation: "Conversation",
|
|
@@ -104489,6 +104492,7 @@ var chatHistoryReportHistory$2 = {
|
|
|
104489
104492
|
download: "Télécharger",
|
|
104490
104493
|
allAgents: "Tous les agents",
|
|
104491
104494
|
allTime: "Toute la période",
|
|
104495
|
+
createdBy: "par {owner}",
|
|
104492
104496
|
agentsCount: "{count, plural, one {# agent} other {# agents}}",
|
|
104493
104497
|
statePending: "En attente",
|
|
104494
104498
|
stateProcessing: "En cours",
|
|
@@ -111490,6 +111494,7 @@ var chatHistoryChatHistoryTab$1 = {
|
|
|
111490
111494
|
exportFailed: "No se pudo exportar el historial de chat. Inténtalo de nuevo.",
|
|
111491
111495
|
downloadFailed: "No se pudo descargar el informe.",
|
|
111492
111496
|
loadFailed: "No se pudo cargar el historial.",
|
|
111497
|
+
forbidden: "No tienes permiso para ver el historial de este usuario.",
|
|
111493
111498
|
noConversations: "No se encontraron conversaciones",
|
|
111494
111499
|
noMessages: "No hay mensajes en esta conversación.",
|
|
111495
111500
|
conversation: "Conversación",
|
|
@@ -111510,6 +111515,7 @@ var chatHistoryReportHistory$1 = {
|
|
|
111510
111515
|
download: "Descargar",
|
|
111511
111516
|
allAgents: "Todos los agentes",
|
|
111512
111517
|
allTime: "Todo el tiempo",
|
|
111518
|
+
createdBy: "por {owner}",
|
|
111513
111519
|
agentsCount: "{count, plural, one {# agente} other {# agentes}}",
|
|
111514
111520
|
statePending: "Pendiente",
|
|
111515
111521
|
stateProcessing: "Procesando",
|
|
@@ -118511,6 +118517,7 @@ var chatHistoryChatHistoryTab = {
|
|
|
118511
118517
|
exportFailed: "导出聊天记录失败,请重试。",
|
|
118512
118518
|
downloadFailed: "下载报告失败。",
|
|
118513
118519
|
loadFailed: "加载历史记录失败。",
|
|
118520
|
+
forbidden: "您无权查看此用户的历史记录。",
|
|
118514
118521
|
noConversations: "未找到对话",
|
|
118515
118522
|
noMessages: "此对话中没有消息。",
|
|
118516
118523
|
conversation: "对话",
|
|
@@ -118531,6 +118538,7 @@ var chatHistoryReportHistory = {
|
|
|
118531
118538
|
download: "下载",
|
|
118532
118539
|
allAgents: "所有代理",
|
|
118533
118540
|
allTime: "全部时间",
|
|
118541
|
+
createdBy: "由 {owner} 创建",
|
|
118534
118542
|
agentsCount: "{count, plural, other {# 个代理}}",
|
|
118535
118543
|
statePending: "等待中",
|
|
118536
118544
|
stateProcessing: "处理中",
|
|
@@ -217694,12 +217702,12 @@ function ReportHistory({ org, username, onDownload }) {
|
|
|
217694
217702
|
setDownloadingId(null);
|
|
217695
217703
|
}
|
|
217696
217704
|
};
|
|
217697
|
-
return (jsx("div", { className: "overflow-hidden rounded-md border", children: jsx("div", { className: "overflow-x-auto sm:mx-0", children: jsx("div", { className: "inline-block min-w-full align-middle", children: isLoading ? (jsx("div", { className: "flex w-full items-center justify-center py-10", children: jsx(Spinner, {}) })) : (jsxs(Table$1, { className: "min-w-full", children: [jsx(TableHeader$1, { children: jsxs(TableRow$1, { className: "bg-muted/50 border-b", children: [jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('chatHistoryReportHistory.statusColumn') }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('chatHistoryReportHistory.createdColumn') }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('chatHistoryReportHistory.filtersColumn') }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('chatHistoryReportHistory.expiresColumn') }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]" })] }) }), jsx(TableBody, { children: reports.length === 0 ? (jsx(TableRow$1, { children: jsx(TableCell$1, { colSpan: 5, className: "p-4 text-center text-[#646464]", children: t('chatHistoryReportHistory.empty') }) })) : (reports.map((report) => {
|
|
217705
|
+
return (jsx("div", { className: "overflow-hidden rounded-md border border-neutral-200", children: jsx("div", { className: "overflow-x-auto sm:mx-0", children: jsx("div", { className: "inline-block min-w-full align-middle", children: isLoading ? (jsx("div", { className: "flex w-full items-center justify-center py-10", children: jsx(Spinner, {}) })) : (jsxs(Table$1, { className: "min-w-full", children: [jsx(TableHeader$1, { children: jsxs(TableRow$1, { className: "bg-muted/50 border-b border-neutral-200", children: [jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('chatHistoryReportHistory.statusColumn') }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('chatHistoryReportHistory.createdColumn') }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('chatHistoryReportHistory.filtersColumn') }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]", children: t('chatHistoryReportHistory.expiresColumn') }), jsx(TableHead, { className: "p-3 text-left text-sm whitespace-nowrap text-[#646464]" })] }) }), jsx(TableBody, { children: reports.length === 0 ? (jsx(TableRow$1, { className: "border-neutral-200", children: jsx(TableCell$1, { colSpan: 5, className: "p-4 text-center text-[#646464]", children: t('chatHistoryReportHistory.empty') }) })) : (reports.map((report) => {
|
|
217698
217706
|
var _a, _b, _c, _d;
|
|
217699
217707
|
const state = (_a = report.state) !== null && _a !== void 0 ? _a : '';
|
|
217700
217708
|
const active = isActiveState$1(state);
|
|
217701
217709
|
const labelKey = (_b = STATE_LABEL_KEYS[state]) !== null && _b !== void 0 ? _b : 'statePending';
|
|
217702
|
-
return (jsxs(TableRow$1, { className: "border-b", children: [jsx(TableCell$1, { className: "p-3 whitespace-nowrap", children: jsxs(Badge, { variant: "outline", className: cn(active ? ACTIVE_BADGE_CLASSES : (_c = STATE_BADGE_CLASSES[state]) !== null && _c !== void 0 ? _c : ''), children: [active && (jsx(LoaderCircle, { className: "mr-1 h-3 w-3 animate-spin", "aria-hidden": "true" })), t(`chatHistoryReportHistory.${labelKey}`)] }) }),
|
|
217710
|
+
return (jsxs(TableRow$1, { className: "border-b border-neutral-200", children: [jsx(TableCell$1, { className: "p-3 whitespace-nowrap", children: jsxs(Badge, { variant: "outline", className: cn(active ? ACTIVE_BADGE_CLASSES : (_c = STATE_BADGE_CLASSES[state]) !== null && _c !== void 0 ? _c : ''), children: [active && (jsx(LoaderCircle, { className: "mr-1 h-3 w-3 animate-spin", "aria-hidden": "true" })), t(`chatHistoryReportHistory.${labelKey}`)] }) }), jsxs(TableCell$1, { className: "p-3 whitespace-nowrap text-[#646464]", children: [timeAgo$1(report.created_at), report.owner && report.owner !== username && (jsx("div", { className: "text-xs text-gray-500", children: t('chatHistoryReportHistory.createdBy', { owner: report.owner }) }))] }), jsx(TableCell$1, { className: "max-w-[280px] truncate p-3 text-[#646464]", children: filterSummary(report, t) }), jsx(TableCell$1, { className: "p-3 whitespace-nowrap text-[#646464]", children: state === 'completed' && report.expires ? timeAgo$1(report.expires) : '—' }), jsx(TableCell$1, { className: "p-3 text-right whitespace-nowrap", children: state === 'completed' && report.url && (jsxs(Button$1, { variant: "outline", size: "sm", className: "flex items-center gap-2 bg-transparent", onClick: () => handleDownload(report), disabled: downloadingId === report.report_id, children: [downloadingId === report.report_id ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" })) : (jsx(Download, { className: "h-4 w-4", "aria-hidden": "true" })), t('chatHistoryReportHistory.download')] })) })] }, (_d = report.report_id) !== null && _d !== void 0 ? _d : report.created_at));
|
|
217703
217711
|
})) })] })) }) }) }));
|
|
217704
217712
|
}
|
|
217705
217713
|
|
|
@@ -217829,8 +217837,10 @@ function buildUserChatHistoryReportBody(filters, reportFormat = 'csv') {
|
|
|
217829
217837
|
}
|
|
217830
217838
|
/**
|
|
217831
217839
|
* Filter, pagination and data state for the profile History tab. All requests
|
|
217832
|
-
* are user-scoped (`my-chat-history*`): the backend
|
|
217833
|
-
*
|
|
217840
|
+
* are user-scoped (`my-chat-history*`): the backend serves the user's own
|
|
217841
|
+
* sessions to that user, to tenant admins, and to watchers of that user. Any
|
|
217842
|
+
* other caller — including a watcher on a user they don't watch — gets a 403,
|
|
217843
|
+
* surfaced here as `isForbidden`.
|
|
217834
217844
|
*/
|
|
217835
217845
|
function useUserChatHistory({ org, username }) {
|
|
217836
217846
|
var _a, _b, _c, _d;
|
|
@@ -217859,7 +217869,8 @@ function useUserChatHistory({ org, username }) {
|
|
|
217859
217869
|
return next;
|
|
217860
217870
|
}, [filters, page]);
|
|
217861
217871
|
const skip = !org || !username;
|
|
217862
|
-
const { data: history, isLoading, isFetching, isError, } = useGetUserChatHistoryQuery({ org, userId: username, params }, { skip });
|
|
217872
|
+
const { data: history, isLoading, isFetching, isError, error, } = useGetUserChatHistoryQuery({ org, userId: username, params }, { skip });
|
|
217873
|
+
const isForbidden = !!error && error.status === 403;
|
|
217863
217874
|
const { data: filterOptions } = useGetUserChatHistoryFilterQuery({
|
|
217864
217875
|
org,
|
|
217865
217876
|
userId: username,
|
|
@@ -217881,6 +217892,7 @@ function useUserChatHistory({ org, username }) {
|
|
|
217881
217892
|
isLoading,
|
|
217882
217893
|
isFetching,
|
|
217883
217894
|
isError,
|
|
217895
|
+
isForbidden,
|
|
217884
217896
|
filterOptions,
|
|
217885
217897
|
};
|
|
217886
217898
|
}
|
|
@@ -218052,7 +218064,7 @@ function ChatHistoryTab({ org, username }) {
|
|
|
218052
218064
|
const isMobile = useIsMobile();
|
|
218053
218065
|
const [selectedSession, setSelectedSession] = React__default.useState(null);
|
|
218054
218066
|
const [isPreviewModalOpen, setIsPreviewModalOpen] = React__default.useState(false);
|
|
218055
|
-
const { filters, setFilters, page, setPage, totalPages, sessions, isLoading, isFetching, isError, filterOptions, } = useUserChatHistory({ org, username });
|
|
218067
|
+
const { filters, setFilters, page, setPage, totalPages, sessions, isLoading, isFetching, isError, isForbidden, filterOptions, } = useUserChatHistory({ org, username });
|
|
218056
218068
|
const { startExport, downloadFromUrl, isExporting } = useChatHistoryExport({ org, username });
|
|
218057
218069
|
// The list payload identifies agents by unique_id only; resolve display
|
|
218058
218070
|
// names and avatars from agent search (plus whatever the payload carries).
|
|
@@ -218098,11 +218110,13 @@ function ChatHistoryTab({ org, username }) {
|
|
|
218098
218110
|
setIsPreviewModalOpen(true);
|
|
218099
218111
|
}
|
|
218100
218112
|
};
|
|
218101
|
-
return (jsxs(Tabs, { defaultValue: "conversations", className: "flex h-full min-h-0 flex-col gap-4", children: [jsxs(TabsList, { className: "w-fit flex-shrink-0", children: [jsx(TabsTrigger, { value: "conversations", children: t('chatHistoryChatHistoryTab.tabConversations') }), jsx(TabsTrigger, { value: "exports", children: t('chatHistoryChatHistoryTab.tabExports') })] }), jsxs(TabsContent, { value: "conversations", className: "mt-0 flex min-h-0 flex-1 flex-col gap-4 data-[state=inactive]:hidden", children: [jsx("div", { className: "flex-shrink-0 rounded-lg border p-4", children: jsxs("div", { className: "flex flex-col gap-3 lg:flex-row", children: [jsxs("div", { className: "flex flex-1 flex-wrap gap-3", children: [jsx(AgentFilterSelect, { tenantKey: org, username: username, value: filters.agent, onChange: (agent) => setFilters({ ...filters, agent }) }), jsxs(Popover, { children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", className: "flex h-9 items-center gap-2 bg-transparent font-normal whitespace-nowrap", children: [jsx(Calendar$1, { className: "h-4 w-4" }), ((_b = filters.dateRange) === null || _b === void 0 ? void 0 : _b.from) && ((_c = filters.dateRange) === null || _c === void 0 ? void 0 : _c.to)
|
|
218113
|
+
return (jsxs(Tabs, { defaultValue: "conversations", className: "flex h-full min-h-0 flex-col gap-4", children: [jsxs(TabsList, { className: "w-fit flex-shrink-0", children: [jsx(TabsTrigger, { value: "conversations", children: t('chatHistoryChatHistoryTab.tabConversations') }), jsx(TabsTrigger, { value: "exports", children: t('chatHistoryChatHistoryTab.tabExports') })] }), jsxs(TabsContent, { value: "conversations", className: "mt-0 flex min-h-0 flex-1 flex-col gap-4 data-[state=inactive]:hidden", children: [jsx("div", { className: "flex-shrink-0 rounded-lg border border-neutral-200 p-4", children: jsxs("div", { className: "flex flex-col gap-3 lg:flex-row", children: [jsxs("div", { className: "flex flex-1 flex-wrap gap-3", children: [jsx(AgentFilterSelect, { tenantKey: org, username: username, value: filters.agent, onChange: (agent) => setFilters({ ...filters, agent }) }), jsxs(Popover, { children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", className: "flex h-9 items-center gap-2 bg-transparent font-normal whitespace-nowrap", children: [jsx(Calendar$1, { className: "h-4 w-4" }), ((_b = filters.dateRange) === null || _b === void 0 ? void 0 : _b.from) && ((_c = filters.dateRange) === null || _c === void 0 ? void 0 : _c.to)
|
|
218102
218114
|
? `${format$1(filters.dateRange.from, 'MMM dd')} - ${format$1(filters.dateRange.to, 'MMM dd')}`
|
|
218103
|
-
: t('chatHistoryChatHistoryTab.pickDateRange')] }) }), jsx(PopoverContent, { className: "w-auto p-0", align: "start", portalled: false, children: jsx(Calendar, { mode: "range", selected: filters.dateRange, onSelect: (dateRange) => setFilters({ ...filters, dateRange }), numberOfMonths: 2, initialFocus: true }) })] }), jsxs(Select$1, { value: filters.sentiment || 'all', onValueChange: (value) => setFilters({ ...filters, sentiment: value === 'all' ? '' : value }), children: [jsx(SelectTrigger, { className: "w-40", "aria-label": t('chatHistoryChatHistoryTab.filterBySentiment'), children: jsx(SelectValue, { placeholder: t('chatHistoryChatHistoryTab.allSentiments') }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: t('chatHistoryChatHistoryTab.allSentiments') }), sentimentOptions.map((sentiment) => (jsx(SelectItem, { value: sentiment, children: sentimentLabel(sentiment) }, sentiment)))] })] }), jsxs(Select$1, { value: filters.topic || 'all', onValueChange: (value) => setFilters({ ...filters, topic: value === 'all' ? '' : value }), children: [jsx(SelectTrigger, { className: "w-40", "aria-label": t('chatHistoryChatHistoryTab.filterByTopic'), children: jsx(SelectValue, { placeholder: t('chatHistoryChatHistoryTab.allTopics') }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: t('chatHistoryChatHistoryTab.allTopics') }), ((_d = filterOptions === null || filterOptions === void 0 ? void 0 : filterOptions.topics) !== null && _d !== void 0 ? _d : []).map((topic) => (jsx(SelectItem, { value: topic.name, children: topic.name }, topic.name)))] })] })] }), jsx("div", { className: "w-full lg:w-auto", children: jsxs(Button$1, { variant: "outline", onClick: () => startExport(buildUserChatHistoryReportBody(filters, 'csv')), disabled: isExporting, className: "flex h-9 w-full items-center justify-center gap-2 bg-transparent lg:w-auto", children: [jsx(Download, { className: "h-4 w-4" }), isExporting
|
|
218115
|
+
: t('chatHistoryChatHistoryTab.pickDateRange')] }) }), jsx(PopoverContent, { className: "w-auto p-0", align: "start", portalled: false, children: jsx(Calendar, { mode: "range", selected: filters.dateRange, onSelect: (dateRange) => setFilters({ ...filters, dateRange }), numberOfMonths: 2, initialFocus: true }) })] }), jsxs(Select$1, { value: filters.sentiment || 'all', onValueChange: (value) => setFilters({ ...filters, sentiment: value === 'all' ? '' : value }), children: [jsx(SelectTrigger, { className: "w-40", "aria-label": t('chatHistoryChatHistoryTab.filterBySentiment'), children: jsx(SelectValue, { placeholder: t('chatHistoryChatHistoryTab.allSentiments') }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: t('chatHistoryChatHistoryTab.allSentiments') }), sentimentOptions.map((sentiment) => (jsx(SelectItem, { value: sentiment, children: sentimentLabel(sentiment) }, sentiment)))] })] }), jsxs(Select$1, { value: filters.topic || 'all', onValueChange: (value) => setFilters({ ...filters, topic: value === 'all' ? '' : value }), children: [jsx(SelectTrigger, { className: "w-40", "aria-label": t('chatHistoryChatHistoryTab.filterByTopic'), children: jsx(SelectValue, { placeholder: t('chatHistoryChatHistoryTab.allTopics') }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "all", children: t('chatHistoryChatHistoryTab.allTopics') }), ((_d = filterOptions === null || filterOptions === void 0 ? void 0 : filterOptions.topics) !== null && _d !== void 0 ? _d : []).map((topic) => (jsx(SelectItem, { value: topic.name, children: topic.name }, topic.name)))] })] })] }), jsx("div", { className: "w-full lg:w-auto", children: jsxs(Button$1, { variant: "outline", onClick: () => startExport(buildUserChatHistoryReportBody(filters, 'csv')), disabled: isExporting || isForbidden, className: "flex h-9 w-full items-center justify-center gap-2 bg-transparent lg:w-auto", children: [jsx(Download, { className: "h-4 w-4" }), isExporting
|
|
218104
218116
|
? t('chatHistoryChatHistoryTab.exporting')
|
|
218105
|
-
: t('chatHistoryChatHistoryTab.export')] }) })] }) }), isLoading && (jsx("div", { className: "flex w-full flex-1 items-center justify-center py-10", children: jsx(Spinner, {}) })), isError && !isLoading && (jsx("div", { className: "flex flex-1 flex-col items-center justify-center py-6", children: jsx("p", { className: "text-sm text-gray-600", children:
|
|
218117
|
+
: t('chatHistoryChatHistoryTab.export')] }) })] }) }), isLoading && (jsx("div", { className: "flex w-full flex-1 items-center justify-center py-10", children: jsx(Spinner, {}) })), isError && !isLoading && (jsx("div", { className: "flex flex-1 flex-col items-center justify-center py-6", children: jsx("p", { className: "text-sm text-gray-600", children: isForbidden
|
|
218118
|
+
? t('chatHistoryChatHistoryTab.forbidden')
|
|
218119
|
+
: t('chatHistoryChatHistoryTab.loadFailed') }) })), sessions.length === 0 && !isLoading && !isError && (jsx("div", { className: "flex flex-1 flex-col items-center justify-center py-6", children: jsx("p", { className: "text-sm text-gray-600", children: t('chatHistoryChatHistoryTab.noConversations') }) })), sessions.length > 0 && (jsxs("div", { className: "grid min-h-[320px] flex-1 grid-cols-1 gap-6 md:grid-cols-2", children: [jsxs("div", { className: "col-span-full flex min-h-0 flex-col gap-3 md:col-span-1", children: [jsx("div", { className: "scrollbar-hide min-h-0 flex-1 overflow-y-auto rounded-md border border-neutral-200", tabIndex: 0, role: "region", "aria-label": t('chatHistoryChatHistoryTab.conversationListLabel'), children: sessions.map((session) => {
|
|
218106
218120
|
var _a, _b, _c, _d, _e;
|
|
218107
218121
|
const firstMessage = normalizeMessages(session.messages)[0];
|
|
218108
218122
|
const title = stripMarkdown$1(session.title ||
|
|
@@ -218111,13 +218125,13 @@ function ChatHistoryTab({ org, username }) {
|
|
|
218111
218125
|
t('chatHistoryChatHistoryTab.conversation'));
|
|
218112
218126
|
const preview = stripMarkdown$1((_a = firstMessage === null || firstMessage === void 0 ? void 0 : firstMessage.ai) !== null && _a !== void 0 ? _a : '');
|
|
218113
218127
|
const sentiment = (_c = (_b = session.sentiment) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _c !== void 0 ? _c : '';
|
|
218114
|
-
return (jsxs("div", { role: "button", tabIndex: 0, "data-testid": "history-conversation-row", "data-session-id": session.id, className: cn('flex cursor-pointer items-center justify-between border-b p-4 last:border-b-0', (selectedSession === null || selectedSession === void 0 ? void 0 : selectedSession.id) === session.id ? 'bg-gray-100' : 'hover:bg-gray-50'), onClick: () => handleConversationClick(session), onKeyDown: (event) => {
|
|
218128
|
+
return (jsxs("div", { role: "button", tabIndex: 0, "data-testid": "history-conversation-row", "data-session-id": session.id, className: cn('flex cursor-pointer items-center justify-between border-b border-neutral-200 p-4 last:border-b-0', (selectedSession === null || selectedSession === void 0 ? void 0 : selectedSession.id) === session.id ? 'bg-gray-100' : 'hover:bg-gray-50'), onClick: () => handleConversationClick(session), onKeyDown: (event) => {
|
|
218115
218129
|
if (event.key === 'Enter' || event.key === ' ') {
|
|
218116
218130
|
event.preventDefault();
|
|
218117
218131
|
handleConversationClick(session);
|
|
218118
218132
|
}
|
|
218119
218133
|
}, children: [jsxs("div", { className: "w-full", children: [jsxs("div", { className: "mb-2 flex items-center justify-between gap-2", children: [jsxs("span", { className: "flex items-center gap-2 text-sm text-gray-600", children: [timeAgo(session.inserted_at), sentiment && (jsx(Badge, { variant: "outline", className: cn('font-normal', (_d = SENTIMENT_CLASSES[sentiment]) !== null && _d !== void 0 ? _d : SENTIMENT_CLASSES.neutral), children: sentimentLabel((_e = session.sentiment) !== null && _e !== void 0 ? _e : '') }))] }), jsx("span", { className: "max-w-[100px] truncate text-sm text-gray-900 sm:max-w-[200px]", children: resolveAgent(session).name })] }), jsx("div", { className: "font-medium text-gray-900", children: textTruncate$2(title, 50) }), preview && (jsx("p", { className: "line-clamp-1 text-sm text-gray-600", children: textTruncate$2(preview, 60) }))] }), jsx("div", { className: "flex items-center gap-2 text-sm text-gray-600", children: jsx(ChevronRight, { className: "h-4 w-4" }) })] }, session.id));
|
|
218120
|
-
}) }), totalPages > 1 && (jsx("div", { className: "flex-shrink-0", children: jsx(IblPagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage, disabled: isFetching || isLoading, disableNumberedButtons: isMobile }) }))] }), jsx("div", { className: "scrollbar-hide hidden min-h-0 flex-col overflow-y-auto rounded-lg border bg-white p-6 shadow-sm md:flex", tabIndex: 0, role: "region", "aria-label": t('chatHistoryChatHistoryTab.conversationPreviewLabel'), children: selectedSession ? (jsx(ConversationPreview, { org: org, username: username, session: selectedSession, agent: resolveAgent(selectedSession) })) : (jsx("div", { className: "flex h-full items-center justify-center text-gray-500", children: t('chatHistoryChatHistoryTab.selectPrompt') })) })] })), jsx(Dialog, { open: isPreviewModalOpen, onOpenChange: setIsPreviewModalOpen, children: jsxs(DialogContent, { className: "scrollbar-hide mx-auto max-h-[80vh] max-w-[90vw] overflow-x-hidden overflow-y-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "text-lg font-semibold text-gray-900", children: selectedSession
|
|
218134
|
+
}) }), totalPages > 1 && (jsx("div", { className: "flex-shrink-0", children: jsx(IblPagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage, disabled: isFetching || isLoading, disableNumberedButtons: isMobile }) }))] }), jsx("div", { className: "scrollbar-hide hidden min-h-0 flex-col overflow-y-auto rounded-lg border border-neutral-200 bg-white p-6 shadow-sm md:flex", tabIndex: 0, role: "region", "aria-label": t('chatHistoryChatHistoryTab.conversationPreviewLabel'), children: selectedSession ? (jsx(ConversationPreview, { org: org, username: username, session: selectedSession, agent: resolveAgent(selectedSession) })) : (jsx("div", { className: "flex h-full items-center justify-center text-gray-500", children: t('chatHistoryChatHistoryTab.selectPrompt') })) })] })), jsx(Dialog, { open: isPreviewModalOpen, onOpenChange: setIsPreviewModalOpen, children: jsxs(DialogContent, { className: "scrollbar-hide mx-auto max-h-[80vh] max-w-[90vw] overflow-x-hidden overflow-y-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "text-lg font-semibold text-gray-900", children: selectedSession
|
|
218121
218135
|
? stripMarkdown$1(selectedSession.title || t('chatHistoryChatHistoryTab.conversation'))
|
|
218122
218136
|
: t('chatHistoryChatHistoryTab.conversation') }) }), jsx("div", { className: "mx-auto max-w-full overflow-x-hidden", children: selectedSession && (jsx(ConversationPreview, { org: org, username: username, session: selectedSession, agent: resolveAgent(selectedSession) })) })] }) })] }), jsx(TabsContent, { value: "exports", className: "mt-0 min-h-0 flex-1 overflow-y-auto data-[state=inactive]:hidden", children: jsx(ReportHistory, { org: org, username: username, onDownload: downloadFromUrl }) })] }));
|
|
218123
218137
|
}
|
|
@@ -218184,6 +218198,12 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
|
|
|
218184
218198
|
const isPurchasesEnabled = currentTenant === null || currentTenant === void 0 ? void 0 : currentTenant.enable_monetization;
|
|
218185
218199
|
const isGradebookEnabled = customization.showGradebookTab;
|
|
218186
218200
|
const isReadOnly = useIsProfilePreview(username);
|
|
218201
|
+
// The chat-history endpoints serve the user themselves, tenant admins and
|
|
218202
|
+
// watchers (for the users they watch), so the History tab stays on your own
|
|
218203
|
+
// profile and appears on someone else's only for admin/watcher viewers.
|
|
218204
|
+
const rbacPermissions = useSelector(selectRbacPermissions);
|
|
218205
|
+
const { currentTenant: viewerTenant } = useCurrentTenant();
|
|
218206
|
+
const isChatHistoryVisible = !isReadOnly || canViewOtherUsersChatHistory(rbacPermissions, viewerTenant);
|
|
218187
218207
|
const baseTabs = [
|
|
218188
218208
|
{ id: 'basic', label: t('profileIndex.tabBasic'), renderIcon: renderLucideIcon(User) },
|
|
218189
218209
|
{ id: 'social', label: t('profileIndex.tabSocial'), renderIcon: renderLucideIcon(Globe) },
|
|
@@ -218237,9 +218257,7 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
|
|
|
218237
218257
|
},
|
|
218238
218258
|
]
|
|
218239
218259
|
: []),
|
|
218240
|
-
|
|
218241
|
-
// sessions, so the tab is hidden when previewing someone else's profile.
|
|
218242
|
-
...(!isReadOnly
|
|
218260
|
+
...(isChatHistoryVisible
|
|
218243
218261
|
? [
|
|
218244
218262
|
{
|
|
218245
218263
|
id: 'chatHistory',
|
|
@@ -218425,7 +218443,7 @@ function Profile({ tenant, username, tenants, onClose, customization = {}, isAdm
|
|
|
218425
218443
|
var _a;
|
|
218426
218444
|
return (jsxs(Fragment$1, { children: [jsxs("div", { className: "relative mb-0", children: [jsx("div", { className: "absolute inset-y-0 left-4 flex items-center pointer-events-none", "aria-hidden": "true", children: jsx("div", { className: "bg-black text-white rounded w-8 h-8 flex items-center justify-center", children: jsx("span", { className: "font-bold text-sm", children: "X" }) }) }), jsx(Input, { id: "x", className: "w-full bg-gray-50 border-gray-200 focus:ring-blue-500 focus:border-blue-500 text-base py-3 pl-16 h-10", placeholder: t('profileIndex.placeholderX'), value: field.state.value, onChange: (e) => handleSocialLinkChange(e.target.value, field.handleChange, X_URL_PREFIX), disabled: socialForm.state.isSubmitting || isReadOnly })] }), jsx("p", { className: "text-red-500 dark:text-gray-400 text-sm", role: ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) ? 'alert' : undefined, "aria-live": "polite", children: field.state.meta.errors })] }));
|
|
218427
218445
|
},
|
|
218428
|
-
})] })] }) })), activeTab === 'education' && (jsxs(Tabs, { value: educationSubTab, onValueChange: setEducationSubTab, className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "education", children: t('profileIndex.tabEducation') }), jsx(TabsTrigger, { value: "credentials", children: t('gradebookGradebookTab.typeCredentials') }), jsx(TabsTrigger, { value: "skills", children: t('gradebookGradebookTab.typeSkills') })] }), headerAddButton] }), jsx(TabsContent, { value: "education", children: jsx(EducationTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "credentials", children: jsx(CredentialsList, { org: tenant, username: username }) }), jsx(TabsContent, { value: "skills", children: jsx(SkillsList, { org: tenant, username: username }) })] })), activeTab === 'gradebook' && jsx(GradebookTab, { org: tenant, username: username }), activeTab === 'experience' && (jsxs(Tabs, { value: experienceSubTab, onValueChange: setExperienceSubTab, className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "experience", children: t('profileIndex.tabExperience') }), jsx(TabsTrigger, { value: "resume", children: t('profileIndex.tabResume') })] }), headerAddButton] }), jsx(TabsContent, { value: "experience", children: jsx(ExperienceTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "resume", children: jsx(ResumeTab, { org: tenant, username: username }) })] })), activeTab === 'purchases' && jsx(PurchasesTab, { org: tenant, username: username }), activeTab === 'memory' && jsx(MemoryTab, { org: tenant, username: username }), activeTab === 'privacy' && jsx(ChatPrivacyTab, { org: tenant, username: username }),
|
|
218446
|
+
})] })] }) })), activeTab === 'education' && (jsxs(Tabs, { value: educationSubTab, onValueChange: setEducationSubTab, className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "education", children: t('profileIndex.tabEducation') }), jsx(TabsTrigger, { value: "credentials", children: t('gradebookGradebookTab.typeCredentials') }), jsx(TabsTrigger, { value: "skills", children: t('gradebookGradebookTab.typeSkills') })] }), headerAddButton] }), jsx(TabsContent, { value: "education", children: jsx(EducationTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "credentials", children: jsx(CredentialsList, { org: tenant, username: username }) }), jsx(TabsContent, { value: "skills", children: jsx(SkillsList, { org: tenant, username: username }) })] })), activeTab === 'gradebook' && jsx(GradebookTab, { org: tenant, username: username }), activeTab === 'experience' && (jsxs(Tabs, { value: experienceSubTab, onValueChange: setExperienceSubTab, className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxs(TabsList, { children: [jsx(TabsTrigger, { value: "experience", children: t('profileIndex.tabExperience') }), jsx(TabsTrigger, { value: "resume", children: t('profileIndex.tabResume') })] }), headerAddButton] }), jsx(TabsContent, { value: "experience", children: jsx(ExperienceTab, { org: tenant, username: username }) }), jsx(TabsContent, { value: "resume", children: jsx(ResumeTab, { org: tenant, username: username }) })] })), activeTab === 'purchases' && jsx(PurchasesTab, { org: tenant, username: username }), activeTab === 'memory' && jsx(MemoryTab, { org: tenant, username: username }), activeTab === 'privacy' && jsx(ChatPrivacyTab, { org: tenant, username: username }), isChatHistoryVisible && activeTab === 'chatHistory' && (jsx(ChatHistoryTab, { org: tenant, username: username })), !isReadOnly && activeTab === 'security' && (jsx(Security, { app: currentSPA || '', email: (userMetadata === null || userMetadata === void 0 ? void 0 : userMetadata.email) || '', platformKey: tenant, onAccountDeleted: onAccountDeleted })), activeTab === 'advanced' && localLLMProps && (jsx("div", { className: "space-y-6", children: jsx(LocalModelsContent, { isAvailable: localLLMProps.isAvailable, state: localLLMProps.state, ollamaStatus: localLLMProps.ollamaStatus, systemMemory: localLLMProps.systemMemory, isUsingFoundry: localLLMProps.isUsingFoundry, foundryModels: localLLMProps.foundryModels, selectedFoundryModel: localLLMProps.selectedFoundryModel, foundryStatus: localLLMProps.foundryStatus, onStartDownload: localLLMProps.onStartDownload, onCancelDownload: localLLMProps.onCancelDownload, onInstallOllama: localLLMProps.onInstallOllama, onStopManager: localLLMProps.onStopManager, onInstallFoundry: localLLMProps.onInstallFoundry, onCheckStatus: localLLMProps.onCheckStatus, onResetState: localLLMProps.onResetState, onSelectFoundryModel: localLLMProps.onSelectFoundryModel }) }))] }), !isReadOnly && ['basic', 'social'].includes(activeTab) && (jsx("div", { className: "flex-shrink-0 border-t border-gray-200 p-6 bg-white dark:bg-gray-900", children: jsxs("div", { className: "flex justify-end gap-3", children: [jsx(Button$1, { onClick: onClose, variant: "outline", children: t('profileIndex.buttonCancel') }), jsx(Button$1, { onClick: () => {
|
|
218429
218447
|
if (activeTab === 'basic') {
|
|
218430
218448
|
basicForm.handleSubmit();
|
|
218431
218449
|
}
|
|
@@ -229471,6 +229489,514 @@ function MonetizationTab({ platformKey, authURL }) {
|
|
|
229471
229489
|
return (jsxs("div", { className: "container mx-auto max-w-7xl !mt-0 space-y-6", children: [isOwner && jsx(StripeConnect, { platformKey: platformKey }), jsx(PaywallConfig, { platformKey: platformKey, authURL: authURL, disabled: !isStripeReady })] }));
|
|
229472
229490
|
}
|
|
229473
229491
|
|
|
229492
|
+
/** Matches the server-side cap on the global memories listing. */
|
|
229493
|
+
const PAGE_SIZE$9 = 25;
|
|
229494
|
+
/**
|
|
229495
|
+
* Popup for managing one user's global memories. Reads them the way the
|
|
229496
|
+
* profile preview does — the caller in the path, the managed user identified
|
|
229497
|
+
* by their id (username) in `user_id` — while writes address the managed
|
|
229498
|
+
* user's path directly, which the backend resolves for admin/RBAC callers.
|
|
229499
|
+
* The list itself is the same {@link MemoriesList} the profile Memory tab
|
|
229500
|
+
* renders.
|
|
229501
|
+
*/
|
|
229502
|
+
function UserMemoriesModal({ isOpen, onClose, tenantKey, adminUsername, user, }) {
|
|
229503
|
+
var _a, _b, _c;
|
|
229504
|
+
const t = useT();
|
|
229505
|
+
const [page, setPage] = useState(1);
|
|
229506
|
+
const [showAdd, setShowAdd] = useState(false);
|
|
229507
|
+
const [editingMemory, setEditingMemory] = useState(null);
|
|
229508
|
+
const [deletingId, setDeletingId] = useState(null);
|
|
229509
|
+
const { data: memoriesData, isLoading, error, } = useGetGlobalMemoriesQuery({
|
|
229510
|
+
org: tenantKey,
|
|
229511
|
+
userId: adminUsername,
|
|
229512
|
+
// `user_id` must be the managed user's id (username) — the backend does
|
|
229513
|
+
// not resolve emails here, so passing one returns an empty list.
|
|
229514
|
+
params: { page, page_size: PAGE_SIZE$9, user_id: user.username },
|
|
229515
|
+
});
|
|
229516
|
+
const memories = (_a = memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.results) !== null && _a !== void 0 ? _a : [];
|
|
229517
|
+
const totalPages = (memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.count) ? Math.ceil(memoriesData.count / PAGE_SIZE$9) : 0;
|
|
229518
|
+
const isForbidden = !!error && error.status === 403;
|
|
229519
|
+
// The managed user's capture/personalization toggles, addressed through
|
|
229520
|
+
// their path the way every admin write here is. Hidden unless they load.
|
|
229521
|
+
const { data: settings } = useGetUserMemorySettingsQuery({
|
|
229522
|
+
org: tenantKey,
|
|
229523
|
+
userId: user.username,
|
|
229524
|
+
});
|
|
229525
|
+
const [updateSettings, { isLoading: isUpdatingSettings }] = useUpdateUserMemorySettingsMutation();
|
|
229526
|
+
const handleToggleSetting = async (key, checked) => {
|
|
229527
|
+
try {
|
|
229528
|
+
await updateSettings({
|
|
229529
|
+
org: tenantKey,
|
|
229530
|
+
userId: user.username,
|
|
229531
|
+
settings: { [key]: checked },
|
|
229532
|
+
}).unwrap();
|
|
229533
|
+
toast.success(t('memoryMemoryTab.memorySettingUpdated'));
|
|
229534
|
+
}
|
|
229535
|
+
catch (_a) {
|
|
229536
|
+
toast.error(t('memoryMemoryTab.failedToUpdateMemorySetting'));
|
|
229537
|
+
}
|
|
229538
|
+
};
|
|
229539
|
+
const [deleteMemory] = useDeleteGlobalMemoryMutation();
|
|
229540
|
+
const handleDeleteMemory = async (memory) => {
|
|
229541
|
+
setDeletingId(memory.id);
|
|
229542
|
+
try {
|
|
229543
|
+
await deleteMemory({
|
|
229544
|
+
org: tenantKey,
|
|
229545
|
+
userId: user.username,
|
|
229546
|
+
memoryId: memory.id,
|
|
229547
|
+
}).unwrap();
|
|
229548
|
+
toast.success(t('memoryAdminUserMemoriesModal.memoryDeleted'));
|
|
229549
|
+
}
|
|
229550
|
+
catch (deleteError) {
|
|
229551
|
+
if ((deleteError === null || deleteError === void 0 ? void 0 : deleteError.status) === 403) {
|
|
229552
|
+
toast.error(t('memoryAdminTab.forbidden'));
|
|
229553
|
+
}
|
|
229554
|
+
else {
|
|
229555
|
+
toast.error(t('memoryAdminUserMemoriesModal.failedToDeleteMemory'));
|
|
229556
|
+
}
|
|
229557
|
+
}
|
|
229558
|
+
finally {
|
|
229559
|
+
setDeletingId(null);
|
|
229560
|
+
}
|
|
229561
|
+
};
|
|
229562
|
+
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', {
|
|
229563
|
+
state: settings.auto_capture_enabled
|
|
229564
|
+
? t('memoryMemoryTab.stateEnabled')
|
|
229565
|
+
: t('memoryMemoryTab.stateDisabled'),
|
|
229566
|
+
}), 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', {
|
|
229567
|
+
state: settings.use_memory_in_responses
|
|
229568
|
+
? t('memoryMemoryTab.stateEnabled')
|
|
229569
|
+
: t('memoryMemoryTab.stateDisabled'),
|
|
229570
|
+
}), 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 }))] }) }));
|
|
229571
|
+
}
|
|
229572
|
+
|
|
229573
|
+
const PAGE_SIZE$8 = 10;
|
|
229574
|
+
const SEARCH_DEBOUNCE_MS = 300;
|
|
229575
|
+
/**
|
|
229576
|
+
* Tenant users table with server-side search. Opening a row shows that user's
|
|
229577
|
+
* global memories in a popup where the admin can manage them.
|
|
229578
|
+
*/
|
|
229579
|
+
function GlobalMemoriesSection({ tenantKey, username }) {
|
|
229580
|
+
var _a;
|
|
229581
|
+
const t = useT();
|
|
229582
|
+
const [page, setPage] = useState(1);
|
|
229583
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
229584
|
+
const [debouncedSearch, setDebouncedSearch] = useState(searchQuery);
|
|
229585
|
+
const [selectedUser, setSelectedUser] = useState(null);
|
|
229586
|
+
// Same debounce contract as the Management tab's user search: terms shorter
|
|
229587
|
+
// than three characters search as empty. Bailing out on an unchanged value
|
|
229588
|
+
// keeps the mount-time timer from resetting a page the user already turned.
|
|
229589
|
+
useEffect(() => {
|
|
229590
|
+
const handler = setTimeout(() => {
|
|
229591
|
+
setDebouncedSearch((previous) => {
|
|
229592
|
+
const next = searchQuery.length > 2 ? searchQuery : '';
|
|
229593
|
+
return previous === next ? previous : next;
|
|
229594
|
+
});
|
|
229595
|
+
}, SEARCH_DEBOUNCE_MS);
|
|
229596
|
+
return () => clearTimeout(handler);
|
|
229597
|
+
}, [searchQuery]);
|
|
229598
|
+
// A new search term invalidates the current page index.
|
|
229599
|
+
useEffect(() => {
|
|
229600
|
+
setPage(1);
|
|
229601
|
+
}, [debouncedSearch]);
|
|
229602
|
+
const { data, isLoading, isFetching, error } = usePlatformUsersQuery({
|
|
229603
|
+
platform_key: tenantKey,
|
|
229604
|
+
platform_org: tenantKey,
|
|
229605
|
+
page,
|
|
229606
|
+
page_size: PAGE_SIZE$8,
|
|
229607
|
+
query: debouncedSearch,
|
|
229608
|
+
return_policies: 'false',
|
|
229609
|
+
});
|
|
229610
|
+
const users = useMemo(() => {
|
|
229611
|
+
var _a;
|
|
229612
|
+
// `results` is a bare array unless policies were requested, in which case
|
|
229613
|
+
// the users sit under `results.data`.
|
|
229614
|
+
const results = data === null || data === void 0 ? void 0 : data.results;
|
|
229615
|
+
const platformUsers = Array.isArray(results)
|
|
229616
|
+
? results
|
|
229617
|
+
: ((_a = results === null || results === void 0 ? void 0 : results.data) !== null && _a !== void 0 ? _a : []);
|
|
229618
|
+
// A user without a username cannot be addressed by the memory endpoints.
|
|
229619
|
+
return platformUsers
|
|
229620
|
+
.filter((user) => !!user.username)
|
|
229621
|
+
.map((user) => ({
|
|
229622
|
+
username: user.username,
|
|
229623
|
+
name: user.name,
|
|
229624
|
+
email: user.email,
|
|
229625
|
+
}));
|
|
229626
|
+
}, [data]);
|
|
229627
|
+
const totalPages = Math.ceil(((_a = data === null || data === void 0 ? void 0 : data.count) !== null && _a !== void 0 ? _a : 0) / PAGE_SIZE$8);
|
|
229628
|
+
const isForbidden = !!error && error.status === 403;
|
|
229629
|
+
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', {
|
|
229630
|
+
name: user.email || user.username,
|
|
229631
|
+
}), 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 }))] }));
|
|
229632
|
+
}
|
|
229633
|
+
|
|
229634
|
+
const EditMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return editMemoryModal; }).then((module) => ({
|
|
229635
|
+
default: module.EditMemoryModal,
|
|
229636
|
+
})), { ssr: false });
|
|
229637
|
+
const AddMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return addMemoryModal; }).then((module) => ({
|
|
229638
|
+
default: module.AddMemoryModal,
|
|
229639
|
+
})), { ssr: false });
|
|
229640
|
+
const DeleteMemoryModal = dynamic(() => Promise.resolve().then(function () { return deleteMemoryModal; }).then((module) => ({
|
|
229641
|
+
default: module.DeleteMemoryModal,
|
|
229642
|
+
})), { ssr: false });
|
|
229643
|
+
const BulkDeleteMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return bulkDeleteMemoryModal; }).then((module) => ({
|
|
229644
|
+
default: module.BulkDeleteMemoryModal,
|
|
229645
|
+
})), { ssr: false });
|
|
229646
|
+
const ManageCategoriesModal$1 = dynamic(() => Promise.resolve().then(function () { return manageCategoriesModal; }).then((module) => ({
|
|
229647
|
+
default: module.ManageCategoriesModal,
|
|
229648
|
+
})), { ssr: false });
|
|
229649
|
+
const PAGE_SIZE$7 = 20;
|
|
229650
|
+
const SNAPSHOT_PAGE_SIZE = 1000;
|
|
229651
|
+
function ManageMemories({ tenantKey, username, mentorId }) {
|
|
229652
|
+
var _a, _b, _c, _d, _e;
|
|
229653
|
+
const t = useT();
|
|
229654
|
+
const [selectedLearner, setSelectedLearner] = useState('');
|
|
229655
|
+
const [dateRange, setDateRange] = useState(undefined);
|
|
229656
|
+
const [selectedCategorySlug, setSelectedCategorySlug] = useState('all');
|
|
229657
|
+
const [page, setPage] = useState(1);
|
|
229658
|
+
// Reset to page 1 whenever any filter changes — otherwise we could land on a
|
|
229659
|
+
// page index that no longer exists in the new result set.
|
|
229660
|
+
useEffect(() => {
|
|
229661
|
+
setPage(1);
|
|
229662
|
+
}, [selectedLearner, dateRange, selectedCategorySlug]);
|
|
229663
|
+
const listParams = useMemo(() => {
|
|
229664
|
+
const params = { page, page_size: PAGE_SIZE$7 };
|
|
229665
|
+
if (selectedLearner)
|
|
229666
|
+
params.email = selectedLearner;
|
|
229667
|
+
if (selectedCategorySlug !== 'all')
|
|
229668
|
+
params.category = selectedCategorySlug;
|
|
229669
|
+
if (dateRange === null || dateRange === void 0 ? void 0 : dateRange.from)
|
|
229670
|
+
params.start_date = format$1(dateRange.from, 'yyyy-MM-dd');
|
|
229671
|
+
if (dateRange === null || dateRange === void 0 ? void 0 : dateRange.to)
|
|
229672
|
+
params.end_date = format$1(dateRange.to, 'yyyy-MM-dd');
|
|
229673
|
+
return params;
|
|
229674
|
+
}, [page, selectedLearner, selectedCategorySlug, dateRange]);
|
|
229675
|
+
const { data: listResponse, isLoading: isLoadingMemories } = useGetMentorMemoriesListQuery({
|
|
229676
|
+
org: tenantKey,
|
|
229677
|
+
userId: username !== null && username !== void 0 ? username : '',
|
|
229678
|
+
mentorId,
|
|
229679
|
+
params: listParams,
|
|
229680
|
+
}, {
|
|
229681
|
+
skip: !tenantKey || !username || !mentorId,
|
|
229682
|
+
});
|
|
229683
|
+
const totalPages = Math.max(1, Math.ceil(((_a = listResponse === null || listResponse === void 0 ? void 0 : listResponse.count) !== null && _a !== void 0 ? _a : 0) / PAGE_SIZE$7));
|
|
229684
|
+
const { data: adminCategories } = useGetMemoryCategoriesAdminQuery({
|
|
229685
|
+
org: tenantKey,
|
|
229686
|
+
mentorId,
|
|
229687
|
+
}, {
|
|
229688
|
+
skip: !tenantKey || !mentorId,
|
|
229689
|
+
});
|
|
229690
|
+
const [deleteMentorMemory, { isLoading: isDeleting }] = useDeleteMentorMemoryMutation();
|
|
229691
|
+
const [updateMentorMemory, { isLoading: isEditing }] = useUpdateMentorMemoryMutation();
|
|
229692
|
+
const [createMentorMemory, { isLoading: isSaving }] = useCreateMentorMemoryMutation();
|
|
229693
|
+
// Flat list of memories on the current page, mapped into the local `Memory`
|
|
229694
|
+
// shape used by the rest of this component.
|
|
229695
|
+
const memories = useMemo(() => {
|
|
229696
|
+
if (!(listResponse === null || listResponse === void 0 ? void 0 : listResponse.results))
|
|
229697
|
+
return [];
|
|
229698
|
+
return listResponse.results.map((memory) => ({
|
|
229699
|
+
id: memory.id,
|
|
229700
|
+
content: memory.content,
|
|
229701
|
+
category: {
|
|
229702
|
+
id: memory.category.id,
|
|
229703
|
+
name: memory.category.name,
|
|
229704
|
+
slug: memory.category.slug,
|
|
229705
|
+
},
|
|
229706
|
+
email: memory.email,
|
|
229707
|
+
createdAt: memory.created_at,
|
|
229708
|
+
}));
|
|
229709
|
+
}, [listResponse]);
|
|
229710
|
+
// Unfiltered snapshot used to derive the learner dropdown and to source the
|
|
229711
|
+
// bulk-delete operation, which needs the full set of memories — not just the
|
|
229712
|
+
// current page.
|
|
229713
|
+
const { data: snapshotResponse } = useGetMentorMemoriesListQuery({
|
|
229714
|
+
org: tenantKey,
|
|
229715
|
+
userId: username !== null && username !== void 0 ? username : '',
|
|
229716
|
+
mentorId,
|
|
229717
|
+
params: { page: 1, page_size: SNAPSHOT_PAGE_SIZE },
|
|
229718
|
+
}, {
|
|
229719
|
+
skip: !tenantKey || !username || !mentorId,
|
|
229720
|
+
});
|
|
229721
|
+
const learners = useMemo(() => {
|
|
229722
|
+
if (!(snapshotResponse === null || snapshotResponse === void 0 ? void 0 : snapshotResponse.results))
|
|
229723
|
+
return [];
|
|
229724
|
+
const emailSet = new Set();
|
|
229725
|
+
snapshotResponse.results.forEach((m) => {
|
|
229726
|
+
if (m.email)
|
|
229727
|
+
emailSet.add(m.email);
|
|
229728
|
+
});
|
|
229729
|
+
return Array.from(emailSet).map((email) => ({ email }));
|
|
229730
|
+
}, [snapshotResponse]);
|
|
229731
|
+
const categories = useMemo(() => {
|
|
229732
|
+
if (adminCategories && adminCategories.length > 0) {
|
|
229733
|
+
return [
|
|
229734
|
+
{ id: 0, name: 'All', slug: 'all' },
|
|
229735
|
+
...adminCategories.map((cat) => ({
|
|
229736
|
+
id: cat.id,
|
|
229737
|
+
name: cat.name,
|
|
229738
|
+
slug: cat.slug,
|
|
229739
|
+
})),
|
|
229740
|
+
];
|
|
229741
|
+
}
|
|
229742
|
+
return [{ id: 0, name: 'All', slug: 'all' }];
|
|
229743
|
+
}, [adminCategories]);
|
|
229744
|
+
const [editingMemory, setEditingMemory] = useState(null);
|
|
229745
|
+
const [editContent, setEditContent] = useState('');
|
|
229746
|
+
const [editCategory, setEditCategory] = useState('');
|
|
229747
|
+
const [showDeleteConfirm, setShowDeleteConfirm] = useState(null);
|
|
229748
|
+
const [showAddMemory, setShowAddMemory] = useState(false);
|
|
229749
|
+
const [newMemoryContent, setNewMemoryContent] = useState('');
|
|
229750
|
+
const [newMemoryCategory, setNewMemoryCategory] = useState('');
|
|
229751
|
+
const [showMobileDropdown, setShowMobileDropdown] = useState(false);
|
|
229752
|
+
const [showBulkDeleteConfirm, setShowBulkDeleteConfirm] = useState(false);
|
|
229753
|
+
const [isBulkDeleting, setIsBulkDeleting] = useState(false);
|
|
229754
|
+
const [showManageCategories, setShowManageCategories] = useState(false);
|
|
229755
|
+
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');
|
|
229756
|
+
const VISIBLE_CATEGORY_LIMIT = 6;
|
|
229757
|
+
const visibleCategories = categories.slice(0, VISIBLE_CATEGORY_LIMIT);
|
|
229758
|
+
const overflowCategories = categories.slice(VISIBLE_CATEGORY_LIMIT);
|
|
229759
|
+
const overflowSelected = overflowCategories.find((c) => c.slug === selectedCategorySlug);
|
|
229760
|
+
// Category is filtered server-side via the `category` query param now, so
|
|
229761
|
+
// `memories` already contains only the relevant entries for the page.
|
|
229762
|
+
const filteredMemories = memories;
|
|
229763
|
+
const handleDeleteMemory = async (id) => {
|
|
229764
|
+
if (!tenantKey || !username)
|
|
229765
|
+
return;
|
|
229766
|
+
try {
|
|
229767
|
+
await deleteMentorMemory({
|
|
229768
|
+
org: tenantKey,
|
|
229769
|
+
userId: username,
|
|
229770
|
+
mentorId,
|
|
229771
|
+
memoryId: id,
|
|
229772
|
+
}).unwrap();
|
|
229773
|
+
setShowDeleteConfirm(null);
|
|
229774
|
+
toast.success(t('memoryTabManageMemories.memoryDeletedSuccessfully'));
|
|
229775
|
+
}
|
|
229776
|
+
catch (error) {
|
|
229777
|
+
console.error('Failed to delete memory:', error);
|
|
229778
|
+
toast.error(t('memoryTabManageMemories.failedToDeleteMemory'));
|
|
229779
|
+
}
|
|
229780
|
+
};
|
|
229781
|
+
const handleBulkDelete = async () => {
|
|
229782
|
+
var _a;
|
|
229783
|
+
if (!tenantKey || !username)
|
|
229784
|
+
return;
|
|
229785
|
+
setIsBulkDeleting(true);
|
|
229786
|
+
try {
|
|
229787
|
+
// Source bulk-delete from the unfiltered snapshot — `memories` only holds
|
|
229788
|
+
// the current page, while bulk delete must remove every entry in the
|
|
229789
|
+
// selected category.
|
|
229790
|
+
const memoriesToDelete = ((_a = snapshotResponse === null || snapshotResponse === void 0 ? void 0 : snapshotResponse.results) !== null && _a !== void 0 ? _a : []).filter((memory) => memory.category.slug === selectedCategorySlug);
|
|
229791
|
+
await Promise.all(memoriesToDelete.map((memory) => deleteMentorMemory({
|
|
229792
|
+
org: tenantKey,
|
|
229793
|
+
userId: username,
|
|
229794
|
+
mentorId,
|
|
229795
|
+
memoryId: memory.id,
|
|
229796
|
+
}).unwrap()));
|
|
229797
|
+
toast.success(t('memoryTabManageMemories.allCategoryMemoriesDeleted', { category: selectedCategoryName }));
|
|
229798
|
+
setShowBulkDeleteConfirm(false);
|
|
229799
|
+
}
|
|
229800
|
+
catch (error) {
|
|
229801
|
+
console.error('Failed to delete memories:', error);
|
|
229802
|
+
toast.error(t('memoryTabManageMemories.failedToDeleteMemories'));
|
|
229803
|
+
}
|
|
229804
|
+
finally {
|
|
229805
|
+
setIsBulkDeleting(false);
|
|
229806
|
+
}
|
|
229807
|
+
};
|
|
229808
|
+
const startEdit = (memory) => {
|
|
229809
|
+
setEditingMemory(memory);
|
|
229810
|
+
setEditContent(memory.content);
|
|
229811
|
+
setEditCategory(memory.category.name);
|
|
229812
|
+
};
|
|
229813
|
+
const saveEdit = async () => {
|
|
229814
|
+
if (!editingMemory || !tenantKey || !username)
|
|
229815
|
+
return;
|
|
229816
|
+
try {
|
|
229817
|
+
const selectedCat = categories.find((c) => c.name === editCategory);
|
|
229818
|
+
const categoryChanged = !!selectedCat && selectedCat.slug !== editingMemory.category.slug;
|
|
229819
|
+
await updateMentorMemory({
|
|
229820
|
+
org: tenantKey,
|
|
229821
|
+
userId: username,
|
|
229822
|
+
mentorId,
|
|
229823
|
+
memoryId: editingMemory.id,
|
|
229824
|
+
data: {
|
|
229825
|
+
content: editContent,
|
|
229826
|
+
...(categoryChanged ? { category_slug: selectedCat.slug } : {}),
|
|
229827
|
+
},
|
|
229828
|
+
}).unwrap();
|
|
229829
|
+
toast.success(t('memoryTabManageMemories.memoryUpdatedSuccessfully'));
|
|
229830
|
+
// Follow the entry to its new category tab so the user doesn't lose
|
|
229831
|
+
// sight of it. Skip when viewing "All" — the entry is still visible.
|
|
229832
|
+
if (categoryChanged && selectedCategorySlug !== 'all') {
|
|
229833
|
+
setSelectedCategorySlug(selectedCat.slug);
|
|
229834
|
+
}
|
|
229835
|
+
setEditingMemory(null);
|
|
229836
|
+
setEditContent('');
|
|
229837
|
+
setEditCategory('');
|
|
229838
|
+
}
|
|
229839
|
+
catch (error) {
|
|
229840
|
+
console.error('Failed to update memory:', error);
|
|
229841
|
+
toast.error(t('memoryTabManageMemories.failedToUpdateMemory'));
|
|
229842
|
+
}
|
|
229843
|
+
};
|
|
229844
|
+
const cancelEdit = () => {
|
|
229845
|
+
setEditingMemory(null);
|
|
229846
|
+
setEditContent('');
|
|
229847
|
+
setEditCategory('');
|
|
229848
|
+
};
|
|
229849
|
+
const startAddMemory = () => {
|
|
229850
|
+
setShowAddMemory(true);
|
|
229851
|
+
setNewMemoryCategory(selectedCategoryName);
|
|
229852
|
+
};
|
|
229853
|
+
const saveNewMemory = async () => {
|
|
229854
|
+
var _a;
|
|
229855
|
+
if (!newMemoryContent.trim() || !tenantKey || !username)
|
|
229856
|
+
return;
|
|
229857
|
+
try {
|
|
229858
|
+
const selectedCat = categories.find((c) => c.name === newMemoryCategory);
|
|
229859
|
+
const categorySlug = (_a = selectedCat === null || selectedCat === void 0 ? void 0 : selectedCat.slug) !== null && _a !== void 0 ? _a : selectedCategorySlug;
|
|
229860
|
+
await createMentorMemory({
|
|
229861
|
+
org: tenantKey,
|
|
229862
|
+
userId: username,
|
|
229863
|
+
mentorId,
|
|
229864
|
+
data: {
|
|
229865
|
+
category_slug: categorySlug === 'all' ? 'general' : categorySlug,
|
|
229866
|
+
content: newMemoryContent.trim(),
|
|
229867
|
+
},
|
|
229868
|
+
}).unwrap();
|
|
229869
|
+
setShowAddMemory(false);
|
|
229870
|
+
setNewMemoryContent('');
|
|
229871
|
+
setNewMemoryCategory('');
|
|
229872
|
+
if (selectedCat) {
|
|
229873
|
+
setSelectedCategorySlug(selectedCat.slug);
|
|
229874
|
+
}
|
|
229875
|
+
toast.success(t('memoryTabManageMemories.memoryCreatedSuccessfully'));
|
|
229876
|
+
}
|
|
229877
|
+
catch (error) {
|
|
229878
|
+
console.error('Failed to create memory:', error);
|
|
229879
|
+
toast.error(t('memoryTabManageMemories.failedToCreateMemory'));
|
|
229880
|
+
}
|
|
229881
|
+
};
|
|
229882
|
+
const cancelAddMemory = () => {
|
|
229883
|
+
setShowAddMemory(false);
|
|
229884
|
+
setNewMemoryContent('');
|
|
229885
|
+
setNewMemoryCategory('');
|
|
229886
|
+
};
|
|
229887
|
+
const categoryNames = categories.map((c) => c.name);
|
|
229888
|
+
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
|
|
229889
|
+
? ((_e = (_d = learners.find((learner) => learner.email === selectedLearner)) === null || _d === void 0 ? void 0 : _d.email) !== null && _e !== void 0 ? _e : selectedLearner)
|
|
229890
|
+
: 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: () => {
|
|
229891
|
+
setSelectedLearner('');
|
|
229892
|
+
}, 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: () => {
|
|
229893
|
+
setSelectedLearner(learner.email);
|
|
229894
|
+
}, 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)
|
|
229895
|
+
? `${format$1(dateRange.from, 'MMM dd')} - ${format$1(dateRange.to, 'MMM dd')}`
|
|
229896
|
+
: 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
|
|
229897
|
+
? 'text-[#38A1E5]'
|
|
229898
|
+
: '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: {
|
|
229899
|
+
width: `${overflowSelected.name.length * 0.55}em`,
|
|
229900
|
+
} }))] }) }), 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: () => {
|
|
229901
|
+
setSelectedCategorySlug(category.slug);
|
|
229902
|
+
setShowMobileDropdown(false);
|
|
229903
|
+
}, 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) => {
|
|
229904
|
+
const timeAgo = memory.createdAt
|
|
229905
|
+
? formatDistanceToNow(new Date(memory.createdAt), {
|
|
229906
|
+
addSuffix: true,
|
|
229907
|
+
})
|
|
229908
|
+
: '';
|
|
229909
|
+
const displayUser = memory.email || t('memoryTabManageMemories.unknown');
|
|
229910
|
+
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));
|
|
229911
|
+
})) }), 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 })] }));
|
|
229912
|
+
}
|
|
229913
|
+
|
|
229914
|
+
/**
|
|
229915
|
+
* Popup hosting the same memory manager the agent settings modal renders —
|
|
229916
|
+
* learner/category/date filters and full CRUD included — for one agent.
|
|
229917
|
+
* Laid out like the Billing tab's agent-limits popup: a fixed divider header
|
|
229918
|
+
* and a body that scrolls vertically while the content fits the width.
|
|
229919
|
+
*/
|
|
229920
|
+
function AgentMemoriesModal({ isOpen, onClose, tenantKey, username, agent, }) {
|
|
229921
|
+
const t = useT();
|
|
229922
|
+
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 }) }) })] }) }));
|
|
229923
|
+
}
|
|
229924
|
+
|
|
229925
|
+
const PAGE_SIZE$6 = 10;
|
|
229926
|
+
/**
|
|
229927
|
+
* Agents table filtered by the same agent autocomplete the Billing tab's
|
|
229928
|
+
* Agent Limits section uses. Opening a row shows that agent's memories in a
|
|
229929
|
+
* popup hosting the same manager the agent settings modal uses.
|
|
229930
|
+
*/
|
|
229931
|
+
function AgentMemoriesSection({ tenantKey, username }) {
|
|
229932
|
+
var _a;
|
|
229933
|
+
const t = useT();
|
|
229934
|
+
const [page, setPage] = useState(1);
|
|
229935
|
+
const [agentFilter, setAgentFilter] = useState(null);
|
|
229936
|
+
const [agentSearch, setAgentSearch] = useState('');
|
|
229937
|
+
const [debouncedAgentSearch] = a$3(agentSearch, 300);
|
|
229938
|
+
const [selectedAgent, setSelectedAgent] = useState(null);
|
|
229939
|
+
// A new filter invalidates the current page index.
|
|
229940
|
+
useEffect(() => {
|
|
229941
|
+
setPage(1);
|
|
229942
|
+
}, [agentFilter]);
|
|
229943
|
+
// Autocomplete options for the filter, fetched once two characters are in.
|
|
229944
|
+
const shouldSearchAgents = Boolean(tenantKey && debouncedAgentSearch.trim().length >= 2);
|
|
229945
|
+
const { data: searchResponse, isFetching: isSearchingAgents } = useGetMentorsQuery({ org: tenantKey, username, limit: 20, query: debouncedAgentSearch.trim() }, { skip: !shouldSearchAgents });
|
|
229946
|
+
const agentOptions = useMemo(() => {
|
|
229947
|
+
var _a;
|
|
229948
|
+
return ((_a = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.results) !== null && _a !== void 0 ? _a : [])
|
|
229949
|
+
.filter((mentor) => Boolean(mentor.unique_id))
|
|
229950
|
+
.map((mentor) => ({
|
|
229951
|
+
value: mentor.unique_id,
|
|
229952
|
+
label: mentor.name || mentor.unique_id,
|
|
229953
|
+
}));
|
|
229954
|
+
}, [searchResponse]);
|
|
229955
|
+
const { data, isLoading, isFetching, error } = useGetMentorsQuery({
|
|
229956
|
+
org: tenantKey,
|
|
229957
|
+
username,
|
|
229958
|
+
limit: PAGE_SIZE$6,
|
|
229959
|
+
offset: (page - 1) * PAGE_SIZE$6,
|
|
229960
|
+
...(agentFilter ? { uniqueId: agentFilter.value } : {}),
|
|
229961
|
+
});
|
|
229962
|
+
const agents = ((_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : []);
|
|
229963
|
+
const totalPages = (data === null || data === void 0 ? void 0 : data.count) ? Math.ceil(data.count / PAGE_SIZE$6) : 0;
|
|
229964
|
+
const isForbidden = !!error && error.status === 403;
|
|
229965
|
+
return (jsxs("div", { "data-testid": "memory-admin-agent-section", children: [jsx("div", { className: "mb-6 max-w-sm", children: jsx(SearchSelect, { labels: {
|
|
229966
|
+
// No field label — the users tab's search carries none either.
|
|
229967
|
+
label: '',
|
|
229968
|
+
placeholder: t('memoryAdminTab.filter.placeholder'),
|
|
229969
|
+
typeToSearch: t('memoryAdminTab.filter.typeToSearch'),
|
|
229970
|
+
searching: t('memoryAdminTab.filter.searching'),
|
|
229971
|
+
noResults: t('memoryAdminTab.filter.noResults'),
|
|
229972
|
+
clear: t('memoryAdminTab.filter.clear'),
|
|
229973
|
+
}, selected: agentFilter, onSelect: (option) => {
|
|
229974
|
+
setAgentFilter(option);
|
|
229975
|
+
setAgentSearch('');
|
|
229976
|
+
}, 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', {
|
|
229977
|
+
name: agent.name,
|
|
229978
|
+
}), 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 }))] }));
|
|
229979
|
+
}
|
|
229980
|
+
|
|
229981
|
+
/**
|
|
229982
|
+
* Tenant-settings Memory tab. Lets admins/RBAC-granted users manage other
|
|
229983
|
+
* users' global memories and per-agent memories from one place, mirroring the
|
|
229984
|
+
* Billing tab's sub-tab layout.
|
|
229985
|
+
*/
|
|
229986
|
+
function MemoryAdminTab({ tenantKey, username }) {
|
|
229987
|
+
const t = useT();
|
|
229988
|
+
// Same platform gate the profile memory tab applies: when memsearch is off
|
|
229989
|
+
// for the tenant there is nothing to manage.
|
|
229990
|
+
const { data: memsearchStatus, isLoading, isError, } = useGetMemsearchStatusQuery({ org: tenantKey, userId: username });
|
|
229991
|
+
if (isLoading) {
|
|
229992
|
+
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" })] }));
|
|
229993
|
+
}
|
|
229994
|
+
if (!isError && memsearchStatus && !memsearchStatus.enable_memsearch) {
|
|
229995
|
+
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') }) }) }));
|
|
229996
|
+
}
|
|
229997
|
+
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 }) })] }));
|
|
229998
|
+
}
|
|
229999
|
+
|
|
229474
230000
|
// ::- Persistent data structure representing an ordered mapping from
|
|
229475
230001
|
// strings to values, with some convenient update methods.
|
|
229476
230002
|
function OrderedMap(content) {
|
|
@@ -258759,7 +259285,7 @@ function SlashSkillPicker({ skills, activeIndex, listboxId, onSelect, onActiveIn
|
|
|
258759
259285
|
onMouseDown: (e) => {
|
|
258760
259286
|
e.preventDefault();
|
|
258761
259287
|
onSelect(skill);
|
|
258762
|
-
}, children: jsxs("span", { className: "flex items-
|
|
259288
|
+
}, children: jsxs("span", { className: "flex items-start gap-2", children: [jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [jsx("span", { "data-testid": "slash-skill-picker-option-name", className: "text-sm font-medium break-words text-gray-800", children: skill.name }), jsxs("span", { "data-testid": "slash-skill-picker-option-slug", className: "text-xs break-all text-gray-400", children: ["/", skill.slug] })] }), skill.category && (jsx("span", { className: "shrink-0 rounded-full bg-gray-100 px-2 py-0.5 text-[0.625rem] text-gray-500", children: skill.category }))] }) }, skill.unique_id))), isFetchingMore && (jsxs("li", { role: "presentation", className: "flex items-center gap-2 px-3 py-2", "data-testid": "slash-skill-picker-loading-more", children: [jsx(LoaderCircle, { className: "h-4 w-4 animate-spin text-blue-500" }), jsx("span", { className: "text-xs text-gray-500", children: t('slashSkillPicker.loading') })] }))] }))] }));
|
|
258763
259289
|
}
|
|
258764
259290
|
|
|
258765
259291
|
/** Matches a composer value that is a single `/`-prefixed token (no whitespace). */
|
|
@@ -259694,7 +260220,7 @@ function RetrievedDocumentsButton({ sessionId }) {
|
|
|
259694
260220
|
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 }) })] }) })] }));
|
|
259695
260221
|
}
|
|
259696
260222
|
|
|
259697
|
-
const PAGE_SIZE$
|
|
260223
|
+
const PAGE_SIZE$5 = 10;
|
|
259698
260224
|
const MemoryMenu = ({ onClose, mentorId, tenantKey, username }) => {
|
|
259699
260225
|
const t = useT();
|
|
259700
260226
|
const [page, setPage] = useState(1);
|
|
@@ -259712,7 +260238,7 @@ const MemoryMenu = ({ onClose, mentorId, tenantKey, username }) => {
|
|
|
259712
260238
|
mentorId,
|
|
259713
260239
|
params: {
|
|
259714
260240
|
page,
|
|
259715
|
-
page_size: PAGE_SIZE$
|
|
260241
|
+
page_size: PAGE_SIZE$5,
|
|
259716
260242
|
my_memory: true,
|
|
259717
260243
|
},
|
|
259718
260244
|
}, {
|
|
@@ -263627,7 +264153,7 @@ function DeleteItemConfirm({ isOpen, onClose, tenantKey, username, datasetName,
|
|
|
263627
264153
|
: t('benchmarksDeleteItemConfirm.delete') })] })] }) }));
|
|
263628
264154
|
}
|
|
263629
264155
|
|
|
263630
|
-
const PAGE_SIZE$
|
|
264156
|
+
const PAGE_SIZE$4 = 10;
|
|
263631
264157
|
function BenchmarkItemsModal({ isOpen, onClose, tenantKey, username, datasetName }) {
|
|
263632
264158
|
var _a;
|
|
263633
264159
|
const t = useT();
|
|
@@ -263639,17 +264165,17 @@ function BenchmarkItemsModal({ isOpen, onClose, tenantKey, username, datasetName
|
|
|
263639
264165
|
userId: username,
|
|
263640
264166
|
datasetName,
|
|
263641
264167
|
page,
|
|
263642
|
-
limit: PAGE_SIZE$
|
|
264168
|
+
limit: PAGE_SIZE$4,
|
|
263643
264169
|
});
|
|
263644
264170
|
const items = (_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : [];
|
|
263645
|
-
const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$
|
|
264171
|
+
const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$4);
|
|
263646
264172
|
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) => {
|
|
263647
264173
|
var _a;
|
|
263648
264174
|
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));
|
|
263649
264175
|
}), 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 }))] }) }));
|
|
263650
264176
|
}
|
|
263651
264177
|
|
|
263652
|
-
const PAGE_SIZE$
|
|
264178
|
+
const PAGE_SIZE$3 = 10;
|
|
263653
264179
|
function BenchmarksTab({ tenantKey, username, }) {
|
|
263654
264180
|
var _a;
|
|
263655
264181
|
const t = useT();
|
|
@@ -263661,13 +264187,13 @@ function BenchmarksTab({ tenantKey, username, }) {
|
|
|
263661
264187
|
org: tenantKey,
|
|
263662
264188
|
userId: username,
|
|
263663
264189
|
page,
|
|
263664
|
-
limit: PAGE_SIZE$
|
|
264190
|
+
limit: PAGE_SIZE$3,
|
|
263665
264191
|
});
|
|
263666
264192
|
const benchmarks = (_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : [];
|
|
263667
264193
|
const filtered = searchQuery.trim()
|
|
263668
264194
|
? benchmarks.filter((benchmark) => benchmark.name.toLowerCase().includes(searchQuery.toLowerCase()))
|
|
263669
264195
|
: benchmarks;
|
|
263670
|
-
const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$
|
|
264196
|
+
const totalPages = evalTotalPages(data === null || data === void 0 ? void 0 : data.count, PAGE_SIZE$3);
|
|
263671
264197
|
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
|
|
263672
264198
|
? formatDistanceToNow(new Date(benchmark.created_at), {
|
|
263673
264199
|
addSuffix: true,
|
|
@@ -263677,514 +264203,6 @@ function BenchmarksTab({ tenantKey, username, }) {
|
|
|
263677
264203
|
}), 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 }))] }));
|
|
263678
264204
|
}
|
|
263679
264205
|
|
|
263680
|
-
/** Matches the server-side cap on the global memories listing. */
|
|
263681
|
-
const PAGE_SIZE$6 = 25;
|
|
263682
|
-
/**
|
|
263683
|
-
* Popup for managing one user's global memories. Reads them the way the
|
|
263684
|
-
* profile preview does — the caller in the path, the managed user identified
|
|
263685
|
-
* by their id (username) in `user_id` — while writes address the managed
|
|
263686
|
-
* user's path directly, which the backend resolves for admin/RBAC callers.
|
|
263687
|
-
* The list itself is the same {@link MemoriesList} the profile Memory tab
|
|
263688
|
-
* renders.
|
|
263689
|
-
*/
|
|
263690
|
-
function UserMemoriesModal({ isOpen, onClose, tenantKey, adminUsername, user, }) {
|
|
263691
|
-
var _a, _b, _c;
|
|
263692
|
-
const t = useT();
|
|
263693
|
-
const [page, setPage] = useState(1);
|
|
263694
|
-
const [showAdd, setShowAdd] = useState(false);
|
|
263695
|
-
const [editingMemory, setEditingMemory] = useState(null);
|
|
263696
|
-
const [deletingId, setDeletingId] = useState(null);
|
|
263697
|
-
const { data: memoriesData, isLoading, error, } = useGetGlobalMemoriesQuery({
|
|
263698
|
-
org: tenantKey,
|
|
263699
|
-
userId: adminUsername,
|
|
263700
|
-
// `user_id` must be the managed user's id (username) — the backend does
|
|
263701
|
-
// not resolve emails here, so passing one returns an empty list.
|
|
263702
|
-
params: { page, page_size: PAGE_SIZE$6, user_id: user.username },
|
|
263703
|
-
});
|
|
263704
|
-
const memories = (_a = memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.results) !== null && _a !== void 0 ? _a : [];
|
|
263705
|
-
const totalPages = (memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.count) ? Math.ceil(memoriesData.count / PAGE_SIZE$6) : 0;
|
|
263706
|
-
const isForbidden = !!error && error.status === 403;
|
|
263707
|
-
// The managed user's capture/personalization toggles, addressed through
|
|
263708
|
-
// their path the way every admin write here is. Hidden unless they load.
|
|
263709
|
-
const { data: settings } = useGetUserMemorySettingsQuery({
|
|
263710
|
-
org: tenantKey,
|
|
263711
|
-
userId: user.username,
|
|
263712
|
-
});
|
|
263713
|
-
const [updateSettings, { isLoading: isUpdatingSettings }] = useUpdateUserMemorySettingsMutation();
|
|
263714
|
-
const handleToggleSetting = async (key, checked) => {
|
|
263715
|
-
try {
|
|
263716
|
-
await updateSettings({
|
|
263717
|
-
org: tenantKey,
|
|
263718
|
-
userId: user.username,
|
|
263719
|
-
settings: { [key]: checked },
|
|
263720
|
-
}).unwrap();
|
|
263721
|
-
toast.success(t('memoryMemoryTab.memorySettingUpdated'));
|
|
263722
|
-
}
|
|
263723
|
-
catch (_a) {
|
|
263724
|
-
toast.error(t('memoryMemoryTab.failedToUpdateMemorySetting'));
|
|
263725
|
-
}
|
|
263726
|
-
};
|
|
263727
|
-
const [deleteMemory] = useDeleteGlobalMemoryMutation();
|
|
263728
|
-
const handleDeleteMemory = async (memory) => {
|
|
263729
|
-
setDeletingId(memory.id);
|
|
263730
|
-
try {
|
|
263731
|
-
await deleteMemory({
|
|
263732
|
-
org: tenantKey,
|
|
263733
|
-
userId: user.username,
|
|
263734
|
-
memoryId: memory.id,
|
|
263735
|
-
}).unwrap();
|
|
263736
|
-
toast.success(t('memoryAdminUserMemoriesModal.memoryDeleted'));
|
|
263737
|
-
}
|
|
263738
|
-
catch (deleteError) {
|
|
263739
|
-
if ((deleteError === null || deleteError === void 0 ? void 0 : deleteError.status) === 403) {
|
|
263740
|
-
toast.error(t('memoryAdminTab.forbidden'));
|
|
263741
|
-
}
|
|
263742
|
-
else {
|
|
263743
|
-
toast.error(t('memoryAdminUserMemoriesModal.failedToDeleteMemory'));
|
|
263744
|
-
}
|
|
263745
|
-
}
|
|
263746
|
-
finally {
|
|
263747
|
-
setDeletingId(null);
|
|
263748
|
-
}
|
|
263749
|
-
};
|
|
263750
|
-
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', {
|
|
263751
|
-
state: settings.auto_capture_enabled
|
|
263752
|
-
? t('memoryMemoryTab.stateEnabled')
|
|
263753
|
-
: t('memoryMemoryTab.stateDisabled'),
|
|
263754
|
-
}), 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', {
|
|
263755
|
-
state: settings.use_memory_in_responses
|
|
263756
|
-
? t('memoryMemoryTab.stateEnabled')
|
|
263757
|
-
: t('memoryMemoryTab.stateDisabled'),
|
|
263758
|
-
}), 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 }))] }) }));
|
|
263759
|
-
}
|
|
263760
|
-
|
|
263761
|
-
const PAGE_SIZE$5 = 10;
|
|
263762
|
-
const SEARCH_DEBOUNCE_MS = 300;
|
|
263763
|
-
/**
|
|
263764
|
-
* Tenant users table with server-side search. Opening a row shows that user's
|
|
263765
|
-
* global memories in a popup where the admin can manage them.
|
|
263766
|
-
*/
|
|
263767
|
-
function GlobalMemoriesSection({ tenantKey, username }) {
|
|
263768
|
-
var _a;
|
|
263769
|
-
const t = useT();
|
|
263770
|
-
const [page, setPage] = useState(1);
|
|
263771
|
-
const [searchQuery, setSearchQuery] = useState('');
|
|
263772
|
-
const [debouncedSearch, setDebouncedSearch] = useState(searchQuery);
|
|
263773
|
-
const [selectedUser, setSelectedUser] = useState(null);
|
|
263774
|
-
// Same debounce contract as the Management tab's user search: terms shorter
|
|
263775
|
-
// than three characters search as empty. Bailing out on an unchanged value
|
|
263776
|
-
// keeps the mount-time timer from resetting a page the user already turned.
|
|
263777
|
-
useEffect(() => {
|
|
263778
|
-
const handler = setTimeout(() => {
|
|
263779
|
-
setDebouncedSearch((previous) => {
|
|
263780
|
-
const next = searchQuery.length > 2 ? searchQuery : '';
|
|
263781
|
-
return previous === next ? previous : next;
|
|
263782
|
-
});
|
|
263783
|
-
}, SEARCH_DEBOUNCE_MS);
|
|
263784
|
-
return () => clearTimeout(handler);
|
|
263785
|
-
}, [searchQuery]);
|
|
263786
|
-
// A new search term invalidates the current page index.
|
|
263787
|
-
useEffect(() => {
|
|
263788
|
-
setPage(1);
|
|
263789
|
-
}, [debouncedSearch]);
|
|
263790
|
-
const { data, isLoading, isFetching, error } = usePlatformUsersQuery({
|
|
263791
|
-
platform_key: tenantKey,
|
|
263792
|
-
platform_org: tenantKey,
|
|
263793
|
-
page,
|
|
263794
|
-
page_size: PAGE_SIZE$5,
|
|
263795
|
-
query: debouncedSearch,
|
|
263796
|
-
return_policies: 'false',
|
|
263797
|
-
});
|
|
263798
|
-
const users = useMemo(() => {
|
|
263799
|
-
var _a;
|
|
263800
|
-
// `results` is a bare array unless policies were requested, in which case
|
|
263801
|
-
// the users sit under `results.data`.
|
|
263802
|
-
const results = data === null || data === void 0 ? void 0 : data.results;
|
|
263803
|
-
const platformUsers = Array.isArray(results)
|
|
263804
|
-
? results
|
|
263805
|
-
: ((_a = results === null || results === void 0 ? void 0 : results.data) !== null && _a !== void 0 ? _a : []);
|
|
263806
|
-
// A user without a username cannot be addressed by the memory endpoints.
|
|
263807
|
-
return platformUsers
|
|
263808
|
-
.filter((user) => !!user.username)
|
|
263809
|
-
.map((user) => ({
|
|
263810
|
-
username: user.username,
|
|
263811
|
-
name: user.name,
|
|
263812
|
-
email: user.email,
|
|
263813
|
-
}));
|
|
263814
|
-
}, [data]);
|
|
263815
|
-
const totalPages = Math.ceil(((_a = data === null || data === void 0 ? void 0 : data.count) !== null && _a !== void 0 ? _a : 0) / PAGE_SIZE$5);
|
|
263816
|
-
const isForbidden = !!error && error.status === 403;
|
|
263817
|
-
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', {
|
|
263818
|
-
name: user.email || user.username,
|
|
263819
|
-
}), 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 }))] }));
|
|
263820
|
-
}
|
|
263821
|
-
|
|
263822
|
-
const EditMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return editMemoryModal; }).then((module) => ({
|
|
263823
|
-
default: module.EditMemoryModal,
|
|
263824
|
-
})), { ssr: false });
|
|
263825
|
-
const AddMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return addMemoryModal; }).then((module) => ({
|
|
263826
|
-
default: module.AddMemoryModal,
|
|
263827
|
-
})), { ssr: false });
|
|
263828
|
-
const DeleteMemoryModal = dynamic(() => Promise.resolve().then(function () { return deleteMemoryModal; }).then((module) => ({
|
|
263829
|
-
default: module.DeleteMemoryModal,
|
|
263830
|
-
})), { ssr: false });
|
|
263831
|
-
const BulkDeleteMemoryModal$1 = dynamic(() => Promise.resolve().then(function () { return bulkDeleteMemoryModal; }).then((module) => ({
|
|
263832
|
-
default: module.BulkDeleteMemoryModal,
|
|
263833
|
-
})), { ssr: false });
|
|
263834
|
-
const ManageCategoriesModal$1 = dynamic(() => Promise.resolve().then(function () { return manageCategoriesModal; }).then((module) => ({
|
|
263835
|
-
default: module.ManageCategoriesModal,
|
|
263836
|
-
})), { ssr: false });
|
|
263837
|
-
const PAGE_SIZE$4 = 20;
|
|
263838
|
-
const SNAPSHOT_PAGE_SIZE = 1000;
|
|
263839
|
-
function ManageMemories({ tenantKey, username, mentorId }) {
|
|
263840
|
-
var _a, _b, _c, _d, _e;
|
|
263841
|
-
const t = useT();
|
|
263842
|
-
const [selectedLearner, setSelectedLearner] = useState('');
|
|
263843
|
-
const [dateRange, setDateRange] = useState(undefined);
|
|
263844
|
-
const [selectedCategorySlug, setSelectedCategorySlug] = useState('all');
|
|
263845
|
-
const [page, setPage] = useState(1);
|
|
263846
|
-
// Reset to page 1 whenever any filter changes — otherwise we could land on a
|
|
263847
|
-
// page index that no longer exists in the new result set.
|
|
263848
|
-
useEffect(() => {
|
|
263849
|
-
setPage(1);
|
|
263850
|
-
}, [selectedLearner, dateRange, selectedCategorySlug]);
|
|
263851
|
-
const listParams = useMemo(() => {
|
|
263852
|
-
const params = { page, page_size: PAGE_SIZE$4 };
|
|
263853
|
-
if (selectedLearner)
|
|
263854
|
-
params.email = selectedLearner;
|
|
263855
|
-
if (selectedCategorySlug !== 'all')
|
|
263856
|
-
params.category = selectedCategorySlug;
|
|
263857
|
-
if (dateRange === null || dateRange === void 0 ? void 0 : dateRange.from)
|
|
263858
|
-
params.start_date = format$1(dateRange.from, 'yyyy-MM-dd');
|
|
263859
|
-
if (dateRange === null || dateRange === void 0 ? void 0 : dateRange.to)
|
|
263860
|
-
params.end_date = format$1(dateRange.to, 'yyyy-MM-dd');
|
|
263861
|
-
return params;
|
|
263862
|
-
}, [page, selectedLearner, selectedCategorySlug, dateRange]);
|
|
263863
|
-
const { data: listResponse, isLoading: isLoadingMemories } = useGetMentorMemoriesListQuery({
|
|
263864
|
-
org: tenantKey,
|
|
263865
|
-
userId: username !== null && username !== void 0 ? username : '',
|
|
263866
|
-
mentorId,
|
|
263867
|
-
params: listParams,
|
|
263868
|
-
}, {
|
|
263869
|
-
skip: !tenantKey || !username || !mentorId,
|
|
263870
|
-
});
|
|
263871
|
-
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));
|
|
263872
|
-
const { data: adminCategories } = useGetMemoryCategoriesAdminQuery({
|
|
263873
|
-
org: tenantKey,
|
|
263874
|
-
mentorId,
|
|
263875
|
-
}, {
|
|
263876
|
-
skip: !tenantKey || !mentorId,
|
|
263877
|
-
});
|
|
263878
|
-
const [deleteMentorMemory, { isLoading: isDeleting }] = useDeleteMentorMemoryMutation();
|
|
263879
|
-
const [updateMentorMemory, { isLoading: isEditing }] = useUpdateMentorMemoryMutation();
|
|
263880
|
-
const [createMentorMemory, { isLoading: isSaving }] = useCreateMentorMemoryMutation();
|
|
263881
|
-
// Flat list of memories on the current page, mapped into the local `Memory`
|
|
263882
|
-
// shape used by the rest of this component.
|
|
263883
|
-
const memories = useMemo(() => {
|
|
263884
|
-
if (!(listResponse === null || listResponse === void 0 ? void 0 : listResponse.results))
|
|
263885
|
-
return [];
|
|
263886
|
-
return listResponse.results.map((memory) => ({
|
|
263887
|
-
id: memory.id,
|
|
263888
|
-
content: memory.content,
|
|
263889
|
-
category: {
|
|
263890
|
-
id: memory.category.id,
|
|
263891
|
-
name: memory.category.name,
|
|
263892
|
-
slug: memory.category.slug,
|
|
263893
|
-
},
|
|
263894
|
-
email: memory.email,
|
|
263895
|
-
createdAt: memory.created_at,
|
|
263896
|
-
}));
|
|
263897
|
-
}, [listResponse]);
|
|
263898
|
-
// Unfiltered snapshot used to derive the learner dropdown and to source the
|
|
263899
|
-
// bulk-delete operation, which needs the full set of memories — not just the
|
|
263900
|
-
// current page.
|
|
263901
|
-
const { data: snapshotResponse } = useGetMentorMemoriesListQuery({
|
|
263902
|
-
org: tenantKey,
|
|
263903
|
-
userId: username !== null && username !== void 0 ? username : '',
|
|
263904
|
-
mentorId,
|
|
263905
|
-
params: { page: 1, page_size: SNAPSHOT_PAGE_SIZE },
|
|
263906
|
-
}, {
|
|
263907
|
-
skip: !tenantKey || !username || !mentorId,
|
|
263908
|
-
});
|
|
263909
|
-
const learners = useMemo(() => {
|
|
263910
|
-
if (!(snapshotResponse === null || snapshotResponse === void 0 ? void 0 : snapshotResponse.results))
|
|
263911
|
-
return [];
|
|
263912
|
-
const emailSet = new Set();
|
|
263913
|
-
snapshotResponse.results.forEach((m) => {
|
|
263914
|
-
if (m.email)
|
|
263915
|
-
emailSet.add(m.email);
|
|
263916
|
-
});
|
|
263917
|
-
return Array.from(emailSet).map((email) => ({ email }));
|
|
263918
|
-
}, [snapshotResponse]);
|
|
263919
|
-
const categories = useMemo(() => {
|
|
263920
|
-
if (adminCategories && adminCategories.length > 0) {
|
|
263921
|
-
return [
|
|
263922
|
-
{ id: 0, name: 'All', slug: 'all' },
|
|
263923
|
-
...adminCategories.map((cat) => ({
|
|
263924
|
-
id: cat.id,
|
|
263925
|
-
name: cat.name,
|
|
263926
|
-
slug: cat.slug,
|
|
263927
|
-
})),
|
|
263928
|
-
];
|
|
263929
|
-
}
|
|
263930
|
-
return [{ id: 0, name: 'All', slug: 'all' }];
|
|
263931
|
-
}, [adminCategories]);
|
|
263932
|
-
const [editingMemory, setEditingMemory] = useState(null);
|
|
263933
|
-
const [editContent, setEditContent] = useState('');
|
|
263934
|
-
const [editCategory, setEditCategory] = useState('');
|
|
263935
|
-
const [showDeleteConfirm, setShowDeleteConfirm] = useState(null);
|
|
263936
|
-
const [showAddMemory, setShowAddMemory] = useState(false);
|
|
263937
|
-
const [newMemoryContent, setNewMemoryContent] = useState('');
|
|
263938
|
-
const [newMemoryCategory, setNewMemoryCategory] = useState('');
|
|
263939
|
-
const [showMobileDropdown, setShowMobileDropdown] = useState(false);
|
|
263940
|
-
const [showBulkDeleteConfirm, setShowBulkDeleteConfirm] = useState(false);
|
|
263941
|
-
const [isBulkDeleting, setIsBulkDeleting] = useState(false);
|
|
263942
|
-
const [showManageCategories, setShowManageCategories] = useState(false);
|
|
263943
|
-
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');
|
|
263944
|
-
const VISIBLE_CATEGORY_LIMIT = 6;
|
|
263945
|
-
const visibleCategories = categories.slice(0, VISIBLE_CATEGORY_LIMIT);
|
|
263946
|
-
const overflowCategories = categories.slice(VISIBLE_CATEGORY_LIMIT);
|
|
263947
|
-
const overflowSelected = overflowCategories.find((c) => c.slug === selectedCategorySlug);
|
|
263948
|
-
// Category is filtered server-side via the `category` query param now, so
|
|
263949
|
-
// `memories` already contains only the relevant entries for the page.
|
|
263950
|
-
const filteredMemories = memories;
|
|
263951
|
-
const handleDeleteMemory = async (id) => {
|
|
263952
|
-
if (!tenantKey || !username)
|
|
263953
|
-
return;
|
|
263954
|
-
try {
|
|
263955
|
-
await deleteMentorMemory({
|
|
263956
|
-
org: tenantKey,
|
|
263957
|
-
userId: username,
|
|
263958
|
-
mentorId,
|
|
263959
|
-
memoryId: id,
|
|
263960
|
-
}).unwrap();
|
|
263961
|
-
setShowDeleteConfirm(null);
|
|
263962
|
-
toast.success(t('memoryTabManageMemories.memoryDeletedSuccessfully'));
|
|
263963
|
-
}
|
|
263964
|
-
catch (error) {
|
|
263965
|
-
console.error('Failed to delete memory:', error);
|
|
263966
|
-
toast.error(t('memoryTabManageMemories.failedToDeleteMemory'));
|
|
263967
|
-
}
|
|
263968
|
-
};
|
|
263969
|
-
const handleBulkDelete = async () => {
|
|
263970
|
-
var _a;
|
|
263971
|
-
if (!tenantKey || !username)
|
|
263972
|
-
return;
|
|
263973
|
-
setIsBulkDeleting(true);
|
|
263974
|
-
try {
|
|
263975
|
-
// Source bulk-delete from the unfiltered snapshot — `memories` only holds
|
|
263976
|
-
// the current page, while bulk delete must remove every entry in the
|
|
263977
|
-
// selected category.
|
|
263978
|
-
const memoriesToDelete = ((_a = snapshotResponse === null || snapshotResponse === void 0 ? void 0 : snapshotResponse.results) !== null && _a !== void 0 ? _a : []).filter((memory) => memory.category.slug === selectedCategorySlug);
|
|
263979
|
-
await Promise.all(memoriesToDelete.map((memory) => deleteMentorMemory({
|
|
263980
|
-
org: tenantKey,
|
|
263981
|
-
userId: username,
|
|
263982
|
-
mentorId,
|
|
263983
|
-
memoryId: memory.id,
|
|
263984
|
-
}).unwrap()));
|
|
263985
|
-
toast.success(t('memoryTabManageMemories.allCategoryMemoriesDeleted', { category: selectedCategoryName }));
|
|
263986
|
-
setShowBulkDeleteConfirm(false);
|
|
263987
|
-
}
|
|
263988
|
-
catch (error) {
|
|
263989
|
-
console.error('Failed to delete memories:', error);
|
|
263990
|
-
toast.error(t('memoryTabManageMemories.failedToDeleteMemories'));
|
|
263991
|
-
}
|
|
263992
|
-
finally {
|
|
263993
|
-
setIsBulkDeleting(false);
|
|
263994
|
-
}
|
|
263995
|
-
};
|
|
263996
|
-
const startEdit = (memory) => {
|
|
263997
|
-
setEditingMemory(memory);
|
|
263998
|
-
setEditContent(memory.content);
|
|
263999
|
-
setEditCategory(memory.category.name);
|
|
264000
|
-
};
|
|
264001
|
-
const saveEdit = async () => {
|
|
264002
|
-
if (!editingMemory || !tenantKey || !username)
|
|
264003
|
-
return;
|
|
264004
|
-
try {
|
|
264005
|
-
const selectedCat = categories.find((c) => c.name === editCategory);
|
|
264006
|
-
const categoryChanged = !!selectedCat && selectedCat.slug !== editingMemory.category.slug;
|
|
264007
|
-
await updateMentorMemory({
|
|
264008
|
-
org: tenantKey,
|
|
264009
|
-
userId: username,
|
|
264010
|
-
mentorId,
|
|
264011
|
-
memoryId: editingMemory.id,
|
|
264012
|
-
data: {
|
|
264013
|
-
content: editContent,
|
|
264014
|
-
...(categoryChanged ? { category_slug: selectedCat.slug } : {}),
|
|
264015
|
-
},
|
|
264016
|
-
}).unwrap();
|
|
264017
|
-
toast.success(t('memoryTabManageMemories.memoryUpdatedSuccessfully'));
|
|
264018
|
-
// Follow the entry to its new category tab so the user doesn't lose
|
|
264019
|
-
// sight of it. Skip when viewing "All" — the entry is still visible.
|
|
264020
|
-
if (categoryChanged && selectedCategorySlug !== 'all') {
|
|
264021
|
-
setSelectedCategorySlug(selectedCat.slug);
|
|
264022
|
-
}
|
|
264023
|
-
setEditingMemory(null);
|
|
264024
|
-
setEditContent('');
|
|
264025
|
-
setEditCategory('');
|
|
264026
|
-
}
|
|
264027
|
-
catch (error) {
|
|
264028
|
-
console.error('Failed to update memory:', error);
|
|
264029
|
-
toast.error(t('memoryTabManageMemories.failedToUpdateMemory'));
|
|
264030
|
-
}
|
|
264031
|
-
};
|
|
264032
|
-
const cancelEdit = () => {
|
|
264033
|
-
setEditingMemory(null);
|
|
264034
|
-
setEditContent('');
|
|
264035
|
-
setEditCategory('');
|
|
264036
|
-
};
|
|
264037
|
-
const startAddMemory = () => {
|
|
264038
|
-
setShowAddMemory(true);
|
|
264039
|
-
setNewMemoryCategory(selectedCategoryName);
|
|
264040
|
-
};
|
|
264041
|
-
const saveNewMemory = async () => {
|
|
264042
|
-
var _a;
|
|
264043
|
-
if (!newMemoryContent.trim() || !tenantKey || !username)
|
|
264044
|
-
return;
|
|
264045
|
-
try {
|
|
264046
|
-
const selectedCat = categories.find((c) => c.name === newMemoryCategory);
|
|
264047
|
-
const categorySlug = (_a = selectedCat === null || selectedCat === void 0 ? void 0 : selectedCat.slug) !== null && _a !== void 0 ? _a : selectedCategorySlug;
|
|
264048
|
-
await createMentorMemory({
|
|
264049
|
-
org: tenantKey,
|
|
264050
|
-
userId: username,
|
|
264051
|
-
mentorId,
|
|
264052
|
-
data: {
|
|
264053
|
-
category_slug: categorySlug === 'all' ? 'general' : categorySlug,
|
|
264054
|
-
content: newMemoryContent.trim(),
|
|
264055
|
-
},
|
|
264056
|
-
}).unwrap();
|
|
264057
|
-
setShowAddMemory(false);
|
|
264058
|
-
setNewMemoryContent('');
|
|
264059
|
-
setNewMemoryCategory('');
|
|
264060
|
-
if (selectedCat) {
|
|
264061
|
-
setSelectedCategorySlug(selectedCat.slug);
|
|
264062
|
-
}
|
|
264063
|
-
toast.success(t('memoryTabManageMemories.memoryCreatedSuccessfully'));
|
|
264064
|
-
}
|
|
264065
|
-
catch (error) {
|
|
264066
|
-
console.error('Failed to create memory:', error);
|
|
264067
|
-
toast.error(t('memoryTabManageMemories.failedToCreateMemory'));
|
|
264068
|
-
}
|
|
264069
|
-
};
|
|
264070
|
-
const cancelAddMemory = () => {
|
|
264071
|
-
setShowAddMemory(false);
|
|
264072
|
-
setNewMemoryContent('');
|
|
264073
|
-
setNewMemoryCategory('');
|
|
264074
|
-
};
|
|
264075
|
-
const categoryNames = categories.map((c) => c.name);
|
|
264076
|
-
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
|
|
264077
|
-
? ((_e = (_d = learners.find((learner) => learner.email === selectedLearner)) === null || _d === void 0 ? void 0 : _d.email) !== null && _e !== void 0 ? _e : selectedLearner)
|
|
264078
|
-
: 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: () => {
|
|
264079
|
-
setSelectedLearner('');
|
|
264080
|
-
}, 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: () => {
|
|
264081
|
-
setSelectedLearner(learner.email);
|
|
264082
|
-
}, 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)
|
|
264083
|
-
? `${format$1(dateRange.from, 'MMM dd')} - ${format$1(dateRange.to, 'MMM dd')}`
|
|
264084
|
-
: 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
|
|
264085
|
-
? 'text-[#38A1E5]'
|
|
264086
|
-
: '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: {
|
|
264087
|
-
width: `${overflowSelected.name.length * 0.55}em`,
|
|
264088
|
-
} }))] }) }), 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: () => {
|
|
264089
|
-
setSelectedCategorySlug(category.slug);
|
|
264090
|
-
setShowMobileDropdown(false);
|
|
264091
|
-
}, 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) => {
|
|
264092
|
-
const timeAgo = memory.createdAt
|
|
264093
|
-
? formatDistanceToNow(new Date(memory.createdAt), {
|
|
264094
|
-
addSuffix: true,
|
|
264095
|
-
})
|
|
264096
|
-
: '';
|
|
264097
|
-
const displayUser = memory.email || t('memoryTabManageMemories.unknown');
|
|
264098
|
-
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));
|
|
264099
|
-
})) }), 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 })] }));
|
|
264100
|
-
}
|
|
264101
|
-
|
|
264102
|
-
/**
|
|
264103
|
-
* Popup hosting the same memory manager the agent settings modal renders —
|
|
264104
|
-
* learner/category/date filters and full CRUD included — for one agent.
|
|
264105
|
-
* Laid out like the Billing tab's agent-limits popup: a fixed divider header
|
|
264106
|
-
* and a body that scrolls vertically while the content fits the width.
|
|
264107
|
-
*/
|
|
264108
|
-
function AgentMemoriesModal({ isOpen, onClose, tenantKey, username, agent, }) {
|
|
264109
|
-
const t = useT();
|
|
264110
|
-
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 }) }) })] }) }));
|
|
264111
|
-
}
|
|
264112
|
-
|
|
264113
|
-
const PAGE_SIZE$3 = 10;
|
|
264114
|
-
/**
|
|
264115
|
-
* Agents table filtered by the same agent autocomplete the Billing tab's
|
|
264116
|
-
* Agent Limits section uses. Opening a row shows that agent's memories in a
|
|
264117
|
-
* popup hosting the same manager the agent settings modal uses.
|
|
264118
|
-
*/
|
|
264119
|
-
function AgentMemoriesSection({ tenantKey, username }) {
|
|
264120
|
-
var _a;
|
|
264121
|
-
const t = useT();
|
|
264122
|
-
const [page, setPage] = useState(1);
|
|
264123
|
-
const [agentFilter, setAgentFilter] = useState(null);
|
|
264124
|
-
const [agentSearch, setAgentSearch] = useState('');
|
|
264125
|
-
const [debouncedAgentSearch] = a$3(agentSearch, 300);
|
|
264126
|
-
const [selectedAgent, setSelectedAgent] = useState(null);
|
|
264127
|
-
// A new filter invalidates the current page index.
|
|
264128
|
-
useEffect(() => {
|
|
264129
|
-
setPage(1);
|
|
264130
|
-
}, [agentFilter]);
|
|
264131
|
-
// Autocomplete options for the filter, fetched once two characters are in.
|
|
264132
|
-
const shouldSearchAgents = Boolean(tenantKey && debouncedAgentSearch.trim().length >= 2);
|
|
264133
|
-
const { data: searchResponse, isFetching: isSearchingAgents } = useGetMentorsQuery({ org: tenantKey, username, limit: 20, query: debouncedAgentSearch.trim() }, { skip: !shouldSearchAgents });
|
|
264134
|
-
const agentOptions = useMemo(() => {
|
|
264135
|
-
var _a;
|
|
264136
|
-
return ((_a = searchResponse === null || searchResponse === void 0 ? void 0 : searchResponse.results) !== null && _a !== void 0 ? _a : [])
|
|
264137
|
-
.filter((mentor) => Boolean(mentor.unique_id))
|
|
264138
|
-
.map((mentor) => ({
|
|
264139
|
-
value: mentor.unique_id,
|
|
264140
|
-
label: mentor.name || mentor.unique_id,
|
|
264141
|
-
}));
|
|
264142
|
-
}, [searchResponse]);
|
|
264143
|
-
const { data, isLoading, isFetching, error } = useGetMentorsQuery({
|
|
264144
|
-
org: tenantKey,
|
|
264145
|
-
username,
|
|
264146
|
-
limit: PAGE_SIZE$3,
|
|
264147
|
-
offset: (page - 1) * PAGE_SIZE$3,
|
|
264148
|
-
...(agentFilter ? { uniqueId: agentFilter.value } : {}),
|
|
264149
|
-
});
|
|
264150
|
-
const agents = ((_a = data === null || data === void 0 ? void 0 : data.results) !== null && _a !== void 0 ? _a : []);
|
|
264151
|
-
const totalPages = (data === null || data === void 0 ? void 0 : data.count) ? Math.ceil(data.count / PAGE_SIZE$3) : 0;
|
|
264152
|
-
const isForbidden = !!error && error.status === 403;
|
|
264153
|
-
return (jsxs("div", { "data-testid": "memory-admin-agent-section", children: [jsx("div", { className: "mb-6 max-w-sm", children: jsx(SearchSelect, { labels: {
|
|
264154
|
-
// No field label — the users tab's search carries none either.
|
|
264155
|
-
label: '',
|
|
264156
|
-
placeholder: t('memoryAdminTab.filter.placeholder'),
|
|
264157
|
-
typeToSearch: t('memoryAdminTab.filter.typeToSearch'),
|
|
264158
|
-
searching: t('memoryAdminTab.filter.searching'),
|
|
264159
|
-
noResults: t('memoryAdminTab.filter.noResults'),
|
|
264160
|
-
clear: t('memoryAdminTab.filter.clear'),
|
|
264161
|
-
}, selected: agentFilter, onSelect: (option) => {
|
|
264162
|
-
setAgentFilter(option);
|
|
264163
|
-
setAgentSearch('');
|
|
264164
|
-
}, 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', {
|
|
264165
|
-
name: agent.name,
|
|
264166
|
-
}), 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 }))] }));
|
|
264167
|
-
}
|
|
264168
|
-
|
|
264169
|
-
/**
|
|
264170
|
-
* Tenant-settings Memory tab. Lets admins/RBAC-granted users manage other
|
|
264171
|
-
* users' global memories and per-agent memories from one place, mirroring the
|
|
264172
|
-
* Billing tab's sub-tab layout.
|
|
264173
|
-
*/
|
|
264174
|
-
function MemoryAdminTab({ tenantKey, username }) {
|
|
264175
|
-
const t = useT();
|
|
264176
|
-
// Same platform gate the profile memory tab applies: when memsearch is off
|
|
264177
|
-
// for the tenant there is nothing to manage.
|
|
264178
|
-
const { data: memsearchStatus, isLoading, isError, } = useGetMemsearchStatusQuery({ org: tenantKey, userId: username });
|
|
264179
|
-
if (isLoading) {
|
|
264180
|
-
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" })] }));
|
|
264181
|
-
}
|
|
264182
|
-
if (!isError && memsearchStatus && !memsearchStatus.enable_memsearch) {
|
|
264183
|
-
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') }) }) }));
|
|
264184
|
-
}
|
|
264185
|
-
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 }) })] }));
|
|
264186
|
-
}
|
|
264187
|
-
|
|
264188
264206
|
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, onboardingBasePath = '', }) {
|
|
264189
264207
|
var _a, _b, _c, _d;
|
|
264190
264208
|
const t = useT();
|
|
@@ -287248,6 +287266,175 @@ function AgentTasksTab({ PaginationComponent = DefaultTasksPagination, labels: l
|
|
|
287248
287266
|
}, selectedLog: selectedLog, labels: labels }))] }));
|
|
287249
287267
|
}
|
|
287250
287268
|
|
|
287269
|
+
function EditMemoryModal({ open, onOpenChange, editContent, editCategory, onContentChange, onCategoryChange, onSave, onCancel, categories, isSaving, }) {
|
|
287270
|
+
const t = useT();
|
|
287271
|
+
return (jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: jsxs(DialogContent, { className: "mx-4 max-w-2xl sm:mx-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "text-gray-700", children: t('memoryTabEditMemoryModal.editMemory') }) }), jsxs("div", { className: "mt-4 space-y-4", children: [jsxs("div", { children: [jsx("label", { className: "text-sm font-medium text-gray-600", children: t('memoryTabEditMemoryModal.category') }), jsxs(Select$1, { value: editCategory, onValueChange: onCategoryChange, children: [jsx(SelectTrigger, { className: "mt-1", children: jsx(SelectValue, { placeholder: t('memoryTabEditMemoryModal.selectCategory') }) }), jsx(SelectContent, { children: categories
|
|
287272
|
+
.filter((cat) => cat !== 'All')
|
|
287273
|
+
.map((category) => (jsx(SelectItem, { value: category, children: category }, category))) })] })] }), jsxs("div", { children: [jsx("label", { className: "text-sm font-medium text-gray-600", children: t('memoryTabEditMemoryModal.memory') }), jsx(Textarea, { value: editContent, onChange: (e) => onContentChange(e.target.value), placeholder: t('memoryTabEditMemoryModal.enterMemoryContent'), className: "mt-1" }), jsx("p", { className: "mt-1 text-xs text-gray-500", children: editContent.trim().length < 10
|
|
287274
|
+
? t('memoryTabEditMemoryModal.charCountMinimum', {
|
|
287275
|
+
count: editContent.trim().length,
|
|
287276
|
+
})
|
|
287277
|
+
: t('memoryTabEditMemoryModal.charCount', { count: editContent.trim().length }) })] }), jsxs("div", { className: "flex justify-end gap-2", children: [jsx(Button$1, { variant: "outline", onClick: onCancel, children: t('memoryTabEditMemoryModal.cancel') }), jsx(Button$1, { onClick: onSave, className: "ibl-button-primary", disabled: editContent.trim().length < 10 || isSaving, children: isSaving ? t('memoryTabEditMemoryModal.saving') : t('memoryTabEditMemoryModal.save') })] })] })] }) }));
|
|
287278
|
+
}
|
|
287279
|
+
|
|
287280
|
+
var editMemoryModal = /*#__PURE__*/Object.freeze({
|
|
287281
|
+
__proto__: null,
|
|
287282
|
+
EditMemoryModal: EditMemoryModal
|
|
287283
|
+
});
|
|
287284
|
+
|
|
287285
|
+
function AddMemoryModal({ open, onOpenChange, newMemoryContent, newMemoryCategory, onContentChange, onCategoryChange, onSave, onCancel, categories, isSaving, }) {
|
|
287286
|
+
const t = useT();
|
|
287287
|
+
return (jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: jsxs(DialogContent, { className: "mx-4 max-w-2xl sm:mx-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "text-gray-700", children: t('memoryTabAddMemoryModal.addMemory') }) }), jsxs("div", { className: "mt-4 space-y-4", children: [jsxs("div", { children: [jsx("label", { className: "text-sm font-medium text-gray-600", children: t('memoryTabAddMemoryModal.category') }), jsxs(Select$1, { value: newMemoryCategory, onValueChange: onCategoryChange, children: [jsx(SelectTrigger, { className: "mt-1", children: jsx(SelectValue, { placeholder: t('memoryTabAddMemoryModal.selectCategory') }) }), jsx(SelectContent, { children: categories
|
|
287288
|
+
.filter((cat) => cat !== 'All')
|
|
287289
|
+
.map((category) => (jsx(SelectItem, { value: category, children: category }, category))) })] })] }), jsxs("div", { children: [jsx("label", { className: "text-sm font-medium text-gray-600", children: t('memoryTabAddMemoryModal.memory') }), jsx(Textarea, { value: newMemoryContent, onChange: (e) => onContentChange(e.target.value), placeholder: t('memoryTabAddMemoryModal.enterMemoryContent'), className: "mt-1" }), jsx("p", { className: "mt-1 text-xs text-gray-500", children: newMemoryContent.trim().length < 10
|
|
287290
|
+
? t('memoryTabAddMemoryModal.charactersMinimum', {
|
|
287291
|
+
count: newMemoryContent.trim().length,
|
|
287292
|
+
})
|
|
287293
|
+
: t('memoryTabAddMemoryModal.characters', {
|
|
287294
|
+
count: newMemoryContent.trim().length,
|
|
287295
|
+
}) })] }), jsxs("div", { className: "flex justify-end gap-2", children: [jsx(Button$1, { variant: "outline", onClick: onCancel, children: t('memoryTabAddMemoryModal.cancel') }), jsx(Button$1, { onClick: onSave, disabled: newMemoryContent.trim().length < 10 || isSaving, className: "ibl-button-primary", children: isSaving ? t('memoryTabAddMemoryModal.saving') : t('memoryTabAddMemoryModal.save') })] })] })] }) }));
|
|
287296
|
+
}
|
|
287297
|
+
|
|
287298
|
+
var addMemoryModal = /*#__PURE__*/Object.freeze({
|
|
287299
|
+
__proto__: null,
|
|
287300
|
+
AddMemoryModal: AddMemoryModal
|
|
287301
|
+
});
|
|
287302
|
+
|
|
287303
|
+
function BulkDeleteMemoryModal({ open, onOpenChange, onConfirm, onCancel, isDeleting, selectedCategory, }) {
|
|
287304
|
+
const isDeleteAll = selectedCategory === 'All';
|
|
287305
|
+
const getConfirmationText = () => {
|
|
287306
|
+
if (isDeleteAll) {
|
|
287307
|
+
return 'Are you sure you want to delete all memories? This action cannot be undone.';
|
|
287308
|
+
}
|
|
287309
|
+
return `Are you sure you want to delete all memories in the ${selectedCategory} category? This action cannot be undone.`;
|
|
287310
|
+
};
|
|
287311
|
+
const getTitle = () => {
|
|
287312
|
+
if (isDeleteAll) {
|
|
287313
|
+
return 'Delete All Memories';
|
|
287314
|
+
}
|
|
287315
|
+
return `Delete All ${selectedCategory} Memories`;
|
|
287316
|
+
};
|
|
287317
|
+
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: getTitle() }) }), jsx("p", { className: "text-muted-foreground text-sm", children: getConfirmationText() }), jsxs("div", { className: "mt-4 flex justify-end gap-2", children: [jsx(Button$1, { variant: "outline", onClick: onCancel, disabled: isDeleting, children: "Cancel" }), jsx(Button$1, { className: "ibl-button-primary", onClick: onConfirm, disabled: isDeleting, children: isDeleting ? 'Deleting...' : 'Delete' })] })] }) }));
|
|
287318
|
+
}
|
|
287319
|
+
|
|
287320
|
+
var bulkDeleteMemoryModal = /*#__PURE__*/Object.freeze({
|
|
287321
|
+
__proto__: null,
|
|
287322
|
+
BulkDeleteMemoryModal: BulkDeleteMemoryModal
|
|
287323
|
+
});
|
|
287324
|
+
|
|
287325
|
+
const toSlug = (name) => name
|
|
287326
|
+
.trim()
|
|
287327
|
+
.toLowerCase()
|
|
287328
|
+
.replace(/[^a-z0-9]+/g, '_')
|
|
287329
|
+
.replace(/^_+|_+$/g, '');
|
|
287330
|
+
function ManageCategoriesModal({ open, onOpenChange, tenantKey, mentorId, }) {
|
|
287331
|
+
const t = useT();
|
|
287332
|
+
const { data: categories = [], isLoading } = useGetMemoryCategoriesAdminQuery({ org: tenantKey, mentorId }, { skip: !open || !tenantKey || !mentorId });
|
|
287333
|
+
const [createCategory, { isLoading: isCreating }] = useCreateMemoryCategoryMutation();
|
|
287334
|
+
const [updateCategory, { isLoading: isUpdating }] = useUpdateMemoryCategoryMutation();
|
|
287335
|
+
const [deleteCategory, { isLoading: isDeleting }] = useDeleteMemoryCategoryMutation();
|
|
287336
|
+
const [newName, setNewName] = useState('');
|
|
287337
|
+
const [editingId, setEditingId] = useState(null);
|
|
287338
|
+
const [editName, setEditName] = useState('');
|
|
287339
|
+
const [confirmDeleteId, setConfirmDeleteId] = useState(null);
|
|
287340
|
+
const handleCreate = async () => {
|
|
287341
|
+
const name = newName.trim();
|
|
287342
|
+
if (!name)
|
|
287343
|
+
return;
|
|
287344
|
+
try {
|
|
287345
|
+
await createCategory({
|
|
287346
|
+
org: tenantKey,
|
|
287347
|
+
mentorId,
|
|
287348
|
+
data: { name, slug: toSlug(name) },
|
|
287349
|
+
}).unwrap();
|
|
287350
|
+
setNewName('');
|
|
287351
|
+
toast.success(t('memoryTabManageCategoriesModal.categoryCreated'));
|
|
287352
|
+
}
|
|
287353
|
+
catch (error) {
|
|
287354
|
+
console.error('Failed to create category:', error);
|
|
287355
|
+
toast.error(t('memoryTabManageCategoriesModal.failedToCreateCategory'));
|
|
287356
|
+
}
|
|
287357
|
+
};
|
|
287358
|
+
const startEdit = (category) => {
|
|
287359
|
+
setEditingId(category.id);
|
|
287360
|
+
setEditName(category.name);
|
|
287361
|
+
};
|
|
287362
|
+
const cancelEdit = () => {
|
|
287363
|
+
setEditingId(null);
|
|
287364
|
+
setEditName('');
|
|
287365
|
+
};
|
|
287366
|
+
const saveEdit = async (categoryId) => {
|
|
287367
|
+
const name = editName.trim();
|
|
287368
|
+
if (!name)
|
|
287369
|
+
return;
|
|
287370
|
+
try {
|
|
287371
|
+
await updateCategory({
|
|
287372
|
+
org: tenantKey,
|
|
287373
|
+
mentorId,
|
|
287374
|
+
categoryId,
|
|
287375
|
+
data: { name },
|
|
287376
|
+
}).unwrap();
|
|
287377
|
+
cancelEdit();
|
|
287378
|
+
toast.success(t('memoryTabManageCategoriesModal.categoryUpdated'));
|
|
287379
|
+
}
|
|
287380
|
+
catch (error) {
|
|
287381
|
+
console.error('Failed to update category:', error);
|
|
287382
|
+
toast.error(t('memoryTabManageCategoriesModal.failedToUpdateCategory'));
|
|
287383
|
+
}
|
|
287384
|
+
};
|
|
287385
|
+
const handleDelete = async (categoryId) => {
|
|
287386
|
+
try {
|
|
287387
|
+
await deleteCategory({
|
|
287388
|
+
org: tenantKey,
|
|
287389
|
+
mentorId,
|
|
287390
|
+
categoryId,
|
|
287391
|
+
}).unwrap();
|
|
287392
|
+
setConfirmDeleteId(null);
|
|
287393
|
+
toast.success(t('memoryTabManageCategoriesModal.categoryDeleted'));
|
|
287394
|
+
}
|
|
287395
|
+
catch (error) {
|
|
287396
|
+
console.error('Failed to delete category:', error);
|
|
287397
|
+
toast.error(t('memoryTabManageCategoriesModal.failedToDeleteCategory'));
|
|
287398
|
+
}
|
|
287399
|
+
};
|
|
287400
|
+
return (jsx(Dialog, { open: open, onOpenChange: (next) => {
|
|
287401
|
+
if (!next) {
|
|
287402
|
+
cancelEdit();
|
|
287403
|
+
setConfirmDeleteId(null);
|
|
287404
|
+
setNewName('');
|
|
287405
|
+
}
|
|
287406
|
+
onOpenChange(next);
|
|
287407
|
+
}, children: jsxs(DialogContent, { className: "mx-4 max-w-md sm:mx-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { children: t('memoryTabManageCategoriesModal.manageCategories') }) }), jsxs("div", { className: "flex gap-2", children: [jsx(Input, { value: newName, onChange: (e) => setNewName(e.target.value), placeholder: t('memoryTabManageCategoriesModal.newCategoryNamePlaceholder'), onKeyDown: (e) => {
|
|
287408
|
+
if (e.key === 'Enter') {
|
|
287409
|
+
e.preventDefault();
|
|
287410
|
+
handleCreate();
|
|
287411
|
+
}
|
|
287412
|
+
} }), jsxs(Button$1, { className: "ibl-button-primary", onClick: handleCreate, disabled: !newName.trim() || isCreating, children: [jsx(Plus, { className: "mr-1 h-4 w-4" }), t('memoryTabManageCategoriesModal.add')] })] }), jsx("div", { className: "max-h-[320px] space-y-2 overflow-y-auto", children: isLoading ? (jsx("p", { className: "text-muted-foreground py-4 text-center text-sm", children: t('memoryTabManageCategoriesModal.loadingCategories') })) : categories.length === 0 ? (jsx("p", { className: "text-muted-foreground py-4 text-center text-sm", children: t('memoryTabManageCategoriesModal.noCategoriesYet') })) : (categories.map((category) => {
|
|
287413
|
+
const isEditing = editingId === category.id;
|
|
287414
|
+
const isConfirming = confirmDeleteId === category.id;
|
|
287415
|
+
return (jsx("div", { className: "flex items-center gap-2 rounded-lg border border-gray-200 bg-white p-2", children: isEditing ? (jsxs(Fragment$1, { children: [jsx(Input, { value: editName, onChange: (e) => setEditName(e.target.value), autoFocus: true, onKeyDown: (e) => {
|
|
287416
|
+
if (e.key === 'Enter') {
|
|
287417
|
+
e.preventDefault();
|
|
287418
|
+
saveEdit(category.id);
|
|
287419
|
+
}
|
|
287420
|
+
else if (e.key === 'Escape') {
|
|
287421
|
+
cancelEdit();
|
|
287422
|
+
}
|
|
287423
|
+
}, className: "h-8" }), jsx(Button$1, { variant: "ghost", size: "sm", className: "h-8 w-8 p-0", onClick: () => saveEdit(category.id), disabled: !editName.trim() || isUpdating, "aria-label": t('memoryTabManageCategoriesModal.saveCategory'), children: jsx(Check, { className: "h-4 w-4" }) }), jsx(Button$1, { variant: "ghost", size: "sm", className: "h-8 w-8 p-0", onClick: cancelEdit, "aria-label": t('memoryTabManageCategoriesModal.cancelEdit'), children: jsx(X$2, { className: "h-4 w-4" }) })] })) : isConfirming ? (jsxs(Fragment$1, { children: [jsx("span", { className: "flex-1 text-sm text-gray-900", children: t('memoryTabManageCategoriesModal.confirmDelete', { name: category.name }) }), jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => setConfirmDeleteId(null), children: t('memoryTabManageCategoriesModal.cancel') }), jsx(Button$1, { variant: "destructive", size: "sm", onClick: () => handleDelete(category.id), disabled: isDeleting, children: isDeleting
|
|
287424
|
+
? t('memoryTabManageCategoriesModal.deleting')
|
|
287425
|
+
: t('memoryTabManageCategoriesModal.delete') })] })) : (jsxs(Fragment$1, { children: [jsx("span", { className: "flex-1 text-sm text-gray-900", children: category.name }), jsx(Button$1, { variant: "ghost", size: "sm", className: "h-8 w-8 p-0", onClick: () => startEdit(category), "aria-label": t('memoryTabManageCategoriesModal.editCategory', {
|
|
287426
|
+
name: category.name,
|
|
287427
|
+
}), children: jsx(Pencil, { className: "h-4 w-4" }) }), jsx(Button$1, { variant: "ghost", size: "sm", className: "h-8 w-8 p-0 text-red-600 hover:text-red-700", onClick: () => setConfirmDeleteId(category.id), "aria-label": t('memoryTabManageCategoriesModal.deleteCategory', {
|
|
287428
|
+
name: category.name,
|
|
287429
|
+
}), children: jsx(Trash2, { className: "h-4 w-4" }) })] })) }, category.id));
|
|
287430
|
+
})) }), jsx("div", { className: "mt-2 flex justify-end", children: jsx(Button$1, { variant: "outline", onClick: () => onOpenChange(false), children: t('memoryTabManageCategoriesModal.done') }) })] }) }));
|
|
287431
|
+
}
|
|
287432
|
+
|
|
287433
|
+
var manageCategoriesModal = /*#__PURE__*/Object.freeze({
|
|
287434
|
+
__proto__: null,
|
|
287435
|
+
ManageCategoriesModal: ManageCategoriesModal
|
|
287436
|
+
});
|
|
287437
|
+
|
|
287251
287438
|
const defaultValues = {
|
|
287252
287439
|
category: '',
|
|
287253
287440
|
prompt: '',
|
|
@@ -287620,175 +287807,6 @@ var trainOrDeleteModal = /*#__PURE__*/Object.freeze({
|
|
|
287620
287807
|
TrainOrDeleteModal: TrainOrDeleteModal
|
|
287621
287808
|
});
|
|
287622
287809
|
|
|
287623
|
-
function EditMemoryModal({ open, onOpenChange, editContent, editCategory, onContentChange, onCategoryChange, onSave, onCancel, categories, isSaving, }) {
|
|
287624
|
-
const t = useT();
|
|
287625
|
-
return (jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: jsxs(DialogContent, { className: "mx-4 max-w-2xl sm:mx-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "text-gray-700", children: t('memoryTabEditMemoryModal.editMemory') }) }), jsxs("div", { className: "mt-4 space-y-4", children: [jsxs("div", { children: [jsx("label", { className: "text-sm font-medium text-gray-600", children: t('memoryTabEditMemoryModal.category') }), jsxs(Select$1, { value: editCategory, onValueChange: onCategoryChange, children: [jsx(SelectTrigger, { className: "mt-1", children: jsx(SelectValue, { placeholder: t('memoryTabEditMemoryModal.selectCategory') }) }), jsx(SelectContent, { children: categories
|
|
287626
|
-
.filter((cat) => cat !== 'All')
|
|
287627
|
-
.map((category) => (jsx(SelectItem, { value: category, children: category }, category))) })] })] }), jsxs("div", { children: [jsx("label", { className: "text-sm font-medium text-gray-600", children: t('memoryTabEditMemoryModal.memory') }), jsx(Textarea, { value: editContent, onChange: (e) => onContentChange(e.target.value), placeholder: t('memoryTabEditMemoryModal.enterMemoryContent'), className: "mt-1" }), jsx("p", { className: "mt-1 text-xs text-gray-500", children: editContent.trim().length < 10
|
|
287628
|
-
? t('memoryTabEditMemoryModal.charCountMinimum', {
|
|
287629
|
-
count: editContent.trim().length,
|
|
287630
|
-
})
|
|
287631
|
-
: t('memoryTabEditMemoryModal.charCount', { count: editContent.trim().length }) })] }), jsxs("div", { className: "flex justify-end gap-2", children: [jsx(Button$1, { variant: "outline", onClick: onCancel, children: t('memoryTabEditMemoryModal.cancel') }), jsx(Button$1, { onClick: onSave, className: "ibl-button-primary", disabled: editContent.trim().length < 10 || isSaving, children: isSaving ? t('memoryTabEditMemoryModal.saving') : t('memoryTabEditMemoryModal.save') })] })] })] }) }));
|
|
287632
|
-
}
|
|
287633
|
-
|
|
287634
|
-
var editMemoryModal = /*#__PURE__*/Object.freeze({
|
|
287635
|
-
__proto__: null,
|
|
287636
|
-
EditMemoryModal: EditMemoryModal
|
|
287637
|
-
});
|
|
287638
|
-
|
|
287639
|
-
function AddMemoryModal({ open, onOpenChange, newMemoryContent, newMemoryCategory, onContentChange, onCategoryChange, onSave, onCancel, categories, isSaving, }) {
|
|
287640
|
-
const t = useT();
|
|
287641
|
-
return (jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: jsxs(DialogContent, { className: "mx-4 max-w-2xl sm:mx-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "text-gray-700", children: t('memoryTabAddMemoryModal.addMemory') }) }), jsxs("div", { className: "mt-4 space-y-4", children: [jsxs("div", { children: [jsx("label", { className: "text-sm font-medium text-gray-600", children: t('memoryTabAddMemoryModal.category') }), jsxs(Select$1, { value: newMemoryCategory, onValueChange: onCategoryChange, children: [jsx(SelectTrigger, { className: "mt-1", children: jsx(SelectValue, { placeholder: t('memoryTabAddMemoryModal.selectCategory') }) }), jsx(SelectContent, { children: categories
|
|
287642
|
-
.filter((cat) => cat !== 'All')
|
|
287643
|
-
.map((category) => (jsx(SelectItem, { value: category, children: category }, category))) })] })] }), jsxs("div", { children: [jsx("label", { className: "text-sm font-medium text-gray-600", children: t('memoryTabAddMemoryModal.memory') }), jsx(Textarea, { value: newMemoryContent, onChange: (e) => onContentChange(e.target.value), placeholder: t('memoryTabAddMemoryModal.enterMemoryContent'), className: "mt-1" }), jsx("p", { className: "mt-1 text-xs text-gray-500", children: newMemoryContent.trim().length < 10
|
|
287644
|
-
? t('memoryTabAddMemoryModal.charactersMinimum', {
|
|
287645
|
-
count: newMemoryContent.trim().length,
|
|
287646
|
-
})
|
|
287647
|
-
: t('memoryTabAddMemoryModal.characters', {
|
|
287648
|
-
count: newMemoryContent.trim().length,
|
|
287649
|
-
}) })] }), jsxs("div", { className: "flex justify-end gap-2", children: [jsx(Button$1, { variant: "outline", onClick: onCancel, children: t('memoryTabAddMemoryModal.cancel') }), jsx(Button$1, { onClick: onSave, disabled: newMemoryContent.trim().length < 10 || isSaving, className: "ibl-button-primary", children: isSaving ? t('memoryTabAddMemoryModal.saving') : t('memoryTabAddMemoryModal.save') })] })] })] }) }));
|
|
287650
|
-
}
|
|
287651
|
-
|
|
287652
|
-
var addMemoryModal = /*#__PURE__*/Object.freeze({
|
|
287653
|
-
__proto__: null,
|
|
287654
|
-
AddMemoryModal: AddMemoryModal
|
|
287655
|
-
});
|
|
287656
|
-
|
|
287657
|
-
function BulkDeleteMemoryModal({ open, onOpenChange, onConfirm, onCancel, isDeleting, selectedCategory, }) {
|
|
287658
|
-
const isDeleteAll = selectedCategory === 'All';
|
|
287659
|
-
const getConfirmationText = () => {
|
|
287660
|
-
if (isDeleteAll) {
|
|
287661
|
-
return 'Are you sure you want to delete all memories? This action cannot be undone.';
|
|
287662
|
-
}
|
|
287663
|
-
return `Are you sure you want to delete all memories in the ${selectedCategory} category? This action cannot be undone.`;
|
|
287664
|
-
};
|
|
287665
|
-
const getTitle = () => {
|
|
287666
|
-
if (isDeleteAll) {
|
|
287667
|
-
return 'Delete All Memories';
|
|
287668
|
-
}
|
|
287669
|
-
return `Delete All ${selectedCategory} Memories`;
|
|
287670
|
-
};
|
|
287671
|
-
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: getTitle() }) }), jsx("p", { className: "text-muted-foreground text-sm", children: getConfirmationText() }), jsxs("div", { className: "mt-4 flex justify-end gap-2", children: [jsx(Button$1, { variant: "outline", onClick: onCancel, disabled: isDeleting, children: "Cancel" }), jsx(Button$1, { className: "ibl-button-primary", onClick: onConfirm, disabled: isDeleting, children: isDeleting ? 'Deleting...' : 'Delete' })] })] }) }));
|
|
287672
|
-
}
|
|
287673
|
-
|
|
287674
|
-
var bulkDeleteMemoryModal = /*#__PURE__*/Object.freeze({
|
|
287675
|
-
__proto__: null,
|
|
287676
|
-
BulkDeleteMemoryModal: BulkDeleteMemoryModal
|
|
287677
|
-
});
|
|
287678
|
-
|
|
287679
|
-
const toSlug = (name) => name
|
|
287680
|
-
.trim()
|
|
287681
|
-
.toLowerCase()
|
|
287682
|
-
.replace(/[^a-z0-9]+/g, '_')
|
|
287683
|
-
.replace(/^_+|_+$/g, '');
|
|
287684
|
-
function ManageCategoriesModal({ open, onOpenChange, tenantKey, mentorId, }) {
|
|
287685
|
-
const t = useT();
|
|
287686
|
-
const { data: categories = [], isLoading } = useGetMemoryCategoriesAdminQuery({ org: tenantKey, mentorId }, { skip: !open || !tenantKey || !mentorId });
|
|
287687
|
-
const [createCategory, { isLoading: isCreating }] = useCreateMemoryCategoryMutation();
|
|
287688
|
-
const [updateCategory, { isLoading: isUpdating }] = useUpdateMemoryCategoryMutation();
|
|
287689
|
-
const [deleteCategory, { isLoading: isDeleting }] = useDeleteMemoryCategoryMutation();
|
|
287690
|
-
const [newName, setNewName] = useState('');
|
|
287691
|
-
const [editingId, setEditingId] = useState(null);
|
|
287692
|
-
const [editName, setEditName] = useState('');
|
|
287693
|
-
const [confirmDeleteId, setConfirmDeleteId] = useState(null);
|
|
287694
|
-
const handleCreate = async () => {
|
|
287695
|
-
const name = newName.trim();
|
|
287696
|
-
if (!name)
|
|
287697
|
-
return;
|
|
287698
|
-
try {
|
|
287699
|
-
await createCategory({
|
|
287700
|
-
org: tenantKey,
|
|
287701
|
-
mentorId,
|
|
287702
|
-
data: { name, slug: toSlug(name) },
|
|
287703
|
-
}).unwrap();
|
|
287704
|
-
setNewName('');
|
|
287705
|
-
toast.success(t('memoryTabManageCategoriesModal.categoryCreated'));
|
|
287706
|
-
}
|
|
287707
|
-
catch (error) {
|
|
287708
|
-
console.error('Failed to create category:', error);
|
|
287709
|
-
toast.error(t('memoryTabManageCategoriesModal.failedToCreateCategory'));
|
|
287710
|
-
}
|
|
287711
|
-
};
|
|
287712
|
-
const startEdit = (category) => {
|
|
287713
|
-
setEditingId(category.id);
|
|
287714
|
-
setEditName(category.name);
|
|
287715
|
-
};
|
|
287716
|
-
const cancelEdit = () => {
|
|
287717
|
-
setEditingId(null);
|
|
287718
|
-
setEditName('');
|
|
287719
|
-
};
|
|
287720
|
-
const saveEdit = async (categoryId) => {
|
|
287721
|
-
const name = editName.trim();
|
|
287722
|
-
if (!name)
|
|
287723
|
-
return;
|
|
287724
|
-
try {
|
|
287725
|
-
await updateCategory({
|
|
287726
|
-
org: tenantKey,
|
|
287727
|
-
mentorId,
|
|
287728
|
-
categoryId,
|
|
287729
|
-
data: { name },
|
|
287730
|
-
}).unwrap();
|
|
287731
|
-
cancelEdit();
|
|
287732
|
-
toast.success(t('memoryTabManageCategoriesModal.categoryUpdated'));
|
|
287733
|
-
}
|
|
287734
|
-
catch (error) {
|
|
287735
|
-
console.error('Failed to update category:', error);
|
|
287736
|
-
toast.error(t('memoryTabManageCategoriesModal.failedToUpdateCategory'));
|
|
287737
|
-
}
|
|
287738
|
-
};
|
|
287739
|
-
const handleDelete = async (categoryId) => {
|
|
287740
|
-
try {
|
|
287741
|
-
await deleteCategory({
|
|
287742
|
-
org: tenantKey,
|
|
287743
|
-
mentorId,
|
|
287744
|
-
categoryId,
|
|
287745
|
-
}).unwrap();
|
|
287746
|
-
setConfirmDeleteId(null);
|
|
287747
|
-
toast.success(t('memoryTabManageCategoriesModal.categoryDeleted'));
|
|
287748
|
-
}
|
|
287749
|
-
catch (error) {
|
|
287750
|
-
console.error('Failed to delete category:', error);
|
|
287751
|
-
toast.error(t('memoryTabManageCategoriesModal.failedToDeleteCategory'));
|
|
287752
|
-
}
|
|
287753
|
-
};
|
|
287754
|
-
return (jsx(Dialog, { open: open, onOpenChange: (next) => {
|
|
287755
|
-
if (!next) {
|
|
287756
|
-
cancelEdit();
|
|
287757
|
-
setConfirmDeleteId(null);
|
|
287758
|
-
setNewName('');
|
|
287759
|
-
}
|
|
287760
|
-
onOpenChange(next);
|
|
287761
|
-
}, children: jsxs(DialogContent, { className: "mx-4 max-w-md sm:mx-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { children: t('memoryTabManageCategoriesModal.manageCategories') }) }), jsxs("div", { className: "flex gap-2", children: [jsx(Input, { value: newName, onChange: (e) => setNewName(e.target.value), placeholder: t('memoryTabManageCategoriesModal.newCategoryNamePlaceholder'), onKeyDown: (e) => {
|
|
287762
|
-
if (e.key === 'Enter') {
|
|
287763
|
-
e.preventDefault();
|
|
287764
|
-
handleCreate();
|
|
287765
|
-
}
|
|
287766
|
-
} }), jsxs(Button$1, { className: "ibl-button-primary", onClick: handleCreate, disabled: !newName.trim() || isCreating, children: [jsx(Plus, { className: "mr-1 h-4 w-4" }), t('memoryTabManageCategoriesModal.add')] })] }), jsx("div", { className: "max-h-[320px] space-y-2 overflow-y-auto", children: isLoading ? (jsx("p", { className: "text-muted-foreground py-4 text-center text-sm", children: t('memoryTabManageCategoriesModal.loadingCategories') })) : categories.length === 0 ? (jsx("p", { className: "text-muted-foreground py-4 text-center text-sm", children: t('memoryTabManageCategoriesModal.noCategoriesYet') })) : (categories.map((category) => {
|
|
287767
|
-
const isEditing = editingId === category.id;
|
|
287768
|
-
const isConfirming = confirmDeleteId === category.id;
|
|
287769
|
-
return (jsx("div", { className: "flex items-center gap-2 rounded-lg border border-gray-200 bg-white p-2", children: isEditing ? (jsxs(Fragment$1, { children: [jsx(Input, { value: editName, onChange: (e) => setEditName(e.target.value), autoFocus: true, onKeyDown: (e) => {
|
|
287770
|
-
if (e.key === 'Enter') {
|
|
287771
|
-
e.preventDefault();
|
|
287772
|
-
saveEdit(category.id);
|
|
287773
|
-
}
|
|
287774
|
-
else if (e.key === 'Escape') {
|
|
287775
|
-
cancelEdit();
|
|
287776
|
-
}
|
|
287777
|
-
}, className: "h-8" }), jsx(Button$1, { variant: "ghost", size: "sm", className: "h-8 w-8 p-0", onClick: () => saveEdit(category.id), disabled: !editName.trim() || isUpdating, "aria-label": t('memoryTabManageCategoriesModal.saveCategory'), children: jsx(Check, { className: "h-4 w-4" }) }), jsx(Button$1, { variant: "ghost", size: "sm", className: "h-8 w-8 p-0", onClick: cancelEdit, "aria-label": t('memoryTabManageCategoriesModal.cancelEdit'), children: jsx(X$2, { className: "h-4 w-4" }) })] })) : isConfirming ? (jsxs(Fragment$1, { children: [jsx("span", { className: "flex-1 text-sm text-gray-900", children: t('memoryTabManageCategoriesModal.confirmDelete', { name: category.name }) }), jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => setConfirmDeleteId(null), children: t('memoryTabManageCategoriesModal.cancel') }), jsx(Button$1, { variant: "destructive", size: "sm", onClick: () => handleDelete(category.id), disabled: isDeleting, children: isDeleting
|
|
287778
|
-
? t('memoryTabManageCategoriesModal.deleting')
|
|
287779
|
-
: t('memoryTabManageCategoriesModal.delete') })] })) : (jsxs(Fragment$1, { children: [jsx("span", { className: "flex-1 text-sm text-gray-900", children: category.name }), jsx(Button$1, { variant: "ghost", size: "sm", className: "h-8 w-8 p-0", onClick: () => startEdit(category), "aria-label": t('memoryTabManageCategoriesModal.editCategory', {
|
|
287780
|
-
name: category.name,
|
|
287781
|
-
}), children: jsx(Pencil, { className: "h-4 w-4" }) }), jsx(Button$1, { variant: "ghost", size: "sm", className: "h-8 w-8 p-0 text-red-600 hover:text-red-700", onClick: () => setConfirmDeleteId(category.id), "aria-label": t('memoryTabManageCategoriesModal.deleteCategory', {
|
|
287782
|
-
name: category.name,
|
|
287783
|
-
}), children: jsx(Trash2, { className: "h-4 w-4" }) })] })) }, category.id));
|
|
287784
|
-
})) }), jsx("div", { className: "mt-2 flex justify-end", children: jsx(Button$1, { variant: "outline", onClick: () => onOpenChange(false), children: t('memoryTabManageCategoriesModal.done') }) })] }) }));
|
|
287785
|
-
}
|
|
287786
|
-
|
|
287787
|
-
var manageCategoriesModal = /*#__PURE__*/Object.freeze({
|
|
287788
|
-
__proto__: null,
|
|
287789
|
-
ManageCategoriesModal: ManageCategoriesModal
|
|
287790
|
-
});
|
|
287791
|
-
|
|
287792
287810
|
function ImagePreviewModal({ url, onClose }) {
|
|
287793
287811
|
return (jsx("div", { className: "bg-opacity-75 fixed inset-0 z-50 flex items-center justify-center bg-black p-4", onClick: onClose, children: jsxs("div", { className: "relative flex h-full w-full items-center justify-center", children: [jsx("button", { className: "bg-opacity-50 hover:bg-opacity-70 absolute top-2 right-2 rounded-full bg-black p-1 text-white", onClick: (e) => {
|
|
287794
287812
|
e.stopPropagation();
|