@iblai/iblai-js 2.3.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { useRef, useEffect, useState, useCallback, useLayoutEffect, forwardRef, createElement as createElement$1, createContext, useContext, useMemo, useReducer, useImperativeHandle, isValidElement, Children, PureComponent, cloneElement, Component, useId as useId$2, useDebugValue, lazy, Suspense } from 'react';
3
3
  import { useDispatch, useSelector } from 'react-redux';
4
- import { selectSessionId, selectActiveChatMessages, useCachedSessionId, chatActions, LOCAL_STORAGE_KEYS, TimeTracker, getInitials, useTenantMetadata, WithPermissions, useStripeUpgrade, openExternalUrl, CHAT_AREA_SIZE, isAlphaNumeric32, checkRbacPermission, getTimeAgo, REQUIRED_ACTIONS_FOR_GROUPS, formatRelativeTime as formatRelativeTime$2, ANONYMOUS_USERNAME, combineCSVData, redirectToAuthSpaJoinTenant, redirectToAuthSpa, getAuthSpaJoinUrl, useOS, selectNumberOfActiveChatMessages, useUsername, selectStreaming, isLoggedIn, TOOLS, hasRemoteAiConfig, isSafariBrowser, useShowAttachment, useShowVoiceCall, useShowVoiceRecorder, useMentorSettings, selectShowingSharedChat, selectRbacPermissions, useShowFreeTrialDialog, useEmbedMode, chatInputSliceSelectors, useResponsive, useAccessingPublicRoute, useVisitingTenant, useModelFileUploadCapabilities, useChatFileUpload, useVoiceChat, selectAttachedFiles, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, chatInputSliceActions, removeFile, WithFormPermissions, MENTOR_VISIBILITY } from '@iblai/web-utils';
4
+ import { selectSessionId, selectActiveChatMessages, useCachedSessionId, chatActions, LOCAL_STORAGE_KEYS, TimeTracker, getInitials, useTenantMetadata, WithPermissions, canWriteField, useStripeUpgrade, openExternalUrl, CHAT_AREA_SIZE, isAlphaNumeric32, checkRbacPermission, getTimeAgo, REQUIRED_ACTIONS_FOR_GROUPS, formatRelativeTime as formatRelativeTime$2, ANONYMOUS_USERNAME, combineCSVData, redirectToAuthSpaJoinTenant, redirectToAuthSpa, getAuthSpaJoinUrl, useOS, selectNumberOfActiveChatMessages, useUsername, selectStreaming, isLoggedIn, TOOLS, hasRemoteAiConfig, isSafariBrowser, useShowAttachment, useShowVoiceCall, useShowVoiceRecorder, useMentorSettings, selectShowingSharedChat, selectRbacPermissions, useShowFreeTrialDialog, useEmbedMode, chatInputSliceSelectors, useResponsive, useAccessingPublicRoute, useVisitingTenant, useModelFileUploadCapabilities, useChatFileUpload, useVoiceChat, selectAttachedFiles, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, chatInputSliceActions, removeFile, WithFormPermissions, MENTOR_VISIBILITY } from '@iblai/web-utils';
5
5
  import * as dataLayer from '@iblai/data-layer';
6
- import { useCreateSessionIdMutation, useTimeTrackingMutation, useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useGetLearnerDetailsQuery, useGetUserEnrolledCoursesQuery, useGetUserEnrolledProgramsQuery, useGetUserCatalogPathwaysQuery, useGetUsersAsAssertionsQuery, useGetUserEarnedSkillsQuery, useGetUserReportedSkillsQuery, useGetUserDesiredSkillsQuery, useCreateGlobalMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacActionsDefinitionQuery, useGetRbacResourceDiscoveryQuery, useGetRbacResourceListQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useGetWatchedGroupsQuery, useCreateWatchedGroupMutation, useUpdateWatchedGroupMutation, useDeleteWatchedGroupMutation, useAddWatchedUserMutation, useRemoveWatchedUserMutation, useAddWatcherMutation, useUpdateWatcherMutation, useDeleteWatcherMutation, useGetWatchedUsersQuery, useGetWatchersQuery, WATCHER_NOTIFICATION_EVENTS, WATCHER_NOTIFICATION_EVENT_LABELS, useGetApplicationFormsQuery, useGetApplicationFormDetailQuery, useCreateApplicationFormMutation, useUpdateApplicationFormMutation, useGetApplicationAdminDetailQuery, useInviteApplicationCandidateMutation, useLazyGetApplicationAttachmentFileQuery, useCreateApplicationWaiverMutation, useDeleteApplicationWaiverMutation, useSubmitApplicationOverrideMutation, useUpdateApplicationPlacementMutation, useDeleteApplicationCourseAssignmentMutation, useCreateApplicationNoteMutation, useUpdateApplicationNoteMutation, useDeleteApplicationNoteMutation, useTransitionApplicationMutation, useLinkApplicationCandidateMutation, useCreateApplicationPlacementsMutation, useGetCustomMentorsQuery, useCreateApplicationCourseAssignmentsMutation, useGetApplicationBlocksQuery, useDeleteApplicationBlockMutation, useGetApplicationsPipelineStatsQuery, useGetApplicationsPipelineQuery, useDeleteApiKeyMutation, useGetApiKeysQuery, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, useGetCustomDomainsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useUpdateTenantMetadataMutation, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useGetMemsearchConfigQuery, useUpdateMemsearchConfigMutation, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useGetAiSearchMentorsQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useGetNotificationsCountQuery, useLazyGetNotificationsQuery, useMarkAllAsReadMutation, useCreateNotificationPreviewMutation, useSendNotificationMutation, useGetMentorsQuery, useUpdateTemplateMutation, useGetTemplateDetailsQuery, useGetTemplatesQuery, useLazyGetTemplateDetailsQuery, useToggleTemplateMutation, useGetTopicsStatsQuery, useGetUsersStatsQuery, useGetSessionStatsQuery, useGetTopicsDetailsStatsQuery, useGetAccessTimeHeatmapQuery, useGetUserDetailsStatsQuery, useGetTranscriptsConversationHeadlineQuery, useGetAverageRatingQuery, useGetFinancialStatsQuery, useGetDetailedFinancialStatsQuery, useGetTranscriptsMessagesDetailsQuery, useGetTranscriptsMessagesQuery, useGetReportDetailQuery, useLazyGetDownloadReportFromURLQuery, useGetMentorPublicSettingsQuery, useGetReportsQuery, useCreateReportMutation, useGetContentAnalyticsQuery, useGetContentAnalyticsDetailsQuery, useGetRevenueQuery, useListSubscribersQuery, useGetAuditLogsQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetUserEnrolledCoursesQuery, useLazyGetUserAssignedCoursesQuery, useLazyGetUserCredentialsQuery, useLazyGetOverTimeActivityQuery, useLazyGetCatalogSearchQuery, useCreateOrUpdateUserReportedSkillMutation, useCreateOrUpdateUserDesiredSkillMutation, useLazyGetPathwayListQuery, useLazyGetUserAssignedPathwaysQuery, useLazyGetUserEnrolledPathwaysQuery, useLazyGetPathwayCompletionQuery, useLazyGetProgramListQuery, useLazyGetProgramCompletionQuery, useLazyGetUserEnrolledProgramsQuery, useLazyGetAssignedProgramsQuery, useLazyGetUserSkillsPointsQuery, useLazyGetUserReportedSkillsQuery, useLazyGetUserDesiredSkillsQuery, useLazyGetUserCatalogPathwaysQuery, useLazyGetPerLearnerInfoQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useLazyGetPersonnalizedSearchQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetClawMentorConfigQuery, useGetClawInstancesQuery, useGetAgentConfigQuery, useUpdateClawMentorConfigMutation, useCreateClawMentorConfigMutation, useDeleteClawMentorConfigMutation, usePushClawConfigMutation, useCreateClawInstanceMutation, useDeleteClawInstanceMutation, useUpdateAgentConfigMutation, useHealthCheckClawInstanceMutation, useTestConnectivityClawInstanceMutation, useUpdateClawInstanceMutation, useGetAgentSkillResourcesQuery, useCreateAgentSkillResourceMutation, useUpdateAgentSkillResourceMutation, useUploadAgentSkillResourceAssetMutation, useDeleteAgentSkillResourceMutation, useGetAgentSkillsQuery, useGetMentorSkillAssignmentsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, resolveEffectiveAgentSkills, filterSlashSkills, useCreateCheckoutMutation, useGetUserProjectsQuery, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useGetVectorDocumentsQuery, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useDeleteMentorMemoryMutation, useUpdateMentorMemoryMutation, useCreateMentorMemoryMutation, useLazyGetConnectedServiceAuthUrlQuery, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorSettingsQuery, useEditMentorMutation, useGetMentorCategoriesQuery, useCreateMentorMutation, useUpdateUserPlatformMetadataMutation, useGetApplicationStatusQuery, useListOwnApplicationsQuery, useGetApplicationFormQuery, useWithdrawApplicationMutation, useRenewApplicationMutation, useCreateApplicationDraftMutation, useSubmitApplicationMutation, useUpdateApplicationMutation, useUploadApplicationAttachmentMutation, useDeleteApplicationAttachmentMutation, useGetPromptCategoriesQuery, useCreatePromptMutation, useDeletePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation } from '@iblai/data-layer';
6
+ import { useCreateSessionIdMutation, useTimeTrackingMutation, useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useGetLearnerDetailsQuery, useGetUserEnrolledCoursesQuery, useGetUserEnrolledProgramsQuery, useGetUserCatalogPathwaysQuery, useGetUsersAsAssertionsQuery, useGetUserEarnedSkillsQuery, useGetUserReportedSkillsQuery, useGetUserDesiredSkillsQuery, useCreateGlobalMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacActionsDefinitionQuery, useGetRbacResourceDiscoveryQuery, useGetRbacResourceListQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useGetWatchedGroupsQuery, useCreateWatchedGroupMutation, useUpdateWatchedGroupMutation, useDeleteWatchedGroupMutation, useAddWatchedUserMutation, useRemoveWatchedUserMutation, useAddWatcherMutation, useUpdateWatcherMutation, useDeleteWatcherMutation, useGetWatchedUsersQuery, useGetWatchersQuery, WATCHER_NOTIFICATION_EVENTS, WATCHER_NOTIFICATION_EVENT_LABELS, useGetApplicationFormsQuery, useGetApplicationFormDetailQuery, useCreateApplicationFormMutation, useUpdateApplicationFormMutation, useGetApplicationAdminDetailQuery, useInviteApplicationCandidateMutation, useLazyGetApplicationAttachmentFileQuery, useCreateApplicationWaiverMutation, useDeleteApplicationWaiverMutation, useSubmitApplicationOverrideMutation, useUpdateApplicationPlacementMutation, useDeleteApplicationCourseAssignmentMutation, useCreateApplicationNoteMutation, useUpdateApplicationNoteMutation, useDeleteApplicationNoteMutation, useTransitionApplicationMutation, useLinkApplicationCandidateMutation, useCreateApplicationPlacementsMutation, useGetCustomMentorsQuery, useCreateApplicationCourseAssignmentsMutation, useGetApplicationBlocksQuery, useDeleteApplicationBlockMutation, useGetApplicationsPipelineStatsQuery, useGetApplicationsPipelineQuery, useDeleteApiKeyMutation, useGetApiKeyQuery, useGetApiKeyFieldPermissionsQuery, useUpdateApiKeyMutation, useGetApiKeysQuery, unwrapApiTokenList, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, useGetCustomDomainsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useUpdateTenantMetadataMutation, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useGetMemsearchConfigQuery, useUpdateMemsearchConfigMutation, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useGetAiSearchMentorsQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useGetNotificationsCountQuery, useLazyGetNotificationsQuery, useMarkAllAsReadMutation, useCreateNotificationPreviewMutation, useSendNotificationMutation, useGetMentorsQuery, useUpdateTemplateMutation, useGetTemplateDetailsQuery, useGetTemplatesQuery, useLazyGetTemplateDetailsQuery, useToggleTemplateMutation, useGetTopicsStatsQuery, useGetUsersStatsQuery, useGetSessionStatsQuery, useGetTopicsDetailsStatsQuery, useGetAccessTimeHeatmapQuery, useGetUserDetailsStatsQuery, useGetTranscriptsConversationHeadlineQuery, useGetAverageRatingQuery, useGetFinancialStatsQuery, useGetDetailedFinancialStatsQuery, useGetTranscriptsMessagesDetailsQuery, useGetTranscriptsMessagesQuery, useGetReportDetailQuery, useLazyGetDownloadReportFromURLQuery, useGetMentorPublicSettingsQuery, useGetReportsQuery, useCreateReportMutation, useGetContentAnalyticsQuery, useGetContentAnalyticsDetailsQuery, useGetRevenueQuery, useListSubscribersQuery, useGetAuditLogsQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetUserEnrolledCoursesQuery, useLazyGetUserAssignedCoursesQuery, useLazyGetUserCredentialsQuery, useLazyGetOverTimeActivityQuery, useLazyGetCatalogSearchQuery, useCreateOrUpdateUserReportedSkillMutation, useCreateOrUpdateUserDesiredSkillMutation, useLazyGetPathwayListQuery, useLazyGetUserAssignedPathwaysQuery, useLazyGetUserEnrolledPathwaysQuery, useLazyGetPathwayCompletionQuery, useLazyGetProgramListQuery, useLazyGetProgramCompletionQuery, useLazyGetUserEnrolledProgramsQuery, useLazyGetAssignedProgramsQuery, useLazyGetUserSkillsPointsQuery, useLazyGetUserReportedSkillsQuery, useLazyGetUserDesiredSkillsQuery, useLazyGetUserCatalogPathwaysQuery, useLazyGetPerLearnerInfoQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useLazyGetPersonnalizedSearchQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetClawMentorConfigQuery, useGetClawInstancesQuery, useGetAgentConfigQuery, useUpdateClawMentorConfigMutation, useCreateClawMentorConfigMutation, useDeleteClawMentorConfigMutation, usePushClawConfigMutation, useCreateClawInstanceMutation, useDeleteClawInstanceMutation, useUpdateAgentConfigMutation, useHealthCheckClawInstanceMutation, useTestConnectivityClawInstanceMutation, useUpdateClawInstanceMutation, useGetAgentSkillResourcesQuery, useCreateAgentSkillResourceMutation, useUpdateAgentSkillResourceMutation, useUploadAgentSkillResourceAssetMutation, useDeleteAgentSkillResourceMutation, useGetAgentSkillsQuery, useGetMentorSkillAssignmentsQuery, useCreateMentorSkillAssignmentMutation, useUpdateMentorSkillAssignmentMutation, useDeleteMentorSkillAssignmentMutation, useCreateAgentSkillMutation, useUpdateAgentSkillMutation, useDeleteAgentSkillMutation, resolveEffectiveAgentSkills, filterSlashSkills, useCreateCheckoutMutation, useGetUserProjectsQuery, useUpdateUserProjectMutation, useGetTrainingDocumentsQuery, useGetVectorDocumentsQuery, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useDeleteMentorMemoryMutation, useUpdateMentorMemoryMutation, useCreateMentorMemoryMutation, useLazyGetConnectedServiceAuthUrlQuery, useCreateUserProjectMutation, useDeleteUserProjectMutation, useGetUserProjectDetailsQuery, useEditTrainingDocumentMutation, useAddTrainingDocumentMutation, useLazyGetCredentialsQuery, useGetMentorSettingsQuery, useEditMentorMutation, useGetMentorCategoriesQuery, useCreateMentorMutation, useUpdateUserPlatformMetadataMutation, useGetApplicationStatusQuery, useListOwnApplicationsQuery, useGetApplicationFormQuery, useWithdrawApplicationMutation, useRenewApplicationMutation, useCreateApplicationDraftMutation, useSubmitApplicationMutation, useUpdateApplicationMutation, useUploadApplicationAttachmentMutation, useDeleteApplicationAttachmentMutation, useGetPromptCategoriesQuery, useCreatePromptMutation, useDeletePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation } from '@iblai/data-layer';
7
7
  import { toast } from 'sonner';
8
8
  import { jsx, Fragment as Fragment$1, jsxs } from 'react/jsx-runtime';
9
9
  import * as ReactDOM from 'react-dom';
@@ -60768,6 +60768,18 @@ var apiTabDeleteApiModal2$3 = {
60768
60768
  successMessage: "API Key deleted successfully",
60769
60769
  errorMessage: "Failed to delete API Key"
60770
60770
  };
