diff --git a/apps/console/src/__generated__/core/AssetGraphCreateMutation.graphql.ts b/apps/console/src/__generated__/core/AssetGraphCreateMutation.graphql.ts index 3729134a9..ab5eaba0d 100644 --- a/apps/console/src/__generated__/core/AssetGraphCreateMutation.graphql.ts +++ b/apps/console/src/__generated__/core/AssetGraphCreateMutation.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<9ebcbef6d786f85d0b88c881d1478938>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -29,6 +29,8 @@ export type AssetGraphCreateMutation$data = { readonly node: { readonly amount: number; readonly assetType: AssetType; + readonly canDelete: boolean; + readonly canUpdate: boolean; readonly createdAt: any; readonly dataTypesStored: string; readonly id: string; @@ -207,6 +209,32 @@ v5 = { "kind": "ScalarField", "name": "createdAt", "storageKey": null + }, + { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:asset:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:asset:update\")" + }, + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:asset:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:asset:delete\")" } ], "storageKey": null @@ -280,16 +308,16 @@ return { ] }, "params": { - "cacheID": "bc22942b9b4b5efb63a0167c083823fc", + "cacheID": "6e077b7787ccbc473247d102b0540e98", "id": null, "metadata": {}, "name": "AssetGraphCreateMutation", "operationKind": "mutation", - "text": "mutation AssetGraphCreateMutation(\n $input: CreateAssetInput!\n) {\n createAsset(input: $input) {\n assetEdge {\n node {\n id\n snapshotId\n name\n amount\n assetType\n dataTypesStored\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\n }\n createdAt\n }\n }\n }\n}\n" + "text": "mutation AssetGraphCreateMutation(\n $input: CreateAssetInput!\n) {\n createAsset(input: $input) {\n assetEdge {\n node {\n id\n snapshotId\n name\n amount\n assetType\n dataTypesStored\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\n }\n createdAt\n canUpdate: permission(action: \"core:asset:update\")\n canDelete: permission(action: \"core:asset:delete\")\n }\n }\n }\n}\n" } }; })(); -(node as any).hash = "92fca40d88a9ea68f013e9953d46388e"; +(node as any).hash = "f337be2dfc0f146f33e1b94f65cfc199"; export default node; diff --git a/apps/console/src/__generated__/core/AssetGraphListQuery.graphql.ts b/apps/console/src/__generated__/core/AssetGraphListQuery.graphql.ts index 83a9a6a17..bd73f9466 100644 --- a/apps/console/src/__generated__/core/AssetGraphListQuery.graphql.ts +++ b/apps/console/src/__generated__/core/AssetGraphListQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -16,6 +16,7 @@ export type AssetGraphListQuery$variables = { }; export type AssetGraphListQuery$data = { readonly node: { + readonly canCreateAsset?: boolean; readonly " $fragmentSpreads": FragmentRefs<"AssetsPageFragment">; }; }; @@ -44,30 +45,43 @@ v1 = [ "variableName": "organizationId" } ], -v2 = [ +v2 = { + "alias": "canCreateAsset", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:asset:create" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:asset:create\")" +}, +v3 = [ { "kind": "Variable", "name": "snapshotId", "variableName": "snapshotId" } ], -v3 = { +v4 = { "alias": null, "args": null, "kind": "ScalarField", "name": "__typename", "storageKey": null }, -v4 = { +v5 = { "alias": null, "args": null, "kind": "ScalarField", "name": "id", "storageKey": null }, -v5 = [ +v6 = [ { - "fields": (v2/*: any*/), + "fields": (v3/*: any*/), "kind": "ObjectValue", "name": "filter" }, @@ -77,7 +91,7 @@ v5 = [ "value": 10 } ], -v6 = { +v7 = { "alias": null, "args": null, "kind": "ScalarField", @@ -102,8 +116,9 @@ return { { "kind": "InlineFragment", "selections": [ + (v2/*: any*/), { - "args": (v2/*: any*/), + "args": (v3/*: any*/), "kind": "FragmentSpread", "name": "AssetsPageFragment" } @@ -132,14 +147,15 @@ return { "name": "node", "plural": false, "selections": [ - (v3/*: any*/), (v4/*: any*/), + (v5/*: any*/), { "kind": "InlineFragment", "selections": [ + (v2/*: any*/), { "alias": null, - "args": (v5/*: any*/), + "args": (v6/*: any*/), "concreteType": "AssetConnection", "kind": "LinkedField", "name": "assets", @@ -161,7 +177,7 @@ return { "name": "node", "plural": false, "selections": [ - (v4/*: any*/), + (v5/*: any*/), { "alias": null, "args": null, @@ -169,7 +185,7 @@ return { "name": "snapshotId", "storageKey": null }, - (v6/*: any*/), + (v7/*: any*/), { "alias": null, "args": null, @@ -199,7 +215,7 @@ return { "name": "owner", "plural": false, "selections": [ - (v4/*: any*/), + (v5/*: any*/), { "alias": null, "args": null, @@ -240,8 +256,8 @@ return { "name": "node", "plural": false, "selections": [ - (v4/*: any*/), - (v6/*: any*/), + (v5/*: any*/), + (v7/*: any*/), { "alias": null, "args": null, @@ -265,7 +281,33 @@ return { "name": "createdAt", "storageKey": null }, - (v3/*: any*/) + { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:asset:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:asset:update\")" + }, + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:asset:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:asset:delete\")" + }, + (v4/*: any*/) ], "storageKey": null }, @@ -335,7 +377,7 @@ return { }, { "alias": null, - "args": (v5/*: any*/), + "args": (v6/*: any*/), "filters": [ "filter" ], @@ -354,16 +396,16 @@ return { ] }, "params": { - "cacheID": "273752608722b727e8c8999b93d45cd4", + "cacheID": "e55d3b21b1689a03329569da5669d216", "id": null, "metadata": {}, "name": "AssetGraphListQuery", "operationKind": "query", - "text": "query AssetGraphListQuery(\n $organizationId: ID!\n $snapshotId: ID\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n ...AssetsPageFragment_3iomuz\n }\n id\n }\n}\n\nfragment AssetsPageFragment_3iomuz on Organization {\n assets(first: 10, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n snapshotId\n name\n amount\n assetType\n dataTypesStored\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\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 AssetGraphListQuery(\n $organizationId: ID!\n $snapshotId: ID\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n canCreateAsset: permission(action: \"core:asset:create\")\n ...AssetsPageFragment_3iomuz\n }\n id\n }\n}\n\nfragment AssetsPageFragment_3iomuz on Organization {\n assets(first: 10, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n snapshotId\n name\n amount\n assetType\n dataTypesStored\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\n }\n createdAt\n canUpdate: permission(action: \"core:asset:update\")\n canDelete: permission(action: \"core:asset: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 = "4cbb1234b0884823285d3660334a2b29"; +(node as any).hash = "319c01153f98cf6c927a07cbe6eed98e"; export default node; diff --git a/apps/console/src/__generated__/core/AssetGraphNodeQuery.graphql.ts b/apps/console/src/__generated__/core/AssetGraphNodeQuery.graphql.ts index 7d77505d7..60ce1c354 100644 --- a/apps/console/src/__generated__/core/AssetGraphNodeQuery.graphql.ts +++ b/apps/console/src/__generated__/core/AssetGraphNodeQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<37dc142d4245fcbf81a63926cd6c1c0e>> * @lightSyntaxTransform * @nogrep */ @@ -18,6 +18,8 @@ export type AssetGraphNodeQuery$data = { readonly node: { readonly amount?: number; readonly assetType?: AssetType; + readonly canDelete?: boolean; + readonly canUpdate?: boolean; readonly createdAt?: any; readonly dataTypesStored?: string; readonly id?: string; @@ -189,6 +191,32 @@ v11 = { "kind": "ScalarField", "name": "updatedAt", "storageKey": null +}, +v12 = { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:asset:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:asset:update\")" +}, +v13 = { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:asset:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:asset:delete\")" }; return { "fragment": { @@ -217,7 +245,9 @@ return { (v8/*: any*/), (v9/*: any*/), (v10/*: any*/), - (v11/*: any*/) + (v11/*: any*/), + (v12/*: any*/), + (v13/*: any*/) ], "type": "Asset", "abstractKey": null @@ -262,7 +292,9 @@ return { (v8/*: any*/), (v9/*: any*/), (v10/*: any*/), - (v11/*: any*/) + (v11/*: any*/), + (v12/*: any*/), + (v13/*: any*/) ], "type": "Asset", "abstractKey": null @@ -273,16 +305,16 @@ return { ] }, "params": { - "cacheID": "f0aebb3dbefaf776a518bb72892d8983", + "cacheID": "6cc4f590468366f12144c88b15704bac", "id": null, "metadata": {}, "name": "AssetGraphNodeQuery", "operationKind": "query", - "text": "query AssetGraphNodeQuery(\n $assetId: ID!\n) {\n node(id: $assetId) {\n __typename\n ... on Asset {\n id\n snapshotId\n name\n amount\n assetType\n dataTypesStored\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n category\n }\n }\n }\n createdAt\n updatedAt\n }\n id\n }\n}\n" + "text": "query AssetGraphNodeQuery(\n $assetId: ID!\n) {\n node(id: $assetId) {\n __typename\n ... on Asset {\n id\n snapshotId\n name\n amount\n assetType\n dataTypesStored\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n category\n }\n }\n }\n createdAt\n updatedAt\n canUpdate: permission(action: \"core:asset:update\")\n canDelete: permission(action: \"core:asset:delete\")\n }\n id\n }\n}\n" } }; })(); -(node as any).hash = "08e11e09bc4462efdbebc36aec347c4c"; +(node as any).hash = "61e648da526c4b332ded50ba1daa3fbf"; export default node; diff --git a/apps/console/src/__generated__/core/AssetsListQuery.graphql.ts b/apps/console/src/__generated__/core/AssetsListQuery.graphql.ts index ee6ef39b3..e170256df 100644 --- a/apps/console/src/__generated__/core/AssetsListQuery.graphql.ts +++ b/apps/console/src/__generated__/core/AssetsListQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<794ba3ed2ccc75355a8c69c83d143587>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -340,6 +340,32 @@ return { "name": "createdAt", "storageKey": null }, + { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:asset:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:asset:update\")" + }, + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:asset:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:asset:delete\")" + }, (v14/*: any*/) ], "storageKey": null @@ -429,16 +455,16 @@ return { ] }, "params": { - "cacheID": "71aa6b89d4eba225262e326fdfe04cf7", + "cacheID": "350938b31ac1c7f7a28849123995da3a", "id": null, "metadata": {}, "name": "AssetsListQuery", "operationKind": "query", - "text": "query AssetsListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 10\n $last: Int = null\n $orderBy: AssetOrder = null\n $snapshotId: ID = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...AssetsPageFragment_38J9tm\n id\n }\n}\n\nfragment AssetsPageFragment_38J9tm on Organization {\n assets(first: $first, after: $after, last: $last, before: $before, orderBy: $orderBy, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n snapshotId\n name\n amount\n assetType\n dataTypesStored\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\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 AssetsListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 10\n $last: Int = null\n $orderBy: AssetOrder = null\n $snapshotId: ID = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...AssetsPageFragment_38J9tm\n id\n }\n}\n\nfragment AssetsPageFragment_38J9tm on Organization {\n assets(first: $first, after: $after, last: $last, before: $before, orderBy: $orderBy, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n snapshotId\n name\n amount\n assetType\n dataTypesStored\n owner {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\n }\n createdAt\n canUpdate: permission(action: \"core:asset:update\")\n canDelete: permission(action: \"core:asset: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 = "a230182c928f189b50fdc39950602ffd"; +(node as any).hash = "4e870b93c801e9f0b6e26ab6069863fe"; export default node; diff --git a/apps/console/src/__generated__/core/AssetsPageFragment.graphql.ts b/apps/console/src/__generated__/core/AssetsPageFragment.graphql.ts index 6e606068c..a1d1c71d9 100644 --- a/apps/console/src/__generated__/core/AssetsPageFragment.graphql.ts +++ b/apps/console/src/__generated__/core/AssetsPageFragment.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<6f077a71ef62a9c059bee1b50d3a23ef>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -18,6 +18,8 @@ export type AssetsPageFragment$data = { readonly node: { readonly amount: number; readonly assetType: AssetType; + readonly canDelete: boolean; + readonly canUpdate: boolean; readonly createdAt: any; readonly dataTypesStored: string; readonly id: string; @@ -274,6 +276,32 @@ return { "name": "createdAt", "storageKey": null }, + { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:asset:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:asset:update\")" + }, + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:asset:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:asset:delete\")" + }, { "alias": null, "args": null, @@ -355,6 +383,6 @@ return { }; })(); -(node as any).hash = "a230182c928f189b50fdc39950602ffd"; +(node as any).hash = "4e870b93c801e9f0b6e26ab6069863fe"; export default node; diff --git a/apps/console/src/hooks/graph/AssetGraph.ts b/apps/console/src/hooks/graph/AssetGraph.ts index 636618a99..5a52e2331 100644 --- a/apps/console/src/hooks/graph/AssetGraph.ts +++ b/apps/console/src/hooks/graph/AssetGraph.ts @@ -9,6 +9,7 @@ export const assetsQuery = graphql` query AssetGraphListQuery($organizationId: ID!, $snapshotId: ID) { node(id: $organizationId) { ... on Organization { + canCreateAsset: permission(action: "core:asset:create") ...AssetsPageFragment @arguments(snapshotId: $snapshotId) } } @@ -41,6 +42,8 @@ export const assetNodeQuery = graphql` } createdAt updatedAt + canUpdate: permission(action: "core:asset:update") + canDelete: permission(action: "core:asset:delete") } } } @@ -74,6 +77,8 @@ export const createAssetMutation = graphql` } } createdAt + canUpdate: permission(action: "core:asset:update") + canDelete: permission(action: "core:asset:delete") } } } diff --git a/apps/console/src/pages/organizations/assets/AssetDetailsPage.tsx b/apps/console/src/pages/organizations/assets/AssetDetailsPage.tsx index ee4011206..545345352 100644 --- a/apps/console/src/pages/organizations/assets/AssetDetailsPage.tsx +++ b/apps/console/src/pages/organizations/assets/AssetDetailsPage.tsx @@ -32,8 +32,6 @@ import { VendorsMultiSelectField } from "/components/form/VendorsMultiSelectFiel import type { AssetGraphNodeQuery } from "/__generated__/core/AssetGraphNodeQuery.graphql"; import { useFormWithSchema } from "/hooks/useFormWithSchema"; import { useOrganizationId } from "/hooks/useOrganizationId"; -import { use } from "react"; -import { PermissionsContext } from "/providers/PermissionsContext"; const updateAssetSchema = z.object({ name: z.string().min(1, "Name is required"), @@ -58,7 +56,6 @@ export default function AssetDetailsPage(props: Props) { const organizationId = useOrganizationId(); const { snapshotId } = useParams<{ snapshotId?: string }>(); const isSnapshotMode = Boolean(snapshotId); - const { isAuthorized } = use(PermissionsContext); validateSnapshotConsistency(assetEntry, snapshotId); @@ -125,7 +122,7 @@ export default function AssetDetailsPage(props: Props) { : __("Virtual")} - {!isSnapshotMode && isAuthorized("Asset", "deleteAsset") && ( + {!isSnapshotMode && asset.node.canDelete && (
- {formState.isDirty && - !isSnapshotMode && - isAuthorized("Asset", "updateAsset") && ( - - )} + {formState.isDirty && !isSnapshotMode && asset.node.canUpdate && ( + + )}
diff --git a/apps/console/src/pages/organizations/assets/AssetsPage.tsx b/apps/console/src/pages/organizations/assets/AssetsPage.tsx index 937d8c466..172363c34 100644 --- a/apps/console/src/pages/organizations/assets/AssetsPage.tsx +++ b/apps/console/src/pages/organizations/assets/AssetsPage.tsx @@ -1,7 +1,6 @@ import { usePageTitle } from "@probo/hooks"; import { useTranslate } from "@probo/i18n"; import { Button, IconPlusLarge, PageHeader } from "@probo/ui"; -import { use } from "react"; import { graphql, usePaginationFragment, @@ -17,7 +16,6 @@ import { SnapshotBanner } from "/components/SnapshotBanner"; import { assetsQuery } from "/hooks/graph/AssetGraph"; import type { AssetGraphListQuery } from "/__generated__/core/AssetGraphListQuery.graphql"; import { useOrganizationId } from "/hooks/useOrganizationId"; -import { PermissionsContext } from "/providers/PermissionsContext"; const paginatedAssetsFragment = graphql` fragment AssetsPageFragment on Organization @@ -61,6 +59,8 @@ const paginatedAssetsFragment = graphql` } } createdAt + canUpdate: permission(action: "core:asset:update") + canDelete: permission(action: "core:asset:delete") } } } @@ -88,10 +88,7 @@ export default function AssetsPage(props: Props) { const assets = pagination.data.assets?.edges.map((edge) => edge.node); const connectionId = pagination.data.assets.__id; - const { isAuthorized } = use(PermissionsContext); - const canWrite = - isAuthorized("Asset", "updateAsset") || - isAuthorized("Asset", "deleteAsset"); + const canWrite = assets.some((asset) => asset.canDelete || asset.canUpdate); usePageTitle(__("Assets")); return ( @@ -103,7 +100,7 @@ export default function AssetsPage(props: Props) { "Manage your organization's assets and their classifications.", )} > - {!isSnapshotMode && isAuthorized("Organization", "createAsset") && ( + {!isSnapshotMode && data.node.canCreateAsset && (