Fix audit pages permission handling

Signed-off-by: Émile Ré <nemile.re@gmail.com>
This commit is contained in:
Émile Ré
2025-12-31 15:59:33 +01:00
committed by Bryan Frimin
parent a59e62782b
commit da3f9c0692
8 changed files with 206 additions and 50 deletions

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<b6236fab1ef470add01b9d9cc7527caa>> * @generated SignedSource<<5cef509d4e44e0e0064c79fc7c3bf2e3>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -28,6 +28,8 @@ export type AuditGraphCreateMutation$data = {
readonly createAudit: { readonly createAudit: {
readonly auditEdge: { readonly auditEdge: {
readonly node: { readonly node: {
readonly canDelete: boolean;
readonly canUpdate: boolean;
readonly createdAt: any; readonly createdAt: any;
readonly framework: { readonly framework: {
readonly id: string; readonly id: string;
@@ -160,6 +162,32 @@ v5 = {
"kind": "ScalarField", "kind": "ScalarField",
"name": "createdAt", "name": "createdAt",
"storageKey": null "storageKey": null
},
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:audit:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:audit:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:audit:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:audit:delete\")"
} }
], ],
"storageKey": null "storageKey": null
@@ -233,16 +261,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "04d44dfd419c2cde11b0138ca175203f", "cacheID": "d5155df01b8fe2fb74b49b953d49aed7",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "AuditGraphCreateMutation", "name": "AuditGraphCreateMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation AuditGraphCreateMutation(\n $input: CreateAuditInput!\n) {\n createAudit(input: $input) {\n auditEdge {\n node {\n id\n name\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\n }\n }\n }\n}\n" "text": "mutation AuditGraphCreateMutation(\n $input: CreateAuditInput!\n) {\n createAudit(input: $input) {\n auditEdge {\n node {\n id\n name\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\n canUpdate: permission(action: \"core:audit:update\")\n canDelete: permission(action: \"core:audit:delete\")\n }\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "4d014b16e02353df354085a151ccfe06"; (node as any).hash = "dcca4ebf33522ad6ef45456612fad03f";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<145565eb150c67f2f1b3c70fe6f6e748>> * @generated SignedSource<<a866ac360421f2cca952ab1305c3de0b>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -15,6 +15,7 @@ export type AuditGraphListQuery$variables = {
}; };
export type AuditGraphListQuery$data = { export type AuditGraphListQuery$data = {
readonly node: { readonly node: {
readonly canCreateAudit?: boolean;
readonly " $fragmentSpreads": FragmentRefs<"AuditsPageFragment">; readonly " $fragmentSpreads": FragmentRefs<"AuditsPageFragment">;
}; };
}; };
@@ -39,27 +40,40 @@ v1 = [
} }
], ],
v2 = { v2 = {
"alias": "canCreateAudit",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:audit:create"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:audit:create\")"
},
v3 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "__typename", "name": "__typename",
"storageKey": null "storageKey": null
}, },
v3 = { v4 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "id", "name": "id",
"storageKey": null "storageKey": null
}, },
v4 = [ v5 = [
{ {
"kind": "Literal", "kind": "Literal",
"name": "first", "name": "first",
"value": 10 "value": 10
} }
], ],
v5 = { v6 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
@@ -84,6 +98,7 @@ return {
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
(v2/*: any*/),
{ {
"args": null, "args": null,
"kind": "FragmentSpread", "kind": "FragmentSpread",
@@ -114,14 +129,15 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v2/*: any*/),
(v3/*: any*/), (v3/*: any*/),
(v4/*: any*/),
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
(v2/*: any*/),
{ {
"alias": null, "alias": null,
"args": (v4/*: any*/), "args": (v5/*: any*/),
"concreteType": "AuditConnection", "concreteType": "AuditConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "audits", "name": "audits",
@@ -143,8 +159,8 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/), (v4/*: any*/),
(v5/*: any*/), (v6/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -167,7 +183,7 @@ return {
"name": "report", "name": "report",
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/), (v4/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -193,8 +209,8 @@ return {
"name": "framework", "name": "framework",
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/), (v4/*: any*/),
(v5/*: any*/) (v6/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -205,7 +221,33 @@ return {
"name": "createdAt", "name": "createdAt",
"storageKey": null "storageKey": null
}, },
(v2/*: any*/) {
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:audit:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:audit:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:audit:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:audit:delete\")"
},
(v3/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -275,7 +317,7 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v4/*: any*/), "args": (v5/*: any*/),
"filters": [ "filters": [
"orderBy" "orderBy"
], ],
@@ -294,16 +336,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "d96d2332efb5f43e2dcb09669173ad7e", "cacheID": "441524ada7aa614fb611f3d64812314f",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "AuditGraphListQuery", "name": "AuditGraphListQuery",
"operationKind": "query", "operationKind": "query",
"text": "query AuditGraphListQuery(\n $organizationId: ID!\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n ...AuditsPageFragment\n }\n id\n }\n}\n\nfragment AuditsPageFragment on Organization {\n audits(first: 10) {\n edges {\n node {\n id\n name\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n" "text": "query AuditGraphListQuery(\n $organizationId: ID!\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n canCreateAudit: permission(action: \"core:audit:create\")\n ...AuditsPageFragment\n }\n id\n }\n}\n\nfragment AuditsPageFragment on Organization {\n audits(first: 10) {\n edges {\n node {\n id\n name\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\n canUpdate: permission(action: \"core:audit:update\")\n canDelete: permission(action: \"core:audit:delete\")\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
} }
}; };
})(); })();
(node as any).hash = "3a082303ae15c8982a08c3bae8312846"; (node as any).hash = "fc989e08b0d6411aac7ca6b1a0125edc";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<c802dc4c6e5b63e48b0050dfcf13b4b4>> * @generated SignedSource<<c8e8bf84dd8523199ec6e0d1eed7eb01>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -15,6 +15,8 @@ export type AuditGraphNodeQuery$variables = {
}; };
export type AuditGraphNodeQuery$data = { export type AuditGraphNodeQuery$data = {
readonly node: { readonly node: {
readonly canDelete?: boolean;
readonly canUpdate?: boolean;
readonly createdAt?: any; readonly createdAt?: any;
readonly framework?: { readonly framework?: {
readonly darkLogoURL: string | null | undefined; readonly darkLogoURL: string | null | undefined;
@@ -199,6 +201,32 @@ v12 = {
"kind": "ScalarField", "kind": "ScalarField",
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "storageKey": null
},
v13 = {
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:audit:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:audit:update\")"
},
v14 = {
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:audit:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:audit:delete\")"
}; };
return { return {
"fragment": { "fragment": {
@@ -228,7 +256,9 @@ return {
(v10/*: any*/), (v10/*: any*/),
(v11/*: any*/), (v11/*: any*/),
(v6/*: any*/), (v6/*: any*/),
(v12/*: any*/) (v12/*: any*/),
(v13/*: any*/),
(v14/*: any*/)
], ],
"type": "Audit", "type": "Audit",
"abstractKey": null "abstractKey": null
@@ -274,7 +304,9 @@ return {
(v10/*: any*/), (v10/*: any*/),
(v11/*: any*/), (v11/*: any*/),
(v6/*: any*/), (v6/*: any*/),
(v12/*: any*/) (v12/*: any*/),
(v13/*: any*/),
(v14/*: any*/)
], ],
"type": "Audit", "type": "Audit",
"abstractKey": null "abstractKey": null
@@ -285,16 +317,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "af5fde4e1522c98b908630fdf1451ae9", "cacheID": "c9d41c45b625f17ccf291ae2c027a027",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "AuditGraphNodeQuery", "name": "AuditGraphNodeQuery",
"operationKind": "query", "operationKind": "query",
"text": "query AuditGraphNodeQuery(\n $auditId: ID!\n) {\n node(id: $auditId) {\n __typename\n ... on Audit {\n id\n name\n validFrom\n validUntil\n report {\n id\n filename\n mimeType\n size\n downloadUrl\n createdAt\n }\n reportUrl\n state\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n organization {\n id\n name\n }\n createdAt\n updatedAt\n }\n id\n }\n}\n" "text": "query AuditGraphNodeQuery(\n $auditId: ID!\n) {\n node(id: $auditId) {\n __typename\n ... on Audit {\n id\n name\n validFrom\n validUntil\n report {\n id\n filename\n mimeType\n size\n downloadUrl\n createdAt\n }\n reportUrl\n state\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n organization {\n id\n name\n }\n createdAt\n updatedAt\n canUpdate: permission(action: \"core:audit:update\")\n canDelete: permission(action: \"core:audit:delete\")\n }\n id\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "db92119c6d6f000963a0ff3d0fb74dfd"; (node as any).hash = "3195b5564b2cf8a21536ebf89f0f5c82";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<0010416e8a5bda346d415bd80fd70dc8>> * @generated SignedSource<<36758d66ccb0304442a2a59898fe95a0>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -266,6 +266,32 @@ return {
"name": "createdAt", "name": "createdAt",
"storageKey": null "storageKey": null
}, },
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:audit:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:audit:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:audit:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:audit:delete\")"
},
(v8/*: any*/) (v8/*: any*/)
], ],
"storageKey": null "storageKey": null
@@ -355,16 +381,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "9d185e504f8c34d5c3fd7211d4e8a2a2", "cacheID": "7804de168f5c2484d6beb2f4d19287b0",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "AuditsListQuery", "name": "AuditsListQuery",
"operationKind": "query", "operationKind": "query",
"text": "query AuditsListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 10\n $last: Int = null\n $orderBy: AuditOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...AuditsPageFragment_sdb03\n id\n }\n}\n\nfragment AuditsPageFragment_sdb03 on Organization {\n audits(first: $first, after: $after, last: $last, before: $before, orderBy: $orderBy) {\n edges {\n node {\n id\n name\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n" "text": "query AuditsListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 10\n $last: Int = null\n $orderBy: AuditOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...AuditsPageFragment_sdb03\n id\n }\n}\n\nfragment AuditsPageFragment_sdb03 on Organization {\n audits(first: $first, after: $after, last: $last, before: $before, orderBy: $orderBy) {\n edges {\n node {\n id\n name\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\n canUpdate: permission(action: \"core:audit:update\")\n canDelete: permission(action: \"core:audit:delete\")\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
} }
}; };
})(); })();
(node as any).hash = "be8d1f1d8015c16539886bc79c8026f7"; (node as any).hash = "4013ec4e657ef7fb9d13afbd572ea9e5";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<8c09163f7cf7b3953aed77791b0d3dd1>> * @generated SignedSource<<075733c8694be657990e9fb8399c1ae6>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -16,6 +16,8 @@ export type AuditsPageFragment$data = {
readonly __id: string; readonly __id: string;
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
readonly node: { readonly node: {
readonly canDelete: boolean;
readonly canUpdate: boolean;
readonly createdAt: any; readonly createdAt: any;
readonly framework: { readonly framework: {
readonly id: string; readonly id: string;
@@ -215,6 +217,32 @@ return {
"name": "createdAt", "name": "createdAt",
"storageKey": null "storageKey": null
}, },
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:audit:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:audit:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:audit:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:audit:delete\")"
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -296,6 +324,6 @@ return {
}; };
})(); })();
(node as any).hash = "be8d1f1d8015c16539886bc79c8026f7"; (node as any).hash = "4013ec4e657ef7fb9d13afbd572ea9e5";
export default node; export default node;

