@iblai/iblai-js 1.9.9 → 1.9.11

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.
@@ -7,7 +7,7 @@ import Link$2 from 'next/link';
7
7
  import * as ReactDOM from 'react-dom';
8
8
  import ReactDOM__default from 'react-dom';
9
9
  import { z as z$1 } from 'zod';
10
- import { useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useCreateGlobalMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, 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, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, useUpdateTenantMetadataMutation, LOGO_ENDPOINTS, useDeleteApiKeyMutation, useGetApiKeysQuery, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, useGetCustomDomainsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useGetMemsearchConfigQuery, useUpdateMemsearchConfigMutation, useGetCustomMentorsQuery, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useGetAiSearchMentorsQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useCreateSessionIdMutation, useGetMentorCategoriesQuery, useGetMentorSettingsQuery, useEditMentorMutation, useDeleteMentorMutation, useForkMentorMutation, useGetToolsQuery, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useDeleteMentorMemoryMutation, useUpdateMentorMemoryMutation, useCreateMentorMemoryMutation, useLazyGetMCPServersQuery, useOauthFindMutation, useLazyStartOAuthFlowQuery, useCreateMCPServerMutation, usePartialUpdateMCPServerMutation, useCreateMCPServerConnectionMutation, usePatchMCPServerConnectionMutation, useGetConnectedServicesQuery, useGetMCPServersQuery, useGetMCPServerConnectionsQuery, useUpdateMCPServerMutation, useDeleteMCPServerMutation, useEditMentorJsonMutation, useDisconnectServiceMutation, useGetPromptCategoriesQuery, useGetMentorPublicSettingsQuery, useGetChatHistoryFilterQuery, useGetChatHistoryQuery, useGetMentorSummariesQuery, useGetConversationMemoriesQuery, useEditTrainingDocumentMutation, useGetTrainingDocumentsQuery, useCreatePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useCreateRedirectTokenMutation, useGetShareableLinkQuery, useCreateShareableLinkMutation, useUpdateShareableLinkMutation, useCreateDisclaimerMutation, useUpdateDisclaimerMutation, useGetDisclaimersQuery, useUpdateRbacMentorAccessMutation, useGetRbacMentorAccessListQuery, useStarMentorMutation, useUnstarMentorMutation, useGetPersonnalizedMentorsQuery, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation } from '@iblai/data-layer';
10
+ import { useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useCreateGlobalMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, 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, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useGetWatchedGroupsQuery, useCreateWatchedGroupMutation, useUpdateWatchedGroupMutation, useDeleteWatchedGroupMutation, useAddWatchedUserMutation, useRemoveWatchedUserMutation, useAddWatcherMutation, useUpdateWatcherMutation, useDeleteWatcherMutation, useGetWatchedUsersQuery, useGetWatchersQuery, WATCHER_NOTIFICATION_EVENTS, WATCHER_NOTIFICATION_EVENT_LABELS, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, useUpdateTenantMetadataMutation, LOGO_ENDPOINTS, useDeleteApiKeyMutation, useGetApiKeysQuery, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, useGetCustomDomainsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useGetMemsearchConfigQuery, useUpdateMemsearchConfigMutation, useGetCustomMentorsQuery, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useGetAiSearchMentorsQuery, useListPaywallsQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useUpdatePaywallMutation, useCreateSessionIdMutation, useGetMentorCategoriesQuery, useGetMentorSettingsQuery, useEditMentorMutation, useDeleteMentorMutation, useForkMentorMutation, useGetToolsQuery, useGetMentorMemoriesListQuery, useGetMemoryCategoriesAdminQuery, useDeleteMentorMemoryMutation, useUpdateMentorMemoryMutation, useCreateMentorMemoryMutation, useLazyGetMCPServersQuery, useOauthFindMutation, useLazyStartOAuthFlowQuery, useCreateMCPServerMutation, usePartialUpdateMCPServerMutation, useCreateMCPServerConnectionMutation, usePatchMCPServerConnectionMutation, useGetConnectedServicesQuery, useGetMCPServersQuery, useGetMCPServerConnectionsQuery, useUpdateMCPServerMutation, useDeleteMCPServerMutation, useEditMentorJsonMutation, useDisconnectServiceMutation, useGetPromptCategoriesQuery, useGetMentorPublicSettingsQuery, useGetChatHistoryFilterQuery, useGetChatHistoryQuery, useGetMentorSummariesQuery, useGetConversationMemoriesQuery, useEditTrainingDocumentMutation, useGetTrainingDocumentsQuery, useCreatePromptMutation, useGetPromptsSearchQuery, useUpdatePromptMutation, useCreateRedirectTokenMutation, useGetShareableLinkQuery, useCreateShareableLinkMutation, useUpdateShareableLinkMutation, useCreateDisclaimerMutation, useUpdateDisclaimerMutation, useGetDisclaimersQuery, useUpdateRbacMentorAccessMutation, useGetRbacMentorAccessListQuery, useStarMentorMutation, useUnstarMentorMutation, useGetPersonnalizedMentorsQuery, useCreateMemoryCategoryMutation, useUpdateMemoryCategoryMutation, useDeleteMemoryCategoryMutation, useDeleteTrainingDocumentMutation, useGetTrainingDocumentRetrainScheduleQuery, useCreateTrainingDocumentRetrainScheduleMutation } from '@iblai/data-layer';
11
11
  import { toast, Toaster as Toaster$1 } from 'sonner';
12
12
  import { getInitials, useTenantMetadata, isAlphaNumeric32, checkRbacPermission, WithPermissions, useTenantContext, useStripeUpgrade, CHAT_AREA_SIZE, TimeTracker, advancedTabsProperties, defaultSessionIds, chatActions, WithFormPermissions } from '@iblai/web-utils';
13
13
  import { MentorVisibilityEnum, TransportEnum, PromptVisibilityEnum } from '@iblai/iblai-api';