60771
+ var apiTabEditApiModal$3 = {
60772
+ title: "Edit API Key",
60773
+ editAriaLabel: "Edit API Key",
60774
+ renameWarning: "The name identifies this key in the API. Renaming it changes that identifier.",
60775
+ expirationHelp: "Clear the date to let this key never expire.",
60776
+ save: "Save",
60777
+ saving: "Saving...",
60778
+ successToast: "API Key updated successfully",
60779
+ errorToast: "Failed to update API Key",
60780
+ loading: "Loading...",
60781
+ loadError: "Failed to load API Key"
60782
+ };
60771
60783
  var apiTabLabels$3 = {
60772
60784
  header: {
60773
60785
  title: "API",
@@ -60778,6 +60790,7 @@ var apiTabLabels$3 = {
60778
60790
  lineTwo: "Do not share your API key with others, or expose it in the browser or other client-side code. In order to protect the security of your account, IBL may also automatically rotate any API key that we’ve found has leaked publicly."
60779
60791
  },
60780
60792
  table: {
60793
+ banner: "These are authentication keys that you've generated for external applications to authenticate with your service. Keys are displayed only once when generated.",
60781
60794
  nameColumn: "NAME",
60782
60795
  createdColumn: "CREATED",
60783
60796
  expiresColumn: "EXPIRES",
@@ -60818,6 +60831,21 @@ var apiTabLabels$3 = {
60818
60831
  descriptionLineTwo: "If you lose your API key, you'll need to generate a new one."
60819
60832
  }
60820
60833
  };
60834
+ var apiTabTokenPolicies$3 = {
60835
+ modeLabel: "Permission Mode",
60836
+ ownerModeLabel: "Owner permissions",
60837
+ ownerModeDescription: "The key inherits the RBAC permissions of the user who created it.",
60838
+ tokenPoliciesModeLabel: "Token policies",
60839
+ tokenPoliciesModeDescription: "The key resolves permissions from the policies and groups assigned below.",
60840
+ policiesLabel: "Policies",
60841
+ policiesPlaceholder: "Search policies...",
60842
+ policiesHelp: "Policies assigned directly to this key.",
60843
+ groupsLabel: "Groups",
60844
+ groupsPlaceholder: "Search groups...",
60845
+ groupsHelp: "Groups whose policies this key inherits.",
60846
+ noneSelected: "None",
60847
+ clearExpiration: "Clear expiration date"
60848
+ };
60821
60849
  var appSidebarIndex$3 = {
60822
60850
  pinnedMessages: "Pinned Messages",
60823
60851
  recentMessages: "Recent Messages"
@@ -65760,7 +65788,9 @@ var en = {
65760
65788
  apiTabApiKeyModal: apiTabApiKeyModal$3,
65761
65789
  apiTabCreateApiModal2: apiTabCreateApiModal2$3,
65762
65790
  apiTabDeleteApiModal2: apiTabDeleteApiModal2$3,
65791
+ apiTabEditApiModal: apiTabEditApiModal$3,
65763
65792
  apiTabLabels: apiTabLabels$3,
65793
+ apiTabTokenPolicies: apiTabTokenPolicies$3,
65764
65794
  appSidebarIndex: appSidebarIndex$3,
65765
65795
  appSidebarProjectItem: appSidebarProjectItem$3,
65766
65796
  appSidebarProjectsSidebarDropdown: appSidebarProjectsSidebarDropdown$3,
@@ -66954,6 +66984,18 @@ var apiTabDeleteApiModal2$2 = {
66954
66984
  successMessage: "Clé API supprimée avec succès",
66955
66985
  errorMessage: "Échec de la suppression de la clé API"
66956
66986
  };
66987
+ var apiTabEditApiModal$2 = {
66988
+ title: "Modifier la clé API",
66989
+ editAriaLabel: "Modifier la clé API",
66990
+ renameWarning: "Le nom identifie cette clé dans l'API. Le modifier change cet identifiant.",
66991
+ expirationHelp: "Effacez la date pour que cette clé n'expire jamais.",
66992
+ save: "Enregistrer",
66993
+ saving: "Enregistrement...",
66994
+ successToast: "Clé API mise à jour avec succès",
66995
+ errorToast: "Échec de la mise à jour de la clé API",
66996
+ loading: "Chargement...",
66997
+ loadError: "Échec du chargement de la clé API"
66998
+ };
66957
66999
  var apiTabLabels$2 = {
66958
67000
  header: {
66959
67001
  title: "API",
@@ -66964,6 +67006,7 @@ var apiTabLabels$2 = {
66964
67006
  lineTwo: "Ne partagez pas votre clé API avec d’autres personnes et ne l’exposez pas dans le navigateur ou dans un autre code côté client. Pour protéger la sécurité de votre compte, IBL peut également faire pivoter automatiquement toute clé API que nous avons détectée comme publiquement exposée."
66965
67007
  },
66966
67008
  table: {
67009
+ banner: "Voici les clés d'authentification que vous avez générées pour permettre à des applications externes de s'authentifier auprès de votre service. Les clés ne s'affichent qu'une seule fois, lors de leur génération.",
66967
67010
  nameColumn: "NOM",
66968
67011
  createdColumn: "CRÉÉ",
66969
67012
  expiresColumn: "EXPIRE",
@@ -67004,6 +67047,21 @@ var apiTabLabels$2 = {
67004
67047
  descriptionLineTwo: "Si vous perdez votre clé API, vous devrez en générer une nouvelle."
67005
67048
  }
67006
67049
  };
67050
+ var apiTabTokenPolicies$2 = {
67051
+ modeLabel: "Mode de permission",
67052
+ ownerModeLabel: "Permissions du propriétaire",
67053
+ ownerModeDescription: "La clé hérite des permissions RBAC de l'utilisateur qui l'a créée.",
67054
+ tokenPoliciesModeLabel: "Politiques du jeton",
67055
+ tokenPoliciesModeDescription: "La clé résout ses permissions à partir des politiques et des groupes attribués ci-dessous.",
67056
+ policiesLabel: "Politiques",
67057
+ policiesPlaceholder: "Rechercher des politiques...",
67058
+ policiesHelp: "Politiques attribuées directement à cette clé.",
67059
+ groupsLabel: "Groupes",
67060
+ groupsPlaceholder: "Rechercher des groupes...",
67061
+ groupsHelp: "Groupes dont cette clé hérite des politiques.",
67062
+ noneSelected: "Aucun",
67063
+ clearExpiration: "Effacer la date d'expiration"
67064
+ };
67007
67065
  var appSidebarIndex$2 = {
67008
67066
  pinnedMessages: "Messages épinglés",
67009
67067
  recentMessages: "Messages récents"
@@ -71946,7 +72004,9 @@ var fr = {
71946
72004
  apiTabApiKeyModal: apiTabApiKeyModal$2,
71947
72005
  apiTabCreateApiModal2: apiTabCreateApiModal2$2,
71948
72006
  apiTabDeleteApiModal2: apiTabDeleteApiModal2$2,
72007
+ apiTabEditApiModal: apiTabEditApiModal$2,
71949
72008
  apiTabLabels: apiTabLabels$2,
72009
+ apiTabTokenPolicies: apiTabTokenPolicies$2,
71950
72010
  appSidebarIndex: appSidebarIndex$2,
71951
72011
  appSidebarProjectItem: appSidebarProjectItem$2,
71952
72012
  appSidebarProjectsSidebarDropdown: appSidebarProjectsSidebarDropdown$2,
@@ -73140,6 +73200,18 @@ var apiTabDeleteApiModal2$1 = {
73140
73200
  successMessage: "Clave API eliminada correctamente",
73141
73201
  errorMessage: "Error al eliminar la clave API"
73142
73202
  };
73203
+ var apiTabEditApiModal$1 = {
73204
+ title: "Editar clave API",
73205
+ editAriaLabel: "Editar clave API",
73206
+ renameWarning: "El nombre identifica esta clave en la API. Cambiarlo modifica ese identificador.",
73207
+ expirationHelp: "Borra la fecha para que esta clave nunca caduque.",
73208
+ save: "Guardar",
73209
+ saving: "Guardando...",
73210
+ successToast: "Clave API actualizada correctamente",
73211
+ errorToast: "No se pudo actualizar la clave API",
73212
+ loading: "Cargando...",
73213
+ loadError: "No se pudo cargar la clave API"
73214
+ };
73143
73215
  var apiTabLabels$1 = {
73144
73216
  header: {
73145
73217
  title: "API",
@@ -73150,6 +73222,7 @@ var apiTabLabels$1 = {
73150
73222
  lineTwo: "No comparta su clave API con otros ni la exponga en el navegador u otro código del lado del cliente. Para proteger la seguridad de su cuenta, IBL también puede rotar automáticamente cualquier clave API que hayamos detectado que se ha filtrado públicamente."
73151
73223
  },
73152
73224
  table: {
73225
+ banner: "Estas son las claves de autenticación que has generado para que aplicaciones externas se autentiquen con tu servicio. Las claves solo se muestran una vez, al generarlas.",
73153
73226
  nameColumn: "NOMBRE",
73154
73227
  createdColumn: "CREADO",
73155
73228
  expiresColumn: "EXPIRA",
@@ -73190,6 +73263,21 @@ var apiTabLabels$1 = {
73190
73263
  descriptionLineTwo: "Si pierde su clave API, deberá generar una nueva."
73191
73264
  }
73192
73265
  };
73266
+ var apiTabTokenPolicies$1 = {
73267
+ modeLabel: "Modo de permisos",
73268
+ ownerModeLabel: "Permisos del propietario",
73269
+ ownerModeDescription: "La clave hereda los permisos RBAC del usuario que la creó.",
73270
+ tokenPoliciesModeLabel: "Políticas del token",
73271
+ tokenPoliciesModeDescription: "La clave resuelve sus permisos a partir de las políticas y los grupos asignados a continuación.",
73272
+ policiesLabel: "Políticas",
73273
+ policiesPlaceholder: "Buscar políticas...",
73274
+ policiesHelp: "Políticas asignadas directamente a esta clave.",
73275
+ groupsLabel: "Grupos",
73276
+ groupsPlaceholder: "Buscar grupos...",
73277
+ groupsHelp: "Grupos cuyas políticas hereda esta clave.",
73278
+ noneSelected: "Ninguno",
73279
+ clearExpiration: "Borrar la fecha de caducidad"
73280
+ };
73193
73281
  var appSidebarIndex$1 = {
73194
73282
  pinnedMessages: "Mensajes anclados",
73195
73283
  recentMessages: "Mensajes recientes"
@@ -78132,7 +78220,9 @@ var es = {
78132
78220
  apiTabApiKeyModal: apiTabApiKeyModal$1,
78133
78221
  apiTabCreateApiModal2: apiTabCreateApiModal2$1,
78134
78222
  apiTabDeleteApiModal2: apiTabDeleteApiModal2$1,
78223
+ apiTabEditApiModal: apiTabEditApiModal$1,
78135
78224
  apiTabLabels: apiTabLabels$1,
78225
+ apiTabTokenPolicies: apiTabTokenPolicies$1,
78136
78226
  appSidebarIndex: appSidebarIndex$1,
78137
78227
  appSidebarProjectItem: appSidebarProjectItem$1,
78138
78228
  appSidebarProjectsSidebarDropdown: appSidebarProjectsSidebarDropdown$1,
@@ -79326,6 +79416,18 @@ var apiTabDeleteApiModal2 = {
79326
79416
  successMessage: "API 密钥已成功删除",
79327
79417
  errorMessage: "删除 API 密钥失败"
79328
79418
  };
79419
+ var apiTabEditApiModal = {
79420
+ title: "编辑 API 密钥",
79421
+ editAriaLabel: "编辑 API 密钥",
79422
+ renameWarning: "名称是此密钥在 API 中的标识,修改名称会更改该标识。",
79423
+ expirationHelp: "清除日期可让此密钥永不过期。",
79424
+ save: "保存",
79425
+ saving: "保存中...",
79426
+ successToast: "API 密钥更新成功",
79427
+ errorToast: "更新 API 密钥失败",
79428
+ loading: "加载中...",
79429
+ loadError: "加载 API 密钥失败"
79430
+ };
79329
79431
  var apiTabLabels = {
79330
79432
  header: {
79331
79433
  title: "API",
@@ -79336,6 +79438,7 @@ var apiTabLabels = {
79336
79438
  lineTwo: "请勿将您的 API 密钥共享给他人,也勿将其暴露在浏览器或其他客户端代码中。为了保护您账户的安全,IBL 也可能会自动轮换我们发现已公开泄露的任何 API 密钥。"
79337
79439
  },
79338
79440
  table: {
79441
+ banner: "以下是您为外部应用程序生成的身份验证密钥,用于向您的服务进行身份验证。密钥仅在生成时显示一次。",
79339
79442
  nameColumn: "名称",
79340
79443
  createdColumn: "创建时间",
79341
79444
  expiresColumn: "过期时间",
@@ -79376,6 +79479,21 @@ var apiTabLabels = {
79376
79479
  descriptionLineTwo: "如果您丢失了 API 密钥,将需要重新生成一个新的。"
79377
79480
  }
79378
79481
  };
79482
+ var apiTabTokenPolicies = {
79483
+ modeLabel: "权限模式",
79484
+ ownerModeLabel: "所有者权限",
79485
+ ownerModeDescription: "此密钥继承创建者的 RBAC 权限。",
79486
+ tokenPoliciesModeLabel: "令牌策略",
79487
+ tokenPoliciesModeDescription: "此密钥根据下方分配的策略和群组解析权限。",
79488
+ policiesLabel: "策略",
79489
+ policiesPlaceholder: "搜索策略...",
79490
+ policiesHelp: "直接分配给此密钥的策略。",
79491
+ groupsLabel: "群组",
79492
+ groupsPlaceholder: "搜索群组...",
79493
+ groupsHelp: "此密钥继承其策略的群组。",
79494
+ noneSelected: "无",
79495
+ clearExpiration: "清除过期日期"
79496
+ };
79379
79497
  var appSidebarIndex = {
79380
79498
  pinnedMessages: "已固定的消息",
79381
79499
  recentMessages: "最近消息"
@@ -84318,7 +84436,9 @@ var zh = {
84318
84436
  apiTabApiKeyModal: apiTabApiKeyModal,
84319
84437
  apiTabCreateApiModal2: apiTabCreateApiModal2,
84320
84438
  apiTabDeleteApiModal2: apiTabDeleteApiModal2,
84439
+ apiTabEditApiModal: apiTabEditApiModal,
84321
84440
  apiTabLabels: apiTabLabels,
84441
+ apiTabTokenPolicies: apiTabTokenPolicies,
84322
84442
  appSidebarIndex: appSidebarIndex,
84323
84443
  appSidebarProjectItem: appSidebarProjectItem,
84324
84444
  appSidebarProjectsSidebarDropdown: appSidebarProjectsSidebarDropdown,
@@ -146927,56 +147047,78 @@ function DeleteApiModal({ isOpen, onClose, apiKey, tenantKey }) {
146927
147047
  return (jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: jsxs(DialogContent, { "aria-describedby": "delete-api-key-description", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "ibl-dialog-title", children: t('apiTabDeleteApiModal2.title') }) }), jsx("div", { className: "my-5", children: jsx("p", { className: "text-sm text-[#646464]", children: t('apiTabDeleteApiModal2.confirmationText', { name: apiKey.name }) }) }), jsxs(DialogFooter, { className: "gap-3", children: [jsx(Button$1, { variant: "outline", onClick: onClose, children: t('apiTabDeleteApiModal2.cancel') }), jsx(Button$1, { className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", onClick: handleDeleteApiKey, disabled: isLoading, children: isLoading ? t('apiTabDeleteApiModal2.deleting') : t('apiTabDeleteApiModal2.delete') })] })] }) }));
146928
147048
  }
146929
147049
 
147050
+ // Platform API token permission modes
147051
+ const API_TOKEN_MODES = {
147052
+ OWNER: 'owner',
147053
+ TOKEN_POLICIES: 'token_policies',
147054
+ };
147055
+ // Rows per page for the API keys table (the endpoint paginates only when page_size is sent)
147056
+ const API_KEYS_PAGE_SIZE = 10;
147057
+ // Result cap and debounce for the policy/group pickers
147058
+ const RBAC_PICKER_PAGE_SIZE = 20;
147059
+ const RBAC_SEARCH_DEBOUNCE_MS = 300;
146930
147060
  /**
146931
- * Blue informational banner used to describe a section, matching the RBAC
146932
- * management tab styling (see `admin.tsx`).
147061
+ * Used when the field-permissions request fails. An absent field means
147062
+ * "unprotected", so a failed lookup must not be read as "everything writable".
146933
147063
  */
146934
- const InfoBanner = ({ icon, title, id, children, className }) => (jsxs("div", { className: `flex gap-3 items-center border rounded-lg p-4 bg-blue-50/60 border-blue-100 ${className !== null && className !== void 0 ? className : ''}`, children: [icon && (jsx("div", { className: "shrink-0 w-9 h-9 rounded-md flex items-center justify-center bg-blue-100 text-blue-600", children: icon })), jsxs("div", { className: "flex-1 min-w-0", children: [title && jsx("h3", { className: "text-sm font-semibold mb-1 text-blue-900", children: title }), jsx("p", { id: id, className: "text-sm text-gray-600 leading-relaxed", children: children })] })] }));
147064
+ const DENIED_TOKEN_POLICY_PERMISSIONS = {
147065
+ mode: { write: false },
147066
+ policies_to_add: { write: false },
147067
+ policies_to_remove: { write: false },
147068
+ groups_to_add: { write: false },
147069
+ groups_to_remove: { write: false },
147070
+ };
146935
147071
 
146936
- function IntegrationAutogeneratedTab({ tenantKey }) {
146937
- const { data: apiKeys, isLoading: isApiKeysLoading } = useGetApiKeysQuery({
146938
- platformKey: tenantKey,
146939
- });
146940
- const [apiKeyToDelete, setApiKeyToDelete] = React__default.useState(null);
146941
- function closeDeleteApiModal() {
146942
- setApiKeyToDelete(null);
146943
- }
146944
- function openDeleteApiModal(apiKey) {
146945
- setApiKeyToDelete(apiKey);
146946
- }
146947
- return (jsxs(Fragment$1, { children: [jsxs("div", { className: "space-y-4", children: [jsx(InfoBanner, { icon: jsx(KeyRound, { className: "w-5 h-5" }), children: "These are authentication keys that you've generated for external applications to authenticate with your service. Keys are displayed only once when generated." }), jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: "Name" }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: "Created" }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: "Expires" }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[50px]" })] }) }), jsx("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: isApiKeysLoading ? (jsx("tr", { children: jsx("td", { colSpan: 4, className: "px-6 py-8 text-center text-sm text-gray-500", children: "Loading..." }) })) : (apiKeys === null || apiKeys === void 0 ? void 0 : apiKeys.length) === 0 ? (jsx("tr", { children: jsx("td", { colSpan: 4, className: "px-6 py-8 text-center text-sm text-gray-500", children: "No API keys found" }) })) : (apiKeys === null || apiKeys === void 0 ? void 0 : apiKeys.map((apiKey) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 whitespace-nowrap text-gray-900 dark:text-gray-100", children: apiKey.name }), jsx("td", { className: "px-6 py-4 whitespace-nowrap text-gray-600 dark:text-gray-300", children: apiKey.created ? format$1(apiKey.created, 'PPP') : 'N/A' }), jsx("td", { className: "px-6 py-4 whitespace-nowrap text-gray-600 dark:text-gray-300", children: apiKey.expires ? format$1(apiKey.expires, 'PPP') : 'N/A' }), jsx("td", { className: "px-6 py-4", children: jsx(Button$1, { variant: "ghost", size: "sm", className: "cursor-pointer", onClick: () => openDeleteApiModal({ name: apiKey.name }), children: jsx(Trash, { className: "h-4 w-4" }) }) })] }, apiKey.name)))) })] }) })] }), apiKeyToDelete && (jsx(DeleteApiModal, { isOpen: !!apiKeyToDelete, onClose: closeDeleteApiModal, apiKey: apiKeyToDelete, tenantKey: tenantKey }))] }));
147072
+ /** Seconds from now until `targetDate`, the unit the `expires_in` duration takes. */
147073
+ function secondsUntil(targetDate) {
147074
+ const oneDay = 24 * 60 * 60 * 1000;
147075
+ const daysDifference = Math.ceil((targetDate.getTime() - Date.now()) / oneDay);
147076
+ return daysDifference * 24 * 3600;
146948
147077
  }
146949
-
146950
- function useCopyToClipboard(timeout = 500) {
146951
- const [status, setStatus] = useState('idle');
146952
- const copy = useCallback(async (text) => {
146953
- if (!(navigator === null || navigator === void 0 ? void 0 : navigator.clipboard)) {
146954
- console.warn('Clipboard not supported');
146955
- return;
146956
- }
146957
- // Try to save to clipboard then save it in the state if worked
146958
- try {
146959
- await navigator.clipboard.writeText(text);
146960
- setStatus('success');
146961
- setTimeout(() => {
146962
- setStatus('idle');
146963
- }, timeout);
146964
- return;
146965
- }
146966
- catch (_a) {
146967
- //Sentry.captureException(String(error));
146968
- setStatus('error');
146969
- return;
146970
- }
146971
- }, [timeout]);
146972
- return { copy, status };
147078
+ function toSelections(associations) {
147079
+ return (associations !== null && associations !== void 0 ? associations : []).map((association) => ({
147080
+ value: String(association.id),
147081
+ label: association.name || `#${association.id}`,
147082
+ }));
146973
147083
  }
146974
-
146975
- function ApiKeyModal({ isOpen, onClose, apiKey }) {
146976
- const t = useT();
146977
- const { copy, status } = useCopyToClipboard(800);
146978
- const Icon = status === 'success' ? Check : Copy;
146979
- return (jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: jsxs(DialogContent, { children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "ibl-dialog-title", children: t('apiTabApiKeyModal.title') }) }), jsx(DialogDescription, { className: "sr-only", children: t('apiTabApiKeyModal.dialogDescription') }), jsxs("div", { className: "grid gap-6", children: [jsxs("p", { className: "text-sm text-muted-foreground grid gap-2", children: [jsx("span", { children: t('apiTabApiKeyModal.securityWarning') }), jsx("span", { children: t('apiTabApiKeyModal.lostKeyWarning') })] }), jsxs("div", { className: "flex items-center gap-4", children: [jsx(Input, { defaultValue: apiKey, readOnly: true }), jsx(Button$1, { size: "icon", className: "ibl-button-primary cursor-pointer", onClick: () => copy(apiKey), children: jsx(Icon, { className: "h-4 w-4" }) })] })] })] }) }));
147084
+ function ids(items) {
147085
+ return items.map((item) => Number(item.value));
147086
+ }
147087
+ /**
147088
+ * `mode` plus the policy/group deltas the endpoint expects, omitting any field
147089
+ * the caller cannot write and any empty delta. On create there is no
147090
+ * `initialMode`/`initial*`, so `mode` is always sent and every selection is an
147091
+ * addition; on edit only what actually changed is included.
147092
+ */
147093
+ function buildTokenPolicyPayload({ mode, initialMode, policies, groups, initialPolicies = [], initialGroups = [], fieldPermissions, }) {
147094
+ const payload = {};
147095
+ if (mode !== initialMode && canWriteField(fieldPermissions, 'mode')) {
147096
+ payload.mode = mode;
147097
+ }
147098
+ if (mode !== API_TOKEN_MODES.TOKEN_POLICIES) {
147099
+ return payload;
147100
+ }
147101
+ const selectedPolicyIds = new Set(ids(policies));
147102
+ const initialPolicyIds = new Set(ids(initialPolicies));
147103
+ const selectedGroupIds = new Set(ids(groups));
147104
+ const initialGroupIds = new Set(ids(initialGroups));
147105
+ const policiesToAdd = [...selectedPolicyIds].filter((id) => !initialPolicyIds.has(id));
147106
+ const policiesToRemove = [...initialPolicyIds].filter((id) => !selectedPolicyIds.has(id));
147107
+ const groupsToAdd = [...selectedGroupIds].filter((id) => !initialGroupIds.has(id));
147108
+ const groupsToRemove = [...initialGroupIds].filter((id) => !selectedGroupIds.has(id));
147109
+ if (policiesToAdd.length && canWriteField(fieldPermissions, 'policies_to_add')) {
147110
+ payload.policies_to_add = policiesToAdd;
147111
+ }
147112
+ if (policiesToRemove.length && canWriteField(fieldPermissions, 'policies_to_remove')) {
147113
+ payload.policies_to_remove = policiesToRemove;
147114
+ }
147115
+ if (groupsToAdd.length && canWriteField(fieldPermissions, 'groups_to_add')) {
147116
+ payload.groups_to_add = groupsToAdd;
147117
+ }
147118
+ if (groupsToRemove.length && canWriteField(fieldPermissions, 'groups_to_remove')) {
147119
+ payload.groups_to_remove = groupsToRemove;
147120
+ }
147121
+ return payload;
146980
147122
  }
146981
147123
 
146982
147124
  const offsetFormatCache = {};
@@ -150691,6 +150833,1096 @@ function CalendarDayButton({ className, day, modifiers, ...props }) {
150691
150833
  !modifiers.range_middle, "data-range-start": modifiers.range_start, "data-range-end": modifiers.range_end, "data-range-middle": modifiers.range_middle, className: cn('data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 dark:hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-70', defaultClassNames.day, className), ...props }));
150692
150834
  }
150693
150835
 
150836
+ /** Inline calendar — a popover would close the surrounding dialog on select. */
150837
+ function ExpirationDateField({ value, onChange, helpText }) {
150838
+ const t = useT();
150839
+ const [isCalendarOpen, setIsCalendarOpen] = React__default.useState(false);
150840
+ return (jsxs("div", { className: "space-y-1.5", children: [jsx(Label$2, { className: "flex items-center text-sm font-medium text-[#646464]", children: t('apiTabLabels.createModal.expirationLabel') }), jsxs("div", { className: "flex items-center gap-2", children: [jsxs(Button$1, { type: "button", variant: "outline", "aria-haspopup": "dialog", "aria-expanded": isCalendarOpen, onClick: () => setIsCalendarOpen((open) => !open), className: cn('flex-1 pl-3 text-left font-normal', !value && 'text-muted-foreground'), children: [value ? (format$1(value, 'PPP')) : (jsx("span", { children: t('apiTabLabels.createModal.expirationPlaceholder') })), jsx(Calendar$1, { className: "ml-auto h-4 w-4 opacity-50" })] }), value && (jsx(Button$1, { type: "button", variant: "ghost", size: "icon", "aria-label": t('apiTabTokenPolicies.clearExpiration'), onClick: () => {
150841
+ onChange(null);
150842
+ setIsCalendarOpen(false);
150843
+ }, children: jsx(X$1, { className: "h-4 w-4" }) }))] }), isCalendarOpen && (jsx("div", { className: "mt-2 w-auto rounded-md border border-gray-200 dark:border-gray-700", children: jsx(Calendar, { mode: "single",
150844
+ // @ts-expect-error - Calendar selected prop expects Date but the field may be null
150845
+ selected: value, onSelect: (date) => {
150846
+ onChange(date !== null && date !== void 0 ? date : null);
150847
+ setIsCalendarOpen(false);
150848
+ }, disabled: (date) => date && date < new Date() }) })), helpText && jsx("p", { className: "text-xs text-muted-foreground", children: helpText })] }));
150849
+ }
150850
+
150851
+ // packages/core/primitive/src/primitive.tsx
150852
+ function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
150853
+ return function handleEvent(event) {
150854
+ originalEventHandler?.(event);
150855
+ if (checkForDefaultPrevented === false || !event.defaultPrevented) {
150856
+ return ourEventHandler?.(event);
150857
+ }
150858
+ };
150859
+ }
150860
+
150861
+ function createCollection(name) {
150862
+ const PROVIDER_NAME = name + "CollectionProvider";
150863
+ const [createCollectionContext, createCollectionScope] = createContextScope(PROVIDER_NAME);
150864
+ const [CollectionProviderImpl, useCollectionContext] = createCollectionContext(
150865
+ PROVIDER_NAME,
150866
+ { collectionRef: { current: null }, itemMap: /* @__PURE__ */ new Map() }
150867
+ );
150868
+ const CollectionProvider = (props) => {
150869
+ const { scope, children } = props;
150870
+ const ref = React__default.useRef(null);
150871
+ const itemMap = React__default.useRef(/* @__PURE__ */ new Map()).current;
150872
+ return /* @__PURE__ */ jsx(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
150873
+ };
150874
+ CollectionProvider.displayName = PROVIDER_NAME;
150875
+ const COLLECTION_SLOT_NAME = name + "CollectionSlot";
150876
+ const CollectionSlot = React__default.forwardRef(
150877
+ (props, forwardedRef) => {
150878
+ const { scope, children } = props;
150879
+ const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
150880
+ const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);
150881
+ return /* @__PURE__ */ jsx(Slot$2, { ref: composedRefs, children });
150882
+ }
150883
+ );
150884
+ CollectionSlot.displayName = COLLECTION_SLOT_NAME;
150885
+ const ITEM_SLOT_NAME = name + "CollectionItemSlot";
150886
+ const ITEM_DATA_ATTR = "data-radix-collection-item";
150887
+ const CollectionItemSlot = React__default.forwardRef(
150888
+ (props, forwardedRef) => {
150889
+ const { scope, children, ...itemData } = props;
150890
+ const ref = React__default.useRef(null);
150891
+ const composedRefs = useComposedRefs(forwardedRef, ref);
150892
+ const context = useCollectionContext(ITEM_SLOT_NAME, scope);
150893
+ React__default.useEffect(() => {
150894
+ context.itemMap.set(ref, { ref, ...itemData });
150895
+ return () => void context.itemMap.delete(ref);
150896
+ });
150897
+ return /* @__PURE__ */ jsx(Slot$2, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
150898
+ }
150899
+ );
150900
+ CollectionItemSlot.displayName = ITEM_SLOT_NAME;
150901
+ function useCollection(scope) {
150902
+ const context = useCollectionContext(name + "CollectionConsumer", scope);
150903
+ const getItems = React__default.useCallback(() => {
150904
+ const collectionNode = context.collectionRef.current;
150905
+ if (!collectionNode) return [];
150906
+ const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));
150907
+ const items = Array.from(context.itemMap.values());
150908
+ const orderedItems = items.sort(
150909
+ (a, b) => orderedNodes.indexOf(a.ref.current) - orderedNodes.indexOf(b.ref.current)
150910
+ );
150911
+ return orderedItems;
150912
+ }, [context.collectionRef, context.itemMap]);
150913
+ return getItems;
150914
+ }
150915
+ return [
150916
+ { Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot },
150917
+ useCollection,
150918
+ createCollectionScope
150919
+ ];
150920
+ }
150921
+
150922
+ // packages/react/use-layout-effect/src/useLayoutEffect.tsx
150923
+ var useLayoutEffect2 = Boolean(globalThis?.document) ? React.useLayoutEffect : () => {
150924
+ };
150925
+
150926
+ // packages/react/id/src/id.tsx
150927
+ var useReactId = React["useId".toString()] || (() => void 0);
150928
+ var count = 0;
150929
+ function useId(deterministicId) {
150930
+ const [id, setId] = React.useState(useReactId());
150931
+ useLayoutEffect2(() => {
150932
+ setId((reactId) => reactId ?? String(count++));
150933
+ }, [deterministicId]);
150934
+ return (id ? `radix-${id}` : "");
150935
+ }
150936
+
150937
+ // packages/react/use-callback-ref/src/useCallbackRef.tsx
150938
+ function useCallbackRef(callback) {
150939
+ const callbackRef = React.useRef(callback);
150940
+ React.useEffect(() => {
150941
+ callbackRef.current = callback;
150942
+ });
150943
+ return React.useMemo(() => (...args) => callbackRef.current?.(...args), []);
150944
+ }
150945
+
150946
+ // packages/react/use-controllable-state/src/useControllableState.tsx
150947
+ function useControllableState({
150948
+ prop,
150949
+ defaultProp,
150950
+ onChange = () => {
150951
+ }
150952
+ }) {
150953
+ const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({ defaultProp, onChange });
150954
+ const isControlled = prop !== void 0;
150955
+ const value = isControlled ? prop : uncontrolledProp;
150956
+ const handleChange = useCallbackRef(onChange);
150957
+ const setValue = React.useCallback(
150958
+ (nextValue) => {
150959
+ if (isControlled) {
150960
+ const setter = nextValue;
150961
+ const value2 = typeof nextValue === "function" ? setter(prop) : nextValue;
150962
+ if (value2 !== prop) handleChange(value2);
150963
+ } else {
150964
+ setUncontrolledProp(nextValue);
150965
+ }
150966
+ },
150967
+ [isControlled, prop, setUncontrolledProp, handleChange]
150968
+ );
150969
+ return [value, setValue];
150970
+ }
150971
+ function useUncontrolledState({
150972
+ defaultProp,
150973
+ onChange
150974
+ }) {
150975
+ const uncontrolledState = React.useState(defaultProp);
150976
+ const [value] = uncontrolledState;
150977
+ const prevValueRef = React.useRef(value);
150978
+ const handleChange = useCallbackRef(onChange);
150979
+ React.useEffect(() => {
150980
+ if (prevValueRef.current !== value) {
150981
+ handleChange(value);
150982
+ prevValueRef.current = value;
150983
+ }
150984
+ }, [value, prevValueRef, handleChange]);
150985
+ return uncontrolledState;
150986
+ }
150987
+
150988
+ // packages/react/direction/src/Direction.tsx
150989
+ var DirectionContext = React.createContext(void 0);
150990
+ function useDirection(localDir) {
150991
+ const globalDir = React.useContext(DirectionContext);
150992
+ return localDir || globalDir || "ltr";
150993
+ }
150994
+
150995
+ var ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
150996
+ var EVENT_OPTIONS = { bubbles: false, cancelable: true };
150997
+ var GROUP_NAME$2 = "RovingFocusGroup";
150998
+ var [Collection$1, useCollection$1, createCollectionScope$1] = createCollection(GROUP_NAME$2);
150999
+ var [createRovingFocusGroupContext, createRovingFocusGroupScope] = createContextScope(
151000
+ GROUP_NAME$2,
151001
+ [createCollectionScope$1]
151002
+ );
151003
+ var [RovingFocusProvider, useRovingFocusContext] = createRovingFocusGroupContext(GROUP_NAME$2);
151004
+ var RovingFocusGroup = React.forwardRef(
151005
+ (props, forwardedRef) => {
151006
+ return /* @__PURE__ */ jsx(Collection$1.Provider, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx(Collection$1.Slot, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });
151007
+ }
151008
+ );
151009
+ RovingFocusGroup.displayName = GROUP_NAME$2;
151010
+ var RovingFocusGroupImpl = React.forwardRef((props, forwardedRef) => {
151011
+ const {
151012
+ __scopeRovingFocusGroup,
151013
+ orientation,
151014
+ loop = false,
151015
+ dir,
151016
+ currentTabStopId: currentTabStopIdProp,
151017
+ defaultCurrentTabStopId,
151018
+ onCurrentTabStopIdChange,
151019
+ onEntryFocus,
151020
+ preventScrollOnEntryFocus = false,
151021
+ ...groupProps
151022
+ } = props;
151023
+ const ref = React.useRef(null);
151024
+ const composedRefs = useComposedRefs(forwardedRef, ref);
151025
+ const direction = useDirection(dir);
151026
+ const [currentTabStopId = null, setCurrentTabStopId] = useControllableState({
151027
+ prop: currentTabStopIdProp,
151028
+ defaultProp: defaultCurrentTabStopId,
151029
+ onChange: onCurrentTabStopIdChange
151030
+ });
151031
+ const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);
151032
+ const handleEntryFocus = useCallbackRef(onEntryFocus);
151033
+ const getItems = useCollection$1(__scopeRovingFocusGroup);
151034
+ const isClickFocusRef = React.useRef(false);
151035
+ const [focusableItemsCount, setFocusableItemsCount] = React.useState(0);
151036
+ React.useEffect(() => {
151037
+ const node = ref.current;
151038
+ if (node) {
151039
+ node.addEventListener(ENTRY_FOCUS, handleEntryFocus);
151040
+ return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);
151041
+ }
151042
+ }, [handleEntryFocus]);
151043
+ return /* @__PURE__ */ jsx(
151044
+ RovingFocusProvider,
151045
+ {
151046
+ scope: __scopeRovingFocusGroup,
151047
+ orientation,
151048
+ dir: direction,
151049
+ loop,
151050
+ currentTabStopId,
151051
+ onItemFocus: React.useCallback(
151052
+ (tabStopId) => setCurrentTabStopId(tabStopId),
151053
+ [setCurrentTabStopId]
151054
+ ),
151055
+ onItemShiftTab: React.useCallback(() => setIsTabbingBackOut(true), []),
151056
+ onFocusableItemAdd: React.useCallback(
151057
+ () => setFocusableItemsCount((prevCount) => prevCount + 1),
151058
+ []
151059
+ ),
151060
+ onFocusableItemRemove: React.useCallback(
151061
+ () => setFocusableItemsCount((prevCount) => prevCount - 1),
151062
+ []
151063
+ ),
151064
+ children: /* @__PURE__ */ jsx(
151065
+ Primitive$1.div,
151066
+ {
151067
+ tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,
151068
+ "data-orientation": orientation,
151069
+ ...groupProps,
151070
+ ref: composedRefs,
151071
+ style: { outline: "none", ...props.style },
151072
+ onMouseDown: composeEventHandlers(props.onMouseDown, () => {
151073
+ isClickFocusRef.current = true;
151074
+ }),
151075
+ onFocus: composeEventHandlers(props.onFocus, (event) => {
151076
+ const isKeyboardFocus = !isClickFocusRef.current;
151077
+ if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
151078
+ const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
151079
+ event.currentTarget.dispatchEvent(entryFocusEvent);
151080
+ if (!entryFocusEvent.defaultPrevented) {
151081
+ const items = getItems().filter((item) => item.focusable);
151082
+ const activeItem = items.find((item) => item.active);
151083
+ const currentItem = items.find((item) => item.id === currentTabStopId);
151084
+ const candidateItems = [activeItem, currentItem, ...items].filter(
151085
+ Boolean
151086
+ );
151087
+ const candidateNodes = candidateItems.map((item) => item.ref.current);
151088
+ focusFirst$1(candidateNodes, preventScrollOnEntryFocus);
151089
+ }
151090
+ }
151091
+ isClickFocusRef.current = false;
151092
+ }),
151093
+ onBlur: composeEventHandlers(props.onBlur, () => setIsTabbingBackOut(false))
151094
+ }
151095
+ )
151096
+ }
151097
+ );
151098
+ });
151099
+ var ITEM_NAME$3 = "RovingFocusGroupItem";
151100
+ var RovingFocusGroupItem = React.forwardRef(
151101
+ (props, forwardedRef) => {
151102
+ const {
151103
+ __scopeRovingFocusGroup,
151104
+ focusable = true,
151105
+ active = false,
151106
+ tabStopId,
151107
+ ...itemProps
151108
+ } = props;
151109
+ const autoId = useId();
151110
+ const id = tabStopId || autoId;
151111
+ const context = useRovingFocusContext(ITEM_NAME$3, __scopeRovingFocusGroup);
151112
+ const isCurrentTabStop = context.currentTabStopId === id;
151113
+ const getItems = useCollection$1(__scopeRovingFocusGroup);
151114
+ const { onFocusableItemAdd, onFocusableItemRemove } = context;
151115
+ React.useEffect(() => {
151116
+ if (focusable) {
151117
+ onFocusableItemAdd();
151118
+ return () => onFocusableItemRemove();
151119
+ }
151120
+ }, [focusable, onFocusableItemAdd, onFocusableItemRemove]);
151121
+ return /* @__PURE__ */ jsx(
151122
+ Collection$1.ItemSlot,
151123
+ {
151124
+ scope: __scopeRovingFocusGroup,
151125
+ id,
151126
+ focusable,
151127
+ active,
151128
+ children: /* @__PURE__ */ jsx(
151129
+ Primitive$1.span,
151130
+ {
151131
+ tabIndex: isCurrentTabStop ? 0 : -1,
151132
+ "data-orientation": context.orientation,
151133
+ ...itemProps,
151134
+ ref: forwardedRef,
151135
+ onMouseDown: composeEventHandlers(props.onMouseDown, (event) => {
151136
+ if (!focusable) event.preventDefault();
151137
+ else context.onItemFocus(id);
151138
+ }),
151139
+ onFocus: composeEventHandlers(props.onFocus, () => context.onItemFocus(id)),
151140
+ onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
151141
+ if (event.key === "Tab" && event.shiftKey) {
151142
+ context.onItemShiftTab();
151143
+ return;
151144
+ }
151145
+ if (event.target !== event.currentTarget) return;
151146
+ const focusIntent = getFocusIntent(event, context.orientation, context.dir);
151147
+ if (focusIntent !== void 0) {
151148
+ if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;
151149
+ event.preventDefault();
151150
+ const items = getItems().filter((item) => item.focusable);
151151
+ let candidateNodes = items.map((item) => item.ref.current);
151152
+ if (focusIntent === "last") candidateNodes.reverse();
151153
+ else if (focusIntent === "prev" || focusIntent === "next") {
151154
+ if (focusIntent === "prev") candidateNodes.reverse();
151155
+ const currentIndex = candidateNodes.indexOf(event.currentTarget);
151156
+ candidateNodes = context.loop ? wrapArray$1(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
151157
+ }
151158
+ setTimeout(() => focusFirst$1(candidateNodes));
151159
+ }
151160
+ })
151161
+ }
151162
+ )
151163
+ }
151164
+ );
151165
+ }
151166
+ );
151167
+ RovingFocusGroupItem.displayName = ITEM_NAME$3;
151168
+ var MAP_KEY_TO_FOCUS_INTENT = {
151169
+ ArrowLeft: "prev",
151170
+ ArrowUp: "prev",
151171
+ ArrowRight: "next",
151172
+ ArrowDown: "next",
151173
+ PageUp: "first",
151174
+ Home: "first",
151175
+ PageDown: "last",
151176
+ End: "last"
151177
+ };
151178
+ function getDirectionAwareKey(key, dir) {
151179
+ if (dir !== "rtl") return key;
151180
+ return key === "ArrowLeft" ? "ArrowRight" : key === "ArrowRight" ? "ArrowLeft" : key;
151181
+ }
151182
+ function getFocusIntent(event, orientation, dir) {
151183
+ const key = getDirectionAwareKey(event.key, dir);
151184
+ if (orientation === "vertical" && ["ArrowLeft", "ArrowRight"].includes(key)) return void 0;
151185
+ if (orientation === "horizontal" && ["ArrowUp", "ArrowDown"].includes(key)) return void 0;
151186
+ return MAP_KEY_TO_FOCUS_INTENT[key];
151187
+ }
151188
+ function focusFirst$1(candidates, preventScroll = false) {
151189
+ const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
151190
+ for (const candidate of candidates) {
151191
+ if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
151192
+ candidate.focus({ preventScroll });
151193
+ if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
151194
+ }
151195
+ }
151196
+ function wrapArray$1(array, startIndex) {
151197
+ return array.map((_, index) => array[(startIndex + index) % array.length]);
151198
+ }
151199
+ var Root$2 = RovingFocusGroup;
151200
+ var Item$1 = RovingFocusGroupItem;
151201
+
151202
+ // packages/react/use-size/src/useSize.tsx
151203
+ function useSize(element) {
151204
+ const [size, setSize] = React.useState(void 0);
151205
+ useLayoutEffect2(() => {
151206
+ if (element) {
151207
+ setSize({ width: element.offsetWidth, height: element.offsetHeight });
151208
+ const resizeObserver = new ResizeObserver((entries) => {
151209
+ if (!Array.isArray(entries)) {
151210
+ return;
151211
+ }
151212
+ if (!entries.length) {
151213
+ return;
151214
+ }
151215
+ const entry = entries[0];
151216
+ let width;
151217
+ let height;
151218
+ if ("borderBoxSize" in entry) {
151219
+ const borderSizeEntry = entry["borderBoxSize"];
151220
+ const borderSize = Array.isArray(borderSizeEntry) ? borderSizeEntry[0] : borderSizeEntry;
151221
+ width = borderSize["inlineSize"];
151222
+ height = borderSize["blockSize"];
151223
+ } else {
151224
+ width = element.offsetWidth;
151225
+ height = element.offsetHeight;
151226
+ }
151227
+ setSize({ width, height });
151228
+ });
151229
+ resizeObserver.observe(element, { box: "border-box" });
151230
+ return () => resizeObserver.unobserve(element);
151231
+ } else {
151232
+ setSize(void 0);
151233
+ }
151234
+ }, [element]);
151235
+ return size;
151236
+ }
151237
+
151238
+ // packages/react/use-previous/src/usePrevious.tsx
151239
+ function usePrevious(value) {
151240
+ const ref = React.useRef({ value, previous: value });
151241
+ return React.useMemo(() => {
151242
+ if (ref.current.value !== value) {
151243
+ ref.current.previous = ref.current.value;
151244
+ ref.current.value = value;
151245
+ }
151246
+ return ref.current.previous;
151247
+ }, [value]);
151248
+ }
151249
+
151250
+ function useStateMachine(initialState, machine) {
151251
+ return React.useReducer((state, event) => {
151252
+ const nextState = machine[state][event];
151253
+ return nextState ?? state;
151254
+ }, initialState);
151255
+ }
151256
+
151257
+ // packages/react/presence/src/Presence.tsx
151258
+ var Presence = (props) => {
151259
+ const { present, children } = props;
151260
+ const presence = usePresence(present);
151261
+ const child = typeof children === "function" ? children({ present: presence.isPresent }) : React.Children.only(children);
151262
+ const ref = useComposedRefs(presence.ref, getElementRef(child));
151263
+ const forceMount = typeof children === "function";
151264
+ return forceMount || presence.isPresent ? React.cloneElement(child, { ref }) : null;
151265
+ };
151266
+ Presence.displayName = "Presence";
151267
+ function usePresence(present) {
151268
+ const [node, setNode] = React.useState();
151269
+ const stylesRef = React.useRef({});
151270
+ const prevPresentRef = React.useRef(present);
151271
+ const prevAnimationNameRef = React.useRef("none");
151272
+ const initialState = present ? "mounted" : "unmounted";
151273
+ const [state, send] = useStateMachine(initialState, {
151274
+ mounted: {
151275
+ UNMOUNT: "unmounted",
151276
+ ANIMATION_OUT: "unmountSuspended"
151277
+ },
151278
+ unmountSuspended: {
151279
+ MOUNT: "mounted",
151280
+ ANIMATION_END: "unmounted"
151281
+ },
151282
+ unmounted: {
151283
+ MOUNT: "mounted"
151284
+ }
151285
+ });
151286
+ React.useEffect(() => {
151287
+ const currentAnimationName = getAnimationName(stylesRef.current);
151288
+ prevAnimationNameRef.current = state === "mounted" ? currentAnimationName : "none";
151289
+ }, [state]);
151290
+ useLayoutEffect2(() => {
151291
+ const styles = stylesRef.current;
151292
+ const wasPresent = prevPresentRef.current;
151293
+ const hasPresentChanged = wasPresent !== present;
151294
+ if (hasPresentChanged) {
151295
+ const prevAnimationName = prevAnimationNameRef.current;
151296
+ const currentAnimationName = getAnimationName(styles);
151297
+ if (present) {
151298
+ send("MOUNT");
151299
+ } else if (currentAnimationName === "none" || styles?.display === "none") {
151300
+ send("UNMOUNT");
151301
+ } else {
151302
+ const isAnimating = prevAnimationName !== currentAnimationName;
151303
+ if (wasPresent && isAnimating) {
151304
+ send("ANIMATION_OUT");
151305
+ } else {
151306
+ send("UNMOUNT");
151307
+ }
151308
+ }
151309
+ prevPresentRef.current = present;
151310
+ }
151311
+ }, [present, send]);
151312
+ useLayoutEffect2(() => {
151313
+ if (node) {
151314
+ let timeoutId;
151315
+ const ownerWindow = node.ownerDocument.defaultView ?? window;
151316
+ const handleAnimationEnd = (event) => {
151317
+ const currentAnimationName = getAnimationName(stylesRef.current);
151318
+ const isCurrentAnimation = currentAnimationName.includes(event.animationName);
151319
+ if (event.target === node && isCurrentAnimation) {
151320
+ send("ANIMATION_END");
151321
+ if (!prevPresentRef.current) {
151322
+ const currentFillMode = node.style.animationFillMode;
151323
+ node.style.animationFillMode = "forwards";
151324
+ timeoutId = ownerWindow.setTimeout(() => {
151325
+ if (node.style.animationFillMode === "forwards") {
151326
+ node.style.animationFillMode = currentFillMode;
151327
+ }
151328
+ });
151329
+ }
151330
+ }
151331
+ };
151332
+ const handleAnimationStart = (event) => {
151333
+ if (event.target === node) {
151334
+ prevAnimationNameRef.current = getAnimationName(stylesRef.current);
151335
+ }
151336
+ };
151337
+ node.addEventListener("animationstart", handleAnimationStart);
151338
+ node.addEventListener("animationcancel", handleAnimationEnd);
151339
+ node.addEventListener("animationend", handleAnimationEnd);
151340
+ return () => {
151341
+ ownerWindow.clearTimeout(timeoutId);
151342
+ node.removeEventListener("animationstart", handleAnimationStart);
151343
+ node.removeEventListener("animationcancel", handleAnimationEnd);
151344
+ node.removeEventListener("animationend", handleAnimationEnd);
151345
+ };
151346
+ } else {
151347
+ send("ANIMATION_END");
151348
+ }
151349
+ }, [node, send]);
151350
+ return {
151351
+ isPresent: ["mounted", "unmountSuspended"].includes(state),
151352
+ ref: React.useCallback((node2) => {
151353
+ if (node2) stylesRef.current = getComputedStyle(node2);
151354
+ setNode(node2);
151355
+ }, [])
151356
+ };
151357
+ }
151358
+ function getAnimationName(styles) {
151359
+ return styles?.animationName || "none";
151360
+ }
151361
+ function getElementRef(element) {
151362
+ let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get;
151363
+ let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
151364
+ if (mayWarn) {
151365
+ return element.ref;
151366
+ }
151367
+ getter = Object.getOwnPropertyDescriptor(element, "ref")?.get;
151368
+ mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
151369
+ if (mayWarn) {
151370
+ return element.props.ref;
151371
+ }
151372
+ return element.props.ref || element.ref;
151373
+ }
151374
+
151375
+ var RADIO_NAME = "Radio";
151376
+ var [createRadioContext, createRadioScope] = createContextScope(RADIO_NAME);
151377
+ var [RadioProvider, useRadioContext] = createRadioContext(RADIO_NAME);
151378
+ var Radio = React.forwardRef(
151379
+ (props, forwardedRef) => {
151380
+ const {
151381
+ __scopeRadio,
151382
+ name,
151383
+ checked = false,
151384
+ required,
151385
+ disabled,
151386
+ value = "on",
151387
+ onCheck,
151388
+ form,
151389
+ ...radioProps
151390
+ } = props;
151391
+ const [button, setButton] = React.useState(null);
151392
+ const composedRefs = useComposedRefs(forwardedRef, (node) => setButton(node));
151393
+ const hasConsumerStoppedPropagationRef = React.useRef(false);
151394
+ const isFormControl = button ? form || !!button.closest("form") : true;
151395
+ return /* @__PURE__ */ jsxs(RadioProvider, { scope: __scopeRadio, checked, disabled, children: [
151396
+ /* @__PURE__ */ jsx(
151397
+ Primitive$1.button,
151398
+ {
151399
+ type: "button",
151400
+ role: "radio",
151401
+ "aria-checked": checked,
151402
+ "data-state": getState(checked),
151403
+ "data-disabled": disabled ? "" : void 0,
151404
+ disabled,
151405
+ value,
151406
+ ...radioProps,
151407
+ ref: composedRefs,
151408
+ onClick: composeEventHandlers(props.onClick, (event) => {
151409
+ if (!checked) onCheck?.();
151410
+ if (isFormControl) {
151411
+ hasConsumerStoppedPropagationRef.current = event.isPropagationStopped();
151412
+ if (!hasConsumerStoppedPropagationRef.current) event.stopPropagation();
151413
+ }
151414
+ })
151415
+ }
151416
+ ),
151417
+ isFormControl && /* @__PURE__ */ jsx(
151418
+ BubbleInput,
151419
+ {
151420
+ control: button,
151421
+ bubbles: !hasConsumerStoppedPropagationRef.current,
151422
+ name,
151423
+ value,
151424
+ checked,
151425
+ required,
151426
+ disabled,
151427
+ form,
151428
+ style: { transform: "translateX(-100%)" }
151429
+ }
151430
+ )
151431
+ ] });
151432
+ }
151433
+ );
151434
+ Radio.displayName = RADIO_NAME;
151435
+ var INDICATOR_NAME$1 = "RadioIndicator";
151436
+ var RadioIndicator = React.forwardRef(
151437
+ (props, forwardedRef) => {
151438
+ const { __scopeRadio, forceMount, ...indicatorProps } = props;
151439
+ const context = useRadioContext(INDICATOR_NAME$1, __scopeRadio);
151440
+ return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.checked, children: /* @__PURE__ */ jsx(
151441
+ Primitive$1.span,
151442
+ {
151443
+ "data-state": getState(context.checked),
151444
+ "data-disabled": context.disabled ? "" : void 0,
151445
+ ...indicatorProps,
151446
+ ref: forwardedRef
151447
+ }
151448
+ ) });
151449
+ }
151450
+ );
151451
+ RadioIndicator.displayName = INDICATOR_NAME$1;
151452
+ var BubbleInput = (props) => {
151453
+ const { control, checked, bubbles = true, ...inputProps } = props;
151454
+ const ref = React.useRef(null);
151455
+ const prevChecked = usePrevious(checked);
151456
+ const controlSize = useSize(control);
151457
+ React.useEffect(() => {
151458
+ const input = ref.current;
151459
+ const inputProto = window.HTMLInputElement.prototype;
151460
+ const descriptor = Object.getOwnPropertyDescriptor(inputProto, "checked");
151461
+ const setChecked = descriptor.set;
151462
+ if (prevChecked !== checked && setChecked) {
151463
+ const event = new Event("click", { bubbles });
151464
+ setChecked.call(input, checked);
151465
+ input.dispatchEvent(event);
151466
+ }
151467
+ }, [prevChecked, checked, bubbles]);
151468
+ return /* @__PURE__ */ jsx(
151469
+ "input",
151470
+ {
151471
+ type: "radio",
151472
+ "aria-hidden": true,
151473
+ defaultChecked: checked,
151474
+ ...inputProps,
151475
+ tabIndex: -1,
151476
+ ref,
151477
+ style: {
151478
+ ...props.style,
151479
+ ...controlSize,
151480
+ position: "absolute",
151481
+ pointerEvents: "none",
151482
+ opacity: 0,
151483
+ margin: 0
151484
+ }
151485
+ }
151486
+ );
151487
+ };
151488
+ function getState(checked) {
151489
+ return checked ? "checked" : "unchecked";
151490
+ }
151491
+ var ARROW_KEYS = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
151492
+ var RADIO_GROUP_NAME$2 = "RadioGroup";
151493
+ var [createRadioGroupContext] = createContextScope(RADIO_GROUP_NAME$2, [
151494
+ createRovingFocusGroupScope,
151495
+ createRadioScope
151496
+ ]);
151497
+ var useRovingFocusGroupScope$1 = createRovingFocusGroupScope();
151498
+ var useRadioScope = createRadioScope();
151499
+ var [RadioGroupProvider$1, useRadioGroupContext$1] = createRadioGroupContext(RADIO_GROUP_NAME$2);
151500
+ var RadioGroup$2 = React.forwardRef(
151501
+ (props, forwardedRef) => {
151502
+ const {
151503
+ __scopeRadioGroup,
151504
+ name,
151505
+ defaultValue,
151506
+ value: valueProp,
151507
+ required = false,
151508
+ disabled = false,
151509
+ orientation,
151510
+ dir,
151511
+ loop = true,
151512
+ onValueChange,
151513
+ ...groupProps
151514
+ } = props;
151515
+ const rovingFocusGroupScope = useRovingFocusGroupScope$1(__scopeRadioGroup);
151516
+ const direction = useDirection(dir);
151517
+ const [value, setValue] = useControllableState({
151518
+ prop: valueProp,
151519
+ defaultProp: defaultValue,
151520
+ onChange: onValueChange
151521
+ });
151522
+ return /* @__PURE__ */ jsx(
151523
+ RadioGroupProvider$1,
151524
+ {
151525
+ scope: __scopeRadioGroup,
151526
+ name,
151527
+ required,
151528
+ disabled,
151529
+ value,
151530
+ onValueChange: setValue,
151531
+ children: /* @__PURE__ */ jsx(
151532
+ Root$2,
151533
+ {
151534
+ asChild: true,
151535
+ ...rovingFocusGroupScope,
151536
+ orientation,
151537
+ dir: direction,
151538
+ loop,
151539
+ children: /* @__PURE__ */ jsx(
151540
+ Primitive$1.div,
151541
+ {
151542
+ role: "radiogroup",
151543
+ "aria-required": required,
151544
+ "aria-orientation": orientation,
151545
+ "data-disabled": disabled ? "" : void 0,
151546
+ dir: direction,
151547
+ ...groupProps,
151548
+ ref: forwardedRef
151549
+ }
151550
+ )
151551
+ }
151552
+ )
151553
+ }
151554
+ );
151555
+ }
151556
+ );
151557
+ RadioGroup$2.displayName = RADIO_GROUP_NAME$2;
151558
+ var ITEM_NAME$2 = "RadioGroupItem";
151559
+ var RadioGroupItem$1 = React.forwardRef(
151560
+ (props, forwardedRef) => {
151561
+ const { __scopeRadioGroup, disabled, ...itemProps } = props;
151562
+ const context = useRadioGroupContext$1(ITEM_NAME$2, __scopeRadioGroup);
151563
+ const isDisabled = context.disabled || disabled;
151564
+ const rovingFocusGroupScope = useRovingFocusGroupScope$1(__scopeRadioGroup);
151565
+ const radioScope = useRadioScope(__scopeRadioGroup);
151566
+ const ref = React.useRef(null);
151567
+ const composedRefs = useComposedRefs(forwardedRef, ref);
151568
+ const checked = context.value === itemProps.value;
151569
+ const isArrowKeyPressedRef = React.useRef(false);
151570
+ React.useEffect(() => {
151571
+ const handleKeyDown = (event) => {
151572
+ if (ARROW_KEYS.includes(event.key)) {
151573
+ isArrowKeyPressedRef.current = true;
151574
+ }
151575
+ };
151576
+ const handleKeyUp = () => isArrowKeyPressedRef.current = false;
151577
+ document.addEventListener("keydown", handleKeyDown);
151578
+ document.addEventListener("keyup", handleKeyUp);
151579
+ return () => {
151580
+ document.removeEventListener("keydown", handleKeyDown);
151581
+ document.removeEventListener("keyup", handleKeyUp);
151582
+ };
151583
+ }, []);
151584
+ return /* @__PURE__ */ jsx(
151585
+ Item$1,
151586
+ {
151587
+ asChild: true,
151588
+ ...rovingFocusGroupScope,
151589
+ focusable: !isDisabled,
151590
+ active: checked,
151591
+ children: /* @__PURE__ */ jsx(
151592
+ Radio,
151593
+ {
151594
+ disabled: isDisabled,
151595
+ required: context.required,
151596
+ checked,
151597
+ ...radioScope,
151598
+ ...itemProps,
151599
+ name: context.name,
151600
+ ref: composedRefs,
151601
+ onCheck: () => context.onValueChange(itemProps.value),
151602
+ onKeyDown: composeEventHandlers((event) => {
151603
+ if (event.key === "Enter") event.preventDefault();
151604
+ }),
151605
+ onFocus: composeEventHandlers(itemProps.onFocus, () => {
151606
+ if (isArrowKeyPressedRef.current) ref.current?.click();
151607
+ })
151608
+ }
151609
+ )
151610
+ }
151611
+ );
151612
+ }
151613
+ );
151614
+ RadioGroupItem$1.displayName = ITEM_NAME$2;
151615
+ var INDICATOR_NAME2 = "RadioGroupIndicator";
151616
+ var RadioGroupIndicator = React.forwardRef(
151617
+ (props, forwardedRef) => {
151618
+ const { __scopeRadioGroup, ...indicatorProps } = props;
151619
+ const radioScope = useRadioScope(__scopeRadioGroup);
151620
+ return /* @__PURE__ */ jsx(RadioIndicator, { ...radioScope, ...indicatorProps, ref: forwardedRef });
151621
+ }
151622
+ );
151623
+ RadioGroupIndicator.displayName = INDICATOR_NAME2;
151624
+ var Root2$2 = RadioGroup$2;
151625
+ var Item2$2 = RadioGroupItem$1;
151626
+ var Indicator = RadioGroupIndicator;
151627
+
151628
+ function RadioGroup$1({ className, ...props }) {
151629
+ return (jsx(Root2$2, { "data-slot": "radio-group", className: cn('grid gap-3', className), ...props }));
151630
+ }
151631
+ function RadioGroupItem({ className, ...props }) {
151632
+ return (jsx(Item2$2, { "data-slot": "radio-group-item", className: cn('border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50', className), ...props, children: jsx(Indicator, { "data-slot": "radio-group-indicator", className: "relative flex items-center justify-center", children: jsx(Circle, { className: "fill-primary absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2" }) }) }));
151633
+ }
151634
+
151635
+ function SearchableMultiSelect({ items, selectedItems, onSelectionChange, searchQuery, onSearchChange, isLoading, placeholder = 'Search and select items...', getItemValue, getItemLabel, className, maxHeight = 'max-h-60', inputId, ariaDescribedBy, onSelectedItemAction, selectedItemActionIcon, selectedItemActionAriaLabel = 'View item details', }) {
151636
+ const [isOpen, setIsOpen] = useState(false);
151637
+ const containerRef = useRef(null);
151638
+ // Handle outside click to close dropdown
151639
+ useEffect(() => {
151640
+ const handleClickOutside = (event) => {
151641
+ if (containerRef.current && !containerRef.current.contains(event.target)) {
151642
+ setIsOpen(false);
151643
+ }
151644
+ };
151645
+ if (isOpen) {
151646
+ document.addEventListener('mousedown', handleClickOutside);
151647
+ }
151648
+ return () => {
151649
+ document.removeEventListener('mousedown', handleClickOutside);
151650
+ };
151651
+ }, [isOpen]);
151652
+ const handleSelectItem = (itemValue, itemLabel) => {
151653
+ const newSelection = selectedItems.some((item) => item.value === itemValue)
151654
+ ? selectedItems.filter((item) => item.value !== itemValue)
151655
+ : [...selectedItems, { label: itemLabel, value: itemValue }];
151656
+ onSelectionChange(newSelection);
151657
+ };
151658
+ const handleRemoveItem = (itemValue) => {
151659
+ onSelectionChange(selectedItems.filter((item) => item.value !== itemValue));
151660
+ };
151661
+ return (jsxs("div", { className: cn('space-y-2', className), ref: containerRef, children: [jsxs("div", { className: "relative", children: [jsxs("div", { className: cn('flex min-h-[40px] w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background', 'focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2', 'cursor-pointer'), children: [jsxs("div", { className: "flex flex-1 items-center gap-2", children: [jsx(Search, { className: "h-4 w-4 text-muted-foreground" }), jsx("input", { type: "text", placeholder: placeholder, value: searchQuery, onChange: (e) => onSearchChange(e.target.value), onFocus: () => setIsOpen(true), id: inputId, "aria-describedby": ariaDescribedBy, className: "flex-1 bg-transparent outline-none placeholder:text-muted-foreground", onClick: (e) => e.stopPropagation() })] }), jsxs("div", { className: "flex items-center gap-1", children: [selectedItems.length > 0 && (jsx(Badge, { variant: "secondary", className: "text-xs", children: selectedItems.length })), jsx(X$1, { className: "h-4 w-4 text-muted-foreground cursor-pointer", onClick: (e) => {
151662
+ e.stopPropagation();
151663
+ onSelectionChange([]);
151664
+ onSearchChange('');
151665
+ setIsOpen(false);
151666
+ } })] })] }), isOpen && (jsx("div", { className: cn('absolute z-50 w-full mt-1 bg-white border rounded-md shadow-lg overflow-auto', maxHeight), children: isLoading ? (jsx("div", { className: "p-3 text-sm text-muted-foreground", children: "Loading..." })) : items.length > 0 ? (items.map((item) => {
151667
+ const itemValue = getItemValue(item);
151668
+ const itemLabel = getItemLabel(item);
151669
+ const isSelected = selectedItems.some((selected) => selected.value === itemValue);
151670
+ return (jsxs("div", { className: "flex items-center space-x-2 p-2 hover:bg-gray-50 cursor-pointer", onClick: () => handleSelectItem(itemValue, itemLabel), children: [jsx("div", { className: "flex items-center justify-center w-4 h-4", children: isSelected && jsx(Check, { className: "h-3 w-3 text-primary" }) }), jsx("span", { className: "text-sm", children: itemLabel })] }, itemValue));
151671
+ })) : (jsx("div", { className: "p-3 text-sm text-muted-foreground", children: searchQuery ? 'No items found' : 'Start typing to search items' })) }))] }), selectedItems.length > 0 && (jsx("div", { className: "flex gap-2 overflow-x-auto pb-2 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100", children: selectedItems
151672
+ .slice()
151673
+ .reverse()
151674
+ .map((selectedItem) => {
151675
+ return (jsxs(Badge, { variant: "secondary", className: "text-xs whitespace-nowrap flex-shrink-0 font-normal", children: [selectedItem.label, onSelectedItemAction && (jsx("button", { type: "button", onClick: (event) => {
151676
+ event.preventDefault();
151677
+ event.stopPropagation();
151678
+ onSelectedItemAction(selectedItem);
151679
+ }, className: "ml-1 text-gray-500 hover:text-gray-700", "aria-label": selectedItemActionAriaLabel, children: selectedItemActionIcon !== null && selectedItemActionIcon !== void 0 ? selectedItemActionIcon : jsx(Eye, { className: "h-3 w-3" }) })), jsx("button", { type: "button", onClick: () => handleRemoveItem(selectedItem.value), className: "ml-1 text-gray-500 hover:text-gray-700", children: "\u00D7" })] }, selectedItem.value));
151680
+ }) }))] }));
151681
+ }
151682
+
151683
+ function useDebouncedValue$3(value, delay) {
151684
+ const [debouncedValue, setDebouncedValue] = React__default.useState(value);
151685
+ React__default.useEffect(() => {
151686
+ const timer = window.setTimeout(() => setDebouncedValue(value), delay);
151687
+ return () => window.clearTimeout(timer);
151688
+ }, [value, delay]);
151689
+ return debouncedValue;
151690
+ }
151691
+ function toList(response) {
151692
+ if (Array.isArray(response))
151693
+ return response;
151694
+ const results = response === null || response === void 0 ? void 0 : response.results;
151695
+ return Array.isArray(results) ? results : [];
151696
+ }
151697
+ function itemLabel(item) {
151698
+ return item.name || item.unique_id || `#${item.id}`;
151699
+ }
151700
+ /**
151701
+ * The platform-provisioned students group is not a meaningful scope for a
151702
+ * token. Matched exactly: user-created groups carry a timestamp-suffixed slug
151703
+ * (see GroupsTab's `generateUniqueId`), so only the provisioned group has this
151704
+ * bare id and a group like `students-cohort-2024` is still selectable.
151705
+ */
151706
+ const EXCLUDED_GROUP_UNIQUE_ID = 'students';
151707
+ function isSelectableGroup(group) {
151708
+ var _a;
151709
+ return ((_a = group.unique_id) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== EXCLUDED_GROUP_UNIQUE_ID;
151710
+ }
151711
+ function ReadOnlySelection({ items, emptyLabel, }) {
151712
+ if (items.length === 0) {
151713
+ return jsx("p", { className: "text-sm text-muted-foreground", children: emptyLabel });
151714
+ }
151715
+ return (jsx("div", { className: "flex gap-2 overflow-x-auto pb-2 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100", children: items.map((item) => (jsx(Badge, { variant: "secondary", className: "text-xs font-normal whitespace-nowrap shrink-0", children: item.label }, item.value))) }));
151716
+ }
151717
+ /**
151718
+ * Permission-mode selector plus the policy/group pickers a `token_policies`
151719
+ * token resolves its permissions from. Each control is gated on the write flag
151720
+ * the `field-permissions` endpoint reports; a field the caller cannot write is
151721
+ * rendered read-only instead of being hidden, so existing associations stay
151722
+ * visible while editing.
151723
+ */
151724
+ function TokenPolicyFields({ tenantKey, mode, onModeChange, policies, onPoliciesChange, groups, onGroupsChange, fieldPermissions, idPrefix, }) {
151725
+ const t = useT();
151726
+ const [policySearch, setPolicySearch] = React__default.useState('');
151727
+ const [groupSearch, setGroupSearch] = React__default.useState('');
151728
+ const debouncedPolicySearch = useDebouncedValue$3(policySearch, RBAC_SEARCH_DEBOUNCE_MS);
151729
+ const debouncedGroupSearch = useDebouncedValue$3(groupSearch, RBAC_SEARCH_DEBOUNCE_MS);
151730
+ const canWriteMode = canWriteField(fieldPermissions, 'mode');
151731
+ const canWritePolicies = canWriteField(fieldPermissions, 'policies_to_add') ||
151732
+ canWriteField(fieldPermissions, 'policies_to_remove');
151733
+ const canWriteGroups = canWriteField(fieldPermissions, 'groups_to_add') ||
151734
+ canWriteField(fieldPermissions, 'groups_to_remove');
151735
+ const isTokenPolicyMode = mode === API_TOKEN_MODES.TOKEN_POLICIES;
151736
+ const { data: policiesResponse, isFetching: isPoliciesFetching } = useGetRbacPoliciesQuery({
151737
+ platformKey: tenantKey,
151738
+ name: debouncedPolicySearch || undefined,
151739
+ pageSize: RBAC_PICKER_PAGE_SIZE,
151740
+ includeUsers: false,
151741
+ includeGroups: false,
151742
+ }, { skip: !tenantKey || !isTokenPolicyMode || !canWritePolicies });
151743
+ const { data: groupsResponse, isFetching: isGroupsFetching } = useGetRbacGroupsQuery({
151744
+ platformKey: tenantKey,
151745
+ name: debouncedGroupSearch || undefined,
151746
+ pageSize: RBAC_PICKER_PAGE_SIZE,
151747
+ includeUsers: false,
151748
+ }, { skip: !tenantKey || !isTokenPolicyMode || !canWriteGroups });
151749
+ const policyOptions = React__default.useMemo(() => toList(policiesResponse), [policiesResponse]);
151750
+ const groupOptions = React__default.useMemo(() => toList(groupsResponse).filter(isSelectableGroup), [groupsResponse]);
151751
+ return (
151752
+ // min-w-0 so this grid item can shrink below the badge rows' min-content
151753
+ // width — without it the dialog scrolls instead of the badge row.
151754
+ jsxs("div", { className: "min-w-0 space-y-5", children: [jsxs("div", { className: "space-y-1.5", children: [jsx(Label$2, { className: "flex items-center text-sm font-medium text-[#646464]", children: t('apiTabTokenPolicies.modeLabel') }), canWriteMode ? (jsx(RadioGroup$1, { value: mode, onValueChange: (value) => onModeChange(value), className: "gap-2", children: [
151755
+ {
151756
+ value: API_TOKEN_MODES.OWNER,
151757
+ label: t('apiTabTokenPolicies.ownerModeLabel'),
151758
+ description: t('apiTabTokenPolicies.ownerModeDescription'),
151759
+ },
151760
+ {
151761
+ value: API_TOKEN_MODES.TOKEN_POLICIES,
151762
+ label: t('apiTabTokenPolicies.tokenPoliciesModeLabel'),
151763
+ description: t('apiTabTokenPolicies.tokenPoliciesModeDescription'),
151764
+ },
151765
+ ].map((option) => (jsxs("div", { className: "flex items-start gap-2", children: [jsx(RadioGroupItem, { value: option.value, id: `${idPrefix}-mode-${option.value}`, className: "mt-0.5" }), jsxs("div", { className: "grid gap-0.5", children: [jsx(Label$2, { htmlFor: `${idPrefix}-mode-${option.value}`, className: "cursor-pointer text-sm font-medium", children: option.label }), jsx("p", { className: "text-xs text-muted-foreground", children: option.description })] })] }, option.value))) })) : (jsx("p", { className: "text-sm text-muted-foreground", children: mode === API_TOKEN_MODES.TOKEN_POLICIES
151766
+ ? t('apiTabTokenPolicies.tokenPoliciesModeLabel')
151767
+ : t('apiTabTokenPolicies.ownerModeLabel') }))] }), isTokenPolicyMode && (jsxs(Fragment$1, { children: [jsxs("div", { className: "space-y-1.5", children: [jsx(Label$2, { className: "flex items-center text-sm font-medium text-[#646464]", htmlFor: `${idPrefix}-policies`, children: t('apiTabTokenPolicies.policiesLabel') }), canWritePolicies ? (jsx(SearchableMultiSelect, { items: policyOptions, selectedItems: policies, onSelectionChange: onPoliciesChange, searchQuery: policySearch, onSearchChange: setPolicySearch, isLoading: isPoliciesFetching, placeholder: t('apiTabTokenPolicies.policiesPlaceholder'), getItemValue: (policy) => String(policy.id), getItemLabel: itemLabel, inputId: `${idPrefix}-policies`, ariaDescribedBy: `${idPrefix}-policies-help` })) : (jsx(ReadOnlySelection, { items: policies, emptyLabel: t('apiTabTokenPolicies.noneSelected') })), jsx("p", { id: `${idPrefix}-policies-help`, className: "text-xs text-muted-foreground", children: t('apiTabTokenPolicies.policiesHelp') })] }), jsxs("div", { className: "space-y-1.5", children: [jsx(Label$2, { className: "flex items-center text-sm font-medium text-[#646464]", htmlFor: `${idPrefix}-groups`, children: t('apiTabTokenPolicies.groupsLabel') }), canWriteGroups ? (jsx(SearchableMultiSelect, { items: groupOptions, selectedItems: groups, onSelectionChange: onGroupsChange, searchQuery: groupSearch, onSearchChange: setGroupSearch, isLoading: isGroupsFetching, placeholder: t('apiTabTokenPolicies.groupsPlaceholder'), getItemValue: (group) => String(group.id), getItemLabel: itemLabel, inputId: `${idPrefix}-groups`, ariaDescribedBy: `${idPrefix}-groups-help` })) : (jsx(ReadOnlySelection, { items: groups, emptyLabel: t('apiTabTokenPolicies.noneSelected') })), jsx("p", { id: `${idPrefix}-groups-help`, className: "text-xs text-muted-foreground", children: t('apiTabTokenPolicies.groupsHelp') })] })] }))] }));
151768
+ }
151769
+
151770
+ const editApiFormSchema = z.object({
151771
+ name: z
151772
+ .string()
151773
+ .min(1, 'API Key name is required')
151774
+ .regex(/^[a-zA-Z0-9_-]+$/, 'can only contain letters, numbers, and hyphens'),
151775
+ expiration_date: z.date().nullable(),
151776
+ });
151777
+ function EditApiKeyForm({ token, tenantKey, fieldPermissions, onClose, }) {
151778
+ var _a;
151779
+ const t = useT();
151780
+ const [updateApiKey, { isLoading }] = useUpdateApiKeyMutation();
151781
+ const initialPolicies = React__default.useMemo(() => toSelections(token.policies), [token.policies]);
151782
+ const initialGroups = React__default.useMemo(() => toSelections(token.groups), [token.groups]);
151783
+ const initialExpiration = React__default.useMemo(() => (token.expires ? new Date(token.expires) : null), [token.expires]);
151784
+ const initialMode = (_a = token.mode) !== null && _a !== void 0 ? _a : API_TOKEN_MODES.OWNER;
151785
+ const [mode, setMode] = React__default.useState(initialMode);
151786
+ const [policies, setPolicies] = React__default.useState(initialPolicies);
151787
+ const [groups, setGroups] = React__default.useState(initialGroups);
151788
+ const form = useForm({
151789
+ defaultValues: {
151790
+ name: token.name,
151791
+ expiration_date: initialExpiration,
151792
+ },
151793
+ validators: {
151794
+ onChange: editApiFormSchema,
151795
+ },
151796
+ onSubmit: async ({ value }) => {
151797
+ var _a, _b, _c;
151798
+ const requestBody = buildTokenPolicyPayload({
151799
+ mode,
151800
+ initialMode,
151801
+ policies,
151802
+ groups,
151803
+ initialPolicies,
151804
+ initialGroups,
151805
+ fieldPermissions,
151806
+ });
151807
+ if (value.name !== token.name) {
151808
+ requestBody.name = value.name;
151809
+ }
151810
+ const nextExpiration = (_b = (_a = value.expiration_date) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : null;
151811
+ const previousExpiration = (_c = initialExpiration === null || initialExpiration === void 0 ? void 0 : initialExpiration.getTime()) !== null && _c !== void 0 ? _c : null;
151812
+ if (nextExpiration !== previousExpiration) {
151813
+ requestBody.expires_in = value.expiration_date
151814
+ ? secondsUntil(value.expiration_date).toString()
151815
+ : null;
151816
+ }
151817
+ if (Object.keys(requestBody).length === 0) {
151818
+ onClose();
151819
+ return;
151820
+ }
151821
+ try {
151822
+ await updateApiKey({
151823
+ name: token.name,
151824
+ platformKey: tenantKey,
151825
+ requestBody,
151826
+ }).unwrap();
151827
+ toast.success(t('apiTabEditApiModal.successToast'));
151828
+ onClose();
151829
+ }
151830
+ catch (error) {
151831
+ console.error(JSON.stringify({ tenant: tenantKey, error }));
151832
+ toast.error(t('apiTabEditApiModal.errorToast'));
151833
+ }
151834
+ },
151835
+ });
151836
+ return (jsxs("form", { onSubmit: (formEvent) => {
151837
+ formEvent.preventDefault();
151838
+ formEvent.stopPropagation();
151839
+ form.handleSubmit();
151840
+ }, className: "mt-5 grid min-w-0 gap-5", children: [jsx(form.Field, { name: "name", children: (field) => {
151841
+ var _a, _b;
151842
+ const hasErrorAndIsDirty = ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) > 0 && field.state.meta.isDirty;
151843
+ return (jsxs("div", { className: "space-y-1.5", children: [jsxs(Label$2, { className: "flex items-center text-sm font-medium text-[#646464]", children: [t('apiTabCreateApiModal2.apiKeyName'), jsx("span", { className: "ml-1 text-red-500", children: "*" })] }), jsx(Input, { value: field.state.value, onChange: (event) => field.handleChange(event.target.value), autoComplete: "off" }), hasErrorAndIsDirty && (jsx("p", { className: "text-red-500 text-xs", children: (_b = field.state.meta.errors[0]) === null || _b === void 0 ? void 0 : _b.message })), field.state.value !== token.name && (jsxs("p", { className: "flex items-start gap-1.5 text-xs text-amber-700", children: [jsx(TriangleAlert, { className: "mt-0.5 h-3.5 w-3.5 shrink-0", "aria-hidden": "true" }), t('apiTabEditApiModal.renameWarning')] }))] }));
151844
+ } }), jsx(form.Field, { name: "expiration_date", children: (field) => (jsx(ExpirationDateField, { value: field.state.value, onChange: (date) => field.handleChange(date), helpText: t('apiTabEditApiModal.expirationHelp') })) }), jsx(TokenPolicyFields, { tenantKey: tenantKey, mode: mode, onModeChange: setMode, policies: policies, onPoliciesChange: setPolicies, groups: groups, onGroupsChange: setGroups, fieldPermissions: fieldPermissions, idPrefix: "edit-api-key" }), jsxs(DialogFooter, { className: "justify-end gap-3", children: [jsx(Button$1, { type: "button", variant: "outline", onClick: onClose, disabled: isLoading, children: t('apiTabDeleteApiModal2.cancel') }), jsx(form.Subscribe, { selector: (state) => ({ canSubmit: state.canSubmit }), children: ({ canSubmit }) => (jsx(Button$1, { type: "submit", disabled: !canSubmit || isLoading, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", children: isLoading ? t('apiTabEditApiModal.saving') : t('apiTabEditApiModal.save') })) })] })] }));
151845
+ }
151846
+ function EditApiModal({ isOpen, onClose, apiKeyName, tenantKey }) {
151847
+ var _a;
151848
+ const t = useT();
151849
+ const skip = !isOpen || !apiKeyName || !tenantKey;
151850
+ const { data: token, isError: isTokenError, isFetching: isTokenFetching, } = useGetApiKeyQuery({ name: apiKeyName, platformKey: tenantKey }, { skip });
151851
+ const { data: fieldPermissionsData, isError: isFieldPermissionsError, isLoading: isFieldPermissionsLoading, } = useGetApiKeyFieldPermissionsQuery({ platformKey: tenantKey }, { skip });
151852
+ // The detail payload wins when it embeds write flags, since those describe
151853
+ // this token rather than the create form.
151854
+ const fieldPermissions = (_a = token === null || token === void 0 ? void 0 : token.field_permissions) !== null && _a !== void 0 ? _a : (isFieldPermissionsError ? DENIED_TOKEN_POLICY_PERMISSIONS : fieldPermissionsData);
151855
+ // Both must settle first: an unresolved permission map reads as "all
151856
+ // writable", which would render controls the caller may not actually have.
151857
+ const isReady = Boolean(token) && !isFieldPermissionsLoading;
151858
+ return (jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: jsxs(DialogContent, { "aria-describedby": "api-key-edit-description", className: "w-full max-w-md max-h-[85vh] overflow-y-auto", children: [jsx(DialogDescription, { className: "sr-only", children: t('apiTabEditApiModal.title') }), jsx(DialogHeader, { children: jsx(DialogTitle, { className: "ibl-dialog-title", children: t('apiTabEditApiModal.title') }) }), isReady && token ? (jsx(EditApiKeyForm, { token: token, tenantKey: tenantKey, fieldPermissions: fieldPermissions, onClose: onClose }, token.name)) : (jsx("p", { className: "py-6 text-center text-sm text-muted-foreground", children: isTokenError && !isTokenFetching
151859
+ ? t('apiTabEditApiModal.loadError')
151860
+ : t('apiTabEditApiModal.loading') }))] }) }));
151861
+ }
151862
+
151863
+ /**
151864
+ * Blue informational banner used to describe a section, matching the RBAC
151865
+ * management tab styling (see `admin.tsx`).
151866
+ */
151867
+ const InfoBanner = ({ icon, title, id, children, className }) => (jsxs("div", { className: `flex gap-3 items-center border rounded-lg p-4 bg-blue-50/60 border-blue-100 ${className !== null && className !== void 0 ? className : ''}`, children: [icon && (jsx("div", { className: "shrink-0 w-9 h-9 rounded-md flex items-center justify-center bg-blue-100 text-blue-600", children: icon })), jsxs("div", { className: "flex-1 min-w-0", children: [title && jsx("h3", { className: "text-sm font-semibold mb-1 text-blue-900", children: title }), jsx("p", { id: id, className: "text-sm text-gray-600 leading-relaxed", children: children })] })] }));
151868
+
151869
+ function IntegrationAutogeneratedTab({ tenantKey }) {
151870
+ const t = useT();
151871
+ const [page, setPage] = React__default.useState(1);
151872
+ const [apiKeyToDelete, setApiKeyToDelete] = React__default.useState(null);
151873
+ const [apiKeyToEdit, setApiKeyToEdit] = React__default.useState(null);
151874
+ const { data, isLoading: isApiKeysLoading } = useGetApiKeysQuery({
151875
+ platformKey: tenantKey,
151876
+ page,
151877
+ pageSize: API_KEYS_PAGE_SIZE,
151878
+ });
151879
+ const { tokens: apiKeys, count } = unwrapApiTokenList(data);
151880
+ const totalPages = Math.ceil(count / API_KEYS_PAGE_SIZE);
151881
+ function closeDeleteApiModal() {
151882
+ setApiKeyToDelete(null);
151883
+ }
151884
+ function openDeleteApiModal(apiKey) {
151885
+ setApiKeyToDelete(apiKey);
151886
+ }
151887
+ return (jsxs(Fragment$1, { children: [jsxs("div", { className: "space-y-4", children: [jsx(InfoBanner, { icon: jsx(KeyRound, { className: "w-5 h-5" }), children: t('apiTabLabels.table.banner') }), jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: "Name" }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: t('apiTabTokenPolicies.modeLabel') }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: "Created" }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: "Expires" }), jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400 w-[100px]" })] }) }), jsx("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: isApiKeysLoading ? (jsx("tr", { children: jsx("td", { colSpan: 5, className: "px-6 py-8 text-center text-sm text-gray-500", children: "Loading..." }) })) : apiKeys.length === 0 ? (jsx("tr", { children: jsx("td", { colSpan: 5, className: "px-6 py-8 text-center text-sm text-gray-500", children: "No API keys found" }) })) : (apiKeys.map((apiKey) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 whitespace-nowrap text-gray-900 dark:text-gray-100", children: apiKey.name }), jsx("td", { className: "px-6 py-4 whitespace-nowrap", children: jsx(Badge, { variant: "secondary", className: "font-normal", children: apiKey.mode === API_TOKEN_MODES.TOKEN_POLICIES
151888
+ ? t('apiTabTokenPolicies.tokenPoliciesModeLabel')
151889
+ : t('apiTabTokenPolicies.ownerModeLabel') }) }), jsx("td", { className: "px-6 py-4 whitespace-nowrap text-gray-600 dark:text-gray-300", children: apiKey.created ? format$1(apiKey.created, 'PPP') : 'N/A' }), jsx("td", { className: "px-6 py-4 whitespace-nowrap text-gray-600 dark:text-gray-300", children: apiKey.expires ? format$1(apiKey.expires, 'PPP') : 'N/A' }), jsx("td", { className: "px-6 py-4", children: jsxs("div", { className: "flex items-center gap-1", children: [jsx(Button$1, { variant: "ghost", size: "sm", className: "cursor-pointer", "aria-label": t('apiTabEditApiModal.editAriaLabel'), onClick: () => setApiKeyToEdit(apiKey.name), children: jsx(Pencil, { className: "h-4 w-4" }) }), jsx(Button$1, { variant: "ghost", size: "sm", className: "cursor-pointer", "aria-label": t('apiTabLabels.table.deleteAriaLabel'), onClick: () => openDeleteApiModal({ name: apiKey.name }), children: jsx(Trash, { className: "h-4 w-4" }) })] }) })] }, apiKey.name)))) })] }) }), totalPages > 1 && (jsx(IblPagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage, disabled: isApiKeysLoading }))] }), apiKeyToDelete && (jsx(DeleteApiModal, { isOpen: !!apiKeyToDelete, onClose: closeDeleteApiModal, apiKey: apiKeyToDelete, tenantKey: tenantKey })), apiKeyToEdit && (jsx(EditApiModal, { isOpen: !!apiKeyToEdit, onClose: () => setApiKeyToEdit(null), apiKeyName: apiKeyToEdit, tenantKey: tenantKey }))] }));
151890
+ }
151891
+
151892
+ function useCopyToClipboard(timeout = 500) {
151893
+ const [status, setStatus] = useState('idle');
151894
+ const copy = useCallback(async (text) => {
151895
+ if (!(navigator === null || navigator === void 0 ? void 0 : navigator.clipboard)) {
151896
+ console.warn('Clipboard not supported');
151897
+ return;
151898
+ }
151899
+ // Try to save to clipboard then save it in the state if worked
151900
+ try {
151901
+ await navigator.clipboard.writeText(text);
151902
+ setStatus('success');
151903
+ setTimeout(() => {
151904
+ setStatus('idle');
151905
+ }, timeout);
151906
+ return;
151907
+ }
151908
+ catch (_a) {
151909
+ //Sentry.captureException(String(error));
151910
+ setStatus('error');
151911
+ return;
151912
+ }
151913
+ }, [timeout]);
151914
+ return { copy, status };
151915
+ }
151916
+
151917
+ function ApiKeyModal({ isOpen, onClose, apiKey }) {
151918
+ const t = useT();
151919
+ const { copy, status } = useCopyToClipboard(800);
151920
+ const Icon = status === 'success' ? Check : Copy;
151921
+ return (jsx(Dialog, { open: isOpen, onOpenChange: onClose, children: jsxs(DialogContent, { children: [jsx(DialogHeader, { children: jsx(DialogTitle, { className: "ibl-dialog-title", children: t('apiTabApiKeyModal.title') }) }), jsx(DialogDescription, { className: "sr-only", children: t('apiTabApiKeyModal.dialogDescription') }), jsxs("div", { className: "grid gap-6", children: [jsxs("p", { className: "text-sm text-muted-foreground grid gap-2", children: [jsx("span", { children: t('apiTabApiKeyModal.securityWarning') }), jsx("span", { children: t('apiTabApiKeyModal.lostKeyWarning') })] }), jsxs("div", { className: "flex items-center gap-4", children: [jsx(Input, { defaultValue: apiKey, readOnly: true }), jsx(Button$1, { size: "icon", className: "ibl-button-primary cursor-pointer", onClick: () => copy(apiKey), children: jsx(Icon, { className: "h-4 w-4" }) })] })] })] }) }));
151922
+ }
151923
+
151924
+ const NAME_FIELD_ID = 'create-api-key-name';
151925
+ const NAME_ERROR_ID = 'create-api-key-name-error';
150694
151926
  const createApiFormSchema = z.object({
150695
151927
  name: z
150696
151928
  .string()
@@ -150702,28 +151934,29 @@ const createApiFormDefaultValues = {
150702
151934
  name: '',
150703
151935
  expiration_date: null,
150704
151936
  };
150705
- function daysFromCurrentDate(targetDate) {
150706
- const currentDate = new Date();
150707
- const oneDay = 24 * 60 * 60 * 1000; // Number of milliseconds in a day
150708
- const timeDifference = targetDate.getTime() - currentDate.getTime();
150709
- const daysDifference = Math.ceil(timeDifference / oneDay);
150710
- return daysDifference * 24 * 3600; // Number of seconds in a day
150711
- }
150712
151937
  function CreateApiModal({ isOpen, onClose, tenantKey, username }) {
150713
151938
  const t = useT();
150714
151939
  const [apiKey, setApiKey] = React__default.useState(null);
150715
- const [isCalendarOpen, setIsCalendarOpen] = React__default.useState(false);
151940
+ const [mode, setMode] = React__default.useState(API_TOKEN_MODES.OWNER);
151941
+ const [policies, setPolicies] = React__default.useState([]);
151942
+ const [groups, setGroups] = React__default.useState([]);
150716
151943
  const [createApiKey, { isLoading }] = useCreateApiKeyMutation();
151944
+ const { data: fieldPermissionsData, isError: isFieldPermissionsError, isLoading: isFieldPermissionsLoading, } = useGetApiKeyFieldPermissionsQuery({ platformKey: tenantKey }, { skip: !isOpen || !tenantKey });
151945
+ const fieldPermissions = isFieldPermissionsError
151946
+ ? DENIED_TOKEN_POLICY_PERMISSIONS
151947
+ : fieldPermissionsData;
150717
151948
  const form = useForm({
150718
151949
  defaultValues: createApiFormDefaultValues,
150719
151950
  validators: {
151951
+ // `onMount` runs the schema against the empty defaults so the required
151952
+ // name keeps Submit disabled from the start, rather than letting the
151953
+ // first click on a pristine form fail silently.
151954
+ onMount: createApiFormSchema,
150720
151955
  onChange: createApiFormSchema,
150721
151956
  },
150722
151957
  onSubmit: async ({ value }) => {
150723
151958
  try {
150724
- const expirationSeconds = value.expiration_date
150725
- ? daysFromCurrentDate(value.expiration_date)
150726
- : 0;
151959
+ const expirationSeconds = value.expiration_date ? secondsUntil(value.expiration_date) : 0;
150727
151960
  const response = await createApiKey({
150728
151961
  requestBody: {
150729
151962
  username: username !== null && username !== void 0 ? username : '',
@@ -150733,11 +151966,18 @@ function CreateApiModal({ isOpen, onClose, tenantKey, username }) {
150733
151966
  created: new Date().toISOString(),
150734
151967
  expires: expirationSeconds === 0 ? '' : expirationSeconds.toString(),
150735
151968
  expires_in: expirationSeconds === 0 ? undefined : expirationSeconds.toString(),
151969
+ ...buildTokenPolicyPayload({ mode, policies, groups, fieldPermissions }),
150736
151970
  },
150737
151971
  }).unwrap();
150738
151972
  toast.success(t('apiTabCreateApiModal2.apiKeyCreatedSuccessfully'));
150739
151973
  form.reset();
151974
+ setMode(API_TOKEN_MODES.OWNER);
151975
+ setPolicies([]);
151976
+ setGroups([]);
151977
+ // The generated key lives outside this dialog, so closing the creation
151978
+ // form still leaves it on screen for the one time it is readable.
150740
151979
  setApiKey(response.key);
151980
+ onClose();
150741
151981
  }
150742
151982
  catch (error) {
150743
151983
  console.error(JSON.stringify(error));
@@ -150746,24 +151986,23 @@ function CreateApiModal({ isOpen, onClose, tenantKey, username }) {
150746
151986
  }
150747
151987
  },
150748
151988
  });
150749
- return (jsxs(Fragment$1, { children: [jsx(Dialog, { open: isOpen, onOpenChange: isLoading ? undefined : onClose, children: jsxs(DialogContent, { "aria-describedby": "api-key-creation-description", className: "w-full max-w-md", children: [jsx(DialogDescription, { className: "sr-only", children: t('apiTabCreateApiModal2.createApiKey') }), jsx(DialogHeader, { children: jsx(DialogTitle, { className: "ibl-dialog-title", children: t('apiTabCreateApiModal2.createApiKey') }) }), jsxs("form", { onSubmit: (formEvent) => {
151989
+ return (jsxs(Fragment$1, { children: [jsx(Dialog, { open: isOpen, onOpenChange: isLoading ? undefined : onClose, children: jsxs(DialogContent, { "aria-describedby": "api-key-creation-description", className: "w-full max-w-md max-h-[85vh] overflow-y-auto", children: [jsx(DialogDescription, { className: "sr-only", children: t('apiTabCreateApiModal2.createApiKey') }), jsx(DialogHeader, { children: jsx(DialogTitle, { className: "ibl-dialog-title", children: t('apiTabCreateApiModal2.createApiKey') }) }), jsxs("form", { onSubmit: (formEvent) => {
150750
151990
  formEvent.preventDefault();
150751
151991
  formEvent.stopPropagation();
150752
151992
  form.handleSubmit();
150753
- }, className: "mt-5 grid gap-5", children: [jsx(form.Field, { name: "name", children: (field) => {
150754
- var _a, _b;
150755
- const hasError = ((_a = field.state.meta.errors) === null || _a === void 0 ? void 0 : _a.length) > 0;
150756
- const isDirty = field.state.meta.isDirty;
150757
- const hasErrorAndIsDirty = hasError && isDirty;
150758
- return (jsxs("div", { className: "space-y-1.5", children: [jsxs(Label$2, { className: "flex items-center text-sm font-medium text-[#646464]", children: [t('apiTabCreateApiModal2.apiKeyName'), jsx("span", { className: "ml-1 text-red-500", children: "*" })] }), jsx(Input, { placeholder: t('apiTabCreateApiModal2.apiKeyNamePlaceholder'), value: field.state.value, onChange: (event) => field.handleChange(event.target.value), autoComplete: "off" }), hasErrorAndIsDirty && (jsx("p", { className: "text-red-500 text-xs", children: (_b = field.state.meta.errors[0]) === null || _b === void 0 ? void 0 : _b.message }))] }));
150759
- } }), jsx(form.Field, { name: "expiration_date", children: (field) => (jsxs("div", { className: "space-y-1.5", children: [jsx(Label$2, { className: "flex items-center text-sm font-medium text-[#646464]", children: "Expiration Date" }), jsxs("div", { children: [jsxs(Button$1, { type: "button", variant: "outline", "aria-haspopup": "dialog", "aria-expanded": isCalendarOpen, onClick: () => setIsCalendarOpen((open) => !open), className: cn('w-full pl-3 text-left font-normal', !field.state.value && 'text-muted-foreground'), children: [field.state.value ? (format$1(field.state.value, 'PPP')) : (jsx("span", { children: "Pick a date" })), jsx(Calendar$1, { className: "ml-auto h-4 w-4 opacity-50" })] }), isCalendarOpen && (jsx("div", { className: "mt-2 w-auto rounded-md border border-gray-200 dark:border-gray-700", children: jsx(Calendar, { mode: "single",
150760
- // @ts-expect-error - Calendar selected prop expects Date but form field may be null
150761
- selected: field.state.value, onSelect: (date) => {
150762
- field.handleChange(date !== null && date !== void 0 ? date : null);
150763
- setIsCalendarOpen(false);
150764
- }, disabled: (date) => date && date < new Date() }) }))] })] })) }), jsx(DialogFooter, { className: "justify-end", children: jsx(form.Subscribe, { selector: (state) => ({
151993
+ }, className: "mt-5 grid min-w-0 gap-5", children: [jsx(form.Field, { name: "name", children: (field) => {
151994
+ var _a;
151995
+ const errorMessage = (_a = field.state.meta.errors[0]) === null || _a === void 0 ? void 0 : _a.message;
151996
+ // Wait for the user to engage with the field — typing or tabbing
151997
+ // away before flagging it, so an untouched form is not red on
151998
+ // open, but an emptied or skipped field always explains itself.
151999
+ const showError = Boolean(errorMessage && (field.state.meta.isDirty || field.state.meta.isBlurred));
152000
+ return (jsxs("div", { className: "space-y-1.5", children: [jsxs(Label$2, { htmlFor: NAME_FIELD_ID, className: "flex items-center text-sm font-medium text-[#646464]", children: [t('apiTabCreateApiModal2.apiKeyName'), jsx("span", { className: "ml-1 text-red-500", children: "*" })] }), jsx(Input, { id: NAME_FIELD_ID, placeholder: t('apiTabCreateApiModal2.apiKeyNamePlaceholder'), value: field.state.value, onChange: (event) => field.handleChange(event.target.value), onBlur: field.handleBlur, autoComplete: "off", "aria-required": "true", "aria-invalid": showError, "aria-describedby": showError ? NAME_ERROR_ID : undefined }), showError && (jsx("p", { id: NAME_ERROR_ID, role: "alert", className: "text-red-500 text-xs", children: errorMessage }))] }));
152001
+ } }), jsx(form.Field, { name: "expiration_date", children: (field) => (jsx(ExpirationDateField, { value: field.state.value, onChange: (date) => field.handleChange(date) })) }), !isFieldPermissionsLoading && (jsx(TokenPolicyFields, { tenantKey: tenantKey, mode: mode, onModeChange: setMode, policies: policies, onPoliciesChange: setPolicies, groups: groups, onGroupsChange: setGroups, fieldPermissions: fieldPermissions, idPrefix: "create-api-key" })), jsx(DialogFooter, { className: "justify-end", children: jsx(form.Subscribe, { selector: (state) => ({
150765
152002
  canSubmit: state.canSubmit,
150766
- }), children: ({ canSubmit }) => (jsx(Button$1, { type: "submit", disabled: !canSubmit || isLoading, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", children: isLoading ? 'Submitting...' : 'Submit' })) }) })] })] }) }), apiKey && jsx(ApiKeyModal, { isOpen: true, onClose: () => setApiKey(null), apiKey: apiKey })] }));
152003
+ }), children: ({ canSubmit }) => (jsx(Button$1, { type: "submit", disabled: !canSubmit || isLoading, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] text-white hover:opacity-90", children: isLoading
152004
+ ? t('apiTabLabels.createModal.submitting')
152005
+ : t('apiTabLabels.createModal.submit') })) }) })] })] }) }), apiKey && jsx(ApiKeyModal, { isOpen: true, onClose: () => setApiKey(null), apiKey: apiKey })] }));
150767
152006
  }
150768
152007
 
150769
152008
  // Dynamic schema based on selected provider
@@ -154243,54 +155482,6 @@ function MonetizationTab({ platformKey, authURL }) {
154243
155482
  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 })] }));
154244
155483
  }
154245
155484
 
154246
- function SearchableMultiSelect({ items, selectedItems, onSelectionChange, searchQuery, onSearchChange, isLoading, placeholder = 'Search and select items...', getItemValue, getItemLabel, className, maxHeight = 'max-h-60', inputId, ariaDescribedBy, onSelectedItemAction, selectedItemActionIcon, selectedItemActionAriaLabel = 'View item details', }) {
154247
- const [isOpen, setIsOpen] = useState(false);
154248
- const containerRef = useRef(null);
154249
- // Handle outside click to close dropdown
154250
- useEffect(() => {
154251
- const handleClickOutside = (event) => {
154252
- if (containerRef.current && !containerRef.current.contains(event.target)) {
154253
- setIsOpen(false);
154254
- }
154255
- };
154256
- if (isOpen) {
154257
- document.addEventListener('mousedown', handleClickOutside);
154258
- }
154259
- return () => {
154260
- document.removeEventListener('mousedown', handleClickOutside);
154261
- };
154262
- }, [isOpen]);
154263
- const handleSelectItem = (itemValue, itemLabel) => {
154264
- const newSelection = selectedItems.some((item) => item.value === itemValue)
154265
- ? selectedItems.filter((item) => item.value !== itemValue)
154266
- : [...selectedItems, { label: itemLabel, value: itemValue }];
154267
- onSelectionChange(newSelection);
154268
- };
154269
- const handleRemoveItem = (itemValue) => {
154270
- onSelectionChange(selectedItems.filter((item) => item.value !== itemValue));
154271
- };
154272
- return (jsxs("div", { className: cn('space-y-2', className), ref: containerRef, children: [jsxs("div", { className: "relative", children: [jsxs("div", { className: cn('flex min-h-[40px] w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background', 'focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2', 'cursor-pointer'), children: [jsxs("div", { className: "flex flex-1 items-center gap-2", children: [jsx(Search, { className: "h-4 w-4 text-muted-foreground" }), jsx("input", { type: "text", placeholder: placeholder, value: searchQuery, onChange: (e) => onSearchChange(e.target.value), onFocus: () => setIsOpen(true), id: inputId, "aria-describedby": ariaDescribedBy, className: "flex-1 bg-transparent outline-none placeholder:text-muted-foreground", onClick: (e) => e.stopPropagation() })] }), jsxs("div", { className: "flex items-center gap-1", children: [selectedItems.length > 0 && (jsx(Badge, { variant: "secondary", className: "text-xs", children: selectedItems.length })), jsx(X$1, { className: "h-4 w-4 text-muted-foreground cursor-pointer", onClick: (e) => {
154273
- e.stopPropagation();
154274
- onSelectionChange([]);
154275
- onSearchChange('');
154276
- setIsOpen(false);
154277
- } })] })] }), isOpen && (jsx("div", { className: cn('absolute z-50 w-full mt-1 bg-white border rounded-md shadow-lg overflow-auto', maxHeight), children: isLoading ? (jsx("div", { className: "p-3 text-sm text-muted-foreground", children: "Loading..." })) : items.length > 0 ? (items.map((item) => {
154278
- const itemValue = getItemValue(item);
154279
- const itemLabel = getItemLabel(item);
154280
- const isSelected = selectedItems.some((selected) => selected.value === itemValue);
154281
- return (jsxs("div", { className: "flex items-center space-x-2 p-2 hover:bg-gray-50 cursor-pointer", onClick: () => handleSelectItem(itemValue, itemLabel), children: [jsx("div", { className: "flex items-center justify-center w-4 h-4", children: isSelected && jsx(Check, { className: "h-3 w-3 text-primary" }) }), jsx("span", { className: "text-sm", children: itemLabel })] }, itemValue));
154282
- })) : (jsx("div", { className: "p-3 text-sm text-muted-foreground", children: searchQuery ? 'No items found' : 'Start typing to search items' })) }))] }), selectedItems.length > 0 && (jsx("div", { className: "flex gap-2 overflow-x-auto pb-2 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100", children: selectedItems
154283
- .slice()
154284
- .reverse()
154285
- .map((selectedItem) => {
154286
- return (jsxs(Badge, { variant: "secondary", className: "text-xs whitespace-nowrap flex-shrink-0 font-normal", children: [selectedItem.label, onSelectedItemAction && (jsx("button", { type: "button", onClick: (event) => {
154287
- event.preventDefault();
154288
- event.stopPropagation();
154289
- onSelectedItemAction(selectedItem);
154290
- }, className: "ml-1 text-gray-500 hover:text-gray-700", "aria-label": selectedItemActionAriaLabel, children: selectedItemActionIcon !== null && selectedItemActionIcon !== void 0 ? selectedItemActionIcon : jsx(Eye, { className: "h-3 w-3" }) })), jsx("button", { type: "button", onClick: () => handleRemoveItem(selectedItem.value), className: "ml-1 text-gray-500 hover:text-gray-700", children: "\u00D7" })] }, selectedItem.value));
154291
- }) }))] }));
154292
- }
154293
-
154294
155485
  // ::- Persistent data structure representing an ordered mapping from
154295
155486
  // strings to values, with some convenient update methods.
154296
155487
  function OrderedMap(content) {
@@ -179599,11 +180790,11 @@ class Branch {
179599
180790
  return;
179600
180791
  }
179601
180792
  if (remap) {
179602
- addBefore.push(new Item$1(item.map));
180793
+ addBefore.push(new Item(item.map));
179603
180794
  let step = item.step.map(remap.slice(mapFrom)), map;
179604
180795
  if (step && transform.maybeStep(step).doc) {
179605
180796
  map = transform.mapping.maps[transform.mapping.maps.length - 1];
179606
- addAfter.push(new Item$1(map, undefined, undefined, addAfter.length + addBefore.length));
180797
+ addAfter.push(new Item(map, undefined, undefined, addAfter.length + addBefore.length));
179607
180798
  }
179608
180799
  mapFrom--;
179609
180800
  if (map)
@@ -179626,7 +180817,7 @@ class Branch {
179626
180817
  let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null;
179627
180818
  for (let i = 0; i < transform.steps.length; i++) {
179628
180819
  let step = transform.steps[i].invert(transform.docs[i]);
179629
- let item = new Item$1(transform.mapping.maps[i], step, selection), merged;
180820
+ let item = new Item(transform.mapping.maps[i], step, selection), merged;
179630
180821
  if (merged = lastItem && lastItem.merge(item)) {
179631
180822
  item = merged;
179632
180823
  if (i)
@@ -179661,7 +180852,7 @@ class Branch {
179661
180852
  addMaps(array) {
179662
180853
  if (this.eventCount == 0)
179663
180854
  return this;
179664
- return new Branch(this.items.append(array.map(map => new Item$1(map))), this.eventCount);
180855
+ return new Branch(this.items.append(array.map(map => new Item(map))), this.eventCount);
179665
180856
  }
179666
180857
  // When the collab module receives remote changes, the history has
179667
180858
  // to know about those, so that it can adjust the steps that were
@@ -179688,15 +180879,15 @@ class Branch {
179688
180879
  let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos));
179689
180880
  if (selection)
179690
180881
  eventCount++;
179691
- rebasedItems.push(new Item$1(map, step, selection));
180882
+ rebasedItems.push(new Item(map, step, selection));
179692
180883
  }
179693
180884
  else {
179694
- rebasedItems.push(new Item$1(map));
180885
+ rebasedItems.push(new Item(map));
179695
180886
  }
179696
180887
  }, start);
179697
180888
  let newMaps = [];
179698
180889
  for (let i = rebasedCount; i < newUntil; i++)
179699
- newMaps.push(new Item$1(mapping.maps[i]));
180890
+ newMaps.push(new Item(mapping.maps[i]));
179700
180891
  let items = this.items.slice(0, start).append(newMaps).append(rebasedItems);
179701
180892
  let branch = new Branch(items, eventCount);
179702
180893
  if (branch.emptyItemCount() > max_empty_items)
@@ -179733,7 +180924,7 @@ class Branch {
179733
180924
  let selection = item.selection && item.selection.map(remap.slice(mapFrom));
179734
180925
  if (selection)
179735
180926
  events++;
179736
- let newItem = new Item$1(map.invert(), step, selection), merged, last = items.length - 1;
180927
+ let newItem = new Item(map.invert(), step, selection), merged, last = items.length - 1;
179737
180928
  if (merged = items.length && items[last].merge(newItem))
179738
180929
  items[last] = merged;
179739
180930
  else
@@ -179758,7 +180949,7 @@ function cutOffEvents(items, n) {
179758
180949
  });
179759
180950
  return items.slice(cutPoint);
179760
180951
  }
179761
- let Item$1 = class Item {
180952
+ class Item {
179762
180953
  constructor(
179763
180954
  // The (forward) step map for this item.
179764
180955
  map,
@@ -179783,7 +180974,7 @@ let Item$1 = class Item {
179783
180974
  return new Item(step.getMap().invert(), step, this.selection);
179784
180975
  }
179785
180976
  }
179786
- };
180977
+ }
179787
180978
  // The value of the state field that tracks undo/redo history for that
179788
180979
  // state. Will be stored in the plugin state when the history plugin
179789
180980
  // is active.
@@ -180950,67 +182141,6 @@ var index_default$1 = TextAlign;
180950
182141
  // src/index.ts
180951
182142
  var index_default = Placeholder;
180952
182143
 
180953
- // packages/core/primitive/src/primitive.tsx
180954
- function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
180955
- return function handleEvent(event) {
180956
- originalEventHandler?.(event);
180957
- if (checkForDefaultPrevented === false || !event.defaultPrevented) {
180958
- return ourEventHandler?.(event);
180959
- }
180960
- };
180961
- }
180962
-
180963
- // packages/react/use-callback-ref/src/useCallbackRef.tsx
180964
- function useCallbackRef(callback) {
180965
- const callbackRef = React.useRef(callback);
180966
- React.useEffect(() => {
180967
- callbackRef.current = callback;
180968
- });
180969
- return React.useMemo(() => (...args) => callbackRef.current?.(...args), []);
180970
- }
180971
-
180972
- // packages/react/use-controllable-state/src/useControllableState.tsx
180973
- function useControllableState({
180974
- prop,
180975
- defaultProp,
180976
- onChange = () => {
180977
- }
180978
- }) {
180979
- const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({ defaultProp, onChange });
180980
- const isControlled = prop !== void 0;
180981
- const value = isControlled ? prop : uncontrolledProp;
180982
- const handleChange = useCallbackRef(onChange);
180983
- const setValue = React.useCallback(
180984
- (nextValue) => {
180985
- if (isControlled) {
180986
- const setter = nextValue;
180987
- const value2 = typeof nextValue === "function" ? setter(prop) : nextValue;
180988
- if (value2 !== prop) handleChange(value2);
180989
- } else {
180990
- setUncontrolledProp(nextValue);
180991
- }
180992
- },
180993
- [isControlled, prop, setUncontrolledProp, handleChange]
180994
- );
180995
- return [value, setValue];
180996
- }
180997
- function useUncontrolledState({
180998
- defaultProp,
180999
- onChange
181000
- }) {
181001
- const uncontrolledState = React.useState(defaultProp);
181002
- const [value] = uncontrolledState;
181003
- const prevValueRef = React.useRef(value);
181004
- const handleChange = useCallbackRef(onChange);
181005
- React.useEffect(() => {
181006
- if (prevValueRef.current !== value) {
181007
- handleChange(value);
181008
- prevValueRef.current = value;
181009
- }
181010
- }, [value, prevValueRef, handleChange]);
181011
- return uncontrolledState;
181012
- }
181013
-
181014
182144
  var NAME$1 = "Toggle";
181015
182145
  var Toggle$1 = React.forwardRef((props, forwardedRef) => {
181016
182146
  const { pressed: pressedProp, defaultPressed = false, onPressedChange, ...buttonProps } = props;
@@ -181037,7 +182167,7 @@ var Toggle$1 = React.forwardRef((props, forwardedRef) => {
181037
182167
  );
181038
182168
  });
181039
182169
  Toggle$1.displayName = NAME$1;
181040
- var Root$2 = Toggle$1;
182170
+ var Root$1 = Toggle$1;
181041
182171
 
181042
182172
  const toggleVariants = cva('inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground', {
181043
182173
  variants: {
@@ -181056,8 +182186,8 @@ const toggleVariants = cva('inline-flex items-center justify-center rounded-md t
181056
182186
  size: 'default',
181057
182187
  },
181058
182188
  });
181059
- const Toggle = React.forwardRef(({ className, variant, size, ...props }, ref) => (jsx(Root$2, { ref: ref, className: cn(toggleVariants({ variant, size, className })), ...props })));
181060
- Toggle.displayName = Root$2.displayName;
182189
+ const Toggle = React.forwardRef(({ className, variant, size, ...props }, ref) => (jsx(Root$1, { ref: ref, className: cn(toggleVariants({ variant, size, className })), ...props })));
182190
+ Toggle.displayName = Root$1.displayName;
181061
182191
 
181062
182192
  // src/separator.tsx
181063
182193
  var NAME = "Separator";
@@ -181082,10 +182212,10 @@ Separator$2.displayName = NAME;
181082
182212
  function isValidOrientation(orientation) {
181083
182213
  return ORIENTATIONS.includes(orientation);
181084
182214
  }
181085
- var Root$1 = Separator$2;
182215
+ var Root = Separator$2;
181086
182216
 
181087
- const Separator$1 = React.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => (jsx(Root$1, { ref: ref, decorative: decorative, orientation: orientation, className: cn("shrink-0 bg-border", orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]", className), ...props })));
181088
- Separator$1.displayName = Root$1.displayName;
182217
+ const Separator$1 = React.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => (jsx(Root, { ref: ref, decorative: decorative, orientation: orientation, className: cn("shrink-0 bg-border", orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]", className), ...props })));
182218
+ Separator$1.displayName = Root.displayName;
181089
182219
 
181090
182220
  // Custom Div extension to preserve div elements with inline styles
181091
182221
  const Div = Node3.create({
@@ -181798,14 +182928,14 @@ var SUB_CLOSE_KEYS = {
181798
182928
  rtl: ["ArrowRight"]
181799
182929
  };
181800
182930
  var MENU_NAME = "Menu";
181801
- var [Collection$1, useCollection$1, createCollectionScope$1] = createCollection$2(MENU_NAME);
182931
+ var [Collection, useCollection, createCollectionScope] = createCollection$2(MENU_NAME);
181802
182932
  var [createMenuContext, createMenuScope] = createContextScope$1(MENU_NAME, [
181803
- createCollectionScope$1,
182933
+ createCollectionScope,
181804
182934
  createPopperScope$1,
181805
182935
  createRovingFocusGroupScope$1
181806
182936
  ]);
181807
182937
  var usePopperScope = createPopperScope$1();
181808
- var useRovingFocusGroupScope$1 = createRovingFocusGroupScope$1();
182938
+ var useRovingFocusGroupScope = createRovingFocusGroupScope$1();
181809
182939
  var [MenuProvider, useMenuContext] = createMenuContext(MENU_NAME);
181810
182940
  var [MenuRootProvider, useMenuRootContext] = createMenuContext(MENU_NAME);
181811
182941
  var Menu = (props) => {
@@ -181879,7 +183009,7 @@ var MenuContent = React.forwardRef(
181879
183009
  const { forceMount = portalContext.forceMount, ...contentProps } = props;
181880
183010
  const context = useMenuContext(CONTENT_NAME$2, props.__scopeMenu);
181881
183011
  const rootContext = useMenuRootContext(CONTENT_NAME$2, props.__scopeMenu);
181882
- return /* @__PURE__ */ jsx(Collection$1.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx(Presence$2, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Collection$1.Slot, { scope: props.__scopeMenu, children: rootContext.modal ? /* @__PURE__ */ jsx(MenuRootContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(MenuRootContentNonModal, { ...contentProps, ref: forwardedRef }) }) }) });
183012
+ return /* @__PURE__ */ jsx(Collection.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx(Presence$2, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Collection.Slot, { scope: props.__scopeMenu, children: rootContext.modal ? /* @__PURE__ */ jsx(MenuRootContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(MenuRootContentNonModal, { ...contentProps, ref: forwardedRef }) }) }) });
181883
183013
  }
181884
183014
  );
181885
183015
  var MenuRootContentModal = React.forwardRef(
@@ -181945,8 +183075,8 @@ var MenuContentImpl = React.forwardRef(
181945
183075
  const context = useMenuContext(CONTENT_NAME$2, __scopeMenu);
181946
183076
  const rootContext = useMenuRootContext(CONTENT_NAME$2, __scopeMenu);
181947
183077
  const popperScope = usePopperScope(__scopeMenu);
181948
- const rovingFocusGroupScope = useRovingFocusGroupScope$1(__scopeMenu);
181949
- const getItems = useCollection$1(__scopeMenu);
183078
+ const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeMenu);
183079
+ const getItems = useCollection(__scopeMenu);
181950
183080
  const [currentItemId, setCurrentItemId] = React.useState(null);
181951
183081
  const contentRef = React.useRef(null);
181952
183082
  const composedRefs = useComposedRefs$1(forwardedRef, contentRef, context.onContentChange);
@@ -182074,7 +183204,7 @@ var MenuContentImpl = React.forwardRef(
182074
183204
  const items = getItems().filter((item) => !item.disabled);
182075
183205
  const candidateNodes = items.map((item) => item.ref.current);
182076
183206
  if (LAST_KEYS.includes(event.key)) candidateNodes.reverse();
182077
- focusFirst$1(candidateNodes);
183207
+ focusFirst(candidateNodes);
182078
183208
  }),
182079
183209
  onBlur: composeEventHandlers$2(props.onBlur, (event) => {
182080
183210
  if (!event.currentTarget.contains(event.target)) {
@@ -182107,14 +183237,14 @@ var MenuContentImpl = React.forwardRef(
182107
183237
  }
182108
183238
  );
182109
183239
  MenuContent.displayName = CONTENT_NAME$2;
182110
- var GROUP_NAME$2 = "MenuGroup";
183240
+ var GROUP_NAME$1 = "MenuGroup";
182111
183241
  var MenuGroup = React.forwardRef(
182112
183242
  (props, forwardedRef) => {
182113
183243
  const { __scopeMenu, ...groupProps } = props;
182114
183244
  return /* @__PURE__ */ jsx(Primitive$4.div, { role: "group", ...groupProps, ref: forwardedRef });
182115
183245
  }
182116
183246
  );
182117
- MenuGroup.displayName = GROUP_NAME$2;
183247
+ MenuGroup.displayName = GROUP_NAME$1;
182118
183248
  var LABEL_NAME$1 = "MenuLabel";
182119
183249
  var MenuLabel = React.forwardRef(
182120
183250
  (props, forwardedRef) => {
@@ -182123,14 +183253,14 @@ var MenuLabel = React.forwardRef(
182123
183253
  }
182124
183254
  );
182125
183255
  MenuLabel.displayName = LABEL_NAME$1;
182126
- var ITEM_NAME$3 = "MenuItem";
183256
+ var ITEM_NAME$1 = "MenuItem";
182127
183257
  var ITEM_SELECT = "menu.itemSelect";
182128
183258
  var MenuItem = React.forwardRef(
182129
183259
  (props, forwardedRef) => {
182130
183260
  const { disabled = false, onSelect, ...itemProps } = props;
182131
183261
  const ref = React.useRef(null);
182132
- const rootContext = useMenuRootContext(ITEM_NAME$3, props.__scopeMenu);
182133
- const contentContext = useMenuContentContext(ITEM_NAME$3, props.__scopeMenu);
183262
+ const rootContext = useMenuRootContext(ITEM_NAME$1, props.__scopeMenu);
183263
+ const contentContext = useMenuContentContext(ITEM_NAME$1, props.__scopeMenu);
182134
183264
  const composedRefs = useComposedRefs$1(forwardedRef, ref);
182135
183265
  const isPointerDownRef = React.useRef(false);
182136
183266
  const handleSelect = () => {
@@ -182172,12 +183302,12 @@ var MenuItem = React.forwardRef(
182172
183302
  );
182173
183303
  }
182174
183304
  );
182175
- MenuItem.displayName = ITEM_NAME$3;
183305
+ MenuItem.displayName = ITEM_NAME$1;
182176
183306
  var MenuItemImpl = React.forwardRef(
182177
183307
  (props, forwardedRef) => {
182178
183308
  const { __scopeMenu, disabled = false, textValue, ...itemProps } = props;
182179
- const contentContext = useMenuContentContext(ITEM_NAME$3, __scopeMenu);
182180
- const rovingFocusGroupScope = useRovingFocusGroupScope$1(__scopeMenu);
183309
+ const contentContext = useMenuContentContext(ITEM_NAME$1, __scopeMenu);
183310
+ const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeMenu);
182181
183311
  const ref = React.useRef(null);
182182
183312
  const composedRefs = useComposedRefs$1(forwardedRef, ref);
182183
183313
  const [isFocused, setIsFocused] = React.useState(false);
@@ -182189,7 +183319,7 @@ var MenuItemImpl = React.forwardRef(
182189
183319
  }
182190
183320
  }, [itemProps.children]);
182191
183321
  return /* @__PURE__ */ jsx(
182192
- Collection$1.ItemSlot,
183322
+ Collection.ItemSlot,
182193
183323
  {
182194
183324
  scope: __scopeMenu,
182195
183325
  disabled,
@@ -182251,9 +183381,9 @@ var MenuCheckboxItem = React.forwardRef(
182251
183381
  }
182252
183382
  );
182253
183383
  MenuCheckboxItem.displayName = CHECKBOX_ITEM_NAME$1;
182254
- var RADIO_GROUP_NAME$2 = "MenuRadioGroup";
182255
- var [RadioGroupProvider$1, useRadioGroupContext$1] = createMenuContext(
182256
- RADIO_GROUP_NAME$2,
183384
+ var RADIO_GROUP_NAME$1 = "MenuRadioGroup";
183385
+ var [RadioGroupProvider, useRadioGroupContext] = createMenuContext(
183386
+ RADIO_GROUP_NAME$1,
182257
183387
  { value: void 0, onValueChange: () => {
182258
183388
  } }
182259
183389
  );
@@ -182261,15 +183391,15 @@ var MenuRadioGroup = React.forwardRef(
182261
183391
  (props, forwardedRef) => {
182262
183392
  const { value, onValueChange, ...groupProps } = props;
182263
183393
  const handleValueChange = useCallbackRef$2(onValueChange);
182264
- return /* @__PURE__ */ jsx(RadioGroupProvider$1, { scope: props.__scopeMenu, value, onValueChange: handleValueChange, children: /* @__PURE__ */ jsx(MenuGroup, { ...groupProps, ref: forwardedRef }) });
183394
+ return /* @__PURE__ */ jsx(RadioGroupProvider, { scope: props.__scopeMenu, value, onValueChange: handleValueChange, children: /* @__PURE__ */ jsx(MenuGroup, { ...groupProps, ref: forwardedRef }) });
182265
183395
  }
182266
183396
  );
182267
- MenuRadioGroup.displayName = RADIO_GROUP_NAME$2;
183397
+ MenuRadioGroup.displayName = RADIO_GROUP_NAME$1;
182268
183398
  var RADIO_ITEM_NAME$1 = "MenuRadioItem";
182269
183399
  var MenuRadioItem = React.forwardRef(
182270
183400
  (props, forwardedRef) => {
182271
183401
  const { value, ...radioItemProps } = props;
182272
- const context = useRadioGroupContext$1(RADIO_ITEM_NAME$1, props.__scopeMenu);
183402
+ const context = useRadioGroupContext(RADIO_ITEM_NAME$1, props.__scopeMenu);
182273
183403
  const checked = value === context.value;
182274
183404
  return /* @__PURE__ */ jsx(ItemIndicatorProvider, { scope: props.__scopeMenu, checked, children: /* @__PURE__ */ jsx(
182275
183405
  MenuItem,
@@ -182487,7 +183617,7 @@ var MenuSubContent = React.forwardRef(
182487
183617
  const subContext = useMenuSubContext(SUB_CONTENT_NAME$1, props.__scopeMenu);
182488
183618
  const ref = React.useRef(null);
182489
183619
  const composedRefs = useComposedRefs$1(forwardedRef, ref);
182490
- return /* @__PURE__ */ jsx(Collection$1.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx(Presence$2, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Collection$1.Slot, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx(
183620
+ return /* @__PURE__ */ jsx(Collection.Provider, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx(Presence$2, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(Collection.Slot, { scope: props.__scopeMenu, children: /* @__PURE__ */ jsx(
182491
183621
  MenuContentImpl,
182492
183622
  {
182493
183623
  id: subContext.contentId,
@@ -182534,7 +183664,7 @@ function isIndeterminate(checked) {
182534
183664
  function getCheckedState(checked) {
182535
183665
  return isIndeterminate(checked) ? "indeterminate" : checked ? "checked" : "unchecked";
182536
183666
  }
182537
- function focusFirst$1(candidates) {
183667
+ function focusFirst(candidates) {
182538
183668
  const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
182539
183669
  for (const candidate of candidates) {
182540
183670
  if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
@@ -182542,14 +183672,14 @@ function focusFirst$1(candidates) {
182542
183672
  if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
182543
183673
  }
182544
183674
  }
182545
- function wrapArray$1(array, startIndex) {
183675
+ function wrapArray(array, startIndex) {
182546
183676
  return array.map((_, index) => array[(startIndex + index) % array.length]);
182547
183677
  }
182548
183678
  function getNextMatch(values, search, currentMatch) {
182549
183679
  const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]);
182550
183680
  const normalizedSearch = isRepeated ? search[0] : search;
182551
183681
  const currentMatchIndex = currentMatch ? values.indexOf(currentMatch) : -1;
182552
- let wrappedValues = wrapArray$1(values, Math.max(currentMatchIndex, 0));
183682
+ let wrappedValues = wrapArray(values, Math.max(currentMatchIndex, 0));
182553
183683
  const excludeCurrentMatch = normalizedSearch.length === 1;
182554
183684
  if (excludeCurrentMatch) wrappedValues = wrappedValues.filter((v) => v !== currentMatch);
182555
183685
  const nextMatch = wrappedValues.find(
@@ -182584,9 +183714,9 @@ var Portal = MenuPortal;
182584
183714
  var Content2$2 = MenuContent;
182585
183715
  var Group = MenuGroup;
182586
183716
  var Label = MenuLabel;
182587
- var Item2$2 = MenuItem;
183717
+ var Item2$1 = MenuItem;
182588
183718
  var CheckboxItem = MenuCheckboxItem;
182589
- var RadioGroup$2 = MenuRadioGroup;
183719
+ var RadioGroup = MenuRadioGroup;
182590
183720
  var RadioItem = MenuRadioItem;
182591
183721
  var ItemIndicator = MenuItemIndicator;
182592
183722
  var Separator = MenuSeparator;
@@ -182720,7 +183850,7 @@ var DropdownMenuContent$1 = React.forwardRef(
182720
183850
  }
182721
183851
  );
182722
183852
  DropdownMenuContent$1.displayName = CONTENT_NAME$1;
182723
- var GROUP_NAME$1 = "DropdownMenuGroup";
183853
+ var GROUP_NAME = "DropdownMenuGroup";
182724
183854
  var DropdownMenuGroup$1 = React.forwardRef(
182725
183855
  (props, forwardedRef) => {
182726
183856
  const { __scopeDropdownMenu, ...groupProps } = props;
@@ -182728,7 +183858,7 @@ var DropdownMenuGroup$1 = React.forwardRef(
182728
183858
  return /* @__PURE__ */ jsx(Group, { ...menuScope, ...groupProps, ref: forwardedRef });
182729
183859
  }
182730
183860
  );
182731
- DropdownMenuGroup$1.displayName = GROUP_NAME$1;
183861
+ DropdownMenuGroup$1.displayName = GROUP_NAME;
182732
183862
  var LABEL_NAME = "DropdownMenuLabel";
182733
183863
  var DropdownMenuLabel$1 = React.forwardRef(
182734
183864
  (props, forwardedRef) => {
@@ -182738,15 +183868,15 @@ var DropdownMenuLabel$1 = React.forwardRef(
182738
183868
  }
182739
183869
  );
182740
183870
  DropdownMenuLabel$1.displayName = LABEL_NAME;
182741
- var ITEM_NAME$2 = "DropdownMenuItem";
183871
+ var ITEM_NAME = "DropdownMenuItem";
182742
183872
  var DropdownMenuItem$1 = React.forwardRef(
182743
183873
  (props, forwardedRef) => {
182744
183874
  const { __scopeDropdownMenu, ...itemProps } = props;
182745
183875
  const menuScope = useMenuScope(__scopeDropdownMenu);
182746
- return /* @__PURE__ */ jsx(Item2$2, { ...menuScope, ...itemProps, ref: forwardedRef });
183876
+ return /* @__PURE__ */ jsx(Item2$1, { ...menuScope, ...itemProps, ref: forwardedRef });
182747
183877
  }
182748
183878
  );
182749
- DropdownMenuItem$1.displayName = ITEM_NAME$2;
183879
+ DropdownMenuItem$1.displayName = ITEM_NAME;
182750
183880
  var CHECKBOX_ITEM_NAME = "DropdownMenuCheckboxItem";
182751
183881
  var DropdownMenuCheckboxItem$1 = React.forwardRef((props, forwardedRef) => {
182752
183882
  const { __scopeDropdownMenu, ...checkboxItemProps } = props;
@@ -182754,13 +183884,13 @@ var DropdownMenuCheckboxItem$1 = React.forwardRef((props, forwardedRef) => {
182754
183884
  return /* @__PURE__ */ jsx(CheckboxItem, { ...menuScope, ...checkboxItemProps, ref: forwardedRef });
182755
183885
  });
182756
183886
  DropdownMenuCheckboxItem$1.displayName = CHECKBOX_ITEM_NAME;
182757
- var RADIO_GROUP_NAME$1 = "DropdownMenuRadioGroup";
183887
+ var RADIO_GROUP_NAME = "DropdownMenuRadioGroup";
182758
183888
  var DropdownMenuRadioGroup$1 = React.forwardRef((props, forwardedRef) => {
182759
183889
  const { __scopeDropdownMenu, ...radioGroupProps } = props;
182760
183890
  const menuScope = useMenuScope(__scopeDropdownMenu);
182761
- return /* @__PURE__ */ jsx(RadioGroup$2, { ...menuScope, ...radioGroupProps, ref: forwardedRef });
183891
+ return /* @__PURE__ */ jsx(RadioGroup, { ...menuScope, ...radioGroupProps, ref: forwardedRef });
182762
183892
  });
182763
- DropdownMenuRadioGroup$1.displayName = RADIO_GROUP_NAME$1;
183893
+ DropdownMenuRadioGroup$1.displayName = RADIO_GROUP_NAME;
182764
183894
  var RADIO_ITEM_NAME = "DropdownMenuRadioItem";
182765
183895
  var DropdownMenuRadioItem$1 = React.forwardRef((props, forwardedRef) => {
182766
183896
  const { __scopeDropdownMenu, ...radioItemProps } = props;
@@ -182768,13 +183898,13 @@ var DropdownMenuRadioItem$1 = React.forwardRef((props, forwardedRef) => {
182768
183898
  return /* @__PURE__ */ jsx(RadioItem, { ...menuScope, ...radioItemProps, ref: forwardedRef });
182769
183899
  });
182770
183900
  DropdownMenuRadioItem$1.displayName = RADIO_ITEM_NAME;
182771
- var INDICATOR_NAME$1 = "DropdownMenuItemIndicator";
183901
+ var INDICATOR_NAME = "DropdownMenuItemIndicator";
182772
183902
  var DropdownMenuItemIndicator = React.forwardRef((props, forwardedRef) => {
182773
183903
  const { __scopeDropdownMenu, ...itemIndicatorProps } = props;
182774
183904
  const menuScope = useMenuScope(__scopeDropdownMenu);
182775
183905
  return /* @__PURE__ */ jsx(ItemIndicator, { ...menuScope, ...itemIndicatorProps, ref: forwardedRef });
182776
183906
  });
182777
- DropdownMenuItemIndicator.displayName = INDICATOR_NAME$1;
183907
+ DropdownMenuItemIndicator.displayName = INDICATOR_NAME;
182778
183908
  var SEPARATOR_NAME = "DropdownMenuSeparator";
182779
183909
  var DropdownMenuSeparator$1 = React.forwardRef((props, forwardedRef) => {
182780
183910
  const { __scopeDropdownMenu, ...separatorProps } = props;
@@ -182833,13 +183963,13 @@ var DropdownMenuSubContent$1 = React.forwardRef((props, forwardedRef) => {
182833
183963
  );
182834
183964
  });
182835
183965
  DropdownMenuSubContent$1.displayName = SUB_CONTENT_NAME;
182836
- var Root2$2 = DropdownMenu$1;
183966
+ var Root2$1 = DropdownMenu$1;
182837
183967
  var Trigger = DropdownMenuTrigger$1;
182838
183968
  var Portal2$1 = DropdownMenuPortal$1;
182839
183969
  var Content2$1 = DropdownMenuContent$1;
182840
183970
  var Group2 = DropdownMenuGroup$1;
182841
183971
  var Label2 = DropdownMenuLabel$1;
182842
- var Item2$1 = DropdownMenuItem$1;
183972
+ var Item2 = DropdownMenuItem$1;
182843
183973
  var CheckboxItem2 = DropdownMenuCheckboxItem$1;
182844
183974
  var RadioGroup2 = DropdownMenuRadioGroup$1;
182845
183975
  var RadioItem2 = DropdownMenuRadioItem$1;
@@ -182850,7 +183980,7 @@ var SubTrigger2 = DropdownMenuSubTrigger$1;
182850
183980
  var SubContent2 = DropdownMenuSubContent$1;
182851
183981
 
182852
183982
  function DropdownMenu({ ...props }) {
182853
- return jsx(Root2$2, { "data-slot": "dropdown-menu", ...props });
183983
+ return jsx(Root2$1, { "data-slot": "dropdown-menu", ...props });
182854
183984
  }
182855
183985
  function DropdownMenuPortal({ ...props }) {
182856
183986
  return jsx(Portal2$1, { "data-slot": "dropdown-menu-portal", ...props });
@@ -182866,7 +183996,7 @@ function DropdownMenuGroup({ ...props }) {
182866
183996
  return jsx(Group2, { "data-slot": "dropdown-menu-group", ...props });
182867
183997
  }
182868
183998
  function DropdownMenuItem({ className, inset, variant = 'default', ...props }) {
182869
- return (jsx(Item2$1, { "data-slot": "dropdown-menu-item", "data-inset": inset, "data-variant": variant, className: cn("focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props }));
183999
+ return (jsx(Item2, { "data-slot": "dropdown-menu-item", "data-inset": inset, "data-variant": variant, className: cn("focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props }));
182870
184000
  }
182871
184001
  function DropdownMenuCheckboxItem({ className, children, checked, ...props }) {
182872
184002
  return (jsxs(CheckboxItem2, { "data-slot": "dropdown-menu-checkbox-item", className: cn("focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), checked: checked, ...props, children: [jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: jsx(ItemIndicator2, { children: jsx(Check, { className: "size-4" }) }) }), children] }));
@@ -182990,729 +184120,6 @@ function NotificationDropdown({ org, userId, className, onViewNotifications, })
182990
184120
  filteredNotifications.some((notification) => notification.status === 'UNREAD') && (jsxs(Fragment$1, { children: [jsx(DropdownMenuSeparator, {}), jsx("div", { className: "px-3 py-2 text-center", children: jsx(Button$1, { variant: "link", className: "text-sm text-blue-600", onClick: () => handleMarkAllAsRead(), children: t('notificationsNotificationDropdown.markAllAsRead') }) })] }))] }))] })] }) }));
182991
184121
  }
182992
184122
 
182993
- function createCollection(name) {
182994
- const PROVIDER_NAME = name + "CollectionProvider";
182995
- const [createCollectionContext, createCollectionScope] = createContextScope(PROVIDER_NAME);
182996
- const [CollectionProviderImpl, useCollectionContext] = createCollectionContext(
182997
- PROVIDER_NAME,
182998
- { collectionRef: { current: null }, itemMap: /* @__PURE__ */ new Map() }
182999
- );
183000
- const CollectionProvider = (props) => {
183001
- const { scope, children } = props;
183002
- const ref = React__default.useRef(null);
183003
- const itemMap = React__default.useRef(/* @__PURE__ */ new Map()).current;
183004
- return /* @__PURE__ */ jsx(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
183005
- };
183006
- CollectionProvider.displayName = PROVIDER_NAME;
183007
- const COLLECTION_SLOT_NAME = name + "CollectionSlot";
183008
- const CollectionSlot = React__default.forwardRef(
183009
- (props, forwardedRef) => {
183010
- const { scope, children } = props;
183011
- const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
183012
- const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);
183013
- return /* @__PURE__ */ jsx(Slot$2, { ref: composedRefs, children });
183014
- }
183015
- );
183016
- CollectionSlot.displayName = COLLECTION_SLOT_NAME;
183017
- const ITEM_SLOT_NAME = name + "CollectionItemSlot";
183018
- const ITEM_DATA_ATTR = "data-radix-collection-item";
183019
- const CollectionItemSlot = React__default.forwardRef(
183020
- (props, forwardedRef) => {
183021
- const { scope, children, ...itemData } = props;
183022
- const ref = React__default.useRef(null);
183023
- const composedRefs = useComposedRefs(forwardedRef, ref);
183024
- const context = useCollectionContext(ITEM_SLOT_NAME, scope);
183025
- React__default.useEffect(() => {
183026
- context.itemMap.set(ref, { ref, ...itemData });
183027
- return () => void context.itemMap.delete(ref);
183028
- });
183029
- return /* @__PURE__ */ jsx(Slot$2, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
183030
- }
183031
- );
183032
- CollectionItemSlot.displayName = ITEM_SLOT_NAME;
183033
- function useCollection(scope) {
183034
- const context = useCollectionContext(name + "CollectionConsumer", scope);
183035
- const getItems = React__default.useCallback(() => {
183036
- const collectionNode = context.collectionRef.current;
183037
- if (!collectionNode) return [];
183038
- const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));
183039
- const items = Array.from(context.itemMap.values());
183040
- const orderedItems = items.sort(
183041
- (a, b) => orderedNodes.indexOf(a.ref.current) - orderedNodes.indexOf(b.ref.current)
183042
- );
183043
- return orderedItems;
183044
- }, [context.collectionRef, context.itemMap]);
183045
- return getItems;
183046
- }
183047
- return [
183048
- { Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot },
183049
- useCollection,
183050
- createCollectionScope
183051
- ];
183052
- }
183053
-
183054
- // packages/react/use-layout-effect/src/useLayoutEffect.tsx
183055
- var useLayoutEffect2 = Boolean(globalThis?.document) ? React.useLayoutEffect : () => {
183056
- };
183057
-
183058
- // packages/react/id/src/id.tsx
183059
- var useReactId = React["useId".toString()] || (() => void 0);
183060
- var count = 0;
183061
- function useId(deterministicId) {
183062
- const [id, setId] = React.useState(useReactId());
183063
- useLayoutEffect2(() => {
183064
- setId((reactId) => reactId ?? String(count++));
183065
- }, [deterministicId]);
183066
- return (id ? `radix-${id}` : "");
183067
- }
183068
-
183069
- // packages/react/direction/src/Direction.tsx
183070
- var DirectionContext = React.createContext(void 0);
183071
- function useDirection(localDir) {
183072
- const globalDir = React.useContext(DirectionContext);
183073
- return localDir || globalDir || "ltr";
183074
- }
183075
-
183076
- var ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
183077
- var EVENT_OPTIONS = { bubbles: false, cancelable: true };
183078
- var GROUP_NAME = "RovingFocusGroup";
183079
- var [Collection, useCollection, createCollectionScope] = createCollection(GROUP_NAME);
183080
- var [createRovingFocusGroupContext, createRovingFocusGroupScope] = createContextScope(
183081
- GROUP_NAME,
183082
- [createCollectionScope]
183083
- );
183084
- var [RovingFocusProvider, useRovingFocusContext] = createRovingFocusGroupContext(GROUP_NAME);
183085
- var RovingFocusGroup = React.forwardRef(
183086
- (props, forwardedRef) => {
183087
- return /* @__PURE__ */ jsx(Collection.Provider, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx(Collection.Slot, { scope: props.__scopeRovingFocusGroup, children: /* @__PURE__ */ jsx(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });
183088
- }
183089
- );
183090
- RovingFocusGroup.displayName = GROUP_NAME;
183091
- var RovingFocusGroupImpl = React.forwardRef((props, forwardedRef) => {
183092
- const {
183093
- __scopeRovingFocusGroup,
183094
- orientation,
183095
- loop = false,
183096
- dir,
183097
- currentTabStopId: currentTabStopIdProp,
183098
- defaultCurrentTabStopId,
183099
- onCurrentTabStopIdChange,
183100
- onEntryFocus,
183101
- preventScrollOnEntryFocus = false,
183102
- ...groupProps
183103
- } = props;
183104
- const ref = React.useRef(null);
183105
- const composedRefs = useComposedRefs(forwardedRef, ref);
183106
- const direction = useDirection(dir);
183107
- const [currentTabStopId = null, setCurrentTabStopId] = useControllableState({
183108
- prop: currentTabStopIdProp,
183109
- defaultProp: defaultCurrentTabStopId,
183110
- onChange: onCurrentTabStopIdChange
183111
- });
183112
- const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);
183113
- const handleEntryFocus = useCallbackRef(onEntryFocus);
183114
- const getItems = useCollection(__scopeRovingFocusGroup);
183115
- const isClickFocusRef = React.useRef(false);
183116
- const [focusableItemsCount, setFocusableItemsCount] = React.useState(0);
183117
- React.useEffect(() => {
183118
- const node = ref.current;
183119
- if (node) {
183120
- node.addEventListener(ENTRY_FOCUS, handleEntryFocus);
183121
- return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);
183122
- }
183123
- }, [handleEntryFocus]);
183124
- return /* @__PURE__ */ jsx(
183125
- RovingFocusProvider,
183126
- {
183127
- scope: __scopeRovingFocusGroup,
183128
- orientation,
183129
- dir: direction,
183130
- loop,
183131
- currentTabStopId,
183132
- onItemFocus: React.useCallback(
183133
- (tabStopId) => setCurrentTabStopId(tabStopId),
183134
- [setCurrentTabStopId]
183135
- ),
183136
- onItemShiftTab: React.useCallback(() => setIsTabbingBackOut(true), []),
183137
- onFocusableItemAdd: React.useCallback(
183138
- () => setFocusableItemsCount((prevCount) => prevCount + 1),
183139
- []
183140
- ),
183141
- onFocusableItemRemove: React.useCallback(
183142
- () => setFocusableItemsCount((prevCount) => prevCount - 1),
183143
- []
183144
- ),
183145
- children: /* @__PURE__ */ jsx(
183146
- Primitive$1.div,
183147
- {
183148
- tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,
183149
- "data-orientation": orientation,
183150
- ...groupProps,
183151
- ref: composedRefs,
183152
- style: { outline: "none", ...props.style },
183153
- onMouseDown: composeEventHandlers(props.onMouseDown, () => {
183154
- isClickFocusRef.current = true;
183155
- }),
183156
- onFocus: composeEventHandlers(props.onFocus, (event) => {
183157
- const isKeyboardFocus = !isClickFocusRef.current;
183158
- if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
183159
- const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
183160
- event.currentTarget.dispatchEvent(entryFocusEvent);
183161
- if (!entryFocusEvent.defaultPrevented) {
183162
- const items = getItems().filter((item) => item.focusable);
183163
- const activeItem = items.find((item) => item.active);
183164
- const currentItem = items.find((item) => item.id === currentTabStopId);
183165
- const candidateItems = [activeItem, currentItem, ...items].filter(
183166
- Boolean
183167
- );
183168
- const candidateNodes = candidateItems.map((item) => item.ref.current);
183169
- focusFirst(candidateNodes, preventScrollOnEntryFocus);
183170
- }
183171
- }
183172
- isClickFocusRef.current = false;
183173
- }),
183174
- onBlur: composeEventHandlers(props.onBlur, () => setIsTabbingBackOut(false))
183175
- }
183176
- )
183177
- }
183178
- );
183179
- });
183180
- var ITEM_NAME$1 = "RovingFocusGroupItem";
183181
- var RovingFocusGroupItem = React.forwardRef(
183182
- (props, forwardedRef) => {
183183
- const {
183184
- __scopeRovingFocusGroup,
183185
- focusable = true,
183186
- active = false,
183187
- tabStopId,
183188
- ...itemProps
183189
- } = props;
183190
- const autoId = useId();
183191
- const id = tabStopId || autoId;
183192
- const context = useRovingFocusContext(ITEM_NAME$1, __scopeRovingFocusGroup);
183193
- const isCurrentTabStop = context.currentTabStopId === id;
183194
- const getItems = useCollection(__scopeRovingFocusGroup);
183195
- const { onFocusableItemAdd, onFocusableItemRemove } = context;
183196
- React.useEffect(() => {
183197
- if (focusable) {
183198
- onFocusableItemAdd();
183199
- return () => onFocusableItemRemove();
183200
- }
183201
- }, [focusable, onFocusableItemAdd, onFocusableItemRemove]);
183202
- return /* @__PURE__ */ jsx(
183203
- Collection.ItemSlot,
183204
- {
183205
- scope: __scopeRovingFocusGroup,
183206
- id,
183207
- focusable,
183208
- active,
183209
- children: /* @__PURE__ */ jsx(
183210
- Primitive$1.span,
183211
- {
183212
- tabIndex: isCurrentTabStop ? 0 : -1,
183213
- "data-orientation": context.orientation,
183214
- ...itemProps,
183215
- ref: forwardedRef,
183216
- onMouseDown: composeEventHandlers(props.onMouseDown, (event) => {
183217
- if (!focusable) event.preventDefault();
183218
- else context.onItemFocus(id);
183219
- }),
183220
- onFocus: composeEventHandlers(props.onFocus, () => context.onItemFocus(id)),
183221
- onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
183222
- if (event.key === "Tab" && event.shiftKey) {
183223
- context.onItemShiftTab();
183224
- return;
183225
- }
183226
- if (event.target !== event.currentTarget) return;
183227
- const focusIntent = getFocusIntent(event, context.orientation, context.dir);
183228
- if (focusIntent !== void 0) {
183229
- if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;
183230
- event.preventDefault();
183231
- const items = getItems().filter((item) => item.focusable);
183232
- let candidateNodes = items.map((item) => item.ref.current);
183233
- if (focusIntent === "last") candidateNodes.reverse();
183234
- else if (focusIntent === "prev" || focusIntent === "next") {
183235
- if (focusIntent === "prev") candidateNodes.reverse();
183236
- const currentIndex = candidateNodes.indexOf(event.currentTarget);
183237
- candidateNodes = context.loop ? wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
183238
- }
183239
- setTimeout(() => focusFirst(candidateNodes));
183240
- }
183241
- })
183242
- }
183243
- )
183244
- }
183245
- );
183246
- }
183247
- );
183248
- RovingFocusGroupItem.displayName = ITEM_NAME$1;
183249
- var MAP_KEY_TO_FOCUS_INTENT = {
183250
- ArrowLeft: "prev",
183251
- ArrowUp: "prev",
183252
- ArrowRight: "next",
183253
- ArrowDown: "next",
183254
- PageUp: "first",
183255
- Home: "first",
183256
- PageDown: "last",
183257
- End: "last"
183258
- };
183259
- function getDirectionAwareKey(key, dir) {
183260
- if (dir !== "rtl") return key;
183261
- return key === "ArrowLeft" ? "ArrowRight" : key === "ArrowRight" ? "ArrowLeft" : key;
183262
- }
183263
- function getFocusIntent(event, orientation, dir) {
183264
- const key = getDirectionAwareKey(event.key, dir);
183265
- if (orientation === "vertical" && ["ArrowLeft", "ArrowRight"].includes(key)) return void 0;
183266
- if (orientation === "horizontal" && ["ArrowUp", "ArrowDown"].includes(key)) return void 0;
183267
- return MAP_KEY_TO_FOCUS_INTENT[key];
183268
- }
183269
- function focusFirst(candidates, preventScroll = false) {
183270
- const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
183271
- for (const candidate of candidates) {
183272
- if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
183273
- candidate.focus({ preventScroll });
183274
- if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
183275
- }
183276
- }
183277
- function wrapArray(array, startIndex) {
183278
- return array.map((_, index) => array[(startIndex + index) % array.length]);
183279
- }
183280
- var Root = RovingFocusGroup;
183281
- var Item = RovingFocusGroupItem;
183282
-
183283
- // packages/react/use-size/src/useSize.tsx
183284
- function useSize(element) {
183285
- const [size, setSize] = React.useState(void 0);
183286
- useLayoutEffect2(() => {
183287
- if (element) {
183288
- setSize({ width: element.offsetWidth, height: element.offsetHeight });
183289
- const resizeObserver = new ResizeObserver((entries) => {
183290
- if (!Array.isArray(entries)) {
183291
- return;
183292
- }
183293
- if (!entries.length) {
183294
- return;
183295
- }
183296
- const entry = entries[0];
183297
- let width;
183298
- let height;
183299
- if ("borderBoxSize" in entry) {
183300
- const borderSizeEntry = entry["borderBoxSize"];
183301
- const borderSize = Array.isArray(borderSizeEntry) ? borderSizeEntry[0] : borderSizeEntry;
183302
- width = borderSize["inlineSize"];
183303
- height = borderSize["blockSize"];
183304
- } else {
183305
- width = element.offsetWidth;
183306
- height = element.offsetHeight;
183307
- }
183308
- setSize({ width, height });
183309
- });
183310
- resizeObserver.observe(element, { box: "border-box" });
183311
- return () => resizeObserver.unobserve(element);
183312
- } else {
183313
- setSize(void 0);
183314
- }
183315
- }, [element]);
183316
- return size;
183317
- }
183318
-
183319
- // packages/react/use-previous/src/usePrevious.tsx
183320
- function usePrevious(value) {
183321
- const ref = React.useRef({ value, previous: value });
183322
- return React.useMemo(() => {
183323
- if (ref.current.value !== value) {
183324
- ref.current.previous = ref.current.value;
183325
- ref.current.value = value;
183326
- }
183327
- return ref.current.previous;
183328
- }, [value]);
183329
- }
183330
-
183331
- function useStateMachine(initialState, machine) {
183332
- return React.useReducer((state, event) => {
183333
- const nextState = machine[state][event];
183334
- return nextState ?? state;
183335
- }, initialState);
183336
- }
183337
-
183338
- // packages/react/presence/src/Presence.tsx
183339
- var Presence = (props) => {
183340
- const { present, children } = props;
183341
- const presence = usePresence(present);
183342
- const child = typeof children === "function" ? children({ present: presence.isPresent }) : React.Children.only(children);
183343
- const ref = useComposedRefs(presence.ref, getElementRef(child));
183344
- const forceMount = typeof children === "function";
183345
- return forceMount || presence.isPresent ? React.cloneElement(child, { ref }) : null;
183346
- };
183347
- Presence.displayName = "Presence";
183348
- function usePresence(present) {
183349
- const [node, setNode] = React.useState();
183350
- const stylesRef = React.useRef({});
183351
- const prevPresentRef = React.useRef(present);
183352
- const prevAnimationNameRef = React.useRef("none");
183353
- const initialState = present ? "mounted" : "unmounted";
183354
- const [state, send] = useStateMachine(initialState, {
183355
- mounted: {
183356
- UNMOUNT: "unmounted",
183357
- ANIMATION_OUT: "unmountSuspended"
183358
- },
183359
- unmountSuspended: {
183360
- MOUNT: "mounted",
183361
- ANIMATION_END: "unmounted"
183362
- },
183363
- unmounted: {
183364
- MOUNT: "mounted"
183365
- }
183366
- });
183367
- React.useEffect(() => {
183368
- const currentAnimationName = getAnimationName(stylesRef.current);
183369
- prevAnimationNameRef.current = state === "mounted" ? currentAnimationName : "none";
183370
- }, [state]);
183371
- useLayoutEffect2(() => {
183372
- const styles = stylesRef.current;
183373
- const wasPresent = prevPresentRef.current;
183374
- const hasPresentChanged = wasPresent !== present;
183375
- if (hasPresentChanged) {
183376
- const prevAnimationName = prevAnimationNameRef.current;
183377
- const currentAnimationName = getAnimationName(styles);
183378
- if (present) {
183379
- send("MOUNT");
183380
- } else if (currentAnimationName === "none" || styles?.display === "none") {
183381
- send("UNMOUNT");
183382
- } else {
183383
- const isAnimating = prevAnimationName !== currentAnimationName;
183384
- if (wasPresent && isAnimating) {
183385
- send("ANIMATION_OUT");
183386
- } else {
183387
- send("UNMOUNT");
183388
- }
183389
- }
183390
- prevPresentRef.current = present;
183391
- }
183392
- }, [present, send]);
183393
- useLayoutEffect2(() => {
183394
- if (node) {
183395
- let timeoutId;
183396
- const ownerWindow = node.ownerDocument.defaultView ?? window;
183397
- const handleAnimationEnd = (event) => {
183398
- const currentAnimationName = getAnimationName(stylesRef.current);
183399
- const isCurrentAnimation = currentAnimationName.includes(event.animationName);
183400
- if (event.target === node && isCurrentAnimation) {
183401
- send("ANIMATION_END");
183402
- if (!prevPresentRef.current) {
183403
- const currentFillMode = node.style.animationFillMode;
183404
- node.style.animationFillMode = "forwards";
183405
- timeoutId = ownerWindow.setTimeout(() => {
183406
- if (node.style.animationFillMode === "forwards") {
183407
- node.style.animationFillMode = currentFillMode;
183408
- }
183409
- });
183410
- }
183411
- }
183412
- };
183413
- const handleAnimationStart = (event) => {
183414
- if (event.target === node) {
183415
- prevAnimationNameRef.current = getAnimationName(stylesRef.current);
183416
- }
183417
- };
183418
- node.addEventListener("animationstart", handleAnimationStart);
183419
- node.addEventListener("animationcancel", handleAnimationEnd);
183420
- node.addEventListener("animationend", handleAnimationEnd);
183421
- return () => {
183422
- ownerWindow.clearTimeout(timeoutId);
183423
- node.removeEventListener("animationstart", handleAnimationStart);
183424
- node.removeEventListener("animationcancel", handleAnimationEnd);
183425
- node.removeEventListener("animationend", handleAnimationEnd);
183426
- };
183427
- } else {
183428
- send("ANIMATION_END");
183429
- }
183430
- }, [node, send]);
183431
- return {
183432
- isPresent: ["mounted", "unmountSuspended"].includes(state),
183433
- ref: React.useCallback((node2) => {
183434
- if (node2) stylesRef.current = getComputedStyle(node2);
183435
- setNode(node2);
183436
- }, [])
183437
- };
183438
- }
183439
- function getAnimationName(styles) {
183440
- return styles?.animationName || "none";
183441
- }
183442
- function getElementRef(element) {
183443
- let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get;
183444
- let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
183445
- if (mayWarn) {
183446
- return element.ref;
183447
- }
183448
- getter = Object.getOwnPropertyDescriptor(element, "ref")?.get;
183449
- mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
183450
- if (mayWarn) {
183451
- return element.props.ref;
183452
- }
183453
- return element.props.ref || element.ref;
183454
- }
183455
-
183456
- var RADIO_NAME = "Radio";
183457
- var [createRadioContext, createRadioScope] = createContextScope(RADIO_NAME);
183458
- var [RadioProvider, useRadioContext] = createRadioContext(RADIO_NAME);
183459
- var Radio = React.forwardRef(
183460
- (props, forwardedRef) => {
183461
- const {
183462
- __scopeRadio,
183463
- name,
183464
- checked = false,
183465
- required,
183466
- disabled,
183467
- value = "on",
183468
- onCheck,
183469
- form,
183470
- ...radioProps
183471
- } = props;
183472
- const [button, setButton] = React.useState(null);
183473
- const composedRefs = useComposedRefs(forwardedRef, (node) => setButton(node));
183474
- const hasConsumerStoppedPropagationRef = React.useRef(false);
183475
- const isFormControl = button ? form || !!button.closest("form") : true;
183476
- return /* @__PURE__ */ jsxs(RadioProvider, { scope: __scopeRadio, checked, disabled, children: [
183477
- /* @__PURE__ */ jsx(
183478
- Primitive$1.button,
183479
- {
183480
- type: "button",
183481
- role: "radio",
183482
- "aria-checked": checked,
183483
- "data-state": getState(checked),
183484
- "data-disabled": disabled ? "" : void 0,
183485
- disabled,
183486
- value,
183487
- ...radioProps,
183488
- ref: composedRefs,
183489
- onClick: composeEventHandlers(props.onClick, (event) => {
183490
- if (!checked) onCheck?.();
183491
- if (isFormControl) {
183492
- hasConsumerStoppedPropagationRef.current = event.isPropagationStopped();
183493
- if (!hasConsumerStoppedPropagationRef.current) event.stopPropagation();
183494
- }
183495
- })
183496
- }
183497
- ),
183498
- isFormControl && /* @__PURE__ */ jsx(
183499
- BubbleInput,
183500
- {
183501
- control: button,
183502
- bubbles: !hasConsumerStoppedPropagationRef.current,
183503
- name,
183504
- value,
183505
- checked,
183506
- required,
183507
- disabled,
183508
- form,
183509
- style: { transform: "translateX(-100%)" }
183510
- }
183511
- )
183512
- ] });
183513
- }
183514
- );
183515
- Radio.displayName = RADIO_NAME;
183516
- var INDICATOR_NAME = "RadioIndicator";
183517
- var RadioIndicator = React.forwardRef(
183518
- (props, forwardedRef) => {
183519
- const { __scopeRadio, forceMount, ...indicatorProps } = props;
183520
- const context = useRadioContext(INDICATOR_NAME, __scopeRadio);
183521
- return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.checked, children: /* @__PURE__ */ jsx(
183522
- Primitive$1.span,
183523
- {
183524
- "data-state": getState(context.checked),
183525
- "data-disabled": context.disabled ? "" : void 0,
183526
- ...indicatorProps,
183527
- ref: forwardedRef
183528
- }
183529
- ) });
183530
- }
183531
- );
183532
- RadioIndicator.displayName = INDICATOR_NAME;
183533
- var BubbleInput = (props) => {
183534
- const { control, checked, bubbles = true, ...inputProps } = props;
183535
- const ref = React.useRef(null);
183536
- const prevChecked = usePrevious(checked);
183537
- const controlSize = useSize(control);
183538
- React.useEffect(() => {
183539
- const input = ref.current;
183540
- const inputProto = window.HTMLInputElement.prototype;
183541
- const descriptor = Object.getOwnPropertyDescriptor(inputProto, "checked");
183542
- const setChecked = descriptor.set;
183543
- if (prevChecked !== checked && setChecked) {
183544
- const event = new Event("click", { bubbles });
183545
- setChecked.call(input, checked);
183546
- input.dispatchEvent(event);
183547
- }
183548
- }, [prevChecked, checked, bubbles]);
183549
- return /* @__PURE__ */ jsx(
183550
- "input",
183551
- {
183552
- type: "radio",
183553
- "aria-hidden": true,
183554
- defaultChecked: checked,
183555
- ...inputProps,
183556
- tabIndex: -1,
183557
- ref,
183558
- style: {
183559
- ...props.style,
183560
- ...controlSize,
183561
- position: "absolute",
183562
- pointerEvents: "none",
183563
- opacity: 0,
183564
- margin: 0
183565
- }
183566
- }
183567
- );
183568
- };
183569
- function getState(checked) {
183570
- return checked ? "checked" : "unchecked";
183571
- }
183572
- var ARROW_KEYS = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
183573
- var RADIO_GROUP_NAME = "RadioGroup";
183574
- var [createRadioGroupContext] = createContextScope(RADIO_GROUP_NAME, [
183575
- createRovingFocusGroupScope,
183576
- createRadioScope
183577
- ]);
183578
- var useRovingFocusGroupScope = createRovingFocusGroupScope();
183579
- var useRadioScope = createRadioScope();
183580
- var [RadioGroupProvider, useRadioGroupContext] = createRadioGroupContext(RADIO_GROUP_NAME);
183581
- var RadioGroup$1 = React.forwardRef(
183582
- (props, forwardedRef) => {
183583
- const {
183584
- __scopeRadioGroup,
183585
- name,
183586
- defaultValue,
183587
- value: valueProp,
183588
- required = false,
183589
- disabled = false,
183590
- orientation,
183591
- dir,
183592
- loop = true,
183593
- onValueChange,
183594
- ...groupProps
183595
- } = props;
183596
- const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeRadioGroup);
183597
- const direction = useDirection(dir);
183598
- const [value, setValue] = useControllableState({
183599
- prop: valueProp,
183600
- defaultProp: defaultValue,
183601
- onChange: onValueChange
183602
- });
183603
- return /* @__PURE__ */ jsx(
183604
- RadioGroupProvider,
183605
- {
183606
- scope: __scopeRadioGroup,
183607
- name,
183608
- required,
183609
- disabled,
183610
- value,
183611
- onValueChange: setValue,
183612
- children: /* @__PURE__ */ jsx(
183613
- Root,
183614
- {
183615
- asChild: true,
183616
- ...rovingFocusGroupScope,
183617
- orientation,
183618
- dir: direction,
183619
- loop,
183620
- children: /* @__PURE__ */ jsx(
183621
- Primitive$1.div,
183622
- {
183623
- role: "radiogroup",
183624
- "aria-required": required,
183625
- "aria-orientation": orientation,
183626
- "data-disabled": disabled ? "" : void 0,
183627
- dir: direction,
183628
- ...groupProps,
183629
- ref: forwardedRef
183630
- }
183631
- )
183632
- }
183633
- )
183634
- }
183635
- );
183636
- }
183637
- );
183638
- RadioGroup$1.displayName = RADIO_GROUP_NAME;
183639
- var ITEM_NAME = "RadioGroupItem";
183640
- var RadioGroupItem$1 = React.forwardRef(
183641
- (props, forwardedRef) => {
183642
- const { __scopeRadioGroup, disabled, ...itemProps } = props;
183643
- const context = useRadioGroupContext(ITEM_NAME, __scopeRadioGroup);
183644
- const isDisabled = context.disabled || disabled;
183645
- const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeRadioGroup);
183646
- const radioScope = useRadioScope(__scopeRadioGroup);
183647
- const ref = React.useRef(null);
183648
- const composedRefs = useComposedRefs(forwardedRef, ref);
183649
- const checked = context.value === itemProps.value;
183650
- const isArrowKeyPressedRef = React.useRef(false);
183651
- React.useEffect(() => {
183652
- const handleKeyDown = (event) => {
183653
- if (ARROW_KEYS.includes(event.key)) {
183654
- isArrowKeyPressedRef.current = true;
183655
- }
183656
- };
183657
- const handleKeyUp = () => isArrowKeyPressedRef.current = false;
183658
- document.addEventListener("keydown", handleKeyDown);
183659
- document.addEventListener("keyup", handleKeyUp);
183660
- return () => {
183661
- document.removeEventListener("keydown", handleKeyDown);
183662
- document.removeEventListener("keyup", handleKeyUp);
183663
- };
183664
- }, []);
183665
- return /* @__PURE__ */ jsx(
183666
- Item,
183667
- {
183668
- asChild: true,
183669
- ...rovingFocusGroupScope,
183670
- focusable: !isDisabled,
183671
- active: checked,
183672
- children: /* @__PURE__ */ jsx(
183673
- Radio,
183674
- {
183675
- disabled: isDisabled,
183676
- required: context.required,
183677
- checked,
183678
- ...radioScope,
183679
- ...itemProps,
183680
- name: context.name,
183681
- ref: composedRefs,
183682
- onCheck: () => context.onValueChange(itemProps.value),
183683
- onKeyDown: composeEventHandlers((event) => {
183684
- if (event.key === "Enter") event.preventDefault();
183685
- }),
183686
- onFocus: composeEventHandlers(itemProps.onFocus, () => {
183687
- if (isArrowKeyPressedRef.current) ref.current?.click();
183688
- })
183689
- }
183690
- )
183691
- }
183692
- );
183693
- }
183694
- );
183695
- RadioGroupItem$1.displayName = ITEM_NAME;
183696
- var INDICATOR_NAME2 = "RadioGroupIndicator";
183697
- var RadioGroupIndicator = React.forwardRef(
183698
- (props, forwardedRef) => {
183699
- const { __scopeRadioGroup, ...indicatorProps } = props;
183700
- const radioScope = useRadioScope(__scopeRadioGroup);
183701
- return /* @__PURE__ */ jsx(RadioIndicator, { ...radioScope, ...indicatorProps, ref: forwardedRef });
183702
- }
183703
- );
183704
- RadioGroupIndicator.displayName = INDICATOR_NAME2;
183705
- var Root2$1 = RadioGroup$1;
183706
- var Item2 = RadioGroupItem$1;
183707
- var Indicator = RadioGroupIndicator;
183708
-
183709
- function RadioGroup({ className, ...props }) {
183710
- return (jsx(Root2$1, { "data-slot": "radio-group", className: cn('grid gap-3', className), ...props }));
183711
- }
183712
- function RadioGroupItem({ className, ...props }) {
183713
- return (jsx(Item2, { "data-slot": "radio-group-item", className: cn('border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50', className), ...props, children: jsx(Indicator, { "data-slot": "radio-group-indicator", className: "relative flex items-center justify-center", children: jsx(Circle, { className: "fill-primary absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2" }) }) }));
183714
- }
183715
-
183716
184123
  function SendNotificationDialog({ open, onOpenChange, tenant, onNotificationSent, hasManageUsersPermission = false, }) {
183717
184124
  const t = useT();
183718
184125
  const [recipientType, setRecipientType] = useState('users');
@@ -183964,7 +184371,7 @@ function SendNotificationDialog({ open, onOpenChange, tenant, onNotificationSent
183964
184371
  })] }), jsxs("div", { className: "space-y-2", children: [jsx(Label$2, { htmlFor: "notification-body", className: "text-sm font-medium", "aria-required": "true", children: t('notificationsSendNotificationDialog.contentLabel') }), form.Field({
183965
184372
  name: 'message',
183966
184373
  children: (field) => (jsx("div", { role: "group", "aria-labelledby": "notification-body", "data-testid": "notification-body-group", children: jsx(RichTextEditor, { value: field.state.value, onChange: field.handleChange, placeholder: t('notificationsSendNotificationDialog.contentPlaceholder'), minHeight: "180px", exportFormat: "html" }) })),
183967
- })] }), jsxs("fieldset", { className: "space-y-3", "data-testid": "send-time-fieldset", children: [jsx("legend", { className: "text-sm font-medium", children: t('notificationsSendNotificationDialog.sendTimeLegend') }), jsxs(RadioGroup, { value: sendType, onValueChange: (value) => setSendType(value), "aria-label": t('notificationsSendNotificationDialog.sendTimeAriaLabel'), "data-testid": "send-time-radio-group", children: [jsxs("div", { className: "flex items-center space-x-2 mt-2", children: [jsx(RadioGroupItem, { value: "now", id: "send-now", "aria-label": t('notificationsSendNotificationDialog.sendImmediately'), "data-testid": "send-now-radio" }), jsx(Label$2, { htmlFor: "send-now", className: "font-normal cursor-pointer", children: t('notificationsSendNotificationDialog.sendImmediately') })] }), jsxs("div", { className: "flex items-center space-x-2", children: [jsx(RadioGroupItem, { value: "schedule", id: "send-schedule", "aria-label": t('notificationsSendNotificationDialog.scheduleForLater'), "data-testid": "send-schedule-radio" }), jsx(Label$2, { htmlFor: "send-schedule", className: "font-normal cursor-pointer", children: t('notificationsSendNotificationDialog.scheduleForLater') })] })] }), sendType === 'schedule' && (jsxs("div", { className: "flex gap-3 mt-4 pl-6", role: "group", "aria-label": t('notificationsSendNotificationDialog.scheduleSettingsAriaLabel'), "data-testid": "schedule-settings", children: [jsxs(Popover, { children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { type: "button", variant: "outline", className: cn('justify-start text-left font-normal min-w-[200px]', !scheduledDate && 'text-muted-foreground'), "aria-label": scheduledDate
184374
+ })] }), jsxs("fieldset", { className: "space-y-3", "data-testid": "send-time-fieldset", children: [jsx("legend", { className: "text-sm font-medium", children: t('notificationsSendNotificationDialog.sendTimeLegend') }), jsxs(RadioGroup$1, { value: sendType, onValueChange: (value) => setSendType(value), "aria-label": t('notificationsSendNotificationDialog.sendTimeAriaLabel'), "data-testid": "send-time-radio-group", children: [jsxs("div", { className: "flex items-center space-x-2 mt-2", children: [jsx(RadioGroupItem, { value: "now", id: "send-now", "aria-label": t('notificationsSendNotificationDialog.sendImmediately'), "data-testid": "send-now-radio" }), jsx(Label$2, { htmlFor: "send-now", className: "font-normal cursor-pointer", children: t('notificationsSendNotificationDialog.sendImmediately') })] }), jsxs("div", { className: "flex items-center space-x-2", children: [jsx(RadioGroupItem, { value: "schedule", id: "send-schedule", "aria-label": t('notificationsSendNotificationDialog.scheduleForLater'), "data-testid": "send-schedule-radio" }), jsx(Label$2, { htmlFor: "send-schedule", className: "font-normal cursor-pointer", children: t('notificationsSendNotificationDialog.scheduleForLater') })] })] }), sendType === 'schedule' && (jsxs("div", { className: "flex gap-3 mt-4 pl-6", role: "group", "aria-label": t('notificationsSendNotificationDialog.scheduleSettingsAriaLabel'), "data-testid": "schedule-settings", children: [jsxs(Popover, { children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { type: "button", variant: "outline", className: cn('justify-start text-left font-normal min-w-[200px]', !scheduledDate && 'text-muted-foreground'), "aria-label": scheduledDate
183968
184375
  ? t('notificationsSendNotificationDialog.selectedDateAriaLabel', {
183969
184376
  date: format$1(scheduledDate, 'PPP'),
183970
184377
  })
@@ -183978,7 +184385,7 @@ function SendNotificationDialog({ open, onOpenChange, tenant, onNotificationSent
183978
184385
  : t('notificationsSendNotificationDialog.groupsSelected', {
183979
184386
  count: selectedGroups.length,
183980
184387
  plural: selectedGroups.length !== 1 ? 's' : '',
183981
- }) })] }), jsxs(RadioGroup, { value: recipientType, onValueChange: (value) => {
184388
+ }) })] }), jsxs(RadioGroup$1, { value: recipientType, onValueChange: (value) => {
183982
184389
  setRecipientType(value);
183983
184390
  setSearchQuery('');
183984
184391
  }, className: "flex gap-4", "aria-label": t('notificationsSendNotificationDialog.recipientTypeAriaLabel'), "data-testid": "recipient-type-radio-group", children: [jsxs("div", { className: "flex items-center space-x-2", children: [jsx(RadioGroupItem, { value: "users", id: "recipient-users", "aria-label": t('notificationsSendNotificationDialog.sendToUsers'), "data-testid": "recipient-users-radio" }), jsxs(Label$2, { htmlFor: "recipient-users", className: "font-normal cursor-pointer flex items-center gap-1.5", children: [jsx(Users, { className: "h-4 w-4", "aria-hidden": "true" }), t('notificationsSendNotificationDialog.usersLabel')] })] }), jsxs("div", { className: "flex items-center space-x-2", children: [jsx(RadioGroupItem, { value: "groups", id: "recipient-groups", "aria-label": t('notificationsSendNotificationDialog.sendToGroups'), "data-testid": "recipient-groups-radio" }), jsxs(Label$2, { htmlFor: "recipient-groups", className: "font-normal cursor-pointer flex items-center gap-1.5", children: [jsx(UsersRound, { className: "h-4 w-4", "aria-hidden": "true" }), t('notificationsSendNotificationDialog.groupsLabel')] })] })] }), jsxs("div", { className: "relative", children: [jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-500", "aria-hidden": "true" }), jsx(Input, { placeholder: recipientType === 'users'
@@ -233928,7 +234335,7 @@ function ApplicationFormSteps({ form, platformKey, formId, shell, submission, to
233928
234335
  return (jsxs("div", { className: "flex items-start gap-2.5", children: [jsx(Checkbox, { id: id, checked: val === true, onCheckedChange: (c) => set(c === true), className: "mt-0.5" }), jsxs(Label$2, { htmlFor: id, className: "text-sm font-normal leading-snug", children: [f.label, req] })] }, f.key));
233929
234336
  }
233930
234337
  if (f.type === 'select' && ((_b = f.ui) === null || _b === void 0 ? void 0 : _b.widget) === 'radio') {
233931
- return (jsxs("div", { className: "grid gap-2", children: [jsxs("span", { className: "text-sm font-medium", children: [f.label, req] }), jsx(RadioGroup, { value: (_c = val) !== null && _c !== void 0 ? _c : '', onValueChange: set, className: "gap-2", children: (_d = f.options) === null || _d === void 0 ? void 0 : _d.map((o) => (jsxs("div", { className: "flex items-center gap-2", children: [jsx(RadioGroupItem, { id: `${id}-${o.value}`, value: o.value }), jsx(Label$2, { htmlFor: `${id}-${o.value}`, className: "text-sm font-normal", children: o.label })] }, o.value))) })] }, f.key));
234338
+ return (jsxs("div", { className: "grid gap-2", children: [jsxs("span", { className: "text-sm font-medium", children: [f.label, req] }), jsx(RadioGroup$1, { value: (_c = val) !== null && _c !== void 0 ? _c : '', onValueChange: set, className: "gap-2", children: (_d = f.options) === null || _d === void 0 ? void 0 : _d.map((o) => (jsxs("div", { className: "flex items-center gap-2", children: [jsx(RadioGroupItem, { id: `${id}-${o.value}`, value: o.value }), jsx(Label$2, { htmlFor: `${id}-${o.value}`, className: "text-sm font-normal", children: o.label })] }, o.value))) })] }, f.key));
233932
234339
  }
233933
234340
  if (f.type === 'select') {
233934
234341
  return (jsxs("div", { className: "grid gap-1.5", children: [jsxs(Label$2, { htmlFor: id, className: "text-sm font-medium", children: [f.label, req] }), jsxs(Select$1, { value: (_e = val) !== null && _e !== void 0 ? _e : '', onValueChange: set, children: [jsx(SelectTrigger, { id: id, children: jsx(SelectValue, { placeholder: t('applyApplyWizard.selectAnOption') }) }), jsx(SelectContent, { children: (_f = f.options) === null || _f === void 0 ? void 0 : _f.map((o) => (jsx(SelectItem, { value: o.value, children: o.label }, o.value))) })] })] }, f.key));