View File

@@ -9,6 +9,7 @@ export const auditsQuery = graphql`
query AuditGraphListQuery($organizationId: ID!) { query AuditGraphListQuery($organizationId: ID!) {
node(id: $organizationId) { node(id: $organizationId) {
... on Organization { ... on Organization {
canCreateAudit: permission(action: "core:audit:create")
...AuditsPageFragment ...AuditsPageFragment
} }
} }
@@ -45,6 +46,8 @@ export const auditNodeQuery = graphql`
} }
createdAt createdAt
updatedAt updatedAt
canUpdate: permission(action: "core:audit:update")
canDelete: permission(action: "core:audit:delete")
} }
} }
} }
@@ -72,6 +75,8 @@ export const createAuditMutation = graphql`
name name
} }
createdAt createdAt
canUpdate: permission(action: "core:audit:update")
canDelete: permission(action: "core:audit:delete")
} }
} }
} }
@@ -115,7 +120,7 @@ export const deleteAuditMutation = graphql`
export const useDeleteAudit = ( export const useDeleteAudit = (
audit: { id: string; framework: { name: string } }, audit: { id: string; framework: { name: string } },
connectionId: string, connectionId: string,
onSuccess?: () => void onSuccess?: () => void,
) => { ) => {
const { __ } = useTranslate(); const { __ } = useTranslate();
const [mutate] = useMutationWithToasts(deleteAuditMutation, { const [mutate] = useMutationWithToasts(deleteAuditMutation, {
@@ -140,11 +145,11 @@ export const useDeleteAudit = (
{ {
message: sprintf( message: sprintf(
__( __(
"This will permanently delete the audit for %s. This action cannot be undone." "This will permanently delete the audit for %s. This action cannot be undone.",
), ),
audit.framework.name audit.framework.name,
), ),
} },
); );
}; };
}; };

View File

@@ -44,8 +44,6 @@ import {
type GraphQLError, type GraphQLError,
} from "@probo/helpers"; } from "@probo/helpers";
import type { AuditGraphNodeQuery } from "/__generated__/core/AuditGraphNodeQuery.graphql"; import type { AuditGraphNodeQuery } from "/__generated__/core/AuditGraphNodeQuery.graphql";
import { use } from "react";
import { PermissionsContext } from "/providers/PermissionsContext";
import { useNavigate } from "react-router"; import { useNavigate } from "react-router";
const updateAuditSchema = z.object({ const updateAuditSchema = z.object({
@@ -73,7 +71,6 @@ export default function AuditDetailsPage(props: Props) {
const auditEntry = audit.node; const auditEntry = audit.node;
const { __ } = useTranslate(); const { __ } = useTranslate();
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();
const { isAuthorized } = use(PermissionsContext);
const navigate = useNavigate(); const navigate = useNavigate();
const deleteAudit = useDeleteAudit( const deleteAudit = useDeleteAudit(
@@ -178,7 +175,7 @@ export default function AuditDetailsPage(props: Props) {
</Badge> </Badge>
</div> </div>
<ActionDropdown variant="secondary"> <ActionDropdown variant="secondary">
{isAuthorized("Audit", "deleteAudit") && ( {auditEntry.canDelete && (
<DropdownItem <DropdownItem
variant="danger" variant="danger"
icon={IconTrashCan} icon={IconTrashCan}
@@ -218,7 +215,7 @@ export default function AuditDetailsPage(props: Props) {
</Field> </Field>
<div className="flex justify-end"> <div className="flex justify-end">
{formState.isDirty && isAuthorized("Audit", "updateAudit") && ( {formState.isDirty && auditEntry.canUpdate && (
<Button type="submit" disabled={formState.isSubmitting}> <Button type="submit" disabled={formState.isSubmitting}>
{formState.isSubmitting ? __("Updating...") : __("Update")} {formState.isSubmitting ? __("Updating...") : __("Update")}
</Button> </Button>

View File

@@ -35,8 +35,6 @@ import type {
AuditsPageFragment$key, AuditsPageFragment$key,
} from "/__generated__/core/AuditsPageFragment.graphql"; } from "/__generated__/core/AuditsPageFragment.graphql";
import { SortableTable } from "/components/SortableTable"; import { SortableTable } from "/components/SortableTable";
import { PermissionsContext } from "/providers/PermissionsContext";
import { use } from "react";
const paginatedAuditsFragment = graphql` const paginatedAuditsFragment = graphql`
fragment AuditsPageFragment on Organization fragment AuditsPageFragment on Organization
@@ -72,6 +70,8 @@ const paginatedAuditsFragment = graphql`
name name
} }
createdAt createdAt
canUpdate: permission(action: "core:audit:update")
canDelete: permission(action: "core:audit:delete")
} }
} }
} }
@@ -87,7 +87,6 @@ type Props = {
export default function AuditsPage(props: Props) { export default function AuditsPage(props: Props) {
const { __ } = useTranslate(); const { __ } = useTranslate();
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();
const { isAuthorized } = use(PermissionsContext);
const data = usePreloadedQuery(auditsQuery, props.queryRef); const data = usePreloadedQuery(auditsQuery, props.queryRef);
const pagination = usePaginationFragment( const pagination = usePaginationFragment(
@@ -99,9 +98,9 @@ export default function AuditsPage(props: Props) {
usePageTitle(__("Audits")); usePageTitle(__("Audits"));
const hasAnyAction = const hasAnyAction = audits.some(
isAuthorized("Audit", "updateAudit") || (audit) => audit.canDelete || audit.canUpdate,
isAuthorized("Audit", "deleteAudit"); );
return ( return (
<div className="space-y-6"> <div className="space-y-6">
@@ -111,7 +110,7 @@ export default function AuditsPage(props: Props) {
"Manage your organization's compliance audits and their progress.", "Manage your organization's compliance audits and their progress.",
)} )}
> >
{isAuthorized("Organization", "createAudit") && ( {data.node.canCreateAudit && (
<CreateAuditDialog <CreateAuditDialog
connection={connectionId} connection={connectionId}
organizationId={organizationId} organizationId={organizationId}
@@ -159,7 +158,6 @@ function AuditRow({
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();
const { __ } = useTranslate(); const { __ } = useTranslate();
const deleteAudit = useDeleteAudit(entry, connectionId); const deleteAudit = useDeleteAudit(entry, connectionId);
const { isAuthorized } = use(PermissionsContext);
return ( return (
<Tr to={`/organizations/${organizationId}/audits/${entry.id}`}> <Tr to={`/organizations/${organizationId}/audits/${entry.id}`}>
@@ -184,7 +182,7 @@ function AuditRow({
{hasAnyAction && ( {hasAnyAction && (
<Td noLink width={50} className="text-end"> <Td noLink width={50} className="text-end">
<ActionDropdown> <ActionDropdown>
{isAuthorized("Audit", "deleteAudit") && ( {entry.canDelete && (
<DropdownItem <DropdownItem
onClick={deleteAudit} onClick={deleteAudit}
variant="danger" variant="danger"