@@ -163131,8 +163131,419 @@ function PoliciesTab({ tenant }) {
163131
163131
  }), className: "w-full text-left px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700", children: jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: group.name }) }, group.id))) }))] })] })] })] }), jsxs(DialogFooter, { className: "mt-6", children: [jsx(Button$1, { variant: "outline", onClick: () => setIsOpen(false), children: "Cancel" }), jsx(TooltipProvider, { children: jsxs(Tooltip, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("span", { tabIndex: 0, children: jsx(Button$1, { onClick: onSubmit, disabled: policyDetails === null || policyDetails === void 0 ? void 0 : policyDetails.is_internal, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", children: editing ? 'Save Policy' : 'Create Policy' }) }) }), editing && (policyDetails === null || policyDetails === void 0 ? void 0 : policyDetails.is_internal) && (jsx(TooltipContent, { children: jsx("p", { children: "Cannot edit internal policies" }) }))] }) })] })] }) })] }));
163132
163132
  }
163133
163133
 
163134
- const Admin = ({ tenant, onInviteClick, hasUserTabPermission = false, hasGroupsTabPermission = false, hasRolesTabPermission = false, hasPoliciesTabPermission = false, hasTeamsTabPermission = false, hasInviteUserPermission = false, hasCreateTeamPermission = false, onLoadGroupPermissions, rbacPermissions = {}, enableRbac = false, }) => {
163135
- return (jsx("div", { className: "border border-gray-200 rounded-lg p-6", children: jsxs(Tabs, { defaultValue: "users", "aria-label": "RBAC Management Tabs", children: [jsxs(TabsList, { "aria-label": "Management tabs", className: "max-w-full overflow-x-auto justify-start px-1", children: [hasUserTabPermission && jsx(TabsTrigger, { value: "users", children: "Users" }), hasGroupsTabPermission && jsx(TabsTrigger, { value: "groups", children: "Groups" }), hasRolesTabPermission && jsx(TabsTrigger, { value: "roles", children: "Roles" }), hasPoliciesTabPermission && jsx(TabsTrigger, { value: "policies", children: "Policies" }), hasTeamsTabPermission && jsx(TabsTrigger, { value: "teams", children: "Teams" })] }), hasUserTabPermission && (jsx(TabsContent, { value: "users", children: jsx(UsersTab, { tenant: tenant, onInviteClick: onInviteClick }) })), hasGroupsTabPermission && (jsx(TabsContent, { value: "groups", children: jsx(GroupsTab, { tenant: tenant }) })), hasRolesTabPermission && (jsx(TabsContent, { value: "roles", children: jsx(RolesTab, { tenant: tenant }) })), hasPoliciesTabPermission && (jsx(TabsContent, { value: "policies", children: jsx(PoliciesTab, { tenant: tenant }) })), hasTeamsTabPermission && (jsx(TabsContent, { value: "teams", children: jsx(GroupsTab, { tenant: tenant, isTeam: true, onInviteClick: onInviteClick, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac }) }))] }) }));
163134
+ const PAGE_SIZE$1 = 10;
163135
+ function normalizeEvents(events) {
163136
+ if (!events)
163137
+ return [];
163138
+ if (Array.isArray(events))
163139
+ return events;
163140
+ // The API may serialize the list as a python-style string e.g. "['A', 'B']"
163141
+ const trimmed = events.trim();
163142
+ if (!trimmed)
163143
+ return [];
163144
+ try {
163145
+ const jsonish = trimmed.replace(/'/g, '"');
163146
+ const parsed = JSON.parse(jsonish);
163147
+ if (Array.isArray(parsed))
163148
+ return parsed.map((v) => String(v));
163149
+ }
163150
+ catch (_a) {
163151
+ // fall through
163152
+ }
163153
+ return trimmed
163154
+ .replace(/[[\]'"]/g, '')
163155
+ .split(',')
163156
+ .map((s) => s.trim())
163157
+ .filter(Boolean);
163158
+ }
163159
+ function AlertsTab({ tenant }) {
163160
+ var _a;
163161
+ const [page, setPage] = useState(1);
163162
+ const [searchQuery, setSearchQuery] = useState('');
163163
+ const [debouncedSearchQuery, setDebouncedSearchQuery] = useState('');
163164
+ useEffect(() => {
163165
+ const handler = setTimeout(() => {
163166
+ if (searchQuery.length > 3) {
163167
+ setDebouncedSearchQuery(searchQuery);
163168
+ setPage(1);
163169
+ }
163170
+ else {
163171
+ setDebouncedSearchQuery('');
163172
+ if (searchQuery.length === 0) {
163173
+ setPage(1);
163174
+ }
163175
+ }
163176
+ }, 300);
163177
+ return () => clearTimeout(handler);
163178
+ }, [searchQuery]);
163179
+ const { data: watchedGroupsData, isLoading, isError, refetch, } = useGetWatchedGroupsQuery({
163180
+ params: {
163181
+ platform_key: tenant,
163182
+ limit: PAGE_SIZE$1,
163183
+ offset: (page - 1) * PAGE_SIZE$1,
163184
+ },
163185
+ });
163186
+ const groups = useMemo(() => {
163187
+ var _a;
163188
+ const results = (_a = watchedGroupsData === null || watchedGroupsData === void 0 ? void 0 : watchedGroupsData.results) !== null && _a !== void 0 ? _a : [];
163189
+ if (debouncedSearchQuery) {
163190
+ const needle = debouncedSearchQuery.toLowerCase();
163191
+ return results.filter((g) => { var _a; return ((_a = g.name) !== null && _a !== void 0 ? _a : '').toLowerCase().includes(needle); });
163192
+ }
163193
+ return results;
163194
+ }, [watchedGroupsData, debouncedSearchQuery]);
163195
+ const totalPages = watchedGroupsData
163196
+ ? Math.max(1, Math.ceil(watchedGroupsData.count / PAGE_SIZE$1))
163197
+ : 0;
163198
+ const handlePageChange = async (newPage) => {
163199
+ setPage(newPage);
163200
+ await refetch();
163201
+ };
163202
+ const [createWatchedGroup] = useCreateWatchedGroupMutation();
163203
+ const [updateWatchedGroup] = useUpdateWatchedGroupMutation();
163204
+ const [deleteWatchedGroup] = useDeleteWatchedGroupMutation();
163205
+ const [addWatchedUser] = useAddWatchedUserMutation();
163206
+ const [removeWatchedUser] = useRemoveWatchedUserMutation();
163207
+ const [addWatcher] = useAddWatcherMutation();
163208
+ const [updateWatcher] = useUpdateWatcherMutation();
163209
+ const [deleteWatcher] = useDeleteWatcherMutation();
163210
+ const [isOpen, setIsOpen] = useState(false);
163211
+ const [editingGroup, setEditingGroup] = useState(null);
163212
+ const [deletingGroupId, setDeletingGroupId] = useState(null);
163213
+ const [formError, setFormError] = useState(null);
163214
+ const [isSubmitting, setIsSubmitting] = useState(false);
163215
+ const [name, setName] = useState('');
163216
+ const [watchedUsers, setWatchedUsers] = useState([]);
163217
+ const [originalWatchedUserIds, setOriginalWatchedUserIds] = useState([]);
163218
+ const [watchedUserLinkIds, setWatchedUserLinkIds] = useState({});
163219
+ const [watchers, setWatchers] = useState([]);
163220
+ const [originalWatchers, setOriginalWatchers] = useState([]);
163221
+ const [watchedUserSearch, setWatchedUserSearch] = useState('');
163222
+ const [showWatchedUserSearch, setShowWatchedUserSearch] = useState(false);
163223
+ const [watcherSearch, setWatcherSearch] = useState('');
163224
+ const [showWatcherSearch, setShowWatcherSearch] = useState(false);
163225
+ const [openEventsPopover, setOpenEventsPopover] = useState(null);
163226
+ const editingGroupId = (_a = editingGroup === null || editingGroup === void 0 ? void 0 : editingGroup.id) !== null && _a !== void 0 ? _a : null;
163227
+ // Pre-populate the dialog with nested data when an existing group is opened.
163228
+ const { data: nestedWatchedUsersData } = useGetWatchedUsersQuery({ watchedGroupPk: editingGroupId, params: { limit: 100 } }, { skip: !editingGroupId || !isOpen });
163229
+ const { data: nestedWatchersData } = useGetWatchersQuery({ watchedGroupPk: editingGroupId, params: { limit: 100 } }, { skip: !editingGroupId || !isOpen });
163230
+ useEffect(() => {
163231
+ var _a;
163232
+ if (!editingGroupId || !isOpen)
163233
+ return;
163234
+ const results = (_a = nestedWatchedUsersData === null || nestedWatchedUsersData === void 0 ? void 0 : nestedWatchedUsersData.results) !== null && _a !== void 0 ? _a : [];
163235
+ const mapped = results.map((u) => {
163236
+ var _a, _b, _c;
163237
+ return ({
163238
+ id: u.id,
163239
+ name: (_a = u.username) !== null && _a !== void 0 ? _a : '',
163240
+ username: (_b = u.username) !== null && _b !== void 0 ? _b : '',
163241
+ email: (_c = u.email) !== null && _c !== void 0 ? _c : '',
163242
+ });
163243
+ });
163244
+ const linkMap = {};
163245
+ results.forEach((u) => {
163246
+ var _a;
163247
+ // Some backends return the link id as `id` and the user id as `user_id`.
163248
+ // Treat the response `id` as the link id; if `user_id` is missing, the
163249
+ // link id equals the user id (sufficient for DELETE-by-user semantics).
163250
+ const userId = (_a = u.user_id) !== null && _a !== void 0 ? _a : u.id;
163251
+ linkMap[userId] = u.id;
163252
+ });
163253
+ setWatchedUsers(mapped);
163254
+ setOriginalWatchedUserIds(mapped.map((u) => u.id));
163255
+ setWatchedUserLinkIds(linkMap);
163256
+ }, [nestedWatchedUsersData, editingGroupId, isOpen]);
163257
+ useEffect(() => {
163258
+ var _a;
163259
+ if (!editingGroupId || !isOpen)
163260
+ return;
163261
+ const results = (_a = nestedWatchersData === null || nestedWatchersData === void 0 ? void 0 : nestedWatchersData.results) !== null && _a !== void 0 ? _a : [];
163262
+ const mapped = results.map((w) => {
163263
+ var _a, _b, _c;
163264
+ return ({
163265
+ id: w.id,
163266
+ user: {
163267
+ id: w.id,
163268
+ name: (_a = w.username) !== null && _a !== void 0 ? _a : '',
163269
+ username: (_b = w.username) !== null && _b !== void 0 ? _b : '',
163270
+ email: (_c = w.email) !== null && _c !== void 0 ? _c : '',
163271
+ },
163272
+ events: normalizeEvents(w.events),
163273
+ });
163274
+ });
163275
+ setWatchers(mapped);
163276
+ setOriginalWatchers(mapped);
163277
+ }, [nestedWatchersData, editingGroupId, isOpen]);
163278
+ // User picker
163279
+ const { data: usersData } = usePlatformUsersQuery({
163280
+ page: 1,
163281
+ page_size: 50,
163282
+ platform_key: tenant,
163283
+ platform_org: tenant,
163284
+ query: watchedUserSearch.length > 2 ? watchedUserSearch : '',
163285
+ return_policies: 'false',
163286
+ });
163287
+ const { data: watcherUsersData } = usePlatformUsersQuery({
163288
+ page: 1,
163289
+ page_size: 50,
163290
+ platform_key: tenant,
163291
+ platform_org: tenant,
163292
+ query: watcherSearch.length > 2 ? watcherSearch : '',
163293
+ return_policies: 'false',
163294
+ });
163295
+ const availableWatchedUsers = useMemo(() => {
163296
+ var _a, _b, _c;
163297
+ const data = (_c = (_b = (_a = usersData === null || usersData === void 0 ? void 0 : usersData.results) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : usersData === null || usersData === void 0 ? void 0 : usersData.results) !== null && _c !== void 0 ? _c : [];
163298
+ return data.filter((u) => {
163299
+ var _a;
163300
+ const userId = (_a = u.user_id) !== null && _a !== void 0 ? _a : u.id;
163301
+ return !watchedUsers.find((m) => m.id === userId);
163302
+ });
163303
+ }, [usersData, watchedUsers]);
163304
+ const availableWatcherUsers = useMemo(() => {
163305
+ var _a, _b, _c;
163306
+ const data = (_c = (_b = (_a = watcherUsersData === null || watcherUsersData === void 0 ? void 0 : watcherUsersData.results) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : watcherUsersData === null || watcherUsersData === void 0 ? void 0 : watcherUsersData.results) !== null && _c !== void 0 ? _c : [];
163307
+ return data.filter((u) => {
163308
+ var _a;
163309
+ const userId = (_a = u.user_id) !== null && _a !== void 0 ? _a : u.id;
163310
+ return !watchers.find((w) => w.user.id === userId);
163311
+ });
163312
+ }, [watcherUsersData, watchers]);
163313
+ function resetForm() {
163314
+ setName('');
163315
+ setWatchedUsers([]);
163316
+ setOriginalWatchedUserIds([]);
163317
+ setWatchedUserLinkIds({});
163318
+ setWatchers([]);
163319
+ setOriginalWatchers([]);
163320
+ setWatchedUserSearch('');
163321
+ setShowWatchedUserSearch(false);
163322
+ setWatcherSearch('');
163323
+ setShowWatcherSearch(false);
163324
+ setFormError(null);
163325
+ }
163326
+ function openNew() {
163327
+ setEditingGroup(null);
163328
+ resetForm();
163329
+ setIsOpen(true);
163330
+ }
163331
+ function openEdit(g) {
163332
+ var _a;
163333
+ setEditingGroup(g);
163334
+ setName((_a = g.name) !== null && _a !== void 0 ? _a : '');
163335
+ // Nested data will be loaded via the queries above.
163336
+ setWatchedUsers([]);
163337
+ setOriginalWatchedUserIds([]);
163338
+ setWatchedUserLinkIds({});
163339
+ setWatchers([]);
163340
+ setOriginalWatchers([]);
163341
+ setWatchedUserSearch('');
163342
+ setShowWatchedUserSearch(false);
163343
+ setWatcherSearch('');
163344
+ setShowWatcherSearch(false);
163345
+ setFormError(null);
163346
+ setIsOpen(true);
163347
+ }
163348
+ function addWatchedUserDraft(u) {
163349
+ if (watchedUsers.find((m) => m.id === u.id))
163350
+ return;
163351
+ setWatchedUsers((prev) => [...prev, u]);
163352
+ setWatchedUserSearch('');
163353
+ setShowWatchedUserSearch(false);
163354
+ }
163355
+ function removeWatchedUserDraft(id) {
163356
+ setWatchedUsers((prev) => prev.filter((m) => m.id !== id));
163357
+ }
163358
+ function addWatcherDraft(u) {
163359
+ if (watchers.find((w) => w.user.id === u.id))
163360
+ return;
163361
+ setWatchers((prev) => [...prev, { user: u, events: [] }]);
163362
+ setWatcherSearch('');
163363
+ setShowWatcherSearch(false);
163364
+ }
163365
+ function removeWatcherDraft(userId) {
163366
+ setWatchers((prev) => prev.filter((w) => w.user.id !== userId));
163367
+ }
163368
+ function toggleWatcherEvent(userId, event) {
163369
+ setWatchers((prev) => prev.map((w) => {
163370
+ if (w.user.id !== userId)
163371
+ return w;
163372
+ const has = w.events.includes(event);
163373
+ return {
163374
+ ...w,
163375
+ events: has ? w.events.filter((e) => e !== event) : [...w.events, event],
163376
+ };
163377
+ }));
163378
+ }
163379
+ async function onSubmit() {
163380
+ var _a, _b;
163381
+ setFormError(null);
163382
+ if (!name.trim()) {
163383
+ setFormError('Name is required');
163384
+ return;
163385
+ }
163386
+ for (const w of watchers) {
163387
+ if (w.events.length === 0) {
163388
+ setFormError(`Watcher "${w.user.username || w.user.name}" must subscribe to at least one event`);
163389
+ return;
163390
+ }
163391
+ }
163392
+ setIsSubmitting(true);
163393
+ try {
163394
+ if (editingGroup) {
163395
+ // 1. Update name if changed
163396
+ if (name !== editingGroup.name) {
163397
+ await updateWatchedGroup({
163398
+ id: editingGroup.id,
163399
+ body: { name },
163400
+ params: { platform_key: tenant },
163401
+ }).unwrap();
163402
+ }
163403
+ // 2. Sync watched users
163404
+ const newIds = new Set(watchedUsers.map((u) => u.id));
163405
+ const oldIds = new Set(originalWatchedUserIds);
163406
+ const toAdd = [...newIds].filter((id) => !oldIds.has(id));
163407
+ const toRemove = [...oldIds].filter((id) => !newIds.has(id));
163408
+ await Promise.all(toAdd.map((id) => addWatchedUser({
163409
+ watchedGroupPk: editingGroup.id,
163410
+ body: { user_id: id },
163411
+ params: { platform_key: tenant },
163412
+ }).unwrap()));
163413
+ await Promise.all(toRemove.map((userId) => {
163414
+ var _a;
163415
+ const linkId = (_a = watchedUserLinkIds[userId]) !== null && _a !== void 0 ? _a : userId;
163416
+ return removeWatchedUser({
163417
+ watchedGroupPk: editingGroup.id,
163418
+ id: linkId,
163419
+ params: { platform_key: tenant },
163420
+ }).unwrap();
163421
+ }));
163422
+ // 3. Sync watchers
163423
+ const originalById = new Map(originalWatchers.map((w) => [w.user.id, w]));
163424
+ const currentById = new Map(watchers.map((w) => [w.user.id, w]));
163425
+ const watcherToAdd = watchers.filter((w) => !originalById.has(w.user.id));
163426
+ const watcherToRemove = originalWatchers.filter((w) => !currentById.has(w.user.id));
163427
+ const watcherToUpdate = watchers.filter((w) => {
163428
+ const orig = originalById.get(w.user.id);
163429
+ if (!orig)
163430
+ return false;
163431
+ const a = [...orig.events].sort().join(',');
163432
+ const b = [...w.events].sort().join(',');
163433
+ return a !== b;
163434
+ });
163435
+ await Promise.all(watcherToAdd.map((w) => addWatcher({
163436
+ watchedGroupPk: editingGroup.id,
163437
+ body: { watcher_id: w.user.id, events: w.events },
163438
+ params: { platform_key: tenant },
163439
+ }).unwrap()));
163440
+ await Promise.all(watcherToRemove.map((w) => {
163441
+ var _a;
163442
+ return deleteWatcher({
163443
+ watchedGroupPk: editingGroup.id,
163444
+ id: (_a = w.id) !== null && _a !== void 0 ? _a : w.user.id,
163445
+ params: { platform_key: tenant },
163446
+ }).unwrap();
163447
+ }));
163448
+ await Promise.all(watcherToUpdate.map((w) => {
163449
+ var _a;
163450
+ return updateWatcher({
163451
+ watchedGroupPk: editingGroup.id,
163452
+ id: (_a = w.id) !== null && _a !== void 0 ? _a : w.user.id,
163453
+ body: { events: w.events },
163454
+ params: { platform_key: tenant },
163455
+ }).unwrap();
163456
+ }));
163457
+ toast.success('Alert updated');
163458
+ }
163459
+ else {
163460
+ await createWatchedGroup({
163461
+ body: {
163462
+ name,
163463
+ watched_users: watchedUsers.map((u) => u.id),
163464
+ watchers: watchers.map((w) => ({ watcher_id: w.user.id, events: w.events })),
163465
+ },
163466
+ params: {
163467
+ platform_key: tenant,
163468
+ watched_user_limit: Math.min(watchedUsers.length, 100),
163469
+ watcher_limit: Math.min(watchers.length, 100),
163470
+ },
163471
+ }).unwrap();
163472
+ toast.success('Alert created');
163473
+ }
163474
+ setIsOpen(false);
163475
+ setEditingGroup(null);
163476
+ resetForm();
163477
+ await refetch();
163478
+ }
163479
+ catch (e) {
163480
+ const message = ((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.detail) || ((_b = e === null || e === void 0 ? void 0 : e.data) === null || _b === void 0 ? void 0 : _b.message) || (e === null || e === void 0 ? void 0 : e.message);
163481
+ const fallback = editingGroup ? 'Failed to update alert' : 'Failed to create alert';
163482
+ setFormError(message || fallback);
163483
+ toast.error(message || fallback);
163484
+ }
163485
+ finally {
163486
+ setIsSubmitting(false);
163487
+ }
163488
+ }
163489
+ async function onDelete(g) {
163490
+ var _a, _b;
163491
+ setDeletingGroupId(g.id);
163492
+ try {
163493
+ await deleteWatchedGroup({ id: g.id, params: { platform_key: tenant } }).unwrap();
163494
+ toast.success('Alert deleted');
163495
+ }
163496
+ catch (e) {
163497
+ toast.error(((_a = e === null || e === void 0 ? void 0 : e.data) === null || _a === void 0 ? void 0 : _a.detail) || ((_b = e === null || e === void 0 ? void 0 : e.data) === null || _b === void 0 ? void 0 : _b.message) || (e === null || e === void 0 ? void 0 : e.message) || 'Failed to delete alert');
163498
+ }
163499
+ finally {
163500
+ setDeletingGroupId(null);
163501
+ }
163502
+ }
163503
+ return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex mb-6 gap-2 flex-row items-center justify-between", children: [jsxs("div", { className: "relative max-w-sm w-full sm:w-auto", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: "Search alerts", "aria-label": "Search alerts", className: "pl-10 pr-10 focus:ring-blue-500 focus:border-blue-500 h-[35px]" }), isLoading && (jsx(LoaderCircle, { "data-testid": "search-spinner", className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400 animate-spin", "aria-hidden": "true" }))] }), jsx("div", { className: "flex gap-2", children: jsx(Button$1, { onClick: openNew, "aria-label": "New alert", className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", children: "New Alert" }) })] }), isLoading && (jsx("div", { className: "flex justify-center items-center h-64", children: jsx("div", { className: "py-8 text-center text-sm text-gray-500 dark:text-gray-400", children: "Loading\u2026" }) })), isError && (jsx("div", { className: "py-8 text-center text-sm text-red-500", children: "Failed to load alerts" })), !isLoading && !isError && (jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: "Name" }), jsx("th", { className: "px-6 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[120px]" })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [groups.map((g) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 text-gray-900 dark:text-gray-100 text-sm", children: g.name }), jsx("td", { className: "px-6 py-4", children: jsxs("div", { className: "flex gap-2 justify-end", children: [jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => openEdit(g), disabled: deletingGroupId === g.id, "aria-label": `Edit alert ${g.name}`, children: jsx(Pencil, { className: "h-4 w-4", "aria-hidden": "true" }) }), jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => onDelete(g), className: "text-red-600 hover:text-red-700", disabled: deletingGroupId === g.id, "aria-label": `Delete alert ${g.name}`, children: deletingGroupId === g.id ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" })) : (jsx(Trash2, { className: "h-4 w-4", "aria-hidden": "true" })) })] }) })] }, g.id))), groups.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 2, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: "No alerts found" }) }))] })] }) })), !isLoading && !isError && totalPages > 1 && (jsx("div", { className: "mt-6", children: jsx(AdvancedPagination, { totalPages: totalPages, currentPage: page, onPageChange: (newPage) => handlePageChange(newPage) }) })), jsx(Dialog, { open: isOpen, onOpenChange: setIsOpen, children: jsxs(DialogContent, { "aria-describedby": undefined, className: "max-w-2xl max-h-[90vh] overflow-y-auto", children: [jsx(DialogHeader, { children: jsx(DialogTitle, { children: editingGroup ? 'Edit Alert' : 'New Alert' }) }), jsxs("div", { className: "space-y-5", children: [jsxs("div", { className: "grid gap-1.5", children: [jsx(Label, { htmlFor: "wg-name", children: "Name" }), jsx(Input, { id: "wg-name", value: name, onChange: (e) => setName(e.target.value), placeholder: "Enter alert name", required: true })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label, { children: "Watched Users" }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Users whose activity is monitored." }), watchedUsers.length > 0 ? (jsx("div", { className: "space-y-2 max-h-48 overflow-y-auto border border-gray-200 dark:border-gray-700 rounded-md p-2", children: watchedUsers.map((user) => (jsxs("div", { className: "flex items-center justify-between bg-gray-50 dark:bg-gray-800 p-2 rounded-md", children: [jsxs("div", { className: "flex flex-col", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: user.name || user.username }), user.email && (jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: user.email }))] }), jsx(Button$1, { type: "button", variant: "ghost", size: "sm", onClick: () => removeWatchedUserDraft(user.id), className: "h-8 w-8 p-0 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20", "aria-label": `Remove watched user ${user.username}`, children: jsx(X$1, { className: "h-4 w-4" }) })] }, user.id))) })) : (jsx("div", { className: "text-sm text-gray-500 dark:text-gray-400 p-4 text-center border border-dashed border-gray-300 dark:border-gray-600 rounded-md", children: "No watched users added yet" })), jsxs("div", { className: "relative", children: [jsx(Input, { value: watchedUserSearch, onChange: (e) => {
163504
+ setWatchedUserSearch(e.target.value);
163505
+ setShowWatchedUserSearch(e.target.value.length > 0);
163506
+ }, onFocus: () => setShowWatchedUserSearch(watchedUserSearch.length > 0), placeholder: "Type to add watched users...", className: "w-full" }), showWatchedUserSearch && availableWatchedUsers.length > 0 && (jsx("div", { className: "absolute top-full left-0 right-0 mt-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md shadow-lg max-h-48 overflow-y-auto z-50", children: availableWatchedUsers.map((user) => {
163507
+ var _a;
163508
+ return (jsxs("button", { type: "button", onClick: () => {
163509
+ var _a, _b;
163510
+ return addWatchedUserDraft({
163511
+ id: (_a = user.user_id) !== null && _a !== void 0 ? _a : user.id,
163512
+ name: (_b = user.name) !== null && _b !== void 0 ? _b : '',
163513
+ email: user.email,
163514
+ username: user.username,
163515
+ });
163516
+ }, className: "w-full text-left px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 flex flex-col", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: user.name || user.username }), jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: user.email })] }, (_a = user.user_id) !== null && _a !== void 0 ? _a : user.id));
163517
+ }) })), showWatchedUserSearch &&
163518
+ watchedUserSearch.length > 2 &&
163519
+ availableWatchedUsers.length === 0 && (jsx("div", { className: "absolute top-full left-0 right-0 mt-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md shadow-lg p-3 z-50", children: jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: "No users found" }) }))] })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label, { children: "Watchers" }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: "Users who receive notifications when watched users perform selected actions." }), watchers.length > 0 ? (jsx("div", { className: "space-y-3 max-h-72 overflow-y-auto border border-gray-200 dark:border-gray-700 rounded-md p-2", children: watchers.map((w) => (jsx("div", { className: "bg-gray-50 dark:bg-gray-800 p-3 rounded-md", children: jsxs("div", { className: "flex items-center justify-between gap-2", children: [jsxs("div", { className: "flex flex-col min-w-0", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100 truncate", children: w.user.name || w.user.username }), w.user.email && (jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400 truncate", children: w.user.email }))] }), jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [jsxs(Popover, { modal: true, open: openEventsPopover === w.user.id, onOpenChange: (open) => setOpenEventsPopover(open ? w.user.id : null), children: [jsx(PopoverTrigger, { asChild: true, children: jsxs(Button$1, { variant: "outline", role: "combobox", "aria-expanded": openEventsPopover === w.user.id, "aria-label": `Select events for ${w.user.username || w.user.name}`, className: "w-44 justify-between text-sm h-9 font-normal", children: [jsx("span", { className: "truncate", children: w.events.length > 0
163520
+ ? `${w.events.length} events selected`
163521
+ : 'No events' }), openEventsPopover === w.user.id ? (jsx(ChevronUp, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })) : (jsx(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" }))] }) }), jsx(PopoverContent, { className: "w-72 p-3 max-h-64 overflow-y-auto", align: "end", onWheel: (e) => e.stopPropagation(), onTouchMove: (e) => e.stopPropagation(), children: jsxs("div", { className: "space-y-2", children: [jsx("div", { className: "text-sm font-medium mb-2", children: "Select Events" }), WATCHER_NOTIFICATION_EVENTS.map((event) => {
163522
+ var _a;
163523
+ const checkboxId = `watcher-${w.user.id}-${event}`;
163524
+ const checked = w.events.includes(event);
163525
+ return (jsxs("div", { className: "flex items-center space-x-2 cursor-pointer rounded px-1 py-0.5 hover:bg-gray-100 dark:hover:bg-gray-700", onClick: () => toggleWatcherEvent(w.user.id, event), children: [jsx(Checkbox, { id: checkboxId, checked: checked, tabIndex: -1, className: "pointer-events-none", "aria-label": `Toggle ${event} for ${w.user.username || w.user.name}` }), jsx("span", { className: "text-sm font-normal select-none", children: (_a = WATCHER_NOTIFICATION_EVENT_LABELS[event]) !== null && _a !== void 0 ? _a : event })] }, event));
163526
+ })] }) })] }), jsx(Button$1, { type: "button", variant: "ghost", size: "sm", onClick: () => removeWatcherDraft(w.user.id), className: "h-8 w-8 p-0 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20", "aria-label": `Remove watcher ${w.user.username}`, children: jsx(X$1, { className: "h-4 w-4" }) })] })] }) }, w.user.id))) })) : (jsx("div", { className: "text-sm text-gray-500 dark:text-gray-400 p-4 text-center border border-dashed border-gray-300 dark:border-gray-600 rounded-md", children: "No watchers added yet" })), jsxs("div", { className: "relative", children: [jsx(Input, { value: watcherSearch, onChange: (e) => {
163527
+ setWatcherSearch(e.target.value);
163528
+ setShowWatcherSearch(e.target.value.length > 0);
163529
+ }, onFocus: () => setShowWatcherSearch(watcherSearch.length > 0), placeholder: "Type to add watchers...", className: "w-full" }), showWatcherSearch && availableWatcherUsers.length > 0 && (jsx("div", { className: "absolute top-full left-0 right-0 mt-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md shadow-lg max-h-48 overflow-y-auto z-50", children: availableWatcherUsers.map((user) => {
163530
+ var _a;
163531
+ return (jsxs("button", { type: "button", onClick: () => {
163532
+ var _a, _b;
163533
+ return addWatcherDraft({
163534
+ id: (_a = user.user_id) !== null && _a !== void 0 ? _a : user.id,
163535
+ name: (_b = user.name) !== null && _b !== void 0 ? _b : '',
163536
+ email: user.email,
163537
+ username: user.username,
163538
+ });
163539
+ }, className: "w-full text-left px-3 py-2 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2", children: [jsx(Plus, { className: "h-3 w-3 text-gray-400" }), jsxs("div", { className: "flex flex-col", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: user.name || user.username }), jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: user.email })] })] }, (_a = user.user_id) !== null && _a !== void 0 ? _a : user.id));
163540
+ }) })), showWatcherSearch &&
163541
+ watcherSearch.length > 2 &&
163542
+ availableWatcherUsers.length === 0 && (jsx("div", { className: "absolute top-full left-0 right-0 mt-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md shadow-lg p-3 z-50", children: jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: "No users found" }) }))] })] })] }), formError && (jsx("div", { className: "mt-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-md", children: jsx("p", { className: "text-sm text-red-600 dark:text-red-400", children: formError }) })), jsxs(DialogFooter, { className: "mt-6", children: [jsx(Button$1, { variant: "outline", onClick: () => setIsOpen(false), children: "Cancel" }), jsxs(Button$1, { onClick: onSubmit, disabled: isSubmitting, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", children: [isSubmitting ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin mr-2", "aria-hidden": "true" })) : null, editingGroup ? 'Save Alert' : 'Create Alert'] })] })] }) })] }));
163543
+ }
163544
+
163545
+ const Admin = ({ tenant, onInviteClick, hasUserTabPermission = false, hasGroupsTabPermission = false, hasRolesTabPermission = false, hasPoliciesTabPermission = false, hasTeamsTabPermission = false, hasAlertsTabPermission = false, hasInviteUserPermission = false, hasCreateTeamPermission = false, onLoadGroupPermissions, rbacPermissions = {}, enableRbac = false, }) => {
163546
+ return (jsx("div", { className: "border border-gray-200 rounded-lg p-6", children: jsxs(Tabs, { defaultValue: "users", "aria-label": "RBAC Management Tabs", children: [jsxs(TabsList, { "aria-label": "Management tabs", className: "max-w-full overflow-x-auto justify-start px-1", children: [hasUserTabPermission && jsx(TabsTrigger, { value: "users", children: "Users" }), hasGroupsTabPermission && jsx(TabsTrigger, { value: "groups", children: "Groups" }), hasRolesTabPermission && jsx(TabsTrigger, { value: "roles", children: "Roles" }), hasPoliciesTabPermission && jsx(TabsTrigger, { value: "policies", children: "Policies" }), hasTeamsTabPermission && jsx(TabsTrigger, { value: "teams", children: "Teams" }), hasAlertsTabPermission && jsx(TabsTrigger, { value: "alerts", children: "Alerts" })] }), hasUserTabPermission && (jsx(TabsContent, { value: "users", children: jsx(UsersTab, { tenant: tenant, onInviteClick: onInviteClick }) })), hasGroupsTabPermission && (jsx(TabsContent, { value: "groups", children: jsx(GroupsTab, { tenant: tenant }) })), hasRolesTabPermission && (jsx(TabsContent, { value: "roles", children: jsx(RolesTab, { tenant: tenant }) })), hasPoliciesTabPermission && (jsx(TabsContent, { value: "policies", children: jsx(PoliciesTab, { tenant: tenant }) })), hasTeamsTabPermission && (jsx(TabsContent, { value: "teams", children: jsx(GroupsTab, { tenant: tenant, isTeam: true, onInviteClick: onInviteClick, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac }) })), hasAlertsTabPermission && (jsx(TabsContent, { value: "alerts", children: jsx(AlertsTab, { tenant: tenant }) }))] }) }));
163136
163547
  };
