From e46a11001adfc561f1f385b0b2fda98552d5981e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Tue, 30 Dec 2025 18:33:18 +0100 Subject: [PATCH] Fix iam pages permissions handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Émile Ré --- ...tationListFragment_RefetchQuery.graphql.ts | 19 +- .../iam/InvitationListItemFragment.graphql.ts | 18 +- ...ionListItem_permissionsFragment.graphql.ts | 59 - ...MemberListFragment_RefetchQuery.graphql.ts | 32 +- .../iam/MemberListItemFragment.graphql.ts | 32 +- ...berListItem_permissionsFragment.graphql.ts | 77 - .../iam/MembersPageQuery.graphql.ts | 298 ++-- .../iam/MembershipLayoutQuery.graphql.ts | 589 ++++--- .../iam/SessionDropdownFragment.graphql.ts | 18 +- .../iam/SidebarFragment.graphql.ts | 118 +- .../iam/memberships/MembershipLayout.tsx | 69 +- .../_components/SessionDropdown.tsx | 19 +- .../iam/memberships/_components/Sidebar.tsx | 409 +++-- .../organizations/settings/MembersPage.tsx | 21 +- .../settings/_components/InvitationList.tsx | 9 +- .../_components/InvitationListItem.tsx | 21 +- .../settings/_components/MemberList.tsx | 9 +- .../settings/_components/MemberListItem.tsx | 28 +- pkg/iam/iam_actions.go | 2 + pkg/iam/iam_policies.go | 3 +- pkg/server/api/connect/v1/resolver.go | 29 + pkg/server/api/connect/v1/schema.graphql | 40 +- pkg/server/api/connect/v1/schema/schema.go | 1464 ++++++++++------- pkg/server/api/connect/v1/types/types.go | 43 +- pkg/server/api/connect/v1/v1_resolver.go | 97 +- pkg/server/api/console/v1/resolver.go | 11 - 26 files changed, 1848 insertions(+), 1686 deletions(-) delete mode 100644 apps/console/src/__generated__/iam/InvitationListItem_permissionsFragment.graphql.ts delete mode 100644 apps/console/src/__generated__/iam/MemberListItem_permissionsFragment.graphql.ts diff --git a/apps/console/src/__generated__/iam/InvitationListFragment_RefetchQuery.graphql.ts b/apps/console/src/__generated__/iam/InvitationListFragment_RefetchQuery.graphql.ts index dc232f7a4..25e3d6717 100644 --- a/apps/console/src/__generated__/iam/InvitationListFragment_RefetchQuery.graphql.ts +++ b/apps/console/src/__generated__/iam/InvitationListFragment_RefetchQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<0da865b38342a3574ae7dc7185a6071d>> * @lightSyntaxTransform * @nogrep */ @@ -271,6 +271,19 @@ return { "name": "acceptedAt", "storageKey": null }, + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "iam:invitation:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"iam:invitation:delete\")" + }, (v11/*: any*/) ], "storageKey": null @@ -360,12 +373,12 @@ return { ] }, "params": { - "cacheID": "4cc36c8fb50b104ebe3fae66bf847ecc", + "cacheID": "2f419e2fcb92f5a188dcd35ff5661fd7", "id": null, "metadata": {}, "name": "InvitationListFragment_RefetchQuery", "operationKind": "query", - "text": "query InvitationListFragment_RefetchQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 20\n $last: Int = null\n $order: InvitationOrder = {direction: ASC, field: CREATED_AT}\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...InvitationListFragment_16fISc\n id\n }\n}\n\nfragment InvitationListFragment_16fISc on Organization {\n invitations(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n totalCount\n edges {\n node {\n id\n ...InvitationListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment InvitationListItemFragment on Invitation {\n id\n fullName\n email\n role\n status\n createdAt\n expiresAt\n acceptedAt\n}\n" + "text": "query InvitationListFragment_RefetchQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 20\n $last: Int = null\n $order: InvitationOrder = {direction: ASC, field: CREATED_AT}\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...InvitationListFragment_16fISc\n id\n }\n}\n\nfragment InvitationListFragment_16fISc on Organization {\n invitations(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n totalCount\n edges {\n node {\n id\n ...InvitationListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment InvitationListItemFragment on Invitation {\n id\n fullName\n email\n role\n status\n createdAt\n expiresAt\n acceptedAt\n canDelete: permission(action: \"iam:invitation:delete\")\n}\n" } }; })(); diff --git a/apps/console/src/__generated__/iam/InvitationListItemFragment.graphql.ts b/apps/console/src/__generated__/iam/InvitationListItemFragment.graphql.ts index ac189f769..131e31298 100644 --- a/apps/console/src/__generated__/iam/InvitationListItemFragment.graphql.ts +++ b/apps/console/src/__generated__/iam/InvitationListItemFragment.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<748bbadd485b1e131e583c119f980e91>> + * @generated SignedSource<<1ff88dc8e6cbfc1d0db4f6d041cd7e51>> * @lightSyntaxTransform * @nogrep */ @@ -14,6 +14,7 @@ export type MembershipRole = "ADMIN" | "AUDITOR" | "EMPLOYEE" | "OWNER" | "VIEWE import { FragmentRefs } from "relay-runtime"; export type InvitationListItemFragment$data = { readonly acceptedAt: any | null | undefined; + readonly canDelete: boolean; readonly createdAt: any; readonly email: any; readonly expiresAt: any; @@ -89,12 +90,25 @@ const node: ReaderFragment = { "kind": "ScalarField", "name": "acceptedAt", "storageKey": null + }, + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "iam:invitation:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"iam:invitation:delete\")" } ], "type": "Invitation", "abstractKey": null }; -(node as any).hash = "772414270b8ce2fed6c7b5fe97082c17"; +(node as any).hash = "c0e21d5dd227cd3fff739dc9f0922657"; export default node; diff --git a/apps/console/src/__generated__/iam/InvitationListItem_permissionsFragment.graphql.ts b/apps/console/src/__generated__/iam/InvitationListItem_permissionsFragment.graphql.ts deleted file mode 100644 index 86a6023ce..000000000 --- a/apps/console/src/__generated__/iam/InvitationListItem_permissionsFragment.graphql.ts +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @generated SignedSource<<0fa501d76c400538c62a44425ebe4b11>> - * @lightSyntaxTransform - * @nogrep - */ - -/* tslint:disable */ -/* eslint-disable */ -// @ts-nocheck - -import { ReaderFragment } from 'relay-runtime'; -import { FragmentRefs } from "relay-runtime"; -export type InvitationListItem_permissionsFragment$data = { - readonly canDeleteInvitation: boolean; - readonly " $fragmentType": "InvitationListItem_permissionsFragment"; -}; -export type InvitationListItem_permissionsFragment$key = { - readonly " $data"?: InvitationListItem_permissionsFragment$data; - readonly " $fragmentSpreads": FragmentRefs<"InvitationListItem_permissionsFragment">; -}; - -const node: ReaderFragment = { - "argumentDefinitions": [ - { - "defaultValue": null, - "kind": "LocalArgument", - "name": "organizationId" - } - ], - "kind": "Fragment", - "metadata": null, - "name": "InvitationListItem_permissionsFragment", - "selections": [ - { - "alias": "canDeleteInvitation", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "iam:invitation:delete" - }, - { - "kind": "Variable", - "name": "id", - "variableName": "organizationId" - } - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - } - ], - "type": "Identity", - "abstractKey": null -}; - -(node as any).hash = "e9e75ae0f5a3755a777acf16e5024ee0"; - -export default node; diff --git a/apps/console/src/__generated__/iam/MemberListFragment_RefetchQuery.graphql.ts b/apps/console/src/__generated__/iam/MemberListFragment_RefetchQuery.graphql.ts index 3999f1eab..e247bc817 100644 --- a/apps/console/src/__generated__/iam/MemberListFragment_RefetchQuery.graphql.ts +++ b/apps/console/src/__generated__/iam/MemberListFragment_RefetchQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<75b9df3cc430ed26d41b88a67a410aca>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -288,6 +288,32 @@ return { "name": "createdAt", "storageKey": null }, + { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "iam:membership:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"iam:membership:update\")" + }, + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "iam:membership:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"iam:membership:delete\")" + }, (v11/*: any*/) ], "storageKey": null @@ -377,12 +403,12 @@ return { ] }, "params": { - "cacheID": "df1f40dcee56d6e5181849cd82acb824", + "cacheID": "a879076e1e75bea4d524852533db17b6", "id": null, "metadata": {}, "name": "MemberListFragment_RefetchQuery", "operationKind": "query", - "text": "query MemberListFragment_RefetchQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 20\n $last: Int = null\n $order: MembershipOrder = {direction: ASC, field: CREATED_AT}\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...MemberListFragment_16fISc\n id\n }\n}\n\nfragment MemberListFragment_16fISc on Organization {\n ...MemberListItem_currentRoleFragment\n members(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n totalCount\n edges {\n node {\n id\n ...MemberListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment MemberListItemFragment on Membership {\n id\n role\n profile {\n fullName\n id\n }\n identity {\n email\n id\n }\n createdAt\n}\n\nfragment MemberListItem_currentRoleFragment on Organization {\n viewerMembership {\n role\n id\n }\n}\n" + "text": "query MemberListFragment_RefetchQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 20\n $last: Int = null\n $order: MembershipOrder = {direction: ASC, field: CREATED_AT}\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...MemberListFragment_16fISc\n id\n }\n}\n\nfragment MemberListFragment_16fISc on Organization {\n ...MemberListItem_currentRoleFragment\n members(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n totalCount\n edges {\n node {\n id\n ...MemberListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment MemberListItemFragment on Membership {\n id\n role\n profile {\n fullName\n id\n }\n identity {\n email\n id\n }\n createdAt\n canUpdate: permission(action: \"iam:membership:update\")\n canDelete: permission(action: \"iam:membership:delete\")\n}\n\nfragment MemberListItem_currentRoleFragment on Organization {\n viewerMembership {\n role\n id\n }\n}\n" } }; })(); diff --git a/apps/console/src/__generated__/iam/MemberListItemFragment.graphql.ts b/apps/console/src/__generated__/iam/MemberListItemFragment.graphql.ts index 162733377..cecadcb4e 100644 --- a/apps/console/src/__generated__/iam/MemberListItemFragment.graphql.ts +++ b/apps/console/src/__generated__/iam/MemberListItemFragment.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<50f7d8bffdec238d8a262e892db7be39>> + * @generated SignedSource<<2a646771572f86908a4000fae533c4d8>> * @lightSyntaxTransform * @nogrep */ @@ -12,6 +12,8 @@ import { ReaderFragment } from 'relay-runtime'; export type MembershipRole = "ADMIN" | "AUDITOR" | "EMPLOYEE" | "OWNER" | "VIEWER"; import { FragmentRefs } from "relay-runtime"; export type MemberListItemFragment$data = { + readonly canDelete: boolean; + readonly canUpdate: boolean; readonly createdAt: any; readonly id: string; readonly identity: { @@ -98,12 +100,38 @@ const node: ReaderFragment = { "kind": "ScalarField", "name": "createdAt", "storageKey": null + }, + { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "iam:membership:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"iam:membership:update\")" + }, + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "iam:membership:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"iam:membership:delete\")" } ], "type": "Membership", "abstractKey": null }; -(node as any).hash = "31ca1c20d23f9709b0c1575ae56aeb64"; +(node as any).hash = "a7adb3da099816d296abd56c0b8dde16"; export default node; diff --git a/apps/console/src/__generated__/iam/MemberListItem_permissionsFragment.graphql.ts b/apps/console/src/__generated__/iam/MemberListItem_permissionsFragment.graphql.ts deleted file mode 100644 index 0bb88145d..000000000 --- a/apps/console/src/__generated__/iam/MemberListItem_permissionsFragment.graphql.ts +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @generated SignedSource<<66b5754d2d4ecfc54f6c698df247e241>> - * @lightSyntaxTransform - * @nogrep - */ - -/* tslint:disable */ -/* eslint-disable */ -// @ts-nocheck - -import { ReaderFragment } from 'relay-runtime'; -import { FragmentRefs } from "relay-runtime"; -export type MemberListItem_permissionsFragment$data = { - readonly canDeleteMembership: boolean; - readonly canUpdateMembership: boolean; - readonly " $fragmentType": "MemberListItem_permissionsFragment"; -}; -export type MemberListItem_permissionsFragment$key = { - readonly " $data"?: MemberListItem_permissionsFragment$data; - readonly " $fragmentSpreads": FragmentRefs<"MemberListItem_permissionsFragment">; -}; - -const node: ReaderFragment = (function(){ -var v0 = { - "kind": "Variable", - "name": "id", - "variableName": "organizationId" -}; -return { - "argumentDefinitions": [ - { - "defaultValue": null, - "kind": "LocalArgument", - "name": "organizationId" - } - ], - "kind": "Fragment", - "metadata": null, - "name": "MemberListItem_permissionsFragment", - "selections": [ - { - "alias": "canUpdateMembership", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "iam:membership:update" - }, - (v0/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canDeleteMembership", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "iam:membership:delete" - }, - (v0/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - } - ], - "type": "Identity", - "abstractKey": null -}; -})(); - -(node as any).hash = "d467db6a9f7f80521cf35c8c1a0c3416"; - -export default node; diff --git a/apps/console/src/__generated__/iam/MembersPageQuery.graphql.ts b/apps/console/src/__generated__/iam/MembersPageQuery.graphql.ts index b3e2f35ea..f5090df36 100644 --- a/apps/console/src/__generated__/iam/MembersPageQuery.graphql.ts +++ b/apps/console/src/__generated__/iam/MembersPageQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<33faed6358cc7fba56a1f493c11f31d4>> + * @generated SignedSource<<5854e660d90c68e5ec01199e55c42a41>> * @lightSyntaxTransform * @nogrep */ @@ -16,6 +16,7 @@ export type MembersPageQuery$variables = { export type MembersPageQuery$data = { readonly organization: { readonly __typename: "Organization"; + readonly canInviteUser: boolean; readonly invitations: { readonly totalCount: number | null | undefined; }; @@ -28,10 +29,6 @@ export type MembersPageQuery$data = { // value in case none of the concrete values match. readonly __typename: "%other"; }; - readonly viewer: { - readonly canInviteUser: boolean; - readonly " $fragmentSpreads": FragmentRefs<"InvitationListItem_permissionsFragment" | "MemberListItem_permissionsFragment">; - }; }; export type MembersPageQuery = { response: MembersPageQuery$data; @@ -46,120 +43,111 @@ var v0 = [ "name": "organizationId" } ], -v1 = { - "kind": "Variable", - "name": "id", - "variableName": "organizationId" -}, -v2 = { - "alias": "canInviteUser", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "iam:membership:create" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null -}, -v3 = [ +v1 = [ { "kind": "Variable", - "name": "organizationId", + "name": "id", "variableName": "organizationId" } ], -v4 = [ - (v1/*: any*/) -], -v5 = { +v2 = { "alias": null, "args": null, "kind": "ScalarField", "name": "__typename", "storageKey": null }, -v6 = { +v3 = { "kind": "Literal", "name": "first", "value": 20 }, -v7 = { +v4 = { "direction": "ASC", "field": "CREATED_AT" }, -v8 = [ - (v6/*: any*/), +v5 = [ + (v3/*: any*/), { "kind": "Literal", "name": "order", - "value": (v7/*: any*/) + "value": (v4/*: any*/) } ], -v9 = [ - (v6/*: any*/), +v6 = [ + (v3/*: any*/), { "kind": "Literal", "name": "orderBy", - "value": (v7/*: any*/) + "value": (v4/*: any*/) } ], -v10 = { +v7 = { "alias": null, "args": null, "kind": "ScalarField", "name": "totalCount", "storageKey": null }, -v11 = [ - (v10/*: any*/) +v8 = [ + (v7/*: any*/) ], -v12 = { +v9 = { + "alias": "canInviteUser", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "iam:invitation:create" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"iam:invitation:create\")" +}, +v10 = { "alias": null, "args": null, "kind": "ScalarField", "name": "id", "storageKey": null }, -v13 = { +v11 = { "alias": null, "args": null, "kind": "ScalarField", "name": "role", "storageKey": null }, -v14 = { +v12 = { "alias": null, "args": null, "kind": "ScalarField", "name": "fullName", "storageKey": null }, -v15 = { +v13 = { "alias": null, "args": null, "kind": "ScalarField", "name": "email", "storageKey": null }, -v16 = { +v14 = { "alias": null, "args": null, "kind": "ScalarField", "name": "createdAt", "storageKey": null }, -v17 = { +v15 = { "alias": null, "args": null, "kind": "ScalarField", "name": "cursor", "storageKey": null }, -v18 = { +v16 = { "alias": null, "args": null, "concreteType": "PageInfo", @@ -198,7 +186,7 @@ v18 = { ], "storageKey": null }, -v19 = { +v17 = { "kind": "ClientExtension", "selections": [ { @@ -210,7 +198,7 @@ v19 = { } ] }, -v20 = [ +v18 = [ "orderBy" ]; return { @@ -220,43 +208,17 @@ return { "metadata": null, "name": "MembersPageQuery", "selections": [ - { - "kind": "RequiredField", - "field": { - "alias": null, - "args": null, - "concreteType": "Identity", - "kind": "LinkedField", - "name": "viewer", - "plural": false, - "selections": [ - (v2/*: any*/), - { - "args": (v3/*: any*/), - "kind": "FragmentSpread", - "name": "InvitationListItem_permissionsFragment" - }, - { - "args": (v3/*: any*/), - "kind": "FragmentSpread", - "name": "MemberListItem_permissionsFragment" - } - ], - "storageKey": null - }, - "action": "THROW" - }, { "kind": "RequiredField", "field": { "alias": "organization", - "args": (v4/*: any*/), + "args": (v1/*: any*/), "concreteType": null, "kind": "LinkedField", "name": "node", "plural": false, "selections": [ - (v5/*: any*/), + (v2/*: any*/), { "kind": "InlineFragment", "selections": [ @@ -266,7 +228,7 @@ return { "name": "InviteUserDialog_currentRoleFragment" }, { - "args": (v8/*: any*/), + "args": (v5/*: any*/), "kind": "FragmentSpread", "name": "MemberListFragment" }, @@ -274,18 +236,18 @@ return { "kind": "RequiredField", "field": { "alias": null, - "args": (v9/*: any*/), + "args": (v6/*: any*/), "concreteType": "MembershipConnection", "kind": "LinkedField", "name": "members", "plural": false, - "selections": (v11/*: any*/), + "selections": (v8/*: any*/), "storageKey": "members(first:20,orderBy:{\"direction\":\"ASC\",\"field\":\"CREATED_AT\"})" }, "action": "THROW" }, { - "args": (v8/*: any*/), + "args": (v5/*: any*/), "kind": "FragmentSpread", "name": "InvitationListFragment" }, @@ -293,16 +255,17 @@ return { "kind": "RequiredField", "field": { "alias": null, - "args": (v9/*: any*/), + "args": (v6/*: any*/), "concreteType": "InvitationConnection", "kind": "LinkedField", "name": "invitations", "plural": false, - "selections": (v11/*: any*/), + "selections": (v8/*: any*/), "storageKey": "invitations(first:20,orderBy:{\"direction\":\"ASC\",\"field\":\"CREATED_AT\"})" }, "action": "THROW" - } + }, + (v9/*: any*/) ], "type": "Organization", "abstractKey": null @@ -322,71 +285,16 @@ return { "kind": "Operation", "name": "MembersPageQuery", "selections": [ - { - "alias": null, - "args": null, - "concreteType": "Identity", - "kind": "LinkedField", - "name": "viewer", - "plural": false, - "selections": [ - (v2/*: any*/), - { - "alias": "canDeleteInvitation", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "iam:invitation:delete" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canUpdateMembership", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "iam:membership:update" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canDeleteMembership", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "iam:membership:delete" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - (v12/*: any*/) - ], - "storageKey": null - }, { "alias": "organization", - "args": (v4/*: any*/), + "args": (v1/*: any*/), "concreteType": null, "kind": "LinkedField", "name": "node", "plural": false, "selections": [ - (v5/*: any*/), - (v12/*: any*/), + (v2/*: any*/), + (v10/*: any*/), { "kind": "InlineFragment", "selections": [ @@ -398,20 +306,20 @@ return { "name": "viewerMembership", "plural": false, "selections": [ - (v13/*: any*/), - (v12/*: any*/) + (v11/*: any*/), + (v10/*: any*/) ], "storageKey": null }, { "alias": null, - "args": (v9/*: any*/), + "args": (v6/*: any*/), "concreteType": "MembershipConnection", "kind": "LinkedField", "name": "members", "plural": false, "selections": [ - (v10/*: any*/), + (v7/*: any*/), { "alias": null, "args": null, @@ -428,8 +336,8 @@ return { "name": "node", "plural": false, "selections": [ - (v12/*: any*/), - (v13/*: any*/), + (v10/*: any*/), + (v11/*: any*/), { "alias": null, "args": null, @@ -438,8 +346,8 @@ return { "name": "profile", "plural": false, "selections": [ - (v14/*: any*/), - (v12/*: any*/) + (v12/*: any*/), + (v10/*: any*/) ], "storageKey": null }, @@ -451,29 +359,55 @@ return { "name": "identity", "plural": false, "selections": [ - (v15/*: any*/), - (v12/*: any*/) + (v13/*: any*/), + (v10/*: any*/) ], "storageKey": null }, - (v16/*: any*/), - (v5/*: any*/) + (v14/*: any*/), + { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "iam:membership:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"iam:membership:update\")" + }, + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "iam:membership:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"iam:membership:delete\")" + }, + (v2/*: any*/) ], "storageKey": null }, - (v17/*: any*/) + (v15/*: any*/) ], "storageKey": null }, - (v18/*: any*/), - (v19/*: any*/) + (v16/*: any*/), + (v17/*: any*/) ], "storageKey": "members(first:20,orderBy:{\"direction\":\"ASC\",\"field\":\"CREATED_AT\"})" }, { "alias": null, - "args": (v9/*: any*/), - "filters": (v20/*: any*/), + "args": (v6/*: any*/), + "filters": (v18/*: any*/), "handle": "connection", "key": "MemberListFragment_members", "kind": "LinkedHandle", @@ -481,13 +415,13 @@ return { }, { "alias": null, - "args": (v9/*: any*/), + "args": (v6/*: any*/), "concreteType": "InvitationConnection", "kind": "LinkedField", "name": "invitations", "plural": false, "selections": [ - (v10/*: any*/), + (v7/*: any*/), { "alias": null, "args": null, @@ -504,10 +438,10 @@ return { "name": "node", "plural": false, "selections": [ + (v10/*: any*/), (v12/*: any*/), - (v14/*: any*/), - (v15/*: any*/), (v13/*: any*/), + (v11/*: any*/), { "alias": null, "args": null, @@ -515,7 +449,7 @@ return { "name": "status", "storageKey": null }, - (v16/*: any*/), + (v14/*: any*/), { "alias": null, "args": null, @@ -530,28 +464,42 @@ return { "name": "acceptedAt", "storageKey": null }, - (v5/*: any*/) + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "iam:invitation:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"iam:invitation:delete\")" + }, + (v2/*: any*/) ], "storageKey": null }, - (v17/*: any*/) + (v15/*: any*/) ], "storageKey": null }, - (v18/*: any*/), - (v19/*: any*/) + (v16/*: any*/), + (v17/*: any*/) ], "storageKey": "invitations(first:20,orderBy:{\"direction\":\"ASC\",\"field\":\"CREATED_AT\"})" }, { "alias": null, - "args": (v9/*: any*/), - "filters": (v20/*: any*/), + "args": (v6/*: any*/), + "filters": (v18/*: any*/), "handle": "connection", "key": "InvitationListFragment_invitations", "kind": "LinkedHandle", "name": "invitations" - } + }, + (v9/*: any*/) ], "type": "Organization", "abstractKey": null @@ -562,16 +510,16 @@ return { ] }, "params": { - "cacheID": "1c006f49a510a658f66a78c66e9289db", + "cacheID": "acfe76e30a3a7db24fec4acf2e3fd987", "id": null, "metadata": {}, "name": "MembersPageQuery", "operationKind": "query", - "text": "query MembersPageQuery(\n $organizationId: ID!\n) {\n viewer {\n canInviteUser: permission(action: \"iam:membership:create\", id: $organizationId)\n ...InvitationListItem_permissionsFragment_4xMPKw\n ...MemberListItem_permissionsFragment_4xMPKw\n id\n }\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n ...InviteUserDialog_currentRoleFragment\n ...MemberListFragment_1jRT0c\n members(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n }\n ...InvitationListFragment_1jRT0c\n invitations(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n }\n }\n id\n }\n}\n\nfragment InvitationListFragment_1jRT0c on Organization {\n invitations(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n edges {\n node {\n id\n ...InvitationListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment InvitationListItemFragment on Invitation {\n id\n fullName\n email\n role\n status\n createdAt\n expiresAt\n acceptedAt\n}\n\nfragment InvitationListItem_permissionsFragment_4xMPKw on Identity {\n canDeleteInvitation: permission(action: \"iam:invitation:delete\", id: $organizationId)\n}\n\nfragment InviteUserDialog_currentRoleFragment on Organization {\n viewerMembership {\n role\n id\n }\n}\n\nfragment MemberListFragment_1jRT0c on Organization {\n ...MemberListItem_currentRoleFragment\n members(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n edges {\n node {\n id\n ...MemberListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment MemberListItemFragment on Membership {\n id\n role\n profile {\n fullName\n id\n }\n identity {\n email\n id\n }\n createdAt\n}\n\nfragment MemberListItem_currentRoleFragment on Organization {\n viewerMembership {\n role\n id\n }\n}\n\nfragment MemberListItem_permissionsFragment_4xMPKw on Identity {\n canUpdateMembership: permission(action: \"iam:membership:update\", id: $organizationId)\n canDeleteMembership: permission(action: \"iam:membership:delete\", id: $organizationId)\n}\n" + "text": "query MembersPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n ...InviteUserDialog_currentRoleFragment\n ...MemberListFragment_1jRT0c\n members(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n }\n ...InvitationListFragment_1jRT0c\n invitations(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n }\n canInviteUser: permission(action: \"iam:invitation:create\")\n }\n id\n }\n}\n\nfragment InvitationListFragment_1jRT0c on Organization {\n invitations(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n edges {\n node {\n id\n ...InvitationListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment InvitationListItemFragment on Invitation {\n id\n fullName\n email\n role\n status\n createdAt\n expiresAt\n acceptedAt\n canDelete: permission(action: \"iam:invitation:delete\")\n}\n\nfragment InviteUserDialog_currentRoleFragment on Organization {\n viewerMembership {\n role\n id\n }\n}\n\nfragment MemberListFragment_1jRT0c on Organization {\n ...MemberListItem_currentRoleFragment\n members(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n edges {\n node {\n id\n ...MemberListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment MemberListItemFragment on Membership {\n id\n role\n profile {\n fullName\n id\n }\n identity {\n email\n id\n }\n createdAt\n canUpdate: permission(action: \"iam:membership:update\")\n canDelete: permission(action: \"iam:membership:delete\")\n}\n\nfragment MemberListItem_currentRoleFragment on Organization {\n viewerMembership {\n role\n id\n }\n}\n" } }; })(); -(node as any).hash = "6e919357c168bbfbdccfa7375ce71660"; +(node as any).hash = "591a88a5e1b0bd427daff74dc27ac512"; export default node; diff --git a/apps/console/src/__generated__/iam/MembershipLayoutQuery.graphql.ts b/apps/console/src/__generated__/iam/MembershipLayoutQuery.graphql.ts index 2cf2fcdc4..df845a4f0 100644 --- a/apps/console/src/__generated__/iam/MembershipLayoutQuery.graphql.ts +++ b/apps/console/src/__generated__/iam/MembershipLayoutQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<90e5e1f754a2b18caa9b6f4f208ec5a8>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -15,13 +15,13 @@ export type MembershipLayoutQuery$variables = { }; export type MembershipLayoutQuery$data = { readonly organization: { - readonly " $fragmentSpreads": FragmentRefs<"MembershipsDropdown_organizationFragment" | "SessionDropdownFragment">; + readonly " $fragmentSpreads": FragmentRefs<"MembershipsDropdown_organizationFragment" | "SessionDropdownFragment" | "SidebarFragment">; }; readonly viewer: { readonly pendingInvitations: { readonly totalCount: number; }; - readonly " $fragmentSpreads": FragmentRefs<"MembershipsDropdown_viewerFragment" | "SidebarFragment">; + readonly " $fragmentSpreads": FragmentRefs<"MembershipsDropdown_viewerFragment">; }; }; export type MembershipLayoutQuery = { @@ -37,22 +37,21 @@ var v0 = [ "name": "organizationId" } ], -v1 = { - "kind": "Variable", - "name": "id", - "variableName": "organizationId" -}, -v2 = [ - (v1/*: any*/) +v1 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "organizationId" + } ], -v3 = { +v2 = { "alias": null, "args": null, "kind": "ScalarField", "name": "totalCount", "storageKey": null }, -v4 = { +v3 = { "alias": null, "args": null, "kind": "ScalarField", @@ -70,7 +69,7 @@ return { "kind": "RequiredField", "field": { "alias": "organization", - "args": (v2/*: any*/), + "args": (v1/*: any*/), "concreteType": null, "kind": "LinkedField", "name": "node", @@ -88,6 +87,11 @@ return { "args": null, "kind": "FragmentSpread", "name": "SessionDropdownFragment" + }, + { + "args": null, + "kind": "FragmentSpread", + "name": "SidebarFragment" } ], "type": "Organization", @@ -108,17 +112,6 @@ return { "name": "viewer", "plural": false, "selections": [ - { - "args": [ - { - "kind": "Variable", - "name": "organizationId", - "variableName": "organizationId" - } - ], - "kind": "FragmentSpread", - "name": "SidebarFragment" - }, { "args": null, "kind": "FragmentSpread", @@ -136,7 +129,7 @@ return { "selections": [ { "kind": "RequiredField", - "field": (v3/*: any*/), + "field": (v2/*: any*/), "action": "THROW" } ], @@ -161,7 +154,7 @@ return { "selections": [ { "alias": "organization", - "args": (v2/*: any*/), + "args": (v1/*: any*/), "concreteType": null, "kind": "LinkedField", "name": "node", @@ -184,6 +177,19 @@ return { "name": "name", "storageKey": null }, + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "iam:organization:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"iam:organization:delete\")" + }, { "alias": null, "args": null, @@ -207,7 +213,7 @@ return { "name": "email", "storageKey": null }, - (v4/*: any*/) + (v3/*: any*/) ], "storageKey": null }, @@ -226,19 +232,266 @@ return { "name": "fullName", "storageKey": null }, - (v4/*: any*/) + (v3/*: any*/) ], "storageKey": null }, - (v4/*: any*/) + (v3/*: any*/) ], "storageKey": null + }, + { + "alias": "canListMeetings", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:meeting:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:meeting:list\")" + }, + { + "alias": "canListTasks", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:task:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:task:list\")" + }, + { + "alias": "canListMeasures", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:measures:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:measures:list\")" + }, + { + "alias": "canListRisks", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:risk:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:risk:list\")" + }, + { + "alias": "canListFrameworks", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:frameworks:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:frameworks:list\")" + }, + { + "alias": "canListPeople", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:people:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:people:list\")" + }, + { + "alias": "canListVendors", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:vendor:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:vendor:list\")" + }, + { + "alias": "canListDocuments", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:document:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:document:list\")" + }, + { + "alias": "canListAssets", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:asset:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:asset:list\")" + }, + { + "alias": "canListData", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:datum:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:datum:list\")" + }, + { + "alias": "canListAudits", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:audit:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:audit:list\")" + }, + { + "alias": "canListNonconformities", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:nonconformity:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:nonconformity:list\")" + }, + { + "alias": "canListObligations", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:obligation:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:obligation:list\")" + }, + { + "alias": "canListContinualImprovements", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:continual-improvement:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:continual-improvement:list\")" + }, + { + "alias": "canListProcessingActivities", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:processing-activity:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:processing-activity:list\")" + }, + { + "alias": "canListStatesOfApplicability", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:state-of-applicability:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:state-of-applicability:list\")" + }, + { + "alias": "canListSnapshots", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:snapshot:list" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:snapshot:list\")" + }, + { + "alias": "canGetTrustCenter", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center:get" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center:get\")" + }, + { + "alias": "canUpdateOrganization", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "iam:organization:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"iam:organization:update\")" } ], "type": "Organization", "abstractKey": null }, - (v4/*: any*/) + (v3/*: any*/) ], "storageKey": null }, @@ -250,272 +503,6 @@ return { "name": "viewer", "plural": false, "selections": [ - { - "alias": "canListMeetings", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:meeting:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListTasks", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:task:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListMeasures", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:measures:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListRisks", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:risk:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListFrameworks", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:frameworks:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListPeople", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:people:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListVendors", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:vendor:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListDocuments", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:document:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListAssets", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:asset:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListData", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:datum:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListAudits", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:audit:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListNonconformities", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:nonconformity:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListObligations", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:obligation:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListContinualImprovements", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:continual-improvement:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListProcessingActivities", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:processing-activity:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListStatesOfApplicability", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:state-of-applicability:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canListSnapshots", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:snapshot:list" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canGetTrustCenter", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:trust-center:get" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, - { - "alias": "canUpdateOrganization", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "iam:organization:update" - }, - (v1/*: any*/) - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": null - }, { "alias": null, "args": null, @@ -524,27 +511,27 @@ return { "name": "pendingInvitations", "plural": false, "selections": [ - (v3/*: any*/) + (v2/*: any*/) ], "storageKey": null }, - (v4/*: any*/) + (v3/*: any*/) ], "storageKey": null } ] }, "params": { - "cacheID": "1fb1002661548737fdb22694a23bca35", + "cacheID": "34a53202cb35bb4f38588dabe5063f6c", "id": null, "metadata": {}, "name": "MembershipLayoutQuery", "operationKind": "query", - "text": "query MembershipLayoutQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n ...MembershipsDropdown_organizationFragment\n ...SessionDropdownFragment\n }\n id\n }\n viewer {\n ...SidebarFragment_4xMPKw\n ...MembershipsDropdown_viewerFragment\n pendingInvitations {\n totalCount\n }\n id\n }\n}\n\nfragment MembershipsDropdown_organizationFragment on Organization {\n name\n}\n\nfragment MembershipsDropdown_viewerFragment on Identity {\n pendingInvitations {\n totalCount\n }\n}\n\nfragment SessionDropdownFragment on Organization {\n viewerMembership {\n identity {\n email\n id\n }\n profile {\n fullName\n id\n }\n id\n }\n}\n\nfragment SidebarFragment_4xMPKw on Identity {\n canListMeetings: permission(action: \"core:meeting:list\", id: $organizationId)\n canListTasks: permission(action: \"core:task:list\", id: $organizationId)\n canListMeasures: permission(action: \"core:measures:list\", id: $organizationId)\n canListRisks: permission(action: \"core:risk:list\", id: $organizationId)\n canListFrameworks: permission(action: \"core:frameworks:list\", id: $organizationId)\n canListPeople: permission(action: \"core:people:list\", id: $organizationId)\n canListVendors: permission(action: \"core:vendor:list\", id: $organizationId)\n canListDocuments: permission(action: \"core:document:list\", id: $organizationId)\n canListAssets: permission(action: \"core:asset:list\", id: $organizationId)\n canListData: permission(action: \"core:datum:list\", id: $organizationId)\n canListAudits: permission(action: \"core:audit:list\", id: $organizationId)\n canListNonconformities: permission(action: \"core:nonconformity:list\", id: $organizationId)\n canListObligations: permission(action: \"core:obligation:list\", id: $organizationId)\n canListContinualImprovements: permission(action: \"core:continual-improvement:list\", id: $organizationId)\n canListProcessingActivities: permission(action: \"core:processing-activity:list\", id: $organizationId)\n canListStatesOfApplicability: permission(action: \"core:state-of-applicability:list\", id: $organizationId)\n canListSnapshots: permission(action: \"core:snapshot:list\", id: $organizationId)\n canGetTrustCenter: permission(action: \"core:trust-center:get\", id: $organizationId)\n canUpdateOrganization: permission(action: \"iam:organization:update\", id: $organizationId)\n}\n" + "text": "query MembershipLayoutQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n ...MembershipsDropdown_organizationFragment\n ...SessionDropdownFragment\n ...SidebarFragment\n }\n id\n }\n viewer {\n ...MembershipsDropdown_viewerFragment\n pendingInvitations {\n totalCount\n }\n id\n }\n}\n\nfragment MembershipsDropdown_organizationFragment on Organization {\n name\n}\n\nfragment MembershipsDropdown_viewerFragment on Identity {\n pendingInvitations {\n totalCount\n }\n}\n\nfragment SessionDropdownFragment on Organization {\n canDelete: permission(action: \"iam:organization:delete\")\n viewerMembership {\n identity {\n email\n id\n }\n profile {\n fullName\n id\n }\n id\n }\n}\n\nfragment SidebarFragment on Organization {\n canListMeetings: permission(action: \"core:meeting:list\")\n canListTasks: permission(action: \"core:task:list\")\n canListMeasures: permission(action: \"core:measures:list\")\n canListRisks: permission(action: \"core:risk:list\")\n canListFrameworks: permission(action: \"core:frameworks:list\")\n canListPeople: permission(action: \"core:people:list\")\n canListVendors: permission(action: \"core:vendor:list\")\n canListDocuments: permission(action: \"core:document:list\")\n canListAssets: permission(action: \"core:asset:list\")\n canListData: permission(action: \"core:datum:list\")\n canListAudits: permission(action: \"core:audit:list\")\n canListNonconformities: permission(action: \"core:nonconformity:list\")\n canListObligations: permission(action: \"core:obligation:list\")\n canListContinualImprovements: permission(action: \"core:continual-improvement:list\")\n canListProcessingActivities: permission(action: \"core:processing-activity:list\")\n canListStatesOfApplicability: permission(action: \"core:state-of-applicability:list\")\n canListSnapshots: permission(action: \"core:snapshot:list\")\n canGetTrustCenter: permission(action: \"core:trust-center:get\")\n canUpdateOrganization: permission(action: \"iam:organization:update\")\n}\n" } }; })(); -(node as any).hash = "bea3f973a014e38e291ecd177da5c5f5"; +(node as any).hash = "9a87ccbe2aa86cca7845e0145b133921"; export default node; diff --git a/apps/console/src/__generated__/iam/SessionDropdownFragment.graphql.ts b/apps/console/src/__generated__/iam/SessionDropdownFragment.graphql.ts index 63504446e..63e92e831 100644 --- a/apps/console/src/__generated__/iam/SessionDropdownFragment.graphql.ts +++ b/apps/console/src/__generated__/iam/SessionDropdownFragment.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<0d0906bc941900bb200a6a9824aaacc4>> + * @generated SignedSource<<2c57cb9a331fb7fedf72b0113bf7cb66>> * @lightSyntaxTransform * @nogrep */ @@ -11,6 +11,7 @@ import { ReaderFragment } from 'relay-runtime'; import { FragmentRefs } from "relay-runtime"; export type SessionDropdownFragment$data = { + readonly canDelete: boolean; readonly viewerMembership: { readonly identity: { readonly email: any; @@ -32,6 +33,19 @@ const node: ReaderFragment = { "metadata": null, "name": "SessionDropdownFragment", "selections": [ + { + "alias": "canDelete", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "iam:organization:delete" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"iam:organization:delete\")" + }, { "kind": "RequiredField", "field": { @@ -96,6 +110,6 @@ const node: ReaderFragment = { "abstractKey": null }; -(node as any).hash = "c283fcefcab15b977b44ece82f7cf450"; +(node as any).hash = "51810eafbf165e7b5eeec42cb268ae54"; export default node; diff --git a/apps/console/src/__generated__/iam/SidebarFragment.graphql.ts b/apps/console/src/__generated__/iam/SidebarFragment.graphql.ts index ea88a9933..3cbae3b6a 100644 --- a/apps/console/src/__generated__/iam/SidebarFragment.graphql.ts +++ b/apps/console/src/__generated__/iam/SidebarFragment.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -37,20 +37,8 @@ export type SidebarFragment$key = { readonly " $fragmentSpreads": FragmentRefs<"SidebarFragment">; }; -const node: ReaderFragment = (function(){ -var v0 = { - "kind": "Variable", - "name": "id", - "variableName": "organizationId" -}; -return { - "argumentDefinitions": [ - { - "defaultValue": null, - "kind": "LocalArgument", - "name": "organizationId" - } - ], +const node: ReaderFragment = { + "argumentDefinitions": [], "kind": "Fragment", "metadata": null, "name": "SidebarFragment", @@ -62,12 +50,11 @@ return { "kind": "Literal", "name": "action", "value": "core:meeting:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:meeting:list\")" }, { "alias": "canListTasks", @@ -76,12 +63,11 @@ return { "kind": "Literal", "name": "action", "value": "core:task:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:task:list\")" }, { "alias": "canListMeasures", @@ -90,12 +76,11 @@ return { "kind": "Literal", "name": "action", "value": "core:measures:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:measures:list\")" }, { "alias": "canListRisks", @@ -104,12 +89,11 @@ return { "kind": "Literal", "name": "action", "value": "core:risk:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:risk:list\")" }, { "alias": "canListFrameworks", @@ -118,12 +102,11 @@ return { "kind": "Literal", "name": "action", "value": "core:frameworks:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:frameworks:list\")" }, { "alias": "canListPeople", @@ -132,12 +115,11 @@ return { "kind": "Literal", "name": "action", "value": "core:people:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:people:list\")" }, { "alias": "canListVendors", @@ -146,12 +128,11 @@ return { "kind": "Literal", "name": "action", "value": "core:vendor:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:vendor:list\")" }, { "alias": "canListDocuments", @@ -160,12 +141,11 @@ return { "kind": "Literal", "name": "action", "value": "core:document:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:document:list\")" }, { "alias": "canListAssets", @@ -174,12 +154,11 @@ return { "kind": "Literal", "name": "action", "value": "core:asset:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:asset:list\")" }, { "alias": "canListData", @@ -188,12 +167,11 @@ return { "kind": "Literal", "name": "action", "value": "core:datum:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:datum:list\")" }, { "alias": "canListAudits", @@ -202,12 +180,11 @@ return { "kind": "Literal", "name": "action", "value": "core:audit:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:audit:list\")" }, { "alias": "canListNonconformities", @@ -216,12 +193,11 @@ return { "kind": "Literal", "name": "action", "value": "core:nonconformity:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:nonconformity:list\")" }, { "alias": "canListObligations", @@ -230,12 +206,11 @@ return { "kind": "Literal", "name": "action", "value": "core:obligation:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:obligation:list\")" }, { "alias": "canListContinualImprovements", @@ -244,12 +219,11 @@ return { "kind": "Literal", "name": "action", "value": "core:continual-improvement:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:continual-improvement:list\")" }, { "alias": "canListProcessingActivities", @@ -258,12 +232,11 @@ return { "kind": "Literal", "name": "action", "value": "core:processing-activity:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:processing-activity:list\")" }, { "alias": "canListStatesOfApplicability", @@ -272,12 +245,11 @@ return { "kind": "Literal", "name": "action", "value": "core:state-of-applicability:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:state-of-applicability:list\")" }, { "alias": "canListSnapshots", @@ -286,12 +258,11 @@ return { "kind": "Literal", "name": "action", "value": "core:snapshot:list" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:snapshot:list\")" }, { "alias": "canGetTrustCenter", @@ -300,12 +271,11 @@ return { "kind": "Literal", "name": "action", "value": "core:trust-center:get" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"core:trust-center:get\")" }, { "alias": "canUpdateOrganization", @@ -314,19 +284,17 @@ return { "kind": "Literal", "name": "action", "value": "iam:organization:update" - }, - (v0/*: any*/) + } ], "kind": "ScalarField", "name": "permission", - "storageKey": null + "storageKey": "permission(action:\"iam:organization:update\")" } ], - "type": "Identity", + "type": "Organization", "abstractKey": null }; -})(); -(node as any).hash = "a116eb6c3f1c2808f90316b34ef43979"; +(node as any).hash = "2baad6a78a98c3e9458cdb1ada294d76"; export default node; diff --git a/apps/console/src/pages/iam/memberships/MembershipLayout.tsx b/apps/console/src/pages/iam/memberships/MembershipLayout.tsx index 08a4a2c16..d324ae81f 100644 --- a/apps/console/src/pages/iam/memberships/MembershipLayout.tsx +++ b/apps/console/src/pages/iam/memberships/MembershipLayout.tsx @@ -4,7 +4,6 @@ import { Badge, Button, IconPeopleAdd, Layout, Skeleton } from "@probo/ui"; import { Sidebar } from "./_components/Sidebar"; import { MembershipsDropdown } from "./MembershipsDropdown"; import type { MembershipLayoutQuery } from "/__generated__/iam/MembershipLayoutQuery.graphql"; -import { PermissionsProvider } from "/providers/PermissionsProvider"; import { SessionDropdown } from "./_components/SessionDropdown"; import { Suspense } from "react"; import { useTranslate } from "@probo/i18n"; @@ -16,10 +15,10 @@ export const membershipLayoutQuery = graphql` ... on Organization { ...MembershipsDropdown_organizationFragment ...SessionDropdownFragment + ...SidebarFragment } } viewer @required(action: THROW) { - ...SidebarFragment @arguments(organizationId: $organizationId) ...MembershipsDropdown_viewerFragment pendingInvitations @required(action: THROW) { totalCount @required(action: THROW) @@ -41,39 +40,37 @@ export function MembershipLayout(props: { ); return ( - - -
- - {viewer.pendingInvitations.totalCount > 0 && ( - -
- }> - - - - } - sidebar={} - > - - - -
-
+ +
+ + {viewer.pendingInvitations.totalCount > 0 && ( + +
+ }> + + + + } + sidebar={} + > + + + +
); } diff --git a/apps/console/src/pages/iam/memberships/_components/SessionDropdown.tsx b/apps/console/src/pages/iam/memberships/_components/SessionDropdown.tsx index cfaf5fe4e..a64d15ec9 100644 --- a/apps/console/src/pages/iam/memberships/_components/SessionDropdown.tsx +++ b/apps/console/src/pages/iam/memberships/_components/SessionDropdown.tsx @@ -8,8 +8,6 @@ import { UserDropdownItem, useToast, } from "@probo/ui"; -import { use } from "react"; -import { PermissionsContext } from "/providers/PermissionsContext"; import { graphql } from "relay-runtime"; import { useOrganizationId } from "/hooks/useOrganizationId"; import { useFragment, useMutation } from "react-relay"; @@ -18,6 +16,7 @@ import type { SessionDropdownFragment$key } from "/__generated__/iam/SessionDrop export const fragment = graphql` fragment SessionDropdownFragment on Organization { + canDelete: permission(action: "iam:organization:delete") viewerMembership @required(action: THROW) { identity @required(action: THROW) { email @@ -42,10 +41,10 @@ export function SessionDropdown(props: { fKey: SessionDropdownFragment$key }) { const { __ } = useTranslate(); const organizationId = useOrganizationId(); - const { isAuthorized } = use(PermissionsContext); const { toast } = useToast(); const { + canDelete, viewerMembership: { identity: { email }, profile: { fullName }, @@ -73,20 +72,18 @@ export function SessionDropdown(props: { fKey: SessionDropdownFragment$key }) { return ( - {isAuthorized("Organization", "deleteOrganization") && ( + {canDelete && ( )} - {isAuthorized("Organization", "listSignableDocuments") && ( - - )} + (fragment, fKey); + const organization = useFragment(fragment, fKey); - const prefix = `/organizations/${organizationId}`; + const prefix = `/organizations/${organizationId}`; - return ( -
    - {permissions.canListMeetings && ( - - )} - {permissions.canListTasks && ( - - )} - {permissions.canListMeasures && ( - - )} - {permissions.canListRisks && ( - - )} - {permissions.canListFrameworks && ( - - )} - {permissions.canListPeople && ( - - )} - {permissions.canListVendors && ( - - )} - {permissions.canListDocuments && ( - - )} - {permissions.canListAssets && ( - - )} - {permissions.canListData && ( - - )} - {permissions.canListAudits && ( - - )} - {permissions.canListNonconformities && ( - - )} - {permissions.canListObligations && ( - - )} - {permissions.canListContinualImprovements && ( - - )} - {permissions.canListProcessingActivities && ( - - )} - {permissions.canListStatesOfApplicability && ( - - )} - {permissions.canListSnapshots && ( - - )} - {permissions.canGetTrustCenter && ( - - )} - {permissions.canUpdateOrganization && ( - - )} -
