Fix uneeded assume + assume after invite accept

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-01-08 19:11:17 +01:00
committed by Bryan Frimin
parent c6094ff572
commit cfcbda4519
15 changed files with 681 additions and 222 deletions

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<8c8ece60966bd2f39668d4ee4459ae86>>
* @generated SignedSource<<2d970c5558233522bbd695a075469cad>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,17 +9,27 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime";
export type AcceptInvitationInput = {
invitationId: string;
};
export type InvitationCardMutation$variables = {
input: AcceptInvitationInput;
membershipConnections: ReadonlyArray<string>;
pendingInvitationConnections: ReadonlyArray<string>;
};
export type InvitationCardMutation$data = {
readonly acceptInvitation: {
readonly invitation: {
readonly id: string;
};
readonly membershipEdge: {
readonly node: {
readonly id: string;
readonly organization: {
readonly name: string;
} | null | undefined;
readonly " $fragmentSpreads": FragmentRefs<"MembershipCardFragment">;
};
};
} | null | undefined;
@@ -35,44 +45,101 @@ var v0 = [
"defaultValue": null,
"kind": "LocalArgument",
"name": "input"
},
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "membershipConnections"
},
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "pendingInvitationConnections"
}
],
v1 = [
{
"alias": null,
"args": [
{
"kind": "Variable",
"name": "input",
"variableName": "input"
}
],
"concreteType": "AcceptInvitationPayload",
"kind": "LinkedField",
"name": "acceptInvitation",
"plural": false,
"kind": "Variable",
"name": "input",
"variableName": "input"
}
],
v2 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
v3 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
};
return {
"fragment": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "InvitationCardMutation",
"selections": [
{
"alias": null,
"args": null,
"concreteType": "MembershipEdge",
"args": (v1/*: any*/),
"concreteType": "AcceptInvitationPayload",
"kind": "LinkedField",
"name": "membershipEdge",
"name": "acceptInvitation",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Membership",
"concreteType": "Invitation",
"kind": "LinkedField",
"name": "node",
"name": "invitation",
"plural": false,
"selections": [
(v2/*: any*/)
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "MembershipEdge",
"kind": "LinkedField",
"name": "membershipEdge",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"concreteType": "Membership",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v2/*: any*/),
{
"args": null,
"kind": "FragmentSpread",
"name": "MembershipCardFragment"
},
{
"alias": null,
"args": null,
"concreteType": "Organization",
"kind": "LinkedField",
"name": "organization",
"plural": false,
"selections": [
(v3/*: any*/)
],
"storageKey": null
}
],
"storageKey": null
}
],
@@ -82,16 +149,6 @@ v1 = [
"storageKey": null
}
],
"storageKey": null
}
];
return {
"fragment": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "InvitationCardMutation",
"selections": (v1/*: any*/),
"type": "Mutation",
"abstractKey": null
},
@@ -100,19 +157,137 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "InvitationCardMutation",
"selections": (v1/*: any*/)
"selections": [
{
"alias": null,
"args": (v1/*: any*/),
"concreteType": "AcceptInvitationPayload",
"kind": "LinkedField",
"name": "acceptInvitation",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Invitation",
"kind": "LinkedField",
"name": "invitation",
"plural": false,
"selections": [
(v2/*: any*/),
{
"alias": null,
"args": null,
"filters": null,
"handle": "deleteEdge",
"key": "",
"kind": "ScalarHandle",
"name": "id",
"handleArgs": [
{
"kind": "Variable",
"name": "connections",
"variableName": "pendingInvitationConnections"
}
]
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "MembershipEdge",
"kind": "LinkedField",
"name": "membershipEdge",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Membership",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v2/*: any*/),
{
"alias": null,
"args": null,
"concreteType": "Session",
"kind": "LinkedField",
"name": "lastSession",
"plural": false,
"selections": [
(v2/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "expiresAt",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "Organization",
"kind": "LinkedField",
"name": "organization",
"plural": false,
"selections": [
(v2/*: any*/),
(v3/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "logoUrl",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"filters": null,
"handle": "prependEdge",
"key": "",
"kind": "LinkedHandle",
"name": "membershipEdge",
"handleArgs": [
{
"kind": "Variable",
"name": "connections",
"variableName": "membershipConnections"
}
]
}
],
"storageKey": null
}
]
},
"params": {
"cacheID": "592fad5ce23af0f457d7e0ccf5f7123f",
"cacheID": "15ed0089d35b0163252ef542a4b1b667",
"id": null,
"metadata": {},
"name": "InvitationCardMutation",
"operationKind": "mutation",
"text": "mutation InvitationCardMutation(\n $input: AcceptInvitationInput!\n) {\n acceptInvitation(input: $input) {\n membershipEdge {\n node {\n id\n }\n }\n }\n}\n"
"text": "mutation InvitationCardMutation(\n $input: AcceptInvitationInput!\n) {\n acceptInvitation(input: $input) {\n invitation {\n id\n }\n membershipEdge {\n node {\n id\n ...MembershipCardFragment\n organization {\n name\n id\n }\n }\n }\n }\n}\n\nfragment MembershipCardFragment on Membership {\n lastSession {\n id\n expiresAt\n }\n organization {\n id\n name\n logoUrl\n }\n}\n"
}
};
})();
(node as any).hash = "00a20b1db5dd8e98838c8c9659560bb9";
(node as any).hash = "587f3fc115f88830e5ee49759f3ab7b5";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<1be91c8373db8ffb1155cb6e52beda6c>>
* @generated SignedSource<<0f048726f7e7371223919d924fa15d54>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -23,6 +23,7 @@ export type MembershipCard_assumeMutation$data = {
readonly membership: {
readonly id: string;
readonly lastSession: {
readonly expiresAt: string;
readonly id: string;
} | null | undefined;
};
@@ -117,7 +118,14 @@ v3 = [
"name": "lastSession",
"plural": false,
"selections": [
(v1/*: any*/)
(v1/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "expiresAt",
"storageKey": null
}
],
"storageKey": null
}
@@ -176,16 +184,16 @@ return {
"selections": (v3/*: any*/)
},
"params": {
"cacheID": "100893dbb5b232a19f4b11bc51598bc8",
"cacheID": "d106c9d8a5a2c3256da2f1f83fb8fde7",
"id": null,
"metadata": {},
"name": "MembershipCard_assumeMutation",
"operationKind": "mutation",
"text": "mutation MembershipCard_assumeMutation(\n $input: AssumeOrganizationSessionInput!\n) {\n assumeOrganizationSession(input: $input) {\n result {\n __typename\n ... on OrganizationSessionCreated {\n membership {\n id\n lastSession {\n id\n }\n }\n }\n ... on PasswordRequired {\n reason\n }\n ... on SAMLAuthenticationRequired {\n reason\n redirectUrl\n }\n }\n }\n}\n"
"text": "mutation MembershipCard_assumeMutation(\n $input: AssumeOrganizationSessionInput!\n) {\n assumeOrganizationSession(input: $input) {\n result {\n __typename\n ... on OrganizationSessionCreated {\n membership {\n id\n lastSession {\n id\n expiresAt\n }\n }\n }\n ... on PasswordRequired {\n reason\n }\n ... on SAMLAuthenticationRequired {\n reason\n redirectUrl\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "f44a07beefbecb0a564858272e3cd244";
(node as any).hash = "7acaa03357731962d7d29eb2c046660a";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<a3cc5c262b8a01f267eb2b549ab95a27>>
* @generated SignedSource<<4beff809268fb32711cc02699683b623>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -19,6 +19,15 @@ export type MembershipsDropdownMenuItem_assumeMutation$variables = {
export type MembershipsDropdownMenuItem_assumeMutation$data = {
readonly assumeOrganizationSession: {
readonly result: {
readonly __typename: "OrganizationSessionCreated";
readonly membership: {
readonly id: string;
readonly lastSession: {
readonly expiresAt: string;
readonly id: string;
} | null | undefined;
};
} | {
readonly __typename: "PasswordRequired";
readonly reason: ReauthenticationReason;
} | {
@@ -46,13 +55,20 @@ var v0 = [
}
],
v1 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
v2 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "reason",
"storageKey": null
},
v2 = [
v3 = [
{
"alias": null,
"args": [
@@ -85,7 +101,45 @@ v2 = [
{
"kind": "InlineFragment",
"selections": [
(v1/*: any*/)
{
"alias": null,
"args": null,
"concreteType": "Membership",
"kind": "LinkedField",
"name": "membership",
"plural": false,
"selections": [
(v1/*: any*/),
{
"alias": null,
"args": null,
"concreteType": "Session",
"kind": "LinkedField",
"name": "lastSession",
"plural": false,
"selections": [
(v1/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "expiresAt",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
],
"type": "OrganizationSessionCreated",
"abstractKey": null
},
{
"kind": "InlineFragment",
"selections": [
(v2/*: any*/)
],
"type": "PasswordRequired",
"abstractKey": null
@@ -93,7 +147,7 @@ v2 = [
{
"kind": "InlineFragment",
"selections": [
(v1/*: any*/),
(v2/*: any*/),
{
"alias": null,
"args": null,
@@ -118,7 +172,7 @@ return {
"kind": "Fragment",
"metadata": null,
"name": "MembershipsDropdownMenuItem_assumeMutation",
"selections": (v2/*: any*/),
"selections": (v3/*: any*/),
"type": "Mutation",
"abstractKey": null
},
@@ -127,19 +181,19 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "MembershipsDropdownMenuItem_assumeMutation",
"selections": (v2/*: any*/)
"selections": (v3/*: any*/)
},
"params": {
"cacheID": "21ebf9c598bd39f2abcb0ace0d9c0c4b",
"cacheID": "96111606700d6d57e20584324fac44c3",
"id": null,
"metadata": {},
"name": "MembershipsDropdownMenuItem_assumeMutation",
"operationKind": "mutation",
"text": "mutation MembershipsDropdownMenuItem_assumeMutation(\n $input: AssumeOrganizationSessionInput!\n) {\n assumeOrganizationSession(input: $input) {\n result {\n __typename\n ... on PasswordRequired {\n reason\n }\n ... on SAMLAuthenticationRequired {\n reason\n redirectUrl\n }\n }\n }\n}\n"
"text": "mutation MembershipsDropdownMenuItem_assumeMutation(\n $input: AssumeOrganizationSessionInput!\n) {\n assumeOrganizationSession(input: $input) {\n result {\n __typename\n ... on OrganizationSessionCreated {\n membership {\n id\n lastSession {\n id\n expiresAt\n }\n }\n }\n ... on PasswordRequired {\n reason\n }\n ... on SAMLAuthenticationRequired {\n reason\n redirectUrl\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "416f824d526d3f92797fec0eb9c2e590";
(node as any).hash = "706b7dd33f09edc34377a52682d85037";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<ab48c4d454e4f9fa4472a103b8144b7c>>
* @generated SignedSource<<1d247c2fede04c2292000421a9e49fa8>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -14,6 +14,7 @@ export type MembershipsPageQuery$variables = Record<PropertyKey, never>;
export type MembershipsPageQuery$data = {
readonly viewer: {
readonly memberships: {
readonly __id: string;
readonly edges: ReadonlyArray<{
readonly node: {
readonly id: string;
@@ -25,6 +26,7 @@ export type MembershipsPageQuery$data = {
}>;
};
readonly pendingInvitations: {
readonly __id: string;
readonly edges: ReadonlyArray<{
readonly node: {
readonly id: string;
@@ -40,35 +42,93 @@ export type MembershipsPageQuery = {
};
const node: ConcreteRequest = (function(){
var v0 = [
{
"kind": "Literal",
"name": "first",
"value": 1000
},
{
"kind": "Literal",
"name": "orderBy",
"value": {
"direction": "DESC",
"field": "CREATED_AT"
}
var v0 = {
"kind": "Literal",
"name": "orderBy",
"value": {
"direction": "DESC",
"field": "CREATED_AT"
}
},
v1 = [
(v0/*: any*/)
],
v1 = {
v2 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
v2 = {
v3 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
};
},
v4 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__typename",
"storageKey": null
},
v5 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cursor",
"storageKey": null
},
v6 = {
"alias": null,
"args": null,
"concreteType": "PageInfo",
"kind": "LinkedField",
"name": "pageInfo",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "endCursor",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasNextPage",
"storageKey": null
}
],
"storageKey": null
},
v7 = {
"kind": "ClientExtension",
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__id",
"storageKey": null
}
]
},
v8 = [
{
"kind": "Literal",
"name": "first",
"value": 1000
},
(v0/*: any*/)
],
v9 = [
"orderBy"
];
return {
"fragment": {
"argumentDefinitions": [],
@@ -89,11 +149,11 @@ return {
{
"kind": "RequiredField",
"field": {
"alias": null,
"args": (v0/*: any*/),
"alias": "memberships",
"args": (v1/*: any*/),
"concreteType": "MembershipConnection",
"kind": "LinkedField",
"name": "memberships",
"name": "__MembershipsPage_memberships_connection",
"plural": false,
"selections": [
{
@@ -107,60 +167,60 @@ return {
"plural": true,
"selections": [
{
"kind": "RequiredField",
"field": {
"alias": null,
"args": null,
"concreteType": "Membership",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v1/*: any*/),
{
"alias": null,
"args": null,
"concreteType": "Membership",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v2/*: any*/),
{
"args": null,
"kind": "FragmentSpread",
"name": "MembershipCardFragment"
},
{
"kind": "RequiredField",
"field": {
"alias": null,
"args": null,
"kind": "FragmentSpread",
"name": "MembershipCardFragment"
"concreteType": "Organization",
"kind": "LinkedField",
"name": "organization",
"plural": false,
"selections": [
(v3/*: any*/)
],
"storageKey": null
},
{
"kind": "RequiredField",
"field": {
"alias": null,
"args": null,
"concreteType": "Organization",
"kind": "LinkedField",
"name": "organization",
"plural": false,
"selections": [
(v2/*: any*/)
],
"storageKey": null
},
"action": "THROW"
}
],
"storageKey": null
},
"action": "THROW"
}
"action": "THROW"
},
(v4/*: any*/)
],
"storageKey": null
},
(v5/*: any*/)
],
"storageKey": null
},
"action": "THROW"
}
},
(v6/*: any*/),
(v7/*: any*/)
],
"storageKey": "memberships(first:1000,orderBy:{\"direction\":\"DESC\",\"field\":\"CREATED_AT\"})"
"storageKey": "__MembershipsPage_memberships_connection(orderBy:{\"direction\":\"DESC\",\"field\":\"CREATED_AT\"})"
},
"action": "THROW"
},
{
"kind": "RequiredField",
"field": {
"alias": null,
"args": (v0/*: any*/),
"alias": "pendingInvitations",
"args": (v1/*: any*/),
"concreteType": "InvitationConnection",
"kind": "LinkedField",
"name": "pendingInvitations",
"name": "__MembershipsPage_pendingInvitations_connection",
"plural": false,
"selections": [
{
@@ -174,33 +234,33 @@ return {
"plural": true,
"selections": [
{
"kind": "RequiredField",
"field": {
"alias": null,
"args": null,
"concreteType": "Invitation",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v1/*: any*/),
{
"args": null,
"kind": "FragmentSpread",
"name": "InvitationCardFragment"
}
],
"storageKey": null
},
"action": "THROW"
}
"alias": null,
"args": null,
"concreteType": "Invitation",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v2/*: any*/),
{
"args": null,
"kind": "FragmentSpread",
"name": "InvitationCardFragment"
},
(v4/*: any*/)
],
"storageKey": null
},
(v5/*: any*/)
],
"storageKey": null
},
"action": "THROW"
}
},
(v6/*: any*/),
(v7/*: any*/)
],
"storageKey": "pendingInvitations(first:1000,orderBy:{\"direction\":\"DESC\",\"field\":\"CREATED_AT\"})"
"storageKey": "__MembershipsPage_pendingInvitations_connection(orderBy:{\"direction\":\"DESC\",\"field\":\"CREATED_AT\"})"
},
"action": "THROW"
}
@@ -229,7 +289,7 @@ return {
"selections": [
{
"alias": null,
"args": (v0/*: any*/),
"args": (v8/*: any*/),
"concreteType": "MembershipConnection",
"kind": "LinkedField",
"name": "memberships",
@@ -251,7 +311,7 @@ return {
"name": "node",
"plural": false,
"selections": [
(v1/*: any*/),
(v2/*: any*/),
{
"alias": null,
"args": null,
@@ -260,7 +320,7 @@ return {
"name": "lastSession",
"plural": false,
"selections": [
(v1/*: any*/),
(v2/*: any*/),
{
"alias": null,
"args": null,
@@ -279,8 +339,8 @@ return {
"name": "organization",
"plural": false,
"selections": [
(v1/*: any*/),
(v2/*: any*/),
(v3/*: any*/),
{
"alias": null,
"args": null,
@@ -290,19 +350,32 @@ return {
}
],
"storageKey": null
}
},
(v4/*: any*/)
],
"storageKey": null
}
},
(v5/*: any*/)
],
"storageKey": null
}
},
(v6/*: any*/),
(v7/*: any*/)
],
"storageKey": "memberships(first:1000,orderBy:{\"direction\":\"DESC\",\"field\":\"CREATED_AT\"})"
},
{
"alias": null,
"args": (v0/*: any*/),
"args": (v8/*: any*/),
"filters": (v9/*: any*/),
"handle": "connection",
"key": "MembershipsPage_memberships",
"kind": "LinkedHandle",
"name": "memberships"
},
{
"alias": null,
"args": (v8/*: any*/),
"concreteType": "InvitationConnection",
"kind": "LinkedField",
"name": "pendingInvitations",
@@ -324,7 +397,7 @@ return {
"name": "node",
"plural": false,
"selections": [
(v1/*: any*/),
(v2/*: any*/),
{
"alias": null,
"args": null,
@@ -347,37 +420,71 @@ return {
"name": "organization",
"plural": false,
"selections": [
(v1/*: any*/),
(v2/*: any*/)
(v2/*: any*/),
(v3/*: any*/)
],
"storageKey": null
}
},
(v4/*: any*/)
],
"storageKey": null
}
},
(v5/*: any*/)
],
"storageKey": null
}
},
(v6/*: any*/),
(v7/*: any*/)
],
"storageKey": "pendingInvitations(first:1000,orderBy:{\"direction\":\"DESC\",\"field\":\"CREATED_AT\"})"
},
(v1/*: any*/)
{
"alias": null,
"args": (v8/*: any*/),
"filters": (v9/*: any*/),
"handle": "connection",
"key": "MembershipsPage_pendingInvitations",
"kind": "LinkedHandle",
"name": "pendingInvitations"
},
(v2/*: any*/)
],
"storageKey": null
}
]
},
"params": {
"cacheID": "70ba2b8cec46ba8154cf7a6a51e03932",
"cacheID": "a3dc3f3e775fa02b7d181fa57ade06b9",
"id": null,
"metadata": {},
"metadata": {
"connection": [
{
"count": null,
"cursor": null,
"direction": "forward",
"path": [
"viewer",
"memberships"
]
},
{
"count": null,
"cursor": null,
"direction": "forward",
"path": [
"viewer",
"pendingInvitations"
]
}
]
},
"name": "MembershipsPageQuery",
"operationKind": "query",
"text": "query MembershipsPageQuery {\n viewer {\n memberships(first: 1000, orderBy: {direction: DESC, field: CREATED_AT}) {\n edges {\n node {\n id\n ...MembershipCardFragment\n organization {\n name\n id\n }\n }\n }\n }\n pendingInvitations(first: 1000, orderBy: {direction: DESC, field: CREATED_AT}) {\n edges {\n node {\n id\n ...InvitationCardFragment\n }\n }\n }\n id\n }\n}\n\nfragment InvitationCardFragment on Invitation {\n id\n role\n createdAt\n organization {\n id\n name\n }\n}\n\nfragment MembershipCardFragment on Membership {\n lastSession {\n id\n expiresAt\n }\n organization {\n id\n name\n logoUrl\n }\n}\n"
"text": "query MembershipsPageQuery {\n viewer {\n memberships(first: 1000, orderBy: {direction: DESC, field: CREATED_AT}) {\n edges {\n node {\n id\n ...MembershipCardFragment\n organization {\n name\n id\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n pendingInvitations(first: 1000, orderBy: {direction: DESC, field: CREATED_AT}) {\n edges {\n node {\n id\n ...InvitationCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n }\n}\n\nfragment InvitationCardFragment on Invitation {\n id\n role\n createdAt\n organization {\n id\n name\n }\n}\n\nfragment MembershipCardFragment on Membership {\n lastSession {\n id\n expiresAt\n }\n organization {\n id\n name\n logoUrl\n }\n}\n"
}
};
})();
(node as any).hash = "4148521eb3eaba1670a2d181b6d2468f";
(node as any).hash = "b21b9cae0ab7a4afdf12fb6ae516b64e";
export default node;

View File

@@ -17,9 +17,11 @@ export const membershipsPageQuery = graphql`
query MembershipsPageQuery {
viewer @required(action: THROW) {
memberships(first: 1000, orderBy: { direction: DESC, field: CREATED_AT })
@connection(key: "MembershipsPage_memberships")
@required(action: THROW) {
__id
edges @required(action: THROW) {
node @required(action: THROW) {
node {
id
...MembershipCardFragment
organization @required(action: THROW) {
@@ -31,9 +33,12 @@ export const membershipsPageQuery = graphql`
pendingInvitations(
first: 1000
orderBy: { direction: DESC, field: CREATED_AT }
) @required(action: THROW) {
)
@connection(key: "MembershipsPage_pendingInvitations")
@required(action: THROW) {
__id
edges @required(action: THROW) {
node @required(action: THROW) {
node {
id
...InvitationCardFragment
}
@@ -54,8 +59,11 @@ export function MembershipsPage(props: {
const { queryRef } = props;
const {
viewer: {
memberships: { edges: initialMemberships },
pendingInvitations: { edges: invitations },
memberships: { __id: membershipConnectionId, edges: initialMemberships },
pendingInvitations: {
__id: pendingInvitationsConnectionId,
edges: invitations,
},
},
} = usePreloadedQuery<MembershipsPageQuery>(membershipsPageQuery, queryRef);
@@ -81,7 +89,14 @@ export function MembershipsPage(props: {
{__("Pending invitations")}
</h2>
{invitations.map(({ node }) => (
<InvitationCard key={node.id} fKey={node} />
<InvitationCard
pendingInvitationsConnectionId={
pendingInvitationsConnectionId
}
membershipConnectionId={membershipConnectionId}
key={node.id}
fKey={node}
/>
))}
</div>
)}

View File

@@ -1,10 +1,10 @@
import { formatDate, formatError } from "@probo/helpers";
import { useTranslate } from "@probo/i18n";
import { Button, Card, useToast } from "@probo/ui";
import { graphql } from "relay-runtime";
import { graphql, type DataID } from "relay-runtime";
import { useFragment, useMutation } from "react-relay";
import type { InvitationCardFragment$key } from "/__generated__/iam/InvitationCardFragment.graphql";
import { useNavigate } from "react-router";
import type { InvitationCardMutation } from "/__generated__/iam/InvitationCardMutation.graphql";
const fragment = graphql`
fragment InvitationCardFragment on Invitation {
@@ -19,11 +19,22 @@ const fragment = graphql`
`;
const acceptMutation = graphql`
mutation InvitationCardMutation($input: AcceptInvitationInput!) {
mutation InvitationCardMutation(
$input: AcceptInvitationInput!
$membershipConnections: [ID!]!
$pendingInvitationConnections: [ID!]!
) {
acceptInvitation(input: $input) {
membershipEdge {
invitation {
id @deleteEdge(connections: $pendingInvitationConnections)
}
membershipEdge @prependEdge(connections: $membershipConnections) {
node {
id
...MembershipCardFragment
organization {
name
}
}
}
}
@@ -31,19 +42,22 @@ const acceptMutation = graphql`
`;
interface InvitationCardProps {
pendingInvitationsConnectionId: DataID;
membershipConnectionId: DataID;
fKey: InvitationCardFragment$key;
}
export function InvitationCard(props: InvitationCardProps) {
const { fKey } = props;
const { pendingInvitationsConnectionId, membershipConnectionId, fKey } =
props;
const navigate = useNavigate();
const { __ } = useTranslate();
const { toast } = useToast();
const invitation = useFragment<InvitationCardFragment$key>(fragment, fKey);
const [acceptInvitation, isAccepting] = useMutation(acceptMutation);
const [acceptInvitation, isAccepting] =
useMutation<InvitationCardMutation>(acceptMutation);
const handleAccept = () => {
acceptInvitation({
@@ -51,6 +65,8 @@ export function InvitationCard(props: InvitationCardProps) {
input: {
invitationId: invitation.id,
},
pendingInvitationConnections: [pendingInvitationsConnectionId],
membershipConnections: [membershipConnectionId],
},
onCompleted: (_, e) => {
if (e) {
@@ -61,7 +77,6 @@ export function InvitationCard(props: InvitationCardProps) {
});
return;
}
navigate(`/organizations/${invitation.organization.id}`);
},
onError: (e) => {
toast({

View File

@@ -42,6 +42,7 @@ const assumeOrganizationSessionMutation = graphql`
id
lastSession {
id
expiresAt
}
}
}

View File

@@ -35,6 +35,15 @@ const assumeOrganizationSessionMutation = graphql`
assumeOrganizationSession(input: $input) {
result {
__typename
... on OrganizationSessionCreated {
membership {
id
lastSession {
id
expiresAt
}
}
}
... on PasswordRequired {
reason
}
@@ -67,32 +76,36 @@ export function MembershipsDropdownMenuItem(props: {
);
const handleAssumeOrganizationSession = useCallback(() => {
assumeOrganizationSession({
variables: {
input: {
organizationId: organization.id,
if (isAuthenticated) {
navigate(`/organizations/${organization.id}`);
} else {
assumeOrganizationSession({
variables: {
input: {
organizationId: organization.id,
},
},
},
onCompleted: ({ assumeOrganizationSession }) => {
if (!assumeOrganizationSession) {
throw new Error("complete mutation result is empty");
}
onCompleted: ({ assumeOrganizationSession }) => {
if (!assumeOrganizationSession) {
throw new Error("complete mutation result is empty");
}
const { result } = assumeOrganizationSession;
const { result } = assumeOrganizationSession;
switch (result.__typename) {
case "PasswordRequired":
navigate("auth/login");
break;
case "SAMLAuthenticationRequired":
window.location.href = result.redirectUrl;
break;
default:
navigate(`/organizations/${organization.id}`);
}
},
});
}, [assumeOrganizationSession, navigate, organization.id]);
switch (result.__typename) {
case "PasswordRequired":
navigate("/auth/login");
break;
case "SAMLAuthenticationRequired":
window.location.href = result.redirectUrl;
break;
default:
navigate(`/organizations/${organization.id}`);
}
},
});
}
}, [assumeOrganizationSession, navigate, organization.id, isAuthenticated]);
return (
<DropdownItem key={id} onClick={handleAssumeOrganizationSession}>

View File

@@ -68,7 +68,7 @@ export function ViewerMembershipDropdown(props: {
});
return;
}
window.location.reload();
window.location.href = "/auth/login";
},
onError: (e) => {
toast({

View File

@@ -3,43 +3,45 @@ import { tv } from "tailwind-variants";
import { Slot } from "../Slot";
type Props = {
asChild?: boolean;
variant?:
| "success"
| "warning"
| "danger"
| "info"
| "neutral"
| "outline"
| "highlight";
size?: "sm" | "md";
asChild?: boolean;
variant?:
| "success"
| "warning"
| "danger"
| "info"
| "neutral"
| "outline"
| "highlight";
size?: "sm" | "md";
} & HTMLAttributes<HTMLElement>;
const badge = tv({
base: "font-medium rounded-lg w-max flex gap-1 items-center group whitespace-nowrap",
variants: {
variant: {
success: "bg-success text-txt-success",
warning: "bg-warning text-txt-warning",
danger: "bg-danger text-txt-danger",
info: "bg-info text-txt-info",
neutral: "bg-subtle text-txt-secondary",
outline: "text-txt-tertiary border border-border-low",
highlight: "bg-highlight text-txt-primary",
},
size: {
sm: "text-xs py-[2px] px-[6px]",
md: "text-sm py-[6px] px-2",
},
base: "font-medium rounded-lg w-max flex gap-1 items-center group whitespace-nowrap",
variants: {
variant: {
success: "bg-success text-txt-success",
warning: "bg-warning text-txt-warning",
danger: "bg-danger text-txt-danger",
info: "bg-info text-txt-info",
neutral: "bg-subtle text-txt-secondary",
outline: "text-txt-tertiary border border-border-low",
highlight: "bg-highlight text-txt-primary",
},
defaultVariants: {
variant: "neutral",
size: "sm",
size: {
sm: "text-xs py-[2px] px-[6px]",
md: "text-sm py-[6px] px-2",
},
},
defaultVariants: {
variant: "neutral",
size: "sm",
},
});
export function Badge(props: Props) {
const Component = props.asChild ? Slot : "div";
const { size, variant, ...restProps } = props;
return <Component {...restProps} className={badge({ size, variant })} />;
const Component = props.asChild ? Slot : "div";
const { className, size, variant, ...restProps } = props;
return (
<Component {...restProps} className={badge({ className, size, variant })} />
);
}

View File

@@ -198,17 +198,17 @@ func (s *AccountService) AcceptInvitation(
ctx context.Context,
identityID gid.GID,
invitationID gid.GID,
) (*coredata.Membership, error) {
) (*coredata.Invitation, *coredata.Membership, error) {
var (
now = time.Now()
membership = &coredata.Membership{}
invitation = &coredata.Invitation{}
)
err := s.pg.WithTx(
ctx,
func(tx pg.Conn) error {
identity := coredata.Identity{}
invitation := coredata.Invitation{}
err := identity.LoadByID(ctx, tx, identityID)
if err != nil {
@@ -306,10 +306,10 @@ func (s *AccountService) AcceptInvitation(
)
if err != nil {
return nil, err
return nil, nil, err
}
return membership, nil
return invitation, membership, nil
}
func (s *AccountService) ListPendingInvitations(

View File

@@ -829,6 +829,7 @@ type RemoveMemberPayload {
type AcceptInvitationPayload {
membershipEdge: MembershipEdge!
invitation: Invitation!
}
type DeleteInvitationPayload {

View File

@@ -72,6 +72,7 @@ type DirectiveRoot struct {
type ComplexityRoot struct {
AcceptInvitationPayload struct {
Invitation func(childComplexity int) int
MembershipEdge func(childComplexity int) int
}
@@ -587,6 +588,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
_ = ec
switch typeName + "." + field {
case "AcceptInvitationPayload.invitation":
if e.complexity.AcceptInvitationPayload.Invitation == nil {
break
}
return e.complexity.AcceptInvitationPayload.Invitation(childComplexity), true
case "AcceptInvitationPayload.membershipEdge":
if e.complexity.AcceptInvitationPayload.MembershipEdge == nil {
break
@@ -3096,6 +3103,7 @@ type RemoveMemberPayload {
type AcceptInvitationPayload {
membershipEdge: MembershipEdge!
invitation: Invitation!
}
type DeleteInvitationPayload {
@@ -3930,6 +3938,57 @@ func (ec *executionContext) fieldContext_AcceptInvitationPayload_membershipEdge(
return fc, nil
}
func (ec *executionContext) _AcceptInvitationPayload_invitation(ctx context.Context, field graphql.CollectedField, obj *types.AcceptInvitationPayload) (ret graphql.Marshaler) {
return graphql.ResolveField(
ctx,
ec.OperationContext,
field,
ec.fieldContext_AcceptInvitationPayload_invitation,
func(ctx context.Context) (any, error) {
return obj.Invitation, nil
},
nil,
ec.marshalNInvitation2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconnectᚋv1ᚋtypesᚐInvitation,
true,
true,
)
}
func (ec *executionContext) fieldContext_AcceptInvitationPayload_invitation(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AcceptInvitationPayload",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "id":
return ec.fieldContext_Invitation_id(ctx, field)
case "email":
return ec.fieldContext_Invitation_email(ctx, field)
case "fullName":
return ec.fieldContext_Invitation_fullName(ctx, field)
case "role":
return ec.fieldContext_Invitation_role(ctx, field)
case "expiresAt":
return ec.fieldContext_Invitation_expiresAt(ctx, field)
case "acceptedAt":
return ec.fieldContext_Invitation_acceptedAt(ctx, field)
case "createdAt":
return ec.fieldContext_Invitation_createdAt(ctx, field)
case "status":
return ec.fieldContext_Invitation_status(ctx, field)
case "organization":
return ec.fieldContext_Invitation_organization(ctx, field)
case "permission":
return ec.fieldContext_Invitation_permission(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type Invitation", field.Name)
},
}
return fc, nil
}
func (ec *executionContext) _AssumeOrganizationSessionPayload_result(ctx context.Context, field graphql.CollectedField, obj *types.AssumeOrganizationSessionPayload) (ret graphql.Marshaler) {
return graphql.ResolveField(
ctx,
@@ -7658,6 +7717,8 @@ func (ec *executionContext) fieldContext_Mutation_acceptInvitation(ctx context.C
switch field.Name {
case "membershipEdge":
return ec.fieldContext_AcceptInvitationPayload_membershipEdge(ctx, field)
case "invitation":
return ec.fieldContext_AcceptInvitationPayload_invitation(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type AcceptInvitationPayload", field.Name)
},
@@ -15154,6 +15215,11 @@ func (ec *executionContext) _AcceptInvitationPayload(ctx context.Context, sel as
if out.Values[i] == graphql.Null {
out.Invalids++
}
case "invitation":
out.Values[i] = ec._AcceptInvitationPayload_invitation(ctx, field, obj)
if out.Values[i] == graphql.Null {
out.Invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}

View File

@@ -31,6 +31,7 @@ type AcceptInvitationInput struct {
type AcceptInvitationPayload struct {
MembershipEdge *MembershipEdge `json:"membershipEdge"`
Invitation *Invitation `json:"invitation"`
}
type AssumeOrganizationSessionInput struct {

View File

@@ -1006,7 +1006,7 @@ func (r *mutationResolver) AcceptInvitation(ctx context.Context, input types.Acc
identity := IdentityFromContext(ctx)
membership, err := r.iam.AccountService.AcceptInvitation(ctx, identity.ID, input.InvitationID)
invitation, membership, err := r.iam.AccountService.AcceptInvitation(ctx, identity.ID, input.InvitationID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot accept invitation", log.Error(err))
return nil, gqlutils.Internal(ctx)
@@ -1014,6 +1014,7 @@ func (r *mutationResolver) AcceptInvitation(ctx context.Context, input types.Acc
return &types.AcceptInvitationPayload{
MembershipEdge: types.NewMembershipEdge(membership, coredata.MembershipOrderFieldCreatedAt),
Invitation: types.NewInvitation(invitation),
}, nil
}