163137
163548
 
163138
163549
  function OrganizationTab({ platformKey, setOrganizationLogoFromOutside, tenant, onTenantUpdate, }) {
@@ -166560,11 +166971,13 @@ function Account({ tenant, tenants = [], username, onInviteClick, email, mainPla
166560
166971
  const hasTeamsTabPermission = checkRbacPermission(rbacPermissions, `/usergroups/#list|/platforms/${tenant}/#can_invite`, enableRbac);
166561
166972
  const hasInviteUserPermission = checkRbacPermission(rbacPermissions, `/platforms/${tenant}/#can_invite`, enableRbac);
166562
166973
  const hasCreateTeamPermission = checkRbacPermission(rbacPermissions, `/usergroups/#list`, enableRbac);
166974
+ const hasAlertsTabPermission = checkRbacPermission(rbacPermissions, `/watchedgroups/#list`, enableRbac);
166563
166975
  const hasManagementPermissions = hasUserTabPermission ||
166564
166976
  hasGroupsTabPermission ||
166565
166977
  hasPoliciesTabPermission ||
166566
166978
  hasRolesTabPermission ||
166567
- hasTeamsTabPermission;
166979
+ hasTeamsTabPermission ||
166980
+ hasAlertsTabPermission;
166568
166981
  useEffect(() => {
166569
166982
  const firstInput = document.getElementById('fullName');
166570
166983
  if (firstInput) {
@@ -166631,7 +167044,7 @@ function Account({ tenant, tenants = [], username, onInviteClick, email, mainPla
166631
167044
  : 'text-gray-600 hover:bg-gray-50'}`, children: [jsx(CreditCard, { className: "h-4 w-4" }), jsx("span", { className: "hidden sm:inline", children: "Billing" }), jsx("span", { className: "sm:hidden", children: "Billing" })] }, 'billing'))] }) }) }), jsxs("div", { className: "flex-1 flex flex-col overflow-hidden", style: { height: '100%' }, children: [jsxs("div", { className: "hidden lg:block flex-shrink-0 p-6 border-b border-gray-200 bg-white dark:bg-gray-900", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2 capitalize", children: activeTab }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'management' && 'Manage users and their permissions in the system.', activeTab === 'organization' && 'Manage your organization settings.', activeTab === 'integrations' && 'Manage your integrations with other services.', activeTab === 'billing' && 'Manage your billing and subscription.', activeTab === 'monetization' && 'Configure paywalls, pricing, and revenue.', activeTab === 'advanced' && 'Configure advanced organization settings.'] })] }), jsxs("div", { className: "flex-1 p-6 space-y-6", style: {
166632
167045
  overflowY: 'auto',
166633
167046
  overflowX: 'hidden',
166634
- }, children: [jsxs("div", { className: "lg:hidden mb-6", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2 capitalize", children: activeTab }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'basic' && 'Manage your basic account information and preferences.', activeTab === 'social' && 'Connect and manage your social media accounts.', activeTab === 'security' && 'Update your security settings and password.', activeTab === 'management' && 'Manage users and their permissions in the system.', activeTab === 'organization' && 'Manage your organization settings.', activeTab === 'monetization' && 'Configure paywalls, pricing, and revenue.', activeTab === 'advanced' && 'Configure advanced organization settings.'] })] }), activeTab === 'management' && hasManagementPermissions && (jsx(Admin, { onInviteClick: onInviteClick, tenant: tenant, hasUserTabPermission: hasUserTabPermission, hasGroupsTabPermission: hasGroupsTabPermission, hasPoliciesTabPermission: hasPoliciesTabPermission, hasRolesTabPermission: hasRolesTabPermission, hasTeamsTabPermission: hasTeamsTabPermission, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, rbacPermissions: rbacPermissions, enableRbac: enableRbac })), activeTab === 'organization' && (jsx(OrganizationTab, { platformKey: tenant, tenant: tenants.find((t) => t.key === tenant), onTenantUpdate: onTenantUpdate, setOrganizationLogoFromOutside: setOrganizationLogo })), activeTab === 'integrations' && (jsx(IntegrationsTab, { tenantKey: tenant, username: username })), activeTab === 'billing' && (jsx(BillingTab, { tenant: tenant, userActiveApp: userActiveApp, username: username, currentUserEmail: email, mainPlatformKey: mainPlatformKey })), activeTab === 'monetization' && (jsx(MonetizationTab, { platformKey: tenant, authURL: authURL })), activeTab === 'advanced' && (jsx(AdvancedTab, { platformKey: tenant, currentSPA: currentSPA, username: username, authURL: authURL, currentPlatformBaseDomain: currentPlatformBaseDomain }))] })] }), jsx(ToastProvider, {})] }));
167047
+ }, children: [jsxs("div", { className: "lg:hidden mb-6", children: [jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100 mb-2 capitalize", children: activeTab }), jsxs("p", { className: "text-gray-600 dark:text-gray-400 text-sm", children: [activeTab === 'basic' && 'Manage your basic account information and preferences.', activeTab === 'social' && 'Connect and manage your social media accounts.', activeTab === 'security' && 'Update your security settings and password.', activeTab === 'management' && 'Manage users and their permissions in the system.', activeTab === 'organization' && 'Manage your organization settings.', activeTab === 'monetization' && 'Configure paywalls, pricing, and revenue.', activeTab === 'advanced' && 'Configure advanced organization settings.'] })] }), activeTab === 'management' && hasManagementPermissions && (jsx(Admin, { onInviteClick: onInviteClick, tenant: tenant, hasUserTabPermission: hasUserTabPermission, hasGroupsTabPermission: hasGroupsTabPermission, hasPoliciesTabPermission: hasPoliciesTabPermission, hasRolesTabPermission: hasRolesTabPermission, hasTeamsTabPermission: hasTeamsTabPermission, hasInviteUserPermission: hasInviteUserPermission, hasCreateTeamPermission: hasCreateTeamPermission, onLoadGroupPermissions: onLoadGroupPermissions, hasAlertsTabPermission: hasAlertsTabPermission, rbacPermissions: rbacPermissions, enableRbac: enableRbac })), activeTab === 'organization' && (jsx(OrganizationTab, { platformKey: tenant, tenant: tenants.find((t) => t.key === tenant), onTenantUpdate: onTenantUpdate, setOrganizationLogoFromOutside: setOrganizationLogo })), activeTab === 'integrations' && (jsx(IntegrationsTab, { tenantKey: tenant, username: username })), activeTab === 'billing' && (jsx(BillingTab, { tenant: tenant, userActiveApp: userActiveApp, username: username, currentUserEmail: email, mainPlatformKey: mainPlatformKey })), activeTab === 'monetization' && (jsx(MonetizationTab, { platformKey: tenant, authURL: authURL })), activeTab === 'advanced' && (jsx(AdvancedTab, { platformKey: tenant, currentSPA: currentSPA, username: username, authURL: authURL, currentPlatformBaseDomain: currentPlatformBaseDomain }))] })] }), jsx(ToastProvider, {})] }));
166635
167048
  }
166636
167049
 
166637
167050
  function UserProfileModal({ isOpen, onClose, params, email, mainPlatformKey, showMentorAIDisplayCheckbox = false, showLeaderboardDisplayCheckbox = false, showUsernameField = false, showPlatformName = false, useGravatarPicFallback = true, enableCatalogInvite = false, targetTab = 'basic', currentPlan = '', currentSPA = '', userActiveApp = null, authURL, tenants = [], onTenantUpdate, currentPlatformBaseDomain = '', rbacPermissions = {}, enableRbac = false, onLoadGroupPermissions, onTabChange, onBillingTabRequest, onAccountDeleted, enableMemoryTab = false, localLLMProps, }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iblai/iblai-js",
3
- "version": "1.9.9",
3
+ "version": "1.9.11",
4
4
  "description": "Unified JavaScript SDK for IBL.ai — re-exports data-layer, web-containers, and web-utils under a single package",
5
5
  "type": "module",
6
6
  "engines": {
@@ -61,10 +61,10 @@
61
61
  "axios": "1.13.6",
62
62
  "dotenv": "16.6.1",
63
63
  "winston": "3.19.0",
64
- "@iblai/data-layer": "1.5.4",
65
- "@iblai/web-containers": "1.6.10",
66
- "@iblai/mcp": "1.4.7",
67
- "@iblai/web-utils": "1.6.6"
64
+ "@iblai/data-layer": "1.5.5",
65
+ "@iblai/mcp": "1.4.8",
66
+ "@iblai/web-containers": "1.6.11",
67
+ "@iblai/web-utils": "1.6.8"
68
68
  },
69
69
  "peerDependencies": {
70
70
  "@radix-ui/react-dialog": "^1.1.7",