- ); + return ( +
    + {organization.canListMeetings && ( + + )} + {organization.canListTasks && ( + + )} + {organization.canListMeasures && ( + + )} + {organization.canListRisks && ( + + )} + {organization.canListFrameworks && ( + + )} + {organization.canListPeople && ( + + )} + {organization.canListVendors && ( + + )} + {organization.canListDocuments && ( + + )} + {organization.canListAssets && ( + + )} + {organization.canListData && ( + + )} + {organization.canListAudits && ( + + )} + {organization.canListNonconformities && ( + + )} + {organization.canListObligations && ( + + )} + {organization.canListContinualImprovements && ( + + )} + {organization.canListProcessingActivities && ( + + )} + {organization.canListStatesOfApplicability && ( + + )} + {organization.canListSnapshots && ( + + )} + {organization.canGetTrustCenter && ( + + )} + {organization.canUpdateOrganization && ( + + )} +
+ ); } diff --git a/apps/console/src/pages/iam/organizations/settings/MembersPage.tsx b/apps/console/src/pages/iam/organizations/settings/MembersPage.tsx index 186792228..19ed05e00 100644 --- a/apps/console/src/pages/iam/organizations/settings/MembersPage.tsx +++ b/apps/console/src/pages/iam/organizations/settings/MembersPage.tsx @@ -10,16 +10,6 @@ import { InviteUserDialog } from "./_components/InviteUserDialog"; export const membersPageQuery = graphql` query MembersPageQuery($organizationId: ID!) { - viewer @required(action: THROW) { - canInviteUser: permission( - action: "iam:membership:create" - id: $organizationId - ) - ...InvitationListItem_permissionsFragment - @arguments(organizationId: $organizationId) - ...MemberListItem_permissionsFragment - @arguments(organizationId: $organizationId) - } organization: node(id: $organizationId) @required(action: THROW) { __typename ... on Organization { @@ -36,6 +26,7 @@ export const membersPageQuery = graphql` @required(action: THROW) { totalCount } + canInviteUser: permission(action: "iam:invitation:create") } } } @@ -52,7 +43,7 @@ export function MembersPage(props: { "memberships", ); - const { organization, viewer } = usePreloadedQuery( + const { organization } = usePreloadedQuery( membersPageQuery, queryRef, ); @@ -64,7 +55,7 @@ export function MembersPage(props: {

{__("Workspace members")}

- {viewer.canInviteUser && ( + {organization.canInviteUser && ( @@ -94,12 +85,10 @@ export function MembersPage(props: {
- {activeTab === "memberships" && ( - - )} + {activeTab === "memberships" && } {activeTab === "invitations" && ( - + )}
diff --git a/apps/console/src/pages/iam/organizations/settings/_components/InvitationList.tsx b/apps/console/src/pages/iam/organizations/settings/_components/InvitationList.tsx index 90c2c12ec..0d0fd8e62 100644 --- a/apps/console/src/pages/iam/organizations/settings/_components/InvitationList.tsx +++ b/apps/console/src/pages/iam/organizations/settings/_components/InvitationList.tsx @@ -4,7 +4,6 @@ import { useTranslate } from "@probo/i18n"; import { graphql, usePaginationFragment } from "react-relay"; import { InvitationListItem } from "./InvitationListItem"; import type { InvitationListFragment$key } from "/__generated__/iam/InvitationListFragment.graphql"; -import type { InvitationListItem_permissionsFragment$key } from "/__generated__/iam/InvitationListItem_permissionsFragment.graphql"; import type { InvitationListFragment_RefetchQuery } from "/__generated__/iam/InvitationListFragment_RefetchQuery.graphql"; const fragment = graphql` @@ -41,11 +40,8 @@ const fragment = graphql` } `; -export function InvitationList(props: { - fKey: InvitationListFragment$key; - permissionsFKey: InvitationListItem_permissionsFragment$key; -}) { - const { fKey, permissionsFKey } = props; +export function InvitationList(props: { fKey: InvitationListFragment$key }) { + const { fKey } = props; const { __ } = useTranslate(); @@ -106,7 +102,6 @@ export function InvitationList(props: { key={invitation.id} fKey={invitation} onRefetch={refetchInvitations} - permissionsFKey={permissionsFKey} /> ), ) diff --git a/apps/console/src/pages/iam/organizations/settings/_components/InvitationListItem.tsx b/apps/console/src/pages/iam/organizations/settings/_components/InvitationListItem.tsx index f83a03d03..6a37884ac 100644 --- a/apps/console/src/pages/iam/organizations/settings/_components/InvitationListItem.tsx +++ b/apps/console/src/pages/iam/organizations/settings/_components/InvitationListItem.tsx @@ -15,7 +15,6 @@ import { useMutationWithToasts } from "/hooks/useMutationWithToasts"; import { sprintf } from "@probo/helpers"; import { useOrganizationId } from "/hooks/useOrganizationId"; import type { InvitationListItemFragment$key } from "/__generated__/iam/InvitationListItemFragment.graphql"; -import type { InvitationListItem_permissionsFragment$key } from "/__generated__/iam/InvitationListItem_permissionsFragment.graphql"; const fragment = graphql` fragment InvitationListItemFragment on Invitation { @@ -27,16 +26,7 @@ const fragment = graphql` createdAt expiresAt acceptedAt - } -`; - -const permissionsFragment = graphql` - fragment InvitationListItem_permissionsFragment on Identity - @argumentDefinitions(organizationId: { type: "ID!" }) { - canDeleteInvitation: permission( - action: "iam:invitation:delete" - id: $organizationId - ) + canDelete: permission(action: "iam:invitation:delete") } `; @@ -54,10 +44,9 @@ const deleteInvitationMutation = graphql` export function InvitationListItem(props: { connectionId: string; fKey: InvitationListItemFragment$key; - permissionsFKey: InvitationListItem_permissionsFragment$key; onRefetch: () => void; }) { - const { connectionId, fKey, permissionsFKey } = props; + const { connectionId, fKey } = props; const organizationId = useOrganizationId(); const { __ } = useTranslate(); @@ -67,10 +56,6 @@ export function InvitationListItem(props: { fragment, fKey, ); - const permissions = useFragment( - permissionsFragment, - permissionsFKey, - ); const [deleteInvitation, isDeleting] = useMutationWithToasts( deleteInvitationMutation, @@ -134,7 +119,7 @@ export function InvitationListItem(props: { {isDeleting ? ( ) : ( - permissions.canDeleteInvitation && ( + invitation.canDelete && (