@iblai/iblai-js 1.26.7 → 1.26.9

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.
@@ -142617,9 +142617,10 @@ function RolesTab({ tenant }) {
142617
142617
  pageSize: 10,
142618
142618
  ...(debouncedSearchQuery.length > 2 && { name: debouncedSearchQuery }),
142619
142619
  });
142620
- const [createRole] = useCreateRbacRoleMutation();
142621
- const [updateRole] = useUpdateRbacRoleMutation();
142620
+ const [createRole, { isLoading: isCreating }] = useCreateRbacRoleMutation();
142621
+ const [updateRole, { isLoading: isUpdating }] = useUpdateRbacRoleMutation();
142622
142622
  const [deleteRole] = useDeleteRbacRoleMutation();
142623
+ const isSaving = isCreating || isUpdating;
142623
142624
  // Debounce search query
142624
142625
  useEffect(() => {
142625
142626
  const handler = setTimeout(() => {
@@ -142757,7 +142758,7 @@ function RolesTab({ tenant }) {
142757
142758
  setDeletingRoleId(null);
142758
142759
  }
142759
142760
  }
142760
- return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex justify-between items-center gap-1 mb-6", children: [jsxs("div", { className: "relative max-w-sm", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: t('tabsRolestab.searchRolesPlaceholder'), "aria-label": t('tabsRolestab.searchRolesAriaLabel'), 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(Button$1, { onClick: openNew, "aria-label": t('tabsRolestab.newRoleAriaLabel'), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", children: t('tabsRolestab.newRoleButton') })] }), isLoading && (jsx("div", { className: "flex justify-center items-center h-64", children: jsx("div", { className: "py-8 text-center text-sm text-gray-500 dark:text-gray-400", children: t('tabsRolestab.loading') }) })), isError && (jsx("div", { className: "py-8 text-center text-sm text-red-500", children: t('tabsRolestab.failedToLoadRoles') })), !isLoading && !isError && (jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: t('tabsRolestab.nameHeader') }), jsx("th", { className: "px-6 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[100px]" })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [roles.map((r) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 text-gray-900 dark:text-gray-100 text-sm", children: r.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(r), disabled: deletingRoleId === r.id, "aria-label": t('tabsRolestab.editRoleAriaLabel', { name: r.name }), children: jsx(Pencil, { className: "h-4 w-4", "aria-hidden": "true" }) }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("span", { tabIndex: 0, children: jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => onDelete(r), className: "text-red-600 hover:text-red-700", disabled: deletingRoleId === r.id || r.is_internal, "aria-label": t('tabsRolestab.deleteRoleAriaLabel', { name: r.name }), children: deletingRoleId === r.id ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" })) : (jsx(Trash2, { className: "h-4 w-4", "aria-hidden": "true" })) }) }) }), r.is_internal && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsRolestab.cannotDeleteInternalRoles') }) }))] }) })] }) })] }, r.id))), roles.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 2, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: t('tabsRolestab.noRolesFound') }) }))] })] }) })), !isLoading && !isError && (jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (newPage) => handlePageChange(newPage), totalCount: data === null || data === void 0 ? void 0 : data.count, itemsPerPage: 10, itemLabel: "roles" })), 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: editing ? t('tabsRolestab.editRoleTitle') : t('tabsRolestab.newRoleTitle') }) }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$2, { htmlFor: "r-name", children: t('tabsRolestab.roleNameLabel') }), jsx(Input, { id: "r-name", value: form.name, onChange: (e) => setForm({ ...form, name: e.target.value }), placeholder: t('tabsRolestab.enterRoleNamePlaceholder'), required: true })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$2, { htmlFor: "r-actions", children: t('tabsRolestab.actionsLabel') }), jsxs("div", { className: "space-y-2", children: [actions.length > 0 && (jsx("div", { className: "flex flex-wrap gap-2 p-2 border border-gray-200 dark:border-gray-700 rounded-md bg-gray-50 dark:bg-gray-800", children: actions.map((action, index) => (jsxs(Badge, { variant: "secondary", className: "px-2 py-1 flex items-center gap-1 font-mono text-xs", children: [jsx("span", { children: action }), jsx("button", { type: "button", onClick: () => removeAction(action), className: "ml-1 hover:text-red-600", "aria-label": t('tabsRolestab.removeActionAriaLabel', { action }), children: jsx(X$1, { className: "h-3 w-3" }) })] }, index))) })), jsx(ActionsCombobox, { selected: actions, onSelect: addActionKey }), jsxs("div", { className: "flex gap-2", children: [jsx(Input, { id: "r-actions", value: actionInput, onChange: (e) => setActionInput(e.target.value), onKeyDown: handleActionKeyDown, placeholder: t('tabsRolestab.customActionPlaceholder'), className: "flex-1 font-mono text-sm" }), jsx(Button$1, { type: "button", variant: "outline", size: "sm", onClick: addAction, disabled: !actionInput.trim(), "aria-label": t('tabsRolestab.addActionAriaLabel'), children: jsx(Plus, { className: "h-4 w-4" }) })] }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('tabsRolestab.actionsHelpText') })] })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$2, { htmlFor: "r-data-actions", children: t('tabsRolestab.dataActionsLabel') }), jsxs("div", { className: "space-y-2", children: [dataActions.length > 0 && (jsx("div", { className: "flex flex-wrap gap-2 p-2 border border-gray-200 dark:border-gray-700 rounded-md bg-gray-50 dark:bg-gray-800", children: dataActions.map((action, index) => (jsxs(Badge, { variant: "secondary", className: "px-2 py-1 flex items-center gap-1 font-mono text-xs", children: [jsx("span", { children: action }), jsx("button", { type: "button", onClick: () => removeDataAction(action), className: "ml-1 hover:text-red-600", "aria-label": t('tabsRolestab.removeDataActionAriaLabel', { action }), children: jsx(X$1, { className: "h-3 w-3" }) })] }, index))) })), jsxs("div", { className: "flex gap-2", children: [jsx(Input, { id: "r-data-actions", value: dataActionInput, onChange: (e) => setDataActionInput(e.target.value), onKeyDown: handleDataActionKeyDown, placeholder: t('tabsRolestab.dataActionPlaceholder'), className: "flex-1 font-mono text-sm" }), jsx(Button$1, { type: "button", variant: "outline", size: "sm", onClick: addDataAction, disabled: !dataActionInput.trim(), "aria-label": t('tabsRolestab.addDataActionAriaLabel'), children: jsx(Plus, { className: "h-4 w-4" }) })] }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('tabsRolestab.dataActionsHelpText') })] })] })] }), jsxs(DialogFooter, { className: "mt-6 gap-1.5", children: [jsx(Button$1, { variant: "outline", onClick: () => setIsOpen(false), children: t('tabsRolestab.cancel') }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("span", { tabIndex: 0, className: "", children: jsx(Button$1, { onClick: onSubmit, disabled: !!editing && (roleDetails === null || roleDetails === void 0 ? void 0 : roleDetails.is_internal), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white w-full", children: editing ? t('tabsRolestab.saveRole') : t('tabsRolestab.createRole') }) }) }), editing && (roleDetails === null || roleDetails === void 0 ? void 0 : roleDetails.is_internal) && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsRolestab.cannotEditInternalRoles') }) }))] }) })] })] }) })] }));
142761
+ return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex justify-between items-center gap-1 mb-6", children: [jsxs("div", { className: "relative max-w-sm", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: t('tabsRolestab.searchRolesPlaceholder'), "aria-label": t('tabsRolestab.searchRolesAriaLabel'), 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(Button$1, { onClick: openNew, "aria-label": t('tabsRolestab.newRoleAriaLabel'), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", children: t('tabsRolestab.newRoleButton') })] }), isLoading && (jsx("div", { className: "flex justify-center items-center h-64", children: jsx("div", { className: "py-8 text-center text-sm text-gray-500 dark:text-gray-400", children: t('tabsRolestab.loading') }) })), isError && (jsx("div", { className: "py-8 text-center text-sm text-red-500", children: t('tabsRolestab.failedToLoadRoles') })), !isLoading && !isError && (jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: t('tabsRolestab.nameHeader') }), jsx("th", { className: "px-6 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[100px]" })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [roles.map((r) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 text-gray-900 dark:text-gray-100 text-sm", children: r.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(r), disabled: deletingRoleId === r.id, "aria-label": t('tabsRolestab.editRoleAriaLabel', { name: r.name }), children: jsx(Pencil, { className: "h-4 w-4", "aria-hidden": "true" }) }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("span", { tabIndex: 0, children: jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => onDelete(r), className: "text-red-600 hover:text-red-700", disabled: deletingRoleId === r.id || r.is_internal, "aria-label": t('tabsRolestab.deleteRoleAriaLabel', { name: r.name }), children: deletingRoleId === r.id ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" })) : (jsx(Trash2, { className: "h-4 w-4", "aria-hidden": "true" })) }) }) }), r.is_internal && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsRolestab.cannotDeleteInternalRoles') }) }))] }) })] }) })] }, r.id))), roles.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 2, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: t('tabsRolestab.noRolesFound') }) }))] })] }) })), !isLoading && !isError && (jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (newPage) => handlePageChange(newPage), totalCount: data === null || data === void 0 ? void 0 : data.count, itemsPerPage: 10, itemLabel: "roles" })), 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: editing ? t('tabsRolestab.editRoleTitle') : t('tabsRolestab.newRoleTitle') }) }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$2, { htmlFor: "r-name", children: t('tabsRolestab.roleNameLabel') }), jsx(Input, { id: "r-name", value: form.name, onChange: (e) => setForm({ ...form, name: e.target.value }), placeholder: t('tabsRolestab.enterRoleNamePlaceholder'), required: true })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$2, { htmlFor: "r-actions", children: t('tabsRolestab.actionsLabel') }), jsxs("div", { className: "space-y-2", children: [actions.length > 0 && (jsx("div", { className: "flex flex-wrap gap-2 p-2 border border-gray-200 dark:border-gray-700 rounded-md bg-gray-50 dark:bg-gray-800", children: actions.map((action, index) => (jsxs(Badge, { variant: "secondary", className: "px-2 py-1 flex items-center gap-1 font-mono text-xs", children: [jsx("span", { children: action }), jsx("button", { type: "button", onClick: () => removeAction(action), className: "ml-1 hover:text-red-600", "aria-label": t('tabsRolestab.removeActionAriaLabel', { action }), children: jsx(X$1, { className: "h-3 w-3" }) })] }, index))) })), jsx(ActionsCombobox, { selected: actions, onSelect: addActionKey }), jsxs("div", { className: "flex gap-2", children: [jsx(Input, { id: "r-actions", value: actionInput, onChange: (e) => setActionInput(e.target.value), onKeyDown: handleActionKeyDown, placeholder: t('tabsRolestab.customActionPlaceholder'), className: "flex-1 font-mono text-sm" }), jsx(Button$1, { type: "button", variant: "outline", size: "sm", onClick: addAction, disabled: !actionInput.trim(), "aria-label": t('tabsRolestab.addActionAriaLabel'), children: jsx(Plus, { className: "h-4 w-4" }) })] }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('tabsRolestab.actionsHelpText') })] })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$2, { htmlFor: "r-data-actions", children: t('tabsRolestab.dataActionsLabel') }), jsxs("div", { className: "space-y-2", children: [dataActions.length > 0 && (jsx("div", { className: "flex flex-wrap gap-2 p-2 border border-gray-200 dark:border-gray-700 rounded-md bg-gray-50 dark:bg-gray-800", children: dataActions.map((action, index) => (jsxs(Badge, { variant: "secondary", className: "px-2 py-1 flex items-center gap-1 font-mono text-xs", children: [jsx("span", { children: action }), jsx("button", { type: "button", onClick: () => removeDataAction(action), className: "ml-1 hover:text-red-600", "aria-label": t('tabsRolestab.removeDataActionAriaLabel', { action }), children: jsx(X$1, { className: "h-3 w-3" }) })] }, index))) })), jsxs("div", { className: "flex gap-2", children: [jsx(Input, { id: "r-data-actions", value: dataActionInput, onChange: (e) => setDataActionInput(e.target.value), onKeyDown: handleDataActionKeyDown, placeholder: t('tabsRolestab.dataActionPlaceholder'), className: "flex-1 font-mono text-sm" }), jsx(Button$1, { type: "button", variant: "outline", size: "sm", onClick: addDataAction, disabled: !dataActionInput.trim(), "aria-label": t('tabsRolestab.addDataActionAriaLabel'), children: jsx(Plus, { className: "h-4 w-4" }) })] }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('tabsRolestab.dataActionsHelpText') })] })] })] }), jsxs(DialogFooter, { className: "mt-6 gap-1.5", children: [jsx(Button$1, { variant: "outline", onClick: () => setIsOpen(false), children: t('tabsRolestab.cancel') }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("span", { tabIndex: 0, className: "", children: jsxs(Button$1, { onClick: onSubmit, disabled: (!!editing && (roleDetails === null || roleDetails === void 0 ? void 0 : roleDetails.is_internal)) || isSaving, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white w-full", children: [isSaving ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin mr-2", "aria-hidden": "true" })) : null, editing ? t('tabsRolestab.saveRole') : t('tabsRolestab.createRole')] }) }) }), editing && (roleDetails === null || roleDetails === void 0 ? void 0 : roleDetails.is_internal) && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsRolestab.cannotEditInternalRoles') }) }))] }) })] })] }) })] }));
142761
142762
  }
