feat: Playbook permissions Inbound & Outbound#2974
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughAdds inbound/outbound playbook permission queries, introduces PermissionResourceCell and table/view changes, a PlaybookPermissionsModal with tabbed permission views and cache invalidation, connection lookup enhancements, multiple UI spacing/style tweaks, and refactors the confirmation dialog/modal implementation. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as PlaybookPermissionsModal (UI)
participant Q as React Query
participant API as permissions service (fetchPermissions)
participant Server as Backend (permissions endpoints)
UI->>Q: open modal / switch tab (inbound/outbound)
Q->>API: fetchPermissions(input with direction/playbookName or subject)
API->>Server: GET /rpc/permissions_for_obj_selector (inbound w/playbookName) or /permissions_summary (others)
Server-->>API: permissions payload
API-->>Q: resolve permissions data
Q-->>UI: render PermissionsView -> PermissionsTable -> PermissionResourceCell
Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
84c9005 to
e461b5d
Compare
d97854a to
dd57355
Compare
dd57355 to
d2579cb
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/ui/AlertDialog/ConfirmationPromptDialog.tsx (1)
14-26:⚠️ Potential issue | 🟠 MajorPreserve the dialog pass-through props.
This exported prop type no longer forwards the underlying
Dialogprops, which unexpectedly narrows bothConfirmationPromptDialogandsrc/ui/Buttons/DeleteButton.tsx, where the remaining props are still forwarded into this component. That is a breaking API change unrelated to the markup refactor.Suggested change
-export type ConfirmationPromptDialogProps = { +export type ConfirmationPromptDialogProps = Omit< + React.ComponentProps<typeof Dialog>, + "open" | "onOpenChange" | "className" +> & { isOpen: boolean; title: string; description: React.ReactNode; onClose: () => void; onConfirm: () => void; @@ isLoading?: boolean; confirmationStyle?: "delete" | "approve"; error?: unknown; className?: string; }; @@ export function ConfirmationPromptDialog({ title, confirmationStyle = "delete", description, isOpen, @@ closeLabel = "Cancel", isLoading = false, error, - className + className, + ...dialogProps }: ConfirmationPromptDialogProps) { return ( <Dialog + {...dialogProps} open={isOpen} onOpenChange={(open) => { if (!open) { onClose(); }Also applies to: 28-50
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/ui/AlertDialog/ConfirmationPromptDialog.tsx` around lines 14 - 26, The exported ConfirmationPromptDialogProps type no longer forwards the underlying Dialog props which breaks callers that spread extra props (e.g., DeleteButton forwarding into ConfirmationPromptDialog); fix by extending the Dialog's prop type (e.g., make ConfirmationPromptDialogProps extend React.ComponentProps<typeof Dialog> or DialogProps) so all pass-through props are preserved, update the ConfirmationPromptDialog component signature to use the extended type and ensure any explicit prop names remain listed as overrides/optional.src/components/Playbooks/Settings/PlaybookSpecCard.tsx (1)
56-69:⚠️ Potential issue | 🟠 MajorDisable repeated deletes while the mutation is running.
The confirmation dialog at line 152-160 does not receive a loading state from the
deletePlaybookmutation. This leaves the confirm button fully clickable during the deletion request, allowing double clicks to trigger multiple delete operations and produce conflicting error toasts.The
useMutationhook at line 56 only destructuresmutate, but@tanstack/react-queryv4 provides anisLoadingstate that must be threaded to the dialog'sisLoadingprop (supported byConfirmationPromptDialogat line 22 of the component definition).Update the mutation destructuring to include the loading flag and pass it to the dialog:
Suggested fix
- const { mutate: deletePlaybook } = useMutation({ + const { mutate: deletePlaybook, isLoading: isDeleting } = useMutation({ mutationFn: async (id: string) => { const res = await deletePlaybookSpec(id); return res; }, onSuccess: () => { toastSuccess("Playbook Spec deleted successfully"); setIsDeleteConfirmOpen(false); refetch(); }, onError: (err: Error) => { toastError("Unable to delete playbook spec: " + err.message); } });<ConfirmationPromptDialog isOpen={isDeleteConfirmOpen} title="Delete Playbook" description={`Are you sure you want to delete ${playbook.title || playbook.name}?`} onClose={() => setIsDeleteConfirmOpen(false)} onConfirm={() => deletePlaybook(playbook.id)} confirmationStyle="delete" + isLoading={isDeleting} - yesLabel="Delete" + yesLabel={isDeleting ? "Deleting..." : "Delete"} />Also applies to: 152-160
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Playbooks/Settings/PlaybookSpecCard.tsx` around lines 56 - 69, The delete mutation currently only destructures mutate from useMutation, so the ConfirmationPromptDialog never receives the mutation loading state and the confirm button remains clickable; change the hook destructuring to pull out isLoading (e.g. const { mutate: deletePlaybook, isLoading: isDeleting } = useMutation(...)), then pass that flag into the ConfirmationPromptDialog's isLoading prop where the dialog is rendered (so the confirm button is disabled while deletePlaybookSpec runs) and keep existing onSuccess/onError behavior (toastSuccess, toastError, setIsDeleteConfirmOpen, refetch).
🧹 Nitpick comments (1)
src/components/Playbooks/Settings/PlaybookCardMenu.tsx (1)
10-18: Don't show a deadPermissionsaction.
onManagePermissionsis optional, but the menu row is always rendered and defaults to a no-op. If any caller omits that callback, users get a clickable item that does nothing.Suggested change
type PlaybookCardMenuDropdownProps = { onDeletePlaybook?: () => void; onEditPlaybook?: () => void; onManagePermissions?: () => void; onHistory?: () => void; }; export default function PlaybookCardMenuDropdown({ onDeletePlaybook = () => {}, onEditPlaybook = () => {}, - onManagePermissions = () => {} + onManagePermissions }: PlaybookCardMenuDropdownProps) { return ( <Menu> @@ - <MenuItem - as="div" - className="flex w-full cursor-pointer items-center gap-2 px-3 py-1.5 text-sm leading-5 text-gray-700 hover:bg-gray-200" - onClick={() => { - onManagePermissions(); - }} - > - <> - <MdSecurity - className="border-l-1 border-0 border-gray-200 text-gray-600" - size={16} - /> - <span>Permissions</span> - </> - </MenuItem> + {onManagePermissions ? ( + <MenuItem + as="div" + className="flex w-full cursor-pointer items-center gap-2 px-3 py-1.5 text-sm leading-5 text-gray-700 hover:bg-gray-200" + onClick={onManagePermissions} + > + <> + <MdSecurity + className="border-l-1 border-0 border-gray-200 text-gray-600" + size={16} + /> + <span>Permissions</span> + </> + </MenuItem> + ) : null}Also applies to: 55-69
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Playbooks/Settings/PlaybookCardMenu.tsx` around lines 10 - 18, The Permissions menu item is always rendered with a no-op when onManagePermissions is omitted, producing a dead clickable row; update PlaybookCardMenuDropdown to only render the Permissions menu entry when the onManagePermissions prop is provided (i.e., check if onManagePermissions !== undefined before rendering the menu row and its Click handler), and apply the same conditional rendering pattern for other optional callbacks such as onHistory so no menu item appears unless its handler is passed in.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/api/services/permissions.ts`:
- Around line 57-59: The current branch incorrectly maps playbookId into the
subject filter (using subject and subject_type), which breaks direct playbook_id
queries; in the block that checks if (playbookId && !subject) update the filters
to push a playbook_id equality filter (e.g., playbook_id=eq.${playbookId})
instead of subject/subject_type, leaving the existing subject-based path
unchanged so outbound callers that provide subject/subject_type still work and
RPC inbound flow continues to bypass this branch.
In `@src/components/Permissions/PermissionResourceCell.tsx`:
- Around line 191-202: The current early return in PermissionResourceCell when
PermissionsSummary.object is truthy causes every concrete resource to be treated
as generic text and can yield blank labels because
permissionObjectList.find(...) may return undefined; update
PermissionResourceCell to first check for and render the concrete-object case
(the renderer that shows links/icons for actual resources) before falling back
to a safe label lookup, and replace use of permissionObjectList.find(...) with
an explicit label map keyed by PermissionGlobalObject (e.g., a const
OBJECT_LABELS: Record<PermissionGlobalObject, string>) to guarantee a fallback
label for values like "playbook" and "component"; ensure PermissionErrorDisplay
is still rendered and remove the early return so the detailed renderer (the
block currently after the return) can execute when appropriate.
In `@src/components/ui/card.tsx`:
- Line 12: The Card primitive has been modified with project-specific classes
("rounded-sm border bg-card p-1 text-card-foreground"); revert the Card
component back to the upstream/default class names (remove those
spacing/radius/padding overrides) and instead create or update a wrapper
component (e.g., PermissionCard) that composes Card and applies the desired
"rounded-sm", "border", "p-1", etc. Move all variant/custom classes currently
added in Card (also present at the other modified spots) into that wrapper so
the original Card primitive stays upstream-consistent.
- Line 12: The Card component's root class list currently includes a global
padding "p-1" which causes unintended spacing regressions; remove "p-1" from the
root class string/array in the Card component (the exported Card element in
src/components/ui/card.tsx) so the container does not inject default padding,
leaving padding to be applied by consumers that need it.
In `@src/ui/AlertDialog/ConfirmationPromptDialog.tsx`:
- Around line 111-126: The confirm button currently still invokes onConfirm
while isLoading is true; update the ConfirmationPromptDialog confirm button (the
element with data-testid={`confirm-button-${yesLabel}`} and the
onClick={onConfirm}) to prevent duplicate confirms by disabling it when
isLoading: add the disabled attribute (disabled={isLoading}) and/or guard the
onClick handler so it no-ops when isLoading is true, and ensure styling reflects
disabled state (e.g., keep clsx logic but include a disabled class or rely on
native disabled) so rapid clicks cannot trigger duplicate mutations.
---
Outside diff comments:
In `@src/components/Playbooks/Settings/PlaybookSpecCard.tsx`:
- Around line 56-69: The delete mutation currently only destructures mutate from
useMutation, so the ConfirmationPromptDialog never receives the mutation loading
state and the confirm button remains clickable; change the hook destructuring to
pull out isLoading (e.g. const { mutate: deletePlaybook, isLoading: isDeleting }
= useMutation(...)), then pass that flag into the ConfirmationPromptDialog's
isLoading prop where the dialog is rendered (so the confirm button is disabled
while deletePlaybookSpec runs) and keep existing onSuccess/onError behavior
(toastSuccess, toastError, setIsDeleteConfirmOpen, refetch).
In `@src/ui/AlertDialog/ConfirmationPromptDialog.tsx`:
- Around line 14-26: The exported ConfirmationPromptDialogProps type no longer
forwards the underlying Dialog props which breaks callers that spread extra
props (e.g., DeleteButton forwarding into ConfirmationPromptDialog); fix by
extending the Dialog's prop type (e.g., make ConfirmationPromptDialogProps
extend React.ComponentProps<typeof Dialog> or DialogProps) so all pass-through
props are preserved, update the ConfirmationPromptDialog component signature to
use the extended type and ensure any explicit prop names remain listed as
overrides/optional.
---
Nitpick comments:
In `@src/components/Playbooks/Settings/PlaybookCardMenu.tsx`:
- Around line 10-18: The Permissions menu item is always rendered with a no-op
when onManagePermissions is omitted, producing a dead clickable row; update
PlaybookCardMenuDropdown to only render the Permissions menu entry when the
onManagePermissions prop is provided (i.e., check if onManagePermissions !==
undefined before rendering the menu row and its Click handler), and apply the
same conditional rendering pattern for other optional callbacks such as
onHistory so no menu item appears unless its handler is passed in.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7fb96171-ad6e-43c9-9309-c1e52ffc8c90
📒 Files selected for processing (21)
AGENTS.mdsrc/api/services/permissions.tssrc/components/Connections/ConnectionForm.tsxsrc/components/Connections/ConnectionFormModal.tsxsrc/components/Permissions/PermissionResourceCell.tsxsrc/components/Permissions/PermissionsTable.tsxsrc/components/Permissions/PermissionsView.tsxsrc/components/Playbooks/Runs/ApprovePlaybookRunModal.tsxsrc/components/Playbooks/Runs/CancelPlaybookRunModal.tsxsrc/components/Playbooks/Settings/PlaybookCardMenu.tsxsrc/components/Playbooks/Settings/PlaybookPermissionsModal.tsxsrc/components/Playbooks/Settings/PlaybookSpecCard.tsxsrc/components/Playbooks/Settings/PlaybookSpecFormModal.tsxsrc/components/Playbooks/Settings/PlaybookSpecsList.tsxsrc/components/Users/UserList.tsxsrc/components/ui/card.tsxsrc/pages/audit-report/components/View/ViewTableFilterForm.tsxsrc/pages/playbooks/PlaybooksList.tsxsrc/ui/AlertDialog/ConfirmationPromptDialog.tsxsrc/ui/Menu/index.tsxsrc/ui/Tabs/FlatTabs.tsx
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
src/components/Permissions/PermissionResourceCell.tsx (1)
190-201:⚠️ Potential issue | 🟡 MinorMissing fallback when
permissionObjectList.find()returns undefined.If
permission.objecthas a value not present inpermissionObjectList(e.g., a new permission type), the.find()returnsundefinedand the cell renders an empty<span>. Consider providing a fallback to display the rawobjectvalue.Proposed fix
<span> - {permissionObjectList.find((o) => o.value === object)?.label} + {permissionObjectList.find((o) => o.value === object)?.label ?? + object} </span>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Permissions/PermissionResourceCell.tsx` around lines 190 - 201, The cell currently calls permissionObjectList.find((o) => o.value === object)?.label which can be undefined; update the rendering in PermissionResourceCell (the branch where object is truthy) to fall back to the raw object value when find returns undefined by using the found label if present otherwise the object string (e.g., compute a displayName from permissionObjectList.find(...) and render displayName || object) so the span never renders empty; keep PermissionErrorDisplay as-is.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/api/services/connections.ts`:
- Around line 19-34: The query-building in getConnectionByNamespaceName
interpolates raw user input into filters causing malformed queries; update the
filter construction to URL-encode name and namespace (e.g., via
encodeURIComponent) before embedding them into the filter strings (or build the
whole query with URLSearchParams) so the final call to IncidentCommander.get
uses encoded values for `name` and `namespace`; ensure you apply encoding to
both the `name` parameter and the optional `namespace` when pushing into
`filters` and keep the existing select portion unchanged.
In `@src/components/Connections/ConnectionLink.tsx`:
- Around line 58-60: The branch in ConnectionLink that returns <ConnectionIcon
showLabel connection={connectionData} /> when connectionData.id is falsy
violates ConnectionIcon's prop requirement (it expects connection:
Pick<Connection, "type" | "name" | "id">). Fix by either (A) changing
ConnectionLink to render a safe fallback when id is missing (e.g., render the
connection name/type text or a simple label instead of using ConnectionIcon) by
checking connectionData.id before passing to ConnectionIcon, or (B) update
ConnectionIcon's props to accept an optional id (make id?: string in its
connection prop and handle missing id inside ConnectionIcon). Reference the
ConnectionLink component branch that returns ConnectionIcon and the
ConnectionIcon component type signature to locate the code.
---
Duplicate comments:
In `@src/components/Permissions/PermissionResourceCell.tsx`:
- Around line 190-201: The cell currently calls permissionObjectList.find((o) =>
o.value === object)?.label which can be undefined; update the rendering in
PermissionResourceCell (the branch where object is truthy) to fall back to the
raw object value when find returns undefined by using the found label if present
otherwise the object string (e.g., compute a displayName from
permissionObjectList.find(...) and render displayName || object) so the span
never renders empty; keep PermissionErrorDisplay as-is.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 803a27d1-214e-4405-8baf-cc51eea8c3e7
📒 Files selected for processing (3)
src/api/services/connections.tssrc/components/Connections/ConnectionLink.tsxsrc/components/Permissions/PermissionResourceCell.tsx
ae2f3ee to
f104fed
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/Connections/ConnectionLink.tsx (1)
45-49:⚠️ Potential issue | 🟠 MajorGuard the loader by fetch intent to avoid a stuck skeleton.
When the query is disabled by the condition at line 45, React Query v4 reports
isLoading=truewithout cache (status is 'loading' butisFetching=false). This causes line 48-49 to return<TextSkeletonLoader />indefinitely, skipping the data rendering at line 52.Use
isInitialLoadinginstead ofisLoadingand guard with the fetch condition to show the loader only during active fetches:Proposed fix
export default function ConnectionLink({ connection, connectionId, connectionName, connectionNamespace }: ConnectionLinkProps) { + const shouldFetchConnection = + connection === undefined && (!!connectionId || !!connectionName); + - const { isLoading, data } = useQuery({ + const { isInitialLoading, data } = useQuery({ queryKey: [ "connections", connectionId, connectionName, connectionNamespace ], queryFn: () => { if (connectionId) { return getConnectionByID(connectionId); } if (connectionName) { return getConnectionByNamespaceName( connectionName, connectionNamespace ); } return Promise.resolve(null); }, - enabled: connection === undefined && (!!connectionId || !!connectionName) + enabled: shouldFetchConnection }); - if (isLoading) { + if (shouldFetchConnection && isInitialLoading) { return <TextSkeletonLoader />; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Connections/ConnectionLink.tsx` around lines 45 - 49, The loader is shown even when the query is disabled because React Query's isLoading can be true for disabled queries; update the ConnectionLink component to use isInitialLoading instead of isLoading and also check the query-enabled condition (the same expression used for the query's enabled option: enabled: connection === undefined && (!!connectionId || !!connectionName)) so the TextSkeletonLoader is returned only when the fetch is actively starting; locate the query hook and replace the isLoading guard with a combined check like "queryEnabled && isInitialLoading" referencing the query's enabled condition and the isInitialLoading variable.
🧹 Nitpick comments (1)
src/components/Playbooks/Settings/PlaybookCardMenu.tsx (1)
29-54: Minor styling inconsistency between menu items.The Edit item uses
IconButtonwrapper withmr-2for spacing, while Permissions and Delete items usegap-2on the parentMenuItem. Consider aligning the approach for consistency.♻️ Option to align Edit item with other items
<MenuItem as="div" - className="flex w-full cursor-pointer items-center px-3 py-1.5 text-sm leading-5 text-gray-700 hover:bg-gray-200" + className="flex w-full cursor-pointer items-center gap-2 px-3 py-1.5 text-sm leading-5 text-gray-700 hover:bg-gray-200" onClick={() => { onEditPlaybook(); }} > <> - <IconButton - className="z-5 mr-2 bg-transparent group-hover:inline-block" - ovalProps={{ - stroke: "blue", - height: "18px", - width: "18px", - fill: "transparent" - }} - icon={ - <MdEdit - className="border-l-1 border-0 border-gray-200 text-gray-600" - size={16} - /> - } - /> + <MdEdit + className="border-l-1 border-0 border-gray-200 text-gray-600" + size={16} + /> <span>Edit</span> </> </MenuItem>Also applies to: 55-69, 70-84
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/Playbooks/Settings/PlaybookCardMenu.tsx` around lines 29 - 54, The Edit menu item's spacing differs from the other items: it uses an IconButton with className "mr-2" while the Permissions and Delete MenuItem entries use "gap-2" on the parent. Update the Edit MenuItem (the JSX block containing MenuItem, IconButton and onEditPlaybook) to match the others by removing the IconButton's "mr-2" spacing and applying "gap-2" to the MenuItem container (or vice-versa across all menu items)—ensure spacing is consistent across MenuItem instances for Edit, Permissions and Delete.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@src/components/Connections/ConnectionLink.tsx`:
- Around line 45-49: The loader is shown even when the query is disabled because
React Query's isLoading can be true for disabled queries; update the
ConnectionLink component to use isInitialLoading instead of isLoading and also
check the query-enabled condition (the same expression used for the query's
enabled option: enabled: connection === undefined && (!!connectionId ||
!!connectionName)) so the TextSkeletonLoader is returned only when the fetch is
actively starting; locate the query hook and replace the isLoading guard with a
combined check like "queryEnabled && isInitialLoading" referencing the query's
enabled condition and the isInitialLoading variable.
---
Nitpick comments:
In `@src/components/Playbooks/Settings/PlaybookCardMenu.tsx`:
- Around line 29-54: The Edit menu item's spacing differs from the other items:
it uses an IconButton with className "mr-2" while the Permissions and Delete
MenuItem entries use "gap-2" on the parent. Update the Edit MenuItem (the JSX
block containing MenuItem, IconButton and onEditPlaybook) to match the others by
removing the IconButton's "mr-2" spacing and applying "gap-2" to the MenuItem
container (or vice-versa across all menu items)—ensure spacing is consistent
across MenuItem instances for Edit, Permissions and Delete.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 832d72e8-da6b-441e-98fa-5463e1b047fc
📒 Files selected for processing (23)
AGENTS.mdsrc/api/services/connections.tssrc/api/services/permissions.tssrc/components/Connections/ConnectionForm.tsxsrc/components/Connections/ConnectionFormModal.tsxsrc/components/Connections/ConnectionLink.tsxsrc/components/Permissions/PermissionResourceCell.tsxsrc/components/Permissions/PermissionsTable.tsxsrc/components/Permissions/PermissionsView.tsxsrc/components/Playbooks/Runs/ApprovePlaybookRunModal.tsxsrc/components/Playbooks/Runs/CancelPlaybookRunModal.tsxsrc/components/Playbooks/Settings/PlaybookCardMenu.tsxsrc/components/Playbooks/Settings/PlaybookPermissionsModal.tsxsrc/components/Playbooks/Settings/PlaybookSpecCard.tsxsrc/components/Playbooks/Settings/PlaybookSpecFormModal.tsxsrc/components/Playbooks/Settings/PlaybookSpecsList.tsxsrc/components/Users/UserList.tsxsrc/components/ui/card.tsxsrc/pages/audit-report/components/View/ViewTableFilterForm.tsxsrc/pages/playbooks/PlaybooksList.tsxsrc/ui/AlertDialog/ConfirmationPromptDialog.tsxsrc/ui/Menu/index.tsxsrc/ui/Tabs/FlatTabs.tsx
✅ Files skipped from review due to trivial changes (9)
- AGENTS.md
- src/pages/playbooks/PlaybooksList.tsx
- src/components/Connections/ConnectionForm.tsx
- src/components/Playbooks/Settings/PlaybookSpecsList.tsx
- src/components/ui/card.tsx
- src/pages/audit-report/components/View/ViewTableFilterForm.tsx
- src/components/Users/UserList.tsx
- src/ui/Menu/index.tsx
- src/components/Playbooks/Settings/PlaybookSpecCard.tsx
🚧 Files skipped from review as they are similar to previous changes (11)
- src/components/Playbooks/Runs/ApprovePlaybookRunModal.tsx
- src/components/Playbooks/Runs/CancelPlaybookRunModal.tsx
- src/components/Connections/ConnectionFormModal.tsx
- src/api/services/connections.ts
- src/components/Playbooks/Settings/PlaybookSpecFormModal.tsx
- src/api/services/permissions.ts
- src/ui/Tabs/FlatTabs.tsx
- src/components/Permissions/PermissionsTable.tsx
- src/components/Permissions/PermissionsView.tsx
- src/components/Playbooks/Settings/PlaybookPermissionsModal.tsx
- src/components/Permissions/PermissionResourceCell.tsx
Summary by CodeRabbit
New Features
Improvements
Documentation
Style