diff --git a/apps/console/src/__generated__/iam/MemberListFragment.graphql.ts b/apps/console/src/__generated__/iam/MemberListFragment.graphql.ts index 511ba41cd..99901ad1d 100644 --- a/apps/console/src/__generated__/iam/MemberListFragment.graphql.ts +++ b/apps/console/src/__generated__/iam/MemberListFragment.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<30bea11238a554ed69a88c9f07d33d9e>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -22,7 +22,6 @@ export type MemberListFragment$data = { }>; readonly totalCount: number | null | undefined; }; - readonly " $fragmentSpreads": FragmentRefs<"MemberListItem_currentRoleFragment">; readonly " $fragmentType": "MemberListFragment"; }; export type MemberListFragment$key = { @@ -108,11 +107,6 @@ return { }, "name": "MemberListFragment", "selections": [ - { - "args": null, - "kind": "FragmentSpread", - "name": "MemberListItem_currentRoleFragment" - }, { "kind": "RequiredField", "field": { @@ -245,6 +239,6 @@ return { }; })(); -(node as any).hash = "909f6c9ed0fcaf7b0d170bded8c97562"; +(node as any).hash = "763331f25e735e2645b0c6949ecad362"; 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 c05802dc8..3e64cb659 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<<6c195e6a85a33dea6ae254caa60b79df>> + * @generated SignedSource<<1a9ee1bf35493db9d5edbbd07f917ff5>> * @lightSyntaxTransform * @nogrep */ @@ -109,14 +109,7 @@ v12 = { "name": "id", "storageKey": null }, -v13 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "role", - "storageKey": null -}, -v14 = [ +v13 = [ (v7/*: any*/), (v8/*: any*/), (v9/*: any*/), @@ -199,20 +192,7 @@ return { "selections": [ { "alias": null, - "args": null, - "concreteType": "Membership", - "kind": "LinkedField", - "name": "viewerMembership", - "plural": false, - "selections": [ - (v13/*: any*/), - (v12/*: any*/) - ], - "storageKey": null - }, - { - "alias": null, - "args": (v14/*: any*/), + "args": (v13/*: any*/), "concreteType": "MembershipConnection", "kind": "LinkedField", "name": "members", @@ -242,7 +222,13 @@ return { "plural": false, "selections": [ (v12/*: any*/), - (v13/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "role", + "storageKey": null + }, { "alias": null, "args": null, @@ -384,7 +370,7 @@ return { }, { "alias": null, - "args": (v14/*: any*/), + "args": (v13/*: any*/), "filters": [ "orderBy" ], @@ -403,16 +389,16 @@ return { ] }, "params": { - "cacheID": "a879076e1e75bea4d524852533db17b6", + "cacheID": "7d90790bce5773e286196cec19c376c9", "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 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" + "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 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" } }; })(); -(node as any).hash = "909f6c9ed0fcaf7b0d170bded8c97562"; +(node as any).hash = "763331f25e735e2645b0c6949ecad362"; export default node; diff --git a/apps/console/src/__generated__/iam/MemberListItem_currentRoleFragment.graphql.ts b/apps/console/src/__generated__/iam/MemberListItem_currentRoleFragment.graphql.ts deleted file mode 100644 index 6f96e4913..000000000 --- a/apps/console/src/__generated__/iam/MemberListItem_currentRoleFragment.graphql.ts +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @generated SignedSource<<89f39cf7aa4cd7702b62f549ed8defdd>> - * @lightSyntaxTransform - * @nogrep - */ - -/* tslint:disable */ -/* eslint-disable */ -// @ts-nocheck - -import { ReaderFragment } from 'relay-runtime'; -export type MembershipRole = "ADMIN" | "AUDITOR" | "EMPLOYEE" | "OWNER" | "VIEWER"; -import { FragmentRefs } from "relay-runtime"; -export type MemberListItem_currentRoleFragment$data = { - readonly viewerMembership: { - readonly role: MembershipRole; - }; - readonly " $fragmentType": "MemberListItem_currentRoleFragment"; -}; -export type MemberListItem_currentRoleFragment$key = { - readonly " $data"?: MemberListItem_currentRoleFragment$data; - readonly " $fragmentSpreads": FragmentRefs<"MemberListItem_currentRoleFragment">; -}; - -const node: ReaderFragment = { - "argumentDefinitions": [], - "kind": "Fragment", - "metadata": null, - "name": "MemberListItem_currentRoleFragment", - "selections": [ - { - "kind": "RequiredField", - "field": { - "alias": null, - "args": null, - "concreteType": "Membership", - "kind": "LinkedField", - "name": "viewerMembership", - "plural": false, - "selections": [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "role", - "storageKey": null - } - ], - "storageKey": null - }, - "action": "THROW" - } - ], - "type": "Organization", - "abstractKey": null -}; - -(node as any).hash = "9e7e3eefcb6f2f4398b0703a9342548b"; - -export default node; diff --git a/apps/console/src/__generated__/iam/MembersPageQuery.graphql.ts b/apps/console/src/__generated__/iam/MembersPageQuery.graphql.ts index f9d1443b2..4289fad88 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<<70828342a675d5b198c87a4a00455155>> + * @generated SignedSource<<3ba2ace33d45535d6c6981f283be9643>> * @lightSyntaxTransform * @nogrep */ @@ -509,12 +509,12 @@ return { ] }, "params": { - "cacheID": "acfe76e30a3a7db24fec4acf2e3fd987", + "cacheID": "a5ff95870e5a269d1b03a123a459678e", "id": null, "metadata": {}, "name": "MembersPageQuery", "operationKind": "query", - "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" + "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 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" } }; })(); diff --git a/apps/console/src/__generated__/iam/MembershipLayoutQuery.graphql.ts b/apps/console/src/__generated__/iam/MembershipLayoutQuery.graphql.ts index 90633e26c..c3fccbdbb 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<<5020a4587a487d695572eb77c5e9a959>> + * @generated SignedSource<<4268d9e187cf29b47f9438cf48cc3e73>> * @lightSyntaxTransform * @nogrep */ @@ -19,6 +19,9 @@ export type MembershipLayoutQuery$data = { readonly organization: { readonly __typename: "Organization"; readonly viewerMembership: { + readonly profile: { + readonly fullName: string; + }; readonly role: MembershipRole; }; readonly " $fragmentSpreads": FragmentRefs<"MembershipsDropdown_organizationFragment" | "SessionDropdownFragment" | "SidebarFragment">; @@ -28,6 +31,7 @@ export type MembershipLayoutQuery$data = { readonly __typename: "%other"; }; readonly viewer: { + readonly email: string; readonly pendingInvitations: { readonly totalCount: number; }; @@ -75,10 +79,24 @@ v5 = { "alias": null, "args": null, "kind": "ScalarField", - "name": "totalCount", + "name": "fullName", "storageKey": null }, v6 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "email", + "storageKey": null +}, +v7 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "totalCount", + "storageKey": null +}, +v8 = { "alias": null, "args": null, "kind": "ScalarField", @@ -141,7 +159,23 @@ return { "name": "viewerMembership", "plural": false, "selections": [ - (v4/*: any*/) + (v4/*: any*/), + { + "kind": "RequiredField", + "field": { + "alias": null, + "args": null, + "concreteType": "MembershipProfile", + "kind": "LinkedField", + "name": "profile", + "plural": false, + "selections": [ + (v5/*: any*/) + ], + "storageKey": null + }, + "action": "THROW" + } ], "storageKey": null }, @@ -166,6 +200,7 @@ return { "name": "viewer", "plural": false, "selections": [ + (v6/*: any*/), { "args": null, "kind": "FragmentSpread", @@ -183,7 +218,7 @@ return { "selections": [ { "kind": "RequiredField", - "field": (v5/*: any*/), + "field": (v7/*: any*/), "action": "THROW" } ], @@ -257,14 +292,8 @@ return { "name": "identity", "plural": false, "selections": [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "email", - "storageKey": null - }, - (v6/*: any*/) + (v6/*: any*/), + (v8/*: any*/) ], "storageKey": null }, @@ -276,18 +305,12 @@ return { "name": "profile", "plural": false, "selections": [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "fullName", - "storageKey": null - }, - (v6/*: any*/) + (v5/*: any*/), + (v8/*: any*/) ], "storageKey": null }, - (v6/*: any*/), + (v8/*: any*/), (v4/*: any*/) ], "storageKey": null @@ -563,7 +586,7 @@ return { "type": "Organization", "abstractKey": null }, - (v6/*: any*/) + (v8/*: any*/) ], "storageKey": null }, @@ -575,6 +598,7 @@ return { "name": "viewer", "plural": false, "selections": [ + (v6/*: any*/), { "alias": null, "args": null, @@ -583,27 +607,27 @@ return { "name": "pendingInvitations", "plural": false, "selections": [ - (v5/*: any*/) + (v7/*: any*/) ], "storageKey": null }, - (v6/*: any*/) + (v8/*: any*/) ], "storageKey": null } ] }, "params": { - "cacheID": "6b0b3a64c02e1c0ff744e57b395d14c8", + "cacheID": "5f50873fa9c14115e307b43d7c1ae822", "id": null, "metadata": {}, "name": "MembershipLayoutQuery", "operationKind": "query", - "text": "query MembershipLayoutQuery(\n $organizationId: ID!\n $hideSidebar: Boolean!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n ...MembershipsDropdown_organizationFragment\n ...SessionDropdownFragment\n ...SidebarFragment @skip(if: $hideSidebar)\n viewerMembership {\n role\n id\n }\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 canListRightsRequests: permission(action: \"core:rights-request:list\")\n canListSnapshots: permission(action: \"core:snapshot:list\")\n canGetTrustCenter: permission(action: \"core:trust-center:get\")\n canUpdateOrganization: permission(action: \"iam:organization:update\")\n canListStatesOfApplicability: permission(action: \"core:state-of-applicability:list\")\n}\n" + "text": "query MembershipLayoutQuery(\n $organizationId: ID!\n $hideSidebar: Boolean!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n ...MembershipsDropdown_organizationFragment\n ...SessionDropdownFragment\n ...SidebarFragment @skip(if: $hideSidebar)\n viewerMembership {\n role\n profile {\n fullName\n id\n }\n id\n }\n }\n id\n }\n viewer {\n email\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 canListRightsRequests: permission(action: \"core:rights-request:list\")\n canListSnapshots: permission(action: \"core:snapshot:list\")\n canGetTrustCenter: permission(action: \"core:trust-center:get\")\n canUpdateOrganization: permission(action: \"iam:organization:update\")\n canListStatesOfApplicability: permission(action: \"core:state-of-applicability:list\")\n}\n" } }; })(); -(node as any).hash = "2d75823d6ae9eee901e54b71d4c397cf"; +(node as any).hash = "e52fc7540b2908e5b4f2c4cef33b5b81"; export default node; diff --git a/apps/console/src/components/documents/PdfDownloadDialog.tsx b/apps/console/src/components/documents/PdfDownloadDialog.tsx index 8d55aa25d..99c4b04c9 100644 --- a/apps/console/src/components/documents/PdfDownloadDialog.tsx +++ b/apps/console/src/components/documents/PdfDownloadDialog.tsx @@ -15,7 +15,11 @@ import { useFormWithSchema } from "/hooks/useFormWithSchema"; const pdfDownloadSchema = z.object({ withWatermark: z.boolean(), - watermarkEmail: z.string().email("Please enter a valid email address").optional().or(z.literal("")), + watermarkEmail: z + .string() + .email("Please enter a valid email address") + .optional() + .or(z.literal("")), withSignatures: z.boolean(), }); @@ -25,7 +29,7 @@ type Props = { children: ReactNode; onDownload: (options: PdfDownloadFormData) => void; isLoading?: boolean; - defaultEmail?: string; + defaultEmail: string; }; export type PdfDownloadDialogRef = { @@ -34,20 +38,18 @@ export type PdfDownloadDialogRef = { }; export const PdfDownloadDialog = forwardRef( - ({ children, onDownload, isLoading = false, defaultEmail = "" }, ref) => { + ({ children, onDownload, isLoading = false, defaultEmail }, ref) => { const { __ } = useTranslate(); const dialogRef = useDialogRef(); - const { register, handleSubmit, formState, watch, setValue } = useFormWithSchema( - pdfDownloadSchema, - { + const { register, handleSubmit, formState, watch, setValue } = + useFormWithSchema(pdfDownloadSchema, { defaultValues: { withWatermark: false, watermarkEmail: defaultEmail, withSignatures: true, }, - } - ); + }); const watchWatermark = watch("withWatermark"); const watchSignatures = watch("withSignatures"); @@ -69,7 +71,11 @@ export const PdfDownloadDialog = forwardRef( return ( <>
dialogRef.current?.open()}>{children}
- +
@@ -83,7 +89,9 @@ export const PdfDownloadDialog = forwardRef( {__("Include signatures")}

- {__("Show signature information and approval details in the PDF")} + {__( + "Show signature information and approval details in the PDF", + )}

@@ -98,7 +106,9 @@ export const PdfDownloadDialog = forwardRef( {__("Add watermark")}

- {__("Add confidential watermark with email and timestamp")} + {__( + "Add confidential watermark with email and timestamp", + )}

@@ -119,10 +129,7 @@ export const PdfDownloadDialog = forwardRef(
-
); - } + }, ); diff --git a/apps/console/src/pages/iam/memberships/MembershipLayout.tsx b/apps/console/src/pages/iam/memberships/MembershipLayout.tsx index 5645d7794..a5a2ca8ce 100644 --- a/apps/console/src/pages/iam/memberships/MembershipLayout.tsx +++ b/apps/console/src/pages/iam/memberships/MembershipLayout.tsx @@ -8,6 +8,7 @@ import { SessionDropdown } from "./_components/SessionDropdown"; import { Suspense } from "react"; import { useTranslate } from "@probo/i18n"; import { CoreRelayProvider } from "/providers/CoreRelayProvider"; +import { CurrentUser } from "/providers/CurrentUser"; export const membershipLayoutQuery = graphql` query MembershipLayoutQuery($organizationId: ID!, $hideSidebar: Boolean!) { @@ -19,10 +20,14 @@ export const membershipLayoutQuery = graphql` ...SidebarFragment @skip(if: $hideSidebar) viewerMembership @required(action: THROW) { role + profile @required(action: THROW) { + fullName + } } } } viewer @required(action: THROW) { + email ...MembershipsDropdown_viewerFragment pendingInvitations @required(action: THROW) { totalCount @required(action: THROW) @@ -77,7 +82,15 @@ export function MembershipLayout(props: { sidebar={!hideSidebar && } > - + + + ); diff --git a/apps/console/src/pages/iam/organizations/settings/_components/EditMemberDialog.tsx b/apps/console/src/pages/iam/organizations/settings/_components/EditMemberDialog.tsx index 0e9a093ef..60c3a39c0 100644 --- a/apps/console/src/pages/iam/organizations/settings/_components/EditMemberDialog.tsx +++ b/apps/console/src/pages/iam/organizations/settings/_components/EditMemberDialog.tsx @@ -1,4 +1,4 @@ -import { getAssignableRoles, Role, sprintf } from "@probo/helpers"; +import { getAssignableRoles, sprintf } from "@probo/helpers"; import { useTranslate } from "@probo/i18n"; import { DialogContent, @@ -10,11 +10,12 @@ import { Spinner, Dialog, } from "@probo/ui"; -import { useState } from "react"; +import { use, useState } from "react"; import { graphql } from "relay-runtime"; import { useMutationWithToasts } from "/hooks/useMutationWithToasts"; import { useOrganizationId } from "/hooks/useOrganizationId"; import type { MemberListItemFragment$data } from "/__generated__/iam/MemberListItemFragment.graphql"; +import { CurrentUser } from "/providers/CurrentUser"; const updateMembershipMutation = graphql` mutation EditMemberDialog_updateMutation($input: UpdateMembershipInput!) { @@ -28,16 +29,16 @@ const updateMembershipMutation = graphql` `; export function EditMemberDialog(props: { - currentRole: Role; membership: MemberListItemFragment$data; onClose: () => void; }) { - const { currentRole, membership, onClose } = props; + const { membership, onClose } = props; const organizationId = useOrganizationId(); const { __ } = useTranslate(); - const availableRoles = getAssignableRoles(currentRole); + const { role } = use(CurrentUser); + const availableRoles = getAssignableRoles(role); const [selectedRole, setSelectedRole] = useState(membership.role); diff --git a/apps/console/src/pages/iam/organizations/settings/_components/MemberList.tsx b/apps/console/src/pages/iam/organizations/settings/_components/MemberList.tsx index 27c950eca..488a4efce 100644 --- a/apps/console/src/pages/iam/organizations/settings/_components/MemberList.tsx +++ b/apps/console/src/pages/iam/organizations/settings/_components/MemberList.tsx @@ -19,7 +19,6 @@ const fragment = graphql` before: { type: "CursorKey", defaultValue: null } last: { type: "Int", defaultValue: null } ) { - ...MemberListItem_currentRoleFragment members( first: $first after: $after @@ -94,7 +93,6 @@ export function MemberList(props: { fKey: MemberListFragment$key }) { key={membership.id} fKey={membership} onRefetch={refetchMemberships} - viewerFKey={membersPagination.data} /> )) )} diff --git a/apps/console/src/pages/iam/organizations/settings/_components/MemberListItem.tsx b/apps/console/src/pages/iam/organizations/settings/_components/MemberListItem.tsx index 581e50815..6585e9e98 100644 --- a/apps/console/src/pages/iam/organizations/settings/_components/MemberListItem.tsx +++ b/apps/console/src/pages/iam/organizations/settings/_components/MemberListItem.tsx @@ -10,15 +10,15 @@ import { useConfirm, } from "@probo/ui"; import clsx from "clsx"; -import { useState } from "react"; +import { use, useState } from "react"; import { useFragment } from "react-relay"; import { graphql } from "relay-runtime"; import type { MemberListItemFragment$key } from "/__generated__/iam/MemberListItemFragment.graphql"; -import type { MemberListItem_currentRoleFragment$key } from "/__generated__/iam/MemberListItem_currentRoleFragment.graphql"; import { useMutationWithToasts } from "/hooks/useMutationWithToasts"; import { useOrganizationId } from "/hooks/useOrganizationId"; import { sprintf } from "@probo/helpers"; import { EditMemberDialog } from "./EditMemberDialog"; +import { CurrentUser } from "/providers/CurrentUser"; const fragment = graphql` fragment MemberListItemFragment on Membership { @@ -36,14 +36,6 @@ const fragment = graphql` } `; -const currentRoleFragment = graphql` - fragment MemberListItem_currentRoleFragment on Organization { - viewerMembership @required(action: THROW) { - role - } - } -`; - const removeMemberMutation = graphql` mutation MemberListItem_removeMutation( $input: RemoveMemberInput! @@ -58,10 +50,9 @@ const removeMemberMutation = graphql` export function MemberListItem(props: { connectionId: string; fKey: MemberListItemFragment$key; - viewerFKey: MemberListItem_currentRoleFragment$key; onRefetch: () => void; }) { - const { fKey, connectionId, viewerFKey } = props; + const { fKey, connectionId } = props; const organizationId = useOrganizationId(); const { __ } = useTranslate(); @@ -69,15 +60,10 @@ export function MemberListItem(props: { const [dialogOpen, setDialogOpen] = useState(false); const membership = useFragment(fragment, fKey); - const { viewerMembership } = - useFragment( - currentRoleFragment, - viewerFKey, - ); + const { role } = use(CurrentUser); // Only OWNER can edit OWNER members - const canEditThisRole = - membership.role === "OWNER" ? viewerMembership.role === "OWNER" : true; + const canEditThisRole = membership.role === "OWNER" ? role === "OWNER" : true; const [removeMembership, isRemoving] = useMutationWithToasts( removeMemberMutation, @@ -162,7 +148,6 @@ export function MemberListItem(props: { {dialogOpen && ( setDialogOpen(false)} membership={membership} /> diff --git a/apps/console/src/pages/organizations/documents/DocumentDetailPage.tsx b/apps/console/src/pages/organizations/documents/DocumentDetailPage.tsx index 2a73428c9..801d724c0 100644 --- a/apps/console/src/pages/organizations/documents/DocumentDetailPage.tsx +++ b/apps/console/src/pages/organizations/documents/DocumentDetailPage.tsx @@ -65,7 +65,7 @@ import { PdfDownloadDialog, type PdfDownloadDialogRef, } from "/components/documents/PdfDownloadDialog"; -import { useRef, useState } from "react"; +import { use, useRef, useState } from "react"; import type { NodeOf } from "/types.ts"; import clsx from "clsx"; import { PeopleSelectField } from "/components/form/PeopleSelectField"; @@ -74,6 +74,7 @@ import { DocumentTypeOptions } from "/components/form/DocumentTypeOptions"; import { DocumentClassificationOptions } from "/components/form/DocumentClassificationOptions"; import { z } from "zod"; import { useFormWithSchema } from "/hooks/useFormWithSchema"; +import { CurrentUser } from "/providers/CurrentUser"; type Props = { queryRef: PreloadedQuery; @@ -92,12 +93,6 @@ const documentFragment = graphql` canUpdate: permission(action: "core:document:update") canDelete: permission(action: "core:document:delete") canPublish: permission(action: "core:document-version:publish") - # canSendSigningNotifications: permission( - # action: "core:document:send-signing-notifications" - # ) - # canRequestSignatures: permission( - # action: "core:document-version:request-signature" - # ) ...DocumentControlsTabFragment controlsInfo: controls(first: 0) { totalCount @@ -187,15 +182,6 @@ const documentUpdateSchema = z.object({ classification: z.enum(documentClassifications), }); -// FIXME -// const UserEmailQuery = graphql` -// query DocumentDetailPageUserEmailQuery { -// viewer { -// email -// } -// } -// `; - export default function DocumentDetailPage(props: Props) { const { versionId } = useParams<{ versionId?: string }>(); const node = usePreloadedQuery(documentNodeQuery, props.queryRef).node; @@ -237,11 +223,7 @@ export default function DocumentDetailPage(props: Props) { }, ); - // const userEmailData = useLazyLoadQuery( - // UserEmailQuery, - // {} - // ); - // const defaultEmail = userEmailData.viewer.user.email; + const { email: defaultEmail } = use(CurrentUser); const [updateDocument, isUpdatingDocument] = useMutationWithToasts( updateDocumentMutation, @@ -454,7 +436,7 @@ export default function DocumentDetailPage(props: Props) { ref={pdfDownloadDialogRef} onDownload={handleDownloadPdf} isLoading={isExporting} - // defaultEmail={defaultEmail} + defaultEmail={defaultEmail} > {null} diff --git a/apps/console/src/providers/CurrentUser.tsx b/apps/console/src/providers/CurrentUser.tsx new file mode 100644 index 000000000..ec8a758a9 --- /dev/null +++ b/apps/console/src/providers/CurrentUser.tsx @@ -0,0 +1,14 @@ +import { Role } from "@probo/helpers"; +import { createContext } from "react"; + +type CurrentUserContextValue = { + email: string; + fullName: string; + role: Role; +}; + +export const CurrentUser = createContext({ + email: "", + fullName: "", + role: Role.VIEWER, +}); diff --git a/apps/console/src/routes.tsx b/apps/console/src/routes.tsx index b6fe0c1b3..fca4074c0 100644 --- a/apps/console/src/routes.tsx +++ b/apps/console/src/routes.tsx @@ -2,7 +2,6 @@ import { createBrowserRouter, Navigate, redirect, - useOutletContext, useRouteError, } from "react-router"; import { CenteredLayout, CenteredLayoutSkeleton } from "@probo/ui"; @@ -35,6 +34,8 @@ import { UnAuthenticatedError, UnauthorizedError, } from "@probo/relay"; +import { CurrentUser } from "./providers/CurrentUser.tsx"; +import { use } from "react"; /** * Top level error boundary @@ -152,7 +153,7 @@ const routes = [ { path: "", Component: () => { - const role = useOutletContext(); + const { role } = use(CurrentUser); switch (role) { case Role.EMPLOYEE: return ;