142762
142763
 
142763
142764
  /**
@@ -142841,8 +142842,8 @@ function PoliciesTab({ tenant }) {
142841
142842
  pageSize: 10,
142842
142843
  ...(debouncedSearchQuery.length > 2 && { name: debouncedSearchQuery }),
142843
142844
  });
142844
- const [createPolicy] = useCreateRbacPolicyMutation();
142845
- const [updatePolicy] = useUpdateRbacPolicyMutation();
142845
+ const [createPolicy, { isLoading: isCreating }] = useCreateRbacPolicyMutation();
142846
+ const [updatePolicy, { isLoading: isUpdating }] = useUpdateRbacPolicyMutation();
142846
142847
  const [deletePolicy] = useDeleteRbacPolicyMutation();
142847
142848
  // Debounce search query
142848
142849
  useEffect(() => {
@@ -142882,6 +142883,7 @@ function PoliciesTab({ tenant }) {
142882
142883
  const [showGroupSearch, setShowGroupSearch] = useState(false);
142883
142884
  const [deletingPolicyId, setDeletingPolicyId] = useState(null);
142884
142885
  const [isResourcePickerOpen, setIsResourcePickerOpen] = useState(false);
142886
+ const isSaving = isCreating || isUpdating;
142885
142887
  const { currentData: policyDetails } = useGetRbacPolicyDetailsQuery({ id: editingPolicyId, platform_key: tenant }, { skip: !editingPolicyId });
142886
142888
  // Debounce role search and query the roles endpoint with the search term
142887
142889
  useEffect(() => {
@@ -143133,9 +143135,9 @@ function PoliciesTab({ tenant }) {
143133
143135
  }, onFocus: () => setShowGroupSearch(groupSearch.length > 0 || availableGroups.length > 0), placeholder: t('tabsPoliciestab.searchGroupsPlaceholder') }), showGroupSearch && availableGroups.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: availableGroups.map((group) => (jsx("button", { type: "button", onClick: () => addGroup({
143134
143136
  id: group.id,
143135
143137
  name: group.name,
143136
- }), 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: t('tabsPoliciestab.cancel') }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { 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
143137
- ? t('tabsPoliciestab.savePolicy')
143138
- : t('tabsPoliciestab.createPolicy') }) }) }), editing && (policyDetails === null || policyDetails === void 0 ? void 0 : policyDetails.is_internal) && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsPoliciestab.cannotEditInternal') }) }))] }) })] })] }) }), jsx(ResourcePickerModal, { open: isResourcePickerOpen, onOpenChange: setIsResourcePickerOpen, tenant: tenant, onSelect: addPickedResource })] }));
143138
+ }), 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: t('tabsPoliciestab.cancel') }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("span", { tabIndex: 0, children: jsxs(Button$1, { onClick: onSubmit, disabled: (policyDetails === null || policyDetails === void 0 ? void 0 : policyDetails.is_internal) || isSaving, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", children: [isSaving ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin mr-2", "aria-hidden": "true" })) : null, editing
143139
+ ? t('tabsPoliciestab.savePolicy')
143140
+ : t('tabsPoliciestab.createPolicy')] }) }) }), editing && (policyDetails === null || policyDetails === void 0 ? void 0 : policyDetails.is_internal) && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsPoliciestab.cannotEditInternal') }) }))] }) })] })] }) }), jsx(ResourcePickerModal, { open: isResourcePickerOpen, onOpenChange: setIsResourcePickerOpen, tenant: tenant, onSelect: addPickedResource })] }));
143139
143141
  }
143140
143142
 
143141
143143
  const PAGE_SIZE$3 = 10;
@@ -177415,9 +177415,10 @@ function RolesTab({ tenant }) {
177415
177415
  pageSize: 10,
177416
177416
  ...(debouncedSearchQuery.length > 2 && { name: debouncedSearchQuery }),
177417
177417
  });
177418
- const [createRole] = useCreateRbacRoleMutation();
177419
- const [updateRole] = useUpdateRbacRoleMutation();
177418
+ const [createRole, { isLoading: isCreating }] = useCreateRbacRoleMutation();
177419
+ const [updateRole, { isLoading: isUpdating }] = useUpdateRbacRoleMutation();
177420
177420
  const [deleteRole] = useDeleteRbacRoleMutation();
177421
+ const isSaving = isCreating || isUpdating;
177421
177422
  // Debounce search query
177422
177423
  useEffect(() => {
177423
177424
  const handler = setTimeout(() => {
@@ -177555,7 +177556,7 @@ function RolesTab({ tenant }) {
177555
177556
  setDeletingRoleId(null);
177556
177557
  }
177557
177558
  }
177558
- return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex justify-between items-center gap-1 mb-6", children: [jsxs("div", { className: "relative max-w-sm", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: t('tabsRolestab.searchRolesPlaceholder'), "aria-label": t('tabsRolestab.searchRolesAriaLabel'), 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(Button$1, { onClick: openNew, "aria-label": t('tabsRolestab.newRoleAriaLabel'), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", children: t('tabsRolestab.newRoleButton') })] }), isLoading && (jsx("div", { className: "flex justify-center items-center h-64", children: jsx("div", { className: "py-8 text-center text-sm text-gray-500 dark:text-gray-400", children: t('tabsRolestab.loading') }) })), isError && (jsx("div", { className: "py-8 text-center text-sm text-red-500", children: t('tabsRolestab.failedToLoadRoles') })), !isLoading && !isError && (jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: t('tabsRolestab.nameHeader') }), jsx("th", { className: "px-6 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[100px]" })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [roles.map((r) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 text-gray-900 dark:text-gray-100 text-sm", children: r.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(r), disabled: deletingRoleId === r.id, "aria-label": t('tabsRolestab.editRoleAriaLabel', { name: r.name }), children: jsx(Pencil, { className: "h-4 w-4", "aria-hidden": "true" }) }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("span", { tabIndex: 0, children: jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => onDelete(r), className: "text-red-600 hover:text-red-700", disabled: deletingRoleId === r.id || r.is_internal, "aria-label": t('tabsRolestab.deleteRoleAriaLabel', { name: r.name }), children: deletingRoleId === r.id ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" })) : (jsx(Trash2, { className: "h-4 w-4", "aria-hidden": "true" })) }) }) }), r.is_internal && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsRolestab.cannotDeleteInternalRoles') }) }))] }) })] }) })] }, r.id))), roles.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 2, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: t('tabsRolestab.noRolesFound') }) }))] })] }) })), !isLoading && !isError && (jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (newPage) => handlePageChange(newPage), totalCount: data === null || data === void 0 ? void 0 : data.count, itemsPerPage: 10, itemLabel: "roles" })), 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: editing ? t('tabsRolestab.editRoleTitle') : t('tabsRolestab.newRoleTitle') }) }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { htmlFor: "r-name", children: t('tabsRolestab.roleNameLabel') }), jsx(Input, { id: "r-name", value: form.name, onChange: (e) => setForm({ ...form, name: e.target.value }), placeholder: t('tabsRolestab.enterRoleNamePlaceholder'), required: true })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { htmlFor: "r-actions", children: t('tabsRolestab.actionsLabel') }), jsxs("div", { className: "space-y-2", children: [actions.length > 0 && (jsx("div", { className: "flex flex-wrap gap-2 p-2 border border-gray-200 dark:border-gray-700 rounded-md bg-gray-50 dark:bg-gray-800", children: actions.map((action, index) => (jsxs(Badge, { variant: "secondary", className: "px-2 py-1 flex items-center gap-1 font-mono text-xs", children: [jsx("span", { children: action }), jsx("button", { type: "button", onClick: () => removeAction(action), className: "ml-1 hover:text-red-600", "aria-label": t('tabsRolestab.removeActionAriaLabel', { action }), children: jsx(X$2, { className: "h-3 w-3" }) })] }, index))) })), jsx(ActionsCombobox, { selected: actions, onSelect: addActionKey }), jsxs("div", { className: "flex gap-2", children: [jsx(Input, { id: "r-actions", value: actionInput, onChange: (e) => setActionInput(e.target.value), onKeyDown: handleActionKeyDown, placeholder: t('tabsRolestab.customActionPlaceholder'), className: "flex-1 font-mono text-sm" }), jsx(Button$1, { type: "button", variant: "outline", size: "sm", onClick: addAction, disabled: !actionInput.trim(), "aria-label": t('tabsRolestab.addActionAriaLabel'), children: jsx(Plus, { className: "h-4 w-4" }) })] }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('tabsRolestab.actionsHelpText') })] })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { htmlFor: "r-data-actions", children: t('tabsRolestab.dataActionsLabel') }), jsxs("div", { className: "space-y-2", children: [dataActions.length > 0 && (jsx("div", { className: "flex flex-wrap gap-2 p-2 border border-gray-200 dark:border-gray-700 rounded-md bg-gray-50 dark:bg-gray-800", children: dataActions.map((action, index) => (jsxs(Badge, { variant: "secondary", className: "px-2 py-1 flex items-center gap-1 font-mono text-xs", children: [jsx("span", { children: action }), jsx("button", { type: "button", onClick: () => removeDataAction(action), className: "ml-1 hover:text-red-600", "aria-label": t('tabsRolestab.removeDataActionAriaLabel', { action }), children: jsx(X$2, { className: "h-3 w-3" }) })] }, index))) })), jsxs("div", { className: "flex gap-2", children: [jsx(Input, { id: "r-data-actions", value: dataActionInput, onChange: (e) => setDataActionInput(e.target.value), onKeyDown: handleDataActionKeyDown, placeholder: t('tabsRolestab.dataActionPlaceholder'), className: "flex-1 font-mono text-sm" }), jsx(Button$1, { type: "button", variant: "outline", size: "sm", onClick: addDataAction, disabled: !dataActionInput.trim(), "aria-label": t('tabsRolestab.addDataActionAriaLabel'), children: jsx(Plus, { className: "h-4 w-4" }) })] }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('tabsRolestab.dataActionsHelpText') })] })] })] }), jsxs(DialogFooter, { className: "mt-6 gap-1.5", children: [jsx(Button$1, { variant: "outline", onClick: () => setIsOpen(false), children: t('tabsRolestab.cancel') }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("span", { tabIndex: 0, className: "", children: jsx(Button$1, { onClick: onSubmit, disabled: !!editing && (roleDetails === null || roleDetails === void 0 ? void 0 : roleDetails.is_internal), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white w-full", children: editing ? t('tabsRolestab.saveRole') : t('tabsRolestab.createRole') }) }) }), editing && (roleDetails === null || roleDetails === void 0 ? void 0 : roleDetails.is_internal) && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsRolestab.cannotEditInternalRoles') }) }))] }) })] })] }) })] }));
177559
+ return (jsxs("div", { className: "mt-4", children: [jsxs("div", { className: "flex justify-between items-center gap-1 mb-6", children: [jsxs("div", { className: "relative max-w-sm", children: [jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), jsx(Input, { value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: t('tabsRolestab.searchRolesPlaceholder'), "aria-label": t('tabsRolestab.searchRolesAriaLabel'), 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(Button$1, { onClick: openNew, "aria-label": t('tabsRolestab.newRoleAriaLabel'), className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white h-[35px]", children: t('tabsRolestab.newRoleButton') })] }), isLoading && (jsx("div", { className: "flex justify-center items-center h-64", children: jsx("div", { className: "py-8 text-center text-sm text-gray-500 dark:text-gray-400", children: t('tabsRolestab.loading') }) })), isError && (jsx("div", { className: "py-8 text-center text-sm text-red-500", children: t('tabsRolestab.failedToLoadRoles') })), !isLoading && !isError && (jsx("div", { className: "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-x-auto", children: jsxs("table", { className: "w-full text-sm", children: [jsx("thead", { className: "bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600", children: jsxs("tr", { children: [jsx("th", { className: "px-6 py-3 text-left font-medium text-gray-500 dark:text-gray-400", children: t('tabsRolestab.nameHeader') }), jsx("th", { className: "px-6 py-3 text-right font-medium text-gray-500 dark:text-gray-400 w-[100px]" })] }) }), jsxs("tbody", { className: "divide-y divide-gray-200 dark:divide-gray-600", children: [roles.map((r) => (jsxs("tr", { children: [jsx("td", { className: "px-6 py-4 text-gray-900 dark:text-gray-100 text-sm", children: r.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(r), disabled: deletingRoleId === r.id, "aria-label": t('tabsRolestab.editRoleAriaLabel', { name: r.name }), children: jsx(Pencil, { className: "h-4 w-4", "aria-hidden": "true" }) }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("span", { tabIndex: 0, children: jsx(Button$1, { variant: "ghost", size: "sm", onClick: () => onDelete(r), className: "text-red-600 hover:text-red-700", disabled: deletingRoleId === r.id || r.is_internal, "aria-label": t('tabsRolestab.deleteRoleAriaLabel', { name: r.name }), children: deletingRoleId === r.id ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin", "aria-hidden": "true" })) : (jsx(Trash2, { className: "h-4 w-4", "aria-hidden": "true" })) }) }) }), r.is_internal && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsRolestab.cannotDeleteInternalRoles') }) }))] }) })] }) })] }, r.id))), roles.length === 0 && (jsx("tr", { children: jsx("td", { colSpan: 2, className: "px-6 py-8 text-center text-gray-500 dark:text-gray-400", children: t('tabsRolestab.noRolesFound') }) }))] })] }) })), !isLoading && !isError && (jsx(AdvancedPagination, { variant: "footer", className: "-mx-6 -mb-6 mt-4 rounded-b-lg", totalPages: totalPages, currentPage: page, onPageChange: (newPage) => handlePageChange(newPage), totalCount: data === null || data === void 0 ? void 0 : data.count, itemsPerPage: 10, itemLabel: "roles" })), 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: editing ? t('tabsRolestab.editRoleTitle') : t('tabsRolestab.newRoleTitle') }) }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { htmlFor: "r-name", children: t('tabsRolestab.roleNameLabel') }), jsx(Input, { id: "r-name", value: form.name, onChange: (e) => setForm({ ...form, name: e.target.value }), placeholder: t('tabsRolestab.enterRoleNamePlaceholder'), required: true })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { htmlFor: "r-actions", children: t('tabsRolestab.actionsLabel') }), jsxs("div", { className: "space-y-2", children: [actions.length > 0 && (jsx("div", { className: "flex flex-wrap gap-2 p-2 border border-gray-200 dark:border-gray-700 rounded-md bg-gray-50 dark:bg-gray-800", children: actions.map((action, index) => (jsxs(Badge, { variant: "secondary", className: "px-2 py-1 flex items-center gap-1 font-mono text-xs", children: [jsx("span", { children: action }), jsx("button", { type: "button", onClick: () => removeAction(action), className: "ml-1 hover:text-red-600", "aria-label": t('tabsRolestab.removeActionAriaLabel', { action }), children: jsx(X$2, { className: "h-3 w-3" }) })] }, index))) })), jsx(ActionsCombobox, { selected: actions, onSelect: addActionKey }), jsxs("div", { className: "flex gap-2", children: [jsx(Input, { id: "r-actions", value: actionInput, onChange: (e) => setActionInput(e.target.value), onKeyDown: handleActionKeyDown, placeholder: t('tabsRolestab.customActionPlaceholder'), className: "flex-1 font-mono text-sm" }), jsx(Button$1, { type: "button", variant: "outline", size: "sm", onClick: addAction, disabled: !actionInput.trim(), "aria-label": t('tabsRolestab.addActionAriaLabel'), children: jsx(Plus, { className: "h-4 w-4" }) })] }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('tabsRolestab.actionsHelpText') })] })] }), jsxs("div", { className: "grid gap-1.5", children: [jsx(Label$1, { htmlFor: "r-data-actions", children: t('tabsRolestab.dataActionsLabel') }), jsxs("div", { className: "space-y-2", children: [dataActions.length > 0 && (jsx("div", { className: "flex flex-wrap gap-2 p-2 border border-gray-200 dark:border-gray-700 rounded-md bg-gray-50 dark:bg-gray-800", children: dataActions.map((action, index) => (jsxs(Badge, { variant: "secondary", className: "px-2 py-1 flex items-center gap-1 font-mono text-xs", children: [jsx("span", { children: action }), jsx("button", { type: "button", onClick: () => removeDataAction(action), className: "ml-1 hover:text-red-600", "aria-label": t('tabsRolestab.removeDataActionAriaLabel', { action }), children: jsx(X$2, { className: "h-3 w-3" }) })] }, index))) })), jsxs("div", { className: "flex gap-2", children: [jsx(Input, { id: "r-data-actions", value: dataActionInput, onChange: (e) => setDataActionInput(e.target.value), onKeyDown: handleDataActionKeyDown, placeholder: t('tabsRolestab.dataActionPlaceholder'), className: "flex-1 font-mono text-sm" }), jsx(Button$1, { type: "button", variant: "outline", size: "sm", onClick: addDataAction, disabled: !dataActionInput.trim(), "aria-label": t('tabsRolestab.addDataActionAriaLabel'), children: jsx(Plus, { className: "h-4 w-4" }) })] }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: t('tabsRolestab.dataActionsHelpText') })] })] })] }), jsxs(DialogFooter, { className: "mt-6 gap-1.5", children: [jsx(Button$1, { variant: "outline", onClick: () => setIsOpen(false), children: t('tabsRolestab.cancel') }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("span", { tabIndex: 0, className: "", children: jsxs(Button$1, { onClick: onSubmit, disabled: (!!editing && (roleDetails === null || roleDetails === void 0 ? void 0 : roleDetails.is_internal)) || isSaving, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white w-full", children: [isSaving ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin mr-2", "aria-hidden": "true" })) : null, editing ? t('tabsRolestab.saveRole') : t('tabsRolestab.createRole')] }) }) }), editing && (roleDetails === null || roleDetails === void 0 ? void 0 : roleDetails.is_internal) && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsRolestab.cannotEditInternalRoles') }) }))] }) })] })] }) })] }));
177559
177560
  }
177560
177561
 
177561
177562
  /**
@@ -177639,8 +177640,8 @@ function PoliciesTab({ tenant }) {
177639
177640
  pageSize: 10,
177640
177641
  ...(debouncedSearchQuery.length > 2 && { name: debouncedSearchQuery }),
177641
177642
  });
177642
- const [createPolicy] = useCreateRbacPolicyMutation();
177643
- const [updatePolicy] = useUpdateRbacPolicyMutation();
177643
+ const [createPolicy, { isLoading: isCreating }] = useCreateRbacPolicyMutation();
177644
+ const [updatePolicy, { isLoading: isUpdating }] = useUpdateRbacPolicyMutation();
177644
177645
  const [deletePolicy] = useDeleteRbacPolicyMutation();
177645
177646
  // Debounce search query
177646
177647
  useEffect(() => {
@@ -177680,6 +177681,7 @@ function PoliciesTab({ tenant }) {
177680
177681
  const [showGroupSearch, setShowGroupSearch] = useState(false);
177681
177682
  const [deletingPolicyId, setDeletingPolicyId] = useState(null);
177682
177683
  const [isResourcePickerOpen, setIsResourcePickerOpen] = useState(false);
177684
+ const isSaving = isCreating || isUpdating;
177683
177685
  const { currentData: policyDetails } = useGetRbacPolicyDetailsQuery({ id: editingPolicyId, platform_key: tenant }, { skip: !editingPolicyId });
177684
177686
  // Debounce role search and query the roles endpoint with the search term
177685
177687
  useEffect(() => {
@@ -177931,9 +177933,9 @@ function PoliciesTab({ tenant }) {
177931
177933
  }, onFocus: () => setShowGroupSearch(groupSearch.length > 0 || availableGroups.length > 0), placeholder: t('tabsPoliciestab.searchGroupsPlaceholder') }), showGroupSearch && availableGroups.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: availableGroups.map((group) => (jsx("button", { type: "button", onClick: () => addGroup({
177932
177934
  id: group.id,
177933
177935
  name: group.name,
177934
- }), 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: t('tabsPoliciestab.cancel') }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { 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
177935
- ? t('tabsPoliciestab.savePolicy')
177936
- : t('tabsPoliciestab.createPolicy') }) }) }), editing && (policyDetails === null || policyDetails === void 0 ? void 0 : policyDetails.is_internal) && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsPoliciestab.cannotEditInternal') }) }))] }) })] })] }) }), jsx(ResourcePickerModal, { open: isResourcePickerOpen, onOpenChange: setIsResourcePickerOpen, tenant: tenant, onSelect: addPickedResource })] }));
177936
+ }), 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: t('tabsPoliciestab.cancel') }), jsx(TooltipProvider, { children: jsxs(Tooltip$1, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx("span", { tabIndex: 0, children: jsxs(Button$1, { onClick: onSubmit, disabled: (policyDetails === null || policyDetails === void 0 ? void 0 : policyDetails.is_internal) || isSaving, className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", children: [isSaving ? (jsx(LoaderCircle, { className: "h-4 w-4 animate-spin mr-2", "aria-hidden": "true" })) : null, editing
177937
+ ? t('tabsPoliciestab.savePolicy')
177938
+ : t('tabsPoliciestab.createPolicy')] }) }) }), editing && (policyDetails === null || policyDetails === void 0 ? void 0 : policyDetails.is_internal) && (jsx(TooltipContent, { children: jsx("p", { children: t('tabsPoliciestab.cannotEditInternal') }) }))] }) })] })] }) }), jsx(ResourcePickerModal, { open: isResourcePickerOpen, onOpenChange: setIsResourcePickerOpen, tenant: tenant, onSelect: addPickedResource })] }));
177937
177939
  }
177938
177940
 
177939
177941
  const PAGE_SIZE$7 = 10;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iblai/iblai-js",
3
- "version": "1.26.7",
3
+ "version": "1.26.9",
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": {
@@ -66,9 +66,9 @@
66
66
  "axios": "1.13.6",
67
67
  "dotenv": "16.6.1",
68
68
  "winston": "3.19.0",
69
- "@iblai/data-layer": "1.9.5",
70
69
  "@iblai/mcp": "1.8.2",
71
- "@iblai/web-containers": "1.15.4",
70
+ "@iblai/web-containers": "1.15.5",
71
+ "@iblai/data-layer": "1.9.6",
72
72
  "@iblai/web-utils": "1.13.5"
73
73
  },
74
74
  "peerDependencies": {