Refactor people list

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-02-19 14:12:25 +01:00
parent 1747e5eddd
commit 23d0f233eb
9 changed files with 1010 additions and 384 deletions

View File

@@ -5,6 +5,7 @@ import {
usePreloadedQuery,
useQueryLoader,
useMutation,
usePaginationFragment,
} from "react-relay";
import { useSearchParams } from "react-router";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
@@ -14,148 +15,140 @@ import { Button } from "@/components/ui/button";
import { Link } from "react-router";
import { Helmet } from "react-helmet-async";
import type { PeopleListPageQuery as PeopleListPageQueryType } from "./__generated__/PeopleListPageQuery.graphql";
import { PeopleListPagePaginationQuery } from "./__generated__/PeopleListPagePaginationQuery.graphql";
import { PeopleListPage_peoples$key } from "./__generated__/PeopleListPage_peoples.graphql";
const ITEMS_PER_PAGE = 25;
const PeopleListPageQuery = graphql`
const peopleListPageQuery = graphql`
query PeopleListPageQuery(
$first: Int
$after: CursorKey
$last: Int
$before: CursorKey
) {
node(id: "AZSfP_xAcAC5IAAAAAAltA") {
currentOrganization: node(id: "AZSfP_xAcAC5IAAAAAAltA") {
id
... on Organization {
peoples(first: $first, after: $after, last: $last, before: $before)
@connection(key: "PeopleListPageQuery_peoples") {
edges {
node {
id
fullName
primaryEmailAddress
additionalEmailAddresses
kind
createdAt
updatedAt
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
...PeopleListPage_peoples
}
}
}
`;
const peopleListFragment = graphql`
fragment PeopleListPage_peoples on Organization
@refetchable(queryName: "PeopleListPagePaginationQuery") {
id
peoples(first: $first, after: $after, last: $last, before: $before)
@connection(key: "PeopleListPage_peoples") {
__id
edges {
node {
id
fullName
primaryEmailAddress
additionalEmailAddresses
kind
createdAt
updatedAt
}
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}
`;
const deletePeopleMutation = graphql`
mutation PeopleListPageDeletePeopleMutation($input: DeletePeopleInput!) {
deletePeople(input: $input)
mutation PeopleListPageDeletePeopleMutation(
$input: DeletePeopleInput!
$connections: [ID!]!
) {
deletePeople(input: $input) {
deletedPeopleId @deleteEdge(connections: $connections)
}
}
`;
function LoadAboveButton({
pageInfo,
isPending,
onPageChange,
isLoading,
hasMore,
onLoadMore,
}: {
pageInfo: {
hasNextPage: boolean;
hasPreviousPage: boolean;
} | null | undefined;
isPending: boolean;
onPageChange: (direction: "prev") => void;
isLoading: boolean;
hasMore: boolean;
onLoadMore: () => void;
}) {
return (
<div className="flex justify-center">
<Button
variant="outline"
onClick={() => onPageChange("prev")}
disabled={isPending || !pageInfo?.hasPreviousPage}
onClick={onLoadMore}
disabled={isLoading || !hasMore}
className="w-full"
>
{isPending ? "Loading..." : "Load above"}
{isLoading ? "Loading..." : "Load above"}
</Button>
</div>
);
}
function LoadBelowButton({
pageInfo,
isPending,
onPageChange,
isLoading,
hasMore,
onLoadMore,
}: {
pageInfo: {
hasNextPage: boolean;
hasPreviousPage: boolean;
} | null | undefined;
isPending: boolean;
onPageChange: (direction: "next") => void;
isLoading: boolean;
hasMore: boolean;
onLoadMore: () => void;
}) {
return (
<div className="flex justify-center">
<Button
variant="outline"
onClick={() => onPageChange("next")}
disabled={isPending || !pageInfo?.hasNextPage}
onClick={onLoadMore}
disabled={isLoading || !hasMore}
className="w-full"
>
{isPending ? "Loading..." : "Load below"}
{isLoading ? "Loading..." : "Load below"}
</Button>
</div>
);
}
function PeopleListPageContent({
function PeopleListContent({
queryRef,
onPageChange,
}: {
queryRef: PreloadedQuery<PeopleListPageQueryType>;
onPageChange: (params: {
first?: number;
after?: string;
last?: number;
before?: string;
}) => void;
}) {
const data = usePreloadedQuery(PeopleListPageQuery, queryRef);
const data = usePreloadedQuery<PeopleListPageQueryType>(
peopleListPageQuery,
queryRef,
);
const [searchParams, setSearchParams] = useSearchParams();
const peoples = data.node.peoples?.edges.map((edge) => edge?.node) ?? [];
const pageInfo = data.node.peoples?.pageInfo;
const [isPending, startTransition] = useTransition();
const [deletePeople] = useMutation(deletePeopleMutation);
const handlePageChange = (direction: "prev" | "next") => {
if (!pageInfo) return;
const {
data: peoplesConnection,
loadNext,
loadPrevious,
hasNext,
hasPrevious,
isLoadingNext,
isLoadingPrevious,
} = usePaginationFragment<
PeopleListPagePaginationQuery,
PeopleListPage_peoples$key
>(peopleListFragment, data.currentOrganization);
if (direction === "next" && !pageInfo.hasNextPage) return;
if (direction === "prev" && !pageInfo.hasPreviousPage) return;
startTransition(() => {
const params =
direction === "next"
? { first: ITEMS_PER_PAGE, after: pageInfo.endCursor }
: { last: ITEMS_PER_PAGE, before: pageInfo.startCursor };
setSearchParams((prev) => {
if (direction === "next") {
prev.set("after", pageInfo.endCursor!);
prev.delete("before");
} else {
prev.set("before", pageInfo.startCursor!);
prev.delete("after");
}
return prev;
});
onPageChange(params);
});
};
const peoples = peoplesConnection.peoples.edges.map((edge) => edge.node) ?? [];
const pageInfo = peoplesConnection.peoples.pageInfo;
return (
<div className="p-6 space-y-6">
@@ -174,9 +167,18 @@ function PeopleListPageContent({
</div>
<LoadAboveButton
pageInfo={pageInfo}
isPending={isPending}
onPageChange={() => handlePageChange("prev")}
isLoading={isLoadingPrevious}
hasMore={hasPrevious}
onLoadMore={() => {
startTransition(() => {
setSearchParams((prev) => {
prev.set("before", pageInfo?.startCursor || "");
prev.delete("after");
return prev;
});
loadPrevious(ITEMS_PER_PAGE);
});
}}
/>
<div className="space-y-2">
@@ -228,18 +230,11 @@ function PeopleListPageContent({
) {
deletePeople({
variables: {
connections: [peoplesConnection.peoples.__id],
input: {
peopleId: person.id,
},
},
onCompleted() {
onPageChange({
first: ITEMS_PER_PAGE,
after: undefined,
last: undefined,
before: undefined,
});
},
});
}
}}
@@ -249,13 +244,22 @@ function PeopleListPageContent({
</div>
</Link>
))}
<LoadBelowButton
pageInfo={pageInfo}
isPending={isPending}
onPageChange={() => handlePageChange("next")}
/>
</div>
<LoadBelowButton
isLoading={isLoadingNext}
hasMore={hasNext}
onLoadMore={() => {
startTransition(() => {
setSearchParams((prev) => {
prev.set("after", pageInfo?.endCursor || "");
prev.delete("before");
return prev;
});
loadNext(ITEMS_PER_PAGE);
});
}}
/>
</div>
);
}
@@ -299,14 +303,10 @@ function PeopleListPageFallback() {
);
}
type LoadQueryType = ReturnType<
typeof useQueryLoader<PeopleListPageQueryType>
>[1];
export default function PeopleListPage() {
const [searchParams] = useSearchParams();
const [queryRef, loadQuery] =
useQueryLoader<PeopleListPageQueryType>(PeopleListPageQuery);
useQueryLoader<PeopleListPageQueryType>(peopleListPageQuery);
useEffect(() => {
const after = searchParams.get("after");
@@ -318,29 +318,7 @@ export default function PeopleListPage() {
last: before ? ITEMS_PER_PAGE : undefined,
before: before || undefined,
});
}, [loadQuery, searchParams]);
const handlePageChange = ({
first,
after,
last,
before,
}: {
first?: number;
after?: string;
last?: number;
before?: string;
}) => {
loadQuery(
{
first,
after,
last,
before,
},
{ fetchPolicy: "network-only" },
);
};
}, [loadQuery]);
if (!queryRef) {
return <PeopleListPageFallback />;
@@ -352,10 +330,7 @@ export default function PeopleListPage() {
<title>People - Probo Console</title>
</Helmet>
<Suspense fallback={<PeopleListPageFallback />}>
<PeopleListPageContent
queryRef={queryRef}
onPageChange={handlePageChange}
/>
<PeopleListContent queryRef={queryRef} />
</Suspense>
</>
);

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<0dfa6dd207341bf77daca8afe8418c41>>
* @generated SignedSource<<c4cdffc060744bb3853074ed3b123f61>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -13,10 +13,13 @@ export type DeletePeopleInput = {
peopleId: string;
};
export type PeopleListPageDeletePeopleMutation$variables = {
connections: ReadonlyArray<string>;
input: DeletePeopleInput;
};
export type PeopleListPageDeletePeopleMutation$data = {
readonly deletePeople: any;
readonly deletePeople: {
readonly deletedPeopleId: string;
};
};
export type PeopleListPageDeletePeopleMutation = {
response: PeopleListPageDeletePeopleMutation$data;
@@ -24,56 +27,106 @@ export type PeopleListPageDeletePeopleMutation = {
};
const node: ConcreteRequest = (function(){
var v0 = [
var v0 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "connections"
},
v1 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "input"
},
v2 = [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "input"
"kind": "Variable",
"name": "input",
"variableName": "input"
}
],
v1 = [
{
"alias": null,
"args": [
{
"kind": "Variable",
"name": "input",
"variableName": "input"
}
],
"kind": "ScalarField",
"name": "deletePeople",
"storageKey": null
}
];
v3 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "deletedPeopleId",
"storageKey": null
};
return {
"fragment": {
"argumentDefinitions": (v0/*: any*/),
"argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/)
],
"kind": "Fragment",
"metadata": null,
"name": "PeopleListPageDeletePeopleMutation",
"selections": (v1/*: any*/),
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "DeletePeoplePayload",
"kind": "LinkedField",
"name": "deletePeople",
"plural": false,
"selections": [
(v3/*: any*/)
],
"storageKey": null
}
],
"type": "Mutation",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": (v0/*: any*/),
"argumentDefinitions": [
(v1/*: any*/),
(v0/*: any*/)
],
"kind": "Operation",
"name": "PeopleListPageDeletePeopleMutation",
"selections": (v1/*: any*/)
"selections": [
{
"alias": null,
"args": (v2/*: any*/),
"concreteType": "DeletePeoplePayload",
"kind": "LinkedField",
"name": "deletePeople",
"plural": false,
"selections": [
(v3/*: any*/),
{
"alias": null,
"args": null,
"filters": null,
"handle": "deleteEdge",
"key": "",
"kind": "ScalarHandle",
"name": "deletedPeopleId",
"handleArgs": [
{
"kind": "Variable",
"name": "connections",
"variableName": "connections"
}
]
}
],
"storageKey": null
}
]
},
"params": {
"cacheID": "ee5d2a94a7fae0b106873b6cd1cc7d0b",
"cacheID": "977639987276708b1e4758508eaaf439",
"id": null,
"metadata": {},
"name": "PeopleListPageDeletePeopleMutation",
"operationKind": "mutation",
"text": "mutation PeopleListPageDeletePeopleMutation(\n $input: DeletePeopleInput!\n) {\n deletePeople(input: $input)\n}\n"
"text": "mutation PeopleListPageDeletePeopleMutation(\n $input: DeletePeopleInput!\n) {\n deletePeople(input: $input) {\n deletedPeopleId\n }\n}\n"
}
};
})();
(node as any).hash = "d6077ac452cabbacf8678fe527ce928a";
(node as any).hash = "6552abc6c02cdc2c8e84ebbce1eb51f1";
export default node;

View File

@@ -0,0 +1,323 @@
/**
* @generated SignedSource<<9ff37ab5131d3343de8f2d0c843377d1>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime";
export type PeopleListPagePaginationQuery$variables = {
after?: any | null | undefined;
before?: any | null | undefined;
first?: number | null | undefined;
id: string;
last?: number | null | undefined;
};
export type PeopleListPagePaginationQuery$data = {
readonly node: {
readonly " $fragmentSpreads": FragmentRefs<"PeopleListPage_peoples">;
};
};
export type PeopleListPagePaginationQuery = {
response: PeopleListPagePaginationQuery$data;
variables: PeopleListPagePaginationQuery$variables;
};
const node: ConcreteRequest = (function(){
var v0 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "after"
},
v1 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "before"
},
v2 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "first"
},
v3 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "id"
},
v4 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "last"
},
v5 = [
{
"kind": "Variable",
"name": "id",
"variableName": "id"
}
],
v6 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__typename",
"storageKey": null
},
v7 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
v8 = [
{
"kind": "Variable",
"name": "after",
"variableName": "after"
},
{
"kind": "Variable",
"name": "before",
"variableName": "before"
},
{
"kind": "Variable",
"name": "first",
"variableName": "first"
},
{
"kind": "Variable",
"name": "last",
"variableName": "last"
}
];
return {
"fragment": {
"argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/),
(v2/*: any*/),
(v3/*: any*/),
(v4/*: any*/)
],
"kind": "Fragment",
"metadata": null,
"name": "PeopleListPagePaginationQuery",
"selections": [
{
"alias": null,
"args": (v5/*: any*/),
"concreteType": null,
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
{
"args": null,
"kind": "FragmentSpread",
"name": "PeopleListPage_peoples"
}
],
"storageKey": null
}
],
"type": "Query",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/),
(v2/*: any*/),
(v4/*: any*/),
(v3/*: any*/)
],
"kind": "Operation",
"name": "PeopleListPagePaginationQuery",
"selections": [
{
"alias": null,
"args": (v5/*: any*/),
"concreteType": null,
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v6/*: any*/),
(v7/*: any*/),
{
"kind": "InlineFragment",
"selections": [
{
"alias": null,
"args": (v8/*: any*/),
"concreteType": "PeopleConnection",
"kind": "LinkedField",
"name": "peoples",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "PeopleEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v7/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "primaryEmailAddress",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "additionalEmailAddresses",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "kind",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "createdAt",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "updatedAt",
"storageKey": null
},
(v6/*: any*/)
],
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cursor",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "PageInfo",
"kind": "LinkedField",
"name": "pageInfo",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasNextPage",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasPreviousPage",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "startCursor",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "endCursor",
"storageKey": null
}
],
"storageKey": null
},
{
"kind": "ClientExtension",
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__id",
"storageKey": null
}
]
}
],
"storageKey": null
},
{
"alias": null,
"args": (v8/*: any*/),
"filters": null,
"handle": "connection",
"key": "PeopleListPage_peoples",
"kind": "LinkedHandle",
"name": "peoples"
}
],
"type": "Organization",
"abstractKey": null
}
],
"storageKey": null
}
]
},
"params": {
"cacheID": "17a418660f5fd222c0400f2825634ed4",
"id": null,
"metadata": {},
"name": "PeopleListPagePaginationQuery",
"operationKind": "query",
"text": "query PeopleListPagePaginationQuery(\n $after: CursorKey\n $before: CursorKey\n $first: Int\n $last: Int\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...PeopleListPage_peoples\n id\n }\n}\n\nfragment PeopleListPage_peoples on Organization {\n id\n peoples(first: $first, after: $after, last: $last, before: $before) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n additionalEmailAddresses\n kind\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n}\n"
}
};
})();
(node as any).hash = "6602dd60c3adf0db89580e752495c910";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<be78dd1183cd02907304e452fdec348b>>
* @generated SignedSource<<7a16966c3cf3d76ae51330e5536df480>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -9,7 +9,7 @@
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type PeopleKind = "CONTRACTOR" | "EMPLOYEE";
import { FragmentRefs } from "relay-runtime";
export type PeopleListPageQuery$variables = {
after?: any | null | undefined;
before?: any | null | undefined;
@@ -17,28 +17,9 @@ export type PeopleListPageQuery$variables = {
last?: number | null | undefined;
};
export type PeopleListPageQuery$data = {
readonly node: {
readonly currentOrganization: {
readonly id: string;
readonly peoples?: {
readonly edges: ReadonlyArray<{
readonly cursor: any;
readonly node: {
readonly additionalEmailAddresses: ReadonlyArray<string>;
readonly createdAt: any;
readonly fullName: string;
readonly id: string;
readonly kind: PeopleKind;
readonly primaryEmailAddress: string;
readonly updatedAt: any;
};
}>;
readonly pageInfo: {
readonly endCursor: any | null | undefined;
readonly hasNextPage: boolean;
readonly hasPreviousPage: boolean;
readonly startCursor: any | null | undefined;
};
};
readonly " $fragmentSpreads": FragmentRefs<"PeopleListPage_peoples">;
};
};
export type PeopleListPageQuery = {
@@ -89,120 +70,6 @@ v6 = {
"storageKey": null
},
v7 = [
{
"alias": null,
"args": null,
"concreteType": "PeopleEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v5/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "primaryEmailAddress",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "additionalEmailAddresses",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "kind",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "createdAt",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "updatedAt",
"storageKey": null
},
(v6/*: any*/)
],
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cursor",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "PageInfo",
"kind": "LinkedField",
"name": "pageInfo",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasNextPage",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasPreviousPage",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "startCursor",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "endCursor",
"storageKey": null
}
],
"storageKey": null
}
],
v8 = [
{
"kind": "Variable",
"name": "after",
@@ -237,7 +104,7 @@ return {
"name": "PeopleListPageQuery",
"selections": [
{
"alias": null,
"alias": "currentOrganization",
"args": (v4/*: any*/),
"concreteType": null,
"kind": "LinkedField",
@@ -249,14 +116,9 @@ return {
"kind": "InlineFragment",
"selections": [
{
"alias": "peoples",
"args": null,
"concreteType": "PeopleConnection",
"kind": "LinkedField",
"name": "__PeopleListPageQuery_peoples_connection",
"plural": false,
"selections": (v7/*: any*/),
"storageKey": null
"kind": "FragmentSpread",
"name": "PeopleListPage_peoples"
}
],
"type": "Organization",
@@ -281,7 +143,7 @@ return {
"name": "PeopleListPageQuery",
"selections": [
{
"alias": null,
"alias": "currentOrganization",
"args": (v4/*: any*/),
"concreteType": null,
"kind": "LinkedField",
@@ -295,20 +157,145 @@ return {
"selections": [
{
"alias": null,
"args": (v8/*: any*/),
"args": (v7/*: any*/),
"concreteType": "PeopleConnection",
"kind": "LinkedField",
"name": "peoples",
"plural": false,
"selections": (v7/*: any*/),
"selections": [
{
"alias": null,
"args": null,
"concreteType": "PeopleEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v5/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "primaryEmailAddress",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "additionalEmailAddresses",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "kind",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "createdAt",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "updatedAt",
"storageKey": null
},
(v6/*: any*/)
],
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cursor",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "PageInfo",
"kind": "LinkedField",
"name": "pageInfo",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasNextPage",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasPreviousPage",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "startCursor",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "endCursor",
"storageKey": null
}
],
"storageKey": null
},
{
"kind": "ClientExtension",
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__id",
"storageKey": null
}
]
}
],
"storageKey": null
},
{
"alias": null,
"args": (v8/*: any*/),
"args": (v7/*: any*/),
"filters": null,
"handle": "connection",
"key": "PeopleListPageQuery_peoples",
"key": "PeopleListPage_peoples",
"kind": "LinkedHandle",
"name": "peoples"
}
@@ -322,28 +309,16 @@ return {
]
},
"params": {
"cacheID": "480538011d1eccb9405f2d495417fc8d",
"cacheID": "99597791fe9f240b902affc3d5e63af6",
"id": null,
"metadata": {
"connection": [
{
"count": null,
"cursor": null,
"direction": "bidirectional",
"path": [
"node",
"peoples"
]
}
]
},
"metadata": {},
"name": "PeopleListPageQuery",
"operationKind": "query",
"text": "query PeopleListPageQuery(\n $first: Int\n $after: CursorKey\n $last: Int\n $before: CursorKey\n) {\n node(id: \"AZSfP_xAcAC5IAAAAAAltA\") {\n __typename\n id\n ... on Organization {\n peoples(first: $first, after: $after, last: $last, before: $before) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n additionalEmailAddresses\n kind\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n}\n"
"text": "query PeopleListPageQuery(\n $first: Int\n $after: CursorKey\n $last: Int\n $before: CursorKey\n) {\n currentOrganization: node(id: \"AZSfP_xAcAC5IAAAAAAltA\") {\n __typename\n id\n ... on Organization {\n ...PeopleListPage_peoples\n }\n }\n}\n\nfragment PeopleListPage_peoples on Organization {\n id\n peoples(first: $first, after: $after, last: $last, before: $before) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n additionalEmailAddresses\n kind\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n}\n"
}
};
})();
(node as any).hash = "cc8b466dc73007c5590ba2e8ffc6def3";
(node as any).hash = "f9f133aa09d9d051cef5697aba2398c5";
export default node;

View File

@@ -0,0 +1,257 @@
/**
* @generated SignedSource<<5e071fe96262050a43c9471c27ff667e>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ReaderFragment } from 'relay-runtime';
export type PeopleKind = "CONTRACTOR" | "EMPLOYEE";
import { FragmentRefs } from "relay-runtime";
export type PeopleListPage_peoples$data = {
readonly id: string;
readonly peoples: {
readonly __id: string;
readonly edges: ReadonlyArray<{
readonly node: {
readonly additionalEmailAddresses: ReadonlyArray<string>;
readonly createdAt: any;
readonly fullName: string;
readonly id: string;
readonly kind: PeopleKind;
readonly primaryEmailAddress: string;
readonly updatedAt: any;
};
}>;
readonly pageInfo: {
readonly endCursor: any | null | undefined;
readonly hasNextPage: boolean;
readonly hasPreviousPage: boolean;
readonly startCursor: any | null | undefined;
};
};
readonly " $fragmentType": "PeopleListPage_peoples";
};
export type PeopleListPage_peoples$key = {
readonly " $data"?: PeopleListPage_peoples$data;
readonly " $fragmentSpreads": FragmentRefs<"PeopleListPage_peoples">;
};
const node: ReaderFragment = (function(){
var v0 = [
"peoples"
],
v1 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
};
return {
"argumentDefinitions": [
{
"kind": "RootArgument",
"name": "after"
},
{
"kind": "RootArgument",
"name": "before"
},
{
"kind": "RootArgument",
"name": "first"
},
{
"kind": "RootArgument",
"name": "last"
}
],
"kind": "Fragment",
"metadata": {
"connection": [
{
"count": null,
"cursor": null,
"direction": "bidirectional",
"path": (v0/*: any*/)
}
],
"refetch": {
"connection": {
"forward": {
"count": "first",
"cursor": "after"
},
"backward": {
"count": "last",
"cursor": "before"
},
"path": (v0/*: any*/)
},
"fragmentPathInResult": [
"node"
],
"operation": require('./PeopleListPagePaginationQuery.graphql'),
"identifierInfo": {
"identifierField": "id",
"identifierQueryVariableName": "id"
}
}
},
"name": "PeopleListPage_peoples",
"selections": [
(v1/*: any*/),
{
"alias": "peoples",
"args": null,
"concreteType": "PeopleConnection",
"kind": "LinkedField",
"name": "__PeopleListPage_peoples_connection",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "PeopleEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v1/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "primaryEmailAddress",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "additionalEmailAddresses",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "kind",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "createdAt",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "updatedAt",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__typename",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cursor",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "PageInfo",
"kind": "LinkedField",
"name": "pageInfo",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasNextPage",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasPreviousPage",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "startCursor",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "endCursor",
"storageKey": null
}
],
"storageKey": null
},
{
"kind": "ClientExtension",
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__id",
"storageKey": null
}
]
}
],
"storageKey": null
}
],
"type": "Organization",
"abstractKey": null
};
})();
(node as any).hash = "6602dd60c3adf0db89580e752495c910";
export default node;

View File

@@ -319,7 +319,7 @@ type Mutation {
deleteVendor(input: DeleteVendorInput!): DeleteVendorPayload!
createPeople(input: CreatePeopleInput!): CreatePeoplePayload!
updatePeople(input: UpdatePeopleInput!): People!
deletePeople(input: DeletePeopleInput!): Void!
deletePeople(input: DeletePeopleInput!): DeletePeoplePayload!
}
input CreateVendorInput {
@@ -395,6 +395,9 @@ type CreateVendorPayload {
}
type DeleteVendorPayload {
vendorEdge: VendorEdge!
deletedVendorId: ID!
}
type DeletePeoplePayload {
deletedPeopleId: ID!
}

View File

@@ -104,9 +104,12 @@ type ComplexityRoot struct {
VendorEdge func(childComplexity int) int
}
DeletePeoplePayload struct {
DeletedPeopleID func(childComplexity int) int
}
DeleteVendorPayload struct {
DeletedVendorID func(childComplexity int) int
VendorEdge func(childComplexity int) int
}
Evidence struct {
@@ -303,7 +306,7 @@ type MutationResolver interface {
DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (*types.DeleteVendorPayload, error)
CreatePeople(ctx context.Context, input types.CreatePeopleInput) (*types.CreatePeoplePayload, error)
UpdatePeople(ctx context.Context, input types.UpdatePeopleInput) (*types.People, error)
DeletePeople(ctx context.Context, input types.DeletePeopleInput) (string, error)
DeletePeople(ctx context.Context, input types.DeletePeopleInput) (*types.DeletePeoplePayload, error)
}
type OrganizationResolver interface {
Frameworks(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.FrameworkConnection, error)
@@ -522,6 +525,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.CreateVendorPayload.VendorEdge(childComplexity), true
case "DeletePeoplePayload.deletedPeopleId":
if e.complexity.DeletePeoplePayload.DeletedPeopleID == nil {
break
}
return e.complexity.DeletePeoplePayload.DeletedPeopleID(childComplexity), true
case "DeleteVendorPayload.deletedVendorId":
if e.complexity.DeleteVendorPayload.DeletedVendorID == nil {
break
@@ -529,13 +539,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.DeleteVendorPayload.DeletedVendorID(childComplexity), true
case "DeleteVendorPayload.vendorEdge":
if e.complexity.DeleteVendorPayload.VendorEdge == nil {
break
}
return e.complexity.DeleteVendorPayload.VendorEdge(childComplexity), true
case "Evidence.createdAt":
if e.complexity.Evidence.CreatedAt == nil {
break
@@ -1752,7 +1755,7 @@ type Mutation {
deleteVendor(input: DeleteVendorInput!): DeleteVendorPayload!
createPeople(input: CreatePeopleInput!): CreatePeoplePayload!
updatePeople(input: UpdatePeopleInput!): People!
deletePeople(input: DeletePeopleInput!): Void!
deletePeople(input: DeletePeopleInput!): DeletePeoplePayload!
}
input CreateVendorInput {
@@ -1828,9 +1831,12 @@ type CreateVendorPayload {
}
type DeleteVendorPayload {
vendorEdge: VendorEdge!
deletedVendorId: ID!
}
type DeletePeoplePayload {
deletedPeopleId: ID!
}
`, BuiltIn: false},
}
var parsedSchema = gqlparser.MustLoadSchema(sources...)
@@ -3814,15 +3820,15 @@ func (ec *executionContext) fieldContext_CreateVendorPayload_vendorEdge(_ contex
return fc, nil
}
func (ec *executionContext) _DeleteVendorPayload_vendorEdge(ctx context.Context, field graphql.CollectedField, obj *types.DeleteVendorPayload) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_DeleteVendorPayload_vendorEdge(ctx, field)
func (ec *executionContext) _DeletePeoplePayload_deletedPeopleId(ctx context.Context, field graphql.CollectedField, obj *types.DeletePeoplePayload) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_DeletePeoplePayload_deletedPeopleId(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.VendorEdge, nil
return obj.DeletedPeopleID, nil
})
if err != nil {
ec.Error(ctx, err)
@@ -3834,25 +3840,19 @@ func (ec *executionContext) _DeleteVendorPayload_vendorEdge(ctx context.Context,
}
return graphql.Null
}
res := resTmp.(*types.VendorEdge)
res := resTmp.(gid.GID)
fc.Result = res
return ec.marshalNVendorEdge2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorEdge(ctx, field.Selections, res)
return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_DeleteVendorPayload_vendorEdge(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
func (ec *executionContext) fieldContext_DeletePeoplePayload_deletedPeopleId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "DeleteVendorPayload",
Object: "DeletePeoplePayload",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "cursor":
return ec.fieldContext_VendorEdge_cursor(ctx, field)
case "node":
return ec.fieldContext_VendorEdge_node(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type VendorEdge", field.Name)
return nil, errors.New("field of type ID does not have child fields")
},
}
return fc, nil
@@ -5373,8 +5373,6 @@ func (ec *executionContext) fieldContext_Mutation_deleteVendor(ctx context.Conte
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "vendorEdge":
return ec.fieldContext_DeleteVendorPayload_vendorEdge(ctx, field)
case "deletedVendorId":
return ec.fieldContext_DeleteVendorPayload_deletedVendorId(ctx, field)
}
@@ -5517,9 +5515,9 @@ func (ec *executionContext) _Mutation_deletePeople(ctx context.Context, field gr
}
return graphql.Null
}
res := resTmp.(string)
res := resTmp.(*types.DeletePeoplePayload)
fc.Result = res
return ec.marshalNVoid2string(ctx, field.Selections, res)
return ec.marshalNDeletePeoplePayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐDeletePeoplePayload(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_deletePeople(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -5529,7 +5527,11 @@ func (ec *executionContext) fieldContext_Mutation_deletePeople(ctx context.Conte
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Void does not have child fields")
switch field.Name {
case "deletedPeopleId":
return ec.fieldContext_DeletePeoplePayload_deletedPeopleId(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type DeletePeoplePayload", field.Name)
},
}
ctx = graphql.WithFieldContext(ctx, fc)
@@ -10679,6 +10681,45 @@ func (ec *executionContext) _CreateVendorPayload(ctx context.Context, sel ast.Se
return out
}
var deletePeoplePayloadImplementors = []string{"DeletePeoplePayload"}
func (ec *executionContext) _DeletePeoplePayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeletePeoplePayload) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, deletePeoplePayloadImplementors)
out := graphql.NewFieldSet(fields)
deferred := make(map[string]*graphql.FieldSet)
for i, field := range fields {
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("DeletePeoplePayload")
case "deletedPeopleId":
out.Values[i] = ec._DeletePeoplePayload_deletedPeopleId(ctx, field, obj)
if out.Values[i] == graphql.Null {
out.Invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
}
out.Dispatch(ctx)
if out.Invalids > 0 {
return graphql.Null
}
atomic.AddInt32(&ec.deferred, int32(len(deferred)))
for label, dfs := range deferred {
ec.processDeferredGroup(graphql.DeferredGroup{
Label: label,
Path: graphql.GetPath(ctx),
FieldSet: dfs,
Context: ctx,
})
}
return out
}
var deleteVendorPayloadImplementors = []string{"DeleteVendorPayload"}
func (ec *executionContext) _DeleteVendorPayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteVendorPayload) graphql.Marshaler {
@@ -10690,11 +10731,6 @@ func (ec *executionContext) _DeleteVendorPayload(ctx context.Context, sel ast.Se
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("DeleteVendorPayload")
case "vendorEdge":
out.Values[i] = ec._DeleteVendorPayload_vendorEdge(ctx, field, obj)
if out.Values[i] == graphql.Null {
out.Invalids++
}
case "deletedVendorId":
out.Values[i] = ec._DeleteVendorPayload_deletedVendorId(ctx, field, obj)
if out.Values[i] == graphql.Null {
@@ -12872,6 +12908,20 @@ func (ec *executionContext) unmarshalNDeletePeopleInput2githubᚗcomᚋgetprobo
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNDeletePeoplePayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐDeletePeoplePayload(ctx context.Context, sel ast.SelectionSet, v types.DeletePeoplePayload) graphql.Marshaler {
return ec._DeletePeoplePayload(ctx, sel, &v)
}
func (ec *executionContext) marshalNDeletePeoplePayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐDeletePeoplePayload(ctx context.Context, sel ast.SelectionSet, v *types.DeletePeoplePayload) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
}
return graphql.Null
}
return ec._DeletePeoplePayload(ctx, sel, v)
}
func (ec *executionContext) unmarshalNDeleteVendorInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorInput(ctx context.Context, v any) (types.DeleteVendorInput, error) {
res, err := ec.unmarshalInputDeleteVendorInput(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
@@ -13651,21 +13701,6 @@ func (ec *executionContext) marshalNVendorEdge2ᚖgithubᚗcomᚋgetproboᚋprob
return ec._VendorEdge(ctx, sel, v)
}
func (ec *executionContext) unmarshalNVoid2string(ctx context.Context, v any) (string, error) {
res, err := graphql.UnmarshalString(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNVoid2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler {
res := graphql.MarshalString(v)
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
}
}
return res
}
func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler {
return ec.___Directive(ctx, sel, &v)
}

View File

@@ -92,13 +92,16 @@ type DeletePeopleInput struct {
PeopleID gid.GID `json:"peopleId"`
}
type DeletePeoplePayload struct {
DeletedPeopleID gid.GID `json:"deletedPeopleId"`
}
type DeleteVendorInput struct {
VendorID gid.GID `json:"vendorId"`
}
type DeleteVendorPayload struct {
VendorEdge *VendorEdge `json:"vendorEdge"`
DeletedVendorID gid.GID `json:"deletedVendorId"`
DeletedVendorID gid.GID `json:"deletedVendorId"`
}
type Evidence struct {

View File

@@ -158,13 +158,15 @@ func (r *mutationResolver) UpdatePeople(ctx context.Context, input types.UpdateP
}
// DeletePeople is the resolver for the deletePeople field.
func (r *mutationResolver) DeletePeople(ctx context.Context, input types.DeletePeopleInput) (string, error) {
func (r *mutationResolver) DeletePeople(ctx context.Context, input types.DeletePeopleInput) (*types.DeletePeoplePayload, error) {
err := r.svc.DeletePeople(ctx, input.PeopleID)
if err != nil {
return "", fmt.Errorf("cannot delete people: %w", err)
return nil, fmt.Errorf("cannot delete people: %w", err)
}
return "", nil
return &types.DeletePeoplePayload{
DeletedPeopleID: input.PeopleID,
}, nil
}
// Frameworks is the resolver for the frameworks field.