Update obligations

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-09-23 14:02:18 +02:00
parent c54051dd8a
commit 98d7e7b7b9
39 changed files with 3746 additions and 394 deletions

View File

@@ -0,0 +1,213 @@
import { graphql } from "relay-runtime";
import {
Card,
IconPlusLarge,
Button,
Tr,
Td,
Table,
Thead,
Tbody,
Th,
IconChevronDown,
IconTrashCan,
TrButton,
Badge,
} from "@probo/ui";
import { useTranslate } from "@probo/i18n";
import type { LinkedObligationsCardFragment$key } from "./__generated__/LinkedObligationsCardFragment.graphql";
import { useFragment } from "react-relay";
import { useMemo, useState } from "react";
import { sprintf, getObligationStatusVariant, getObligationStatusLabel } from "@probo/helpers";
import { LinkedObligationDialog } from "./LinkedObligationsDialog";
import clsx from "clsx";
import { useParams } from "react-router";
import { useOrganizationId } from "/hooks/useOrganizationId";
const linkedObligationFragment = graphql`
fragment LinkedObligationsCardFragment on Obligation {
id
requirement
area
source
status
owner {
fullName
}
}
`;
type Mutation<Params> = (p: {
variables: {
input: {
obligationId: string;
} & Params;
connections: string[];
};
}) => void;
type Props<Params> = {
obligations: (LinkedObligationsCardFragment$key & { id: string })[];
connectionId: string;
disabled?: boolean;
variant?: "card" | "table";
params: Params;
onAttach: Mutation<Params>;
onDetach: Mutation<Params>;
};
export function LinkedObligationsCard<Params>(props: Props<Params>) {
const { __ } = useTranslate();
const [limit, setLimit] = useState<number | null>(
props.variant === "card" ? 4 : null
);
const onAttach = (obligationId: string) => {
props.onAttach({
variables: {
input: {
obligationId,
...props.params,
},
connections: [props.connectionId],
},
});
};
const onDetach = (obligationId: string) => {
props.onDetach({
variables: {
input: {
obligationId,
...props.params,
},
connections: [props.connectionId],
},
});
};
const obligations = useMemo(() => {
return limit ? props.obligations.slice(0, limit) : props.obligations;
}, [props.obligations, limit]);
const showMoreButton = limit !== null && props.obligations.length > limit;
const variant = props.variant ?? "table";
const Wrapper = variant === "card" ? Card : "div";
return (
<Wrapper padded className="space-y-[10px]">
{variant === "card" && (
<div className="flex justify-between">
<div className="text-lg font-semibold">{__("Obligations")}</div>
<LinkedObligationDialog
connectionId={props.connectionId}
disabled={props.disabled}
linkedObligations={props.obligations}
onLink={onAttach}
onUnlink={onDetach}
>
<Button variant="tertiary" icon={IconPlusLarge}>
{__("Link obligation")}
</Button>
</LinkedObligationDialog>
</div>
)}
<Table className={clsx(variant === "card" && "bg-invert")}>
<Thead>
<Tr>
<Th>{__("Area")}</Th>
<Th>{__("Source")}</Th>
<Th>{__("Status")}</Th>
<Th>{__("Owner")}</Th>
<Th></Th>
</Tr>
</Thead>
<Tbody>
{obligations.length === 0 && (
<Tr>
<Td colSpan={4} className="text-center text-txt-secondary">
{__("No obligations linked")}
</Td>
</Tr>
)}
{obligations.map((obligation) => (
<ObligationRow key={obligation.id} obligation={obligation} onClick={onDetach} />
))}
{variant === "table" && (
<LinkedObligationDialog
connectionId={props.connectionId}
disabled={props.disabled}
linkedObligations={props.obligations}
onLink={onAttach}
onUnlink={onDetach}
>
<TrButton colspan={5} icon={IconPlusLarge}>
{__("Link obligation")}
</TrButton>
</LinkedObligationDialog>
)}
</Tbody>
</Table>
{showMoreButton && (
<Button
variant="tertiary"
onClick={() => setLimit(null)}
className="mt-3 mx-auto"
icon={IconChevronDown}
>
{sprintf(__("Show %s more"), props.obligations.length - limit)}
</Button>
)}
</Wrapper>
);
}
function ObligationRow(props: {
obligation: LinkedObligationsCardFragment$key & { id: string };
onClick: (obligationId: string) => void;
}) {
const { __ } = useTranslate();
const obligation = useFragment(linkedObligationFragment, props.obligation);
const organizationId = useOrganizationId();
const { snapshotId } = useParams<{ snapshotId?: string }>();
const isSnapshotMode = Boolean(snapshotId);
const onDetach = () => {
props.onClick(obligation.id);
};
const detailsUrl = isSnapshotMode
? `/organizations/${organizationId}/snapshots/${snapshotId}/obligations/${obligation.id}`
: `/organizations/${organizationId}/obligations/${obligation.id}`;
return (
<Tr to={detailsUrl}>
<Td>
{obligation.area || __("No area specified")}
</Td>
<Td>
{obligation.source || __("No source specified")}
</Td>
<Td>
<Badge variant={getObligationStatusVariant(obligation.status)}>
{getObligationStatusLabel(obligation.status)}
</Badge>
</Td>
<Td>
{obligation.owner?.fullName || __("Unassigned")}
</Td>
<Td noLink width={50} className="text-end">
<Button
variant="secondary"
icon={IconTrashCan}
onClick={onDetach}
>
{__("Unlink")}
</Button>
</Td>
</Tr>
);
}

View File

@@ -0,0 +1,199 @@
import {
Button,
Dialog,
DialogContent,
DialogFooter,
IconMagnifyingGlass,
IconPlusLarge,
IconTrashCan,
InfiniteScrollTrigger,
Input,
Spinner,
Badge,
} from "@probo/ui";
import { useTranslate } from "@probo/i18n";
import { getObligationStatusVariant, getObligationStatusLabel } from "@probo/helpers";
import { Suspense, useMemo, useState, type ReactNode } from "react";
import { graphql } from "relay-runtime";
import { useLazyLoadQuery, usePaginationFragment } from "react-relay";
import type { LinkedObligationsDialogQuery } from "./__generated__/LinkedObligationsDialogQuery.graphql";
import { useOrganizationId } from "/hooks/useOrganizationId";
import type { NodeOf } from "/types";
import type {
LinkedObligationsDialogFragment$data,
LinkedObligationsDialogFragment$key,
} from "./__generated__/LinkedObligationsDialogFragment.graphql";
const obligationsQuery = graphql`
query LinkedObligationsDialogQuery($organizationId: ID!) {
organization: node(id: $organizationId) {
id
... on Organization {
...LinkedObligationsDialogFragment
}
}
}
`;
const obligationsFragment = graphql`
fragment LinkedObligationsDialogFragment on Organization
@refetchable(queryName: "LinkedObligationsDialogQuery_fragment")
@argumentDefinitions(
first: { type: "Int", defaultValue: 20 }
order: { type: "ObligationOrder", defaultValue: null }
after: { type: "CursorKey", defaultValue: null }
before: { type: "CursorKey", defaultValue: null }
last: { type: "Int", defaultValue: null }
) {
obligations(
first: $first
after: $after
last: $last
before: $before
orderBy: $order
) @connection(key: "LinkedObligationsDialogQuery_obligations") {
edges {
node {
id
requirement
area
source
status
owner {
fullName
}
}
}
}
}
`;
type Props = {
children: ReactNode;
connectionId: string;
disabled?: boolean;
linkedObligations?: { id: string }[];
onLink: (obligationId: string) => void;
onUnlink: (obligationId: string) => void;
};
export function LinkedObligationDialog({ children, ...props }: Props) {
const { __ } = useTranslate();
return (
<Dialog trigger={children} title={__("Link obligations")}>
<DialogContent>
<Suspense fallback={<Spinner centered />}>
<LinkedObligationsDialogContent {...props} />
</Suspense>
</DialogContent>
<DialogFooter exitLabel={__("Close")} />
</Dialog>
);
}
function LinkedObligationsDialogContent(props: Omit<Props, "children">) {
const organizationId = useOrganizationId();
const query = useLazyLoadQuery<LinkedObligationsDialogQuery>(obligationsQuery, {
organizationId,
}, { fetchPolicy: "network-only" });
const { data, loadNext, hasNext, isLoadingNext } = usePaginationFragment(
obligationsFragment,
query.organization as LinkedObligationsDialogFragment$key
);
const { __ } = useTranslate();
const [search, setSearch] = useState("");
const obligations = data.obligations?.edges?.map((edge) => edge.node) ?? [];
const linkedIds = useMemo(() => {
return new Set(props.linkedObligations?.map((o) => o.id) ?? []);
}, [props.linkedObligations]);
const filteredObligations = useMemo(() => {
return obligations.filter((obligation) =>
obligation.area?.toLowerCase().includes(search.toLowerCase()) ||
obligation.source?.toLowerCase().includes(search.toLowerCase()) ||
obligation.owner?.fullName?.toLowerCase().includes(search.toLowerCase())
);
}, [obligations, search]);
return (
<>
<div className="flex items-center gap-2 sticky top-0 relative py-4 bg-linear-to-b from-50% from-level-2 to-level-2/0 px-6">
<Input
icon={IconMagnifyingGlass}
placeholder={__("Search obligations...")}
onValueChange={setSearch}
/>
</div>
<div className="divide-y divide-border-low">
{filteredObligations.map((obligation) => (
<ObligationRow
key={obligation.id}
obligation={obligation}
linkedObligations={linkedIds}
onLink={props.onLink}
onUnlink={props.onUnlink}
disabled={props.disabled}
/>
))}
{hasNext && (
<InfiniteScrollTrigger
loading={isLoadingNext}
onView={() => loadNext(20)}
/>
)}
</div>
</>
);
}
type Obligation = NodeOf<LinkedObligationsDialogFragment$data["obligations"]>;
function ObligationRow(props: {
obligation: Obligation;
linkedObligations: Set<string>;
onLink: (obligationId: string) => void;
onUnlink: (obligationId: string) => void;
disabled?: boolean;
}) {
const { __ } = useTranslate();
const isLinked = props.linkedObligations.has(props.obligation.id);
const onToggle = () => {
if (isLinked) {
props.onUnlink(props.obligation.id);
} else {
props.onLink(props.obligation.id);
}
};
return (
<div className="flex items-center justify-between p-4 hover:bg-level-1">
<div className="flex-1 min-w-0">
<div className="flex items-center gap-3">
<div className="flex-1 min-w-0">
<div className="text-sm font-medium text-txt-primary truncate">
{props.obligation.area || __("No area specified")}
{props.obligation.source || __("No source specified")}
</div>
<div className="text-xs text-txt-secondary">
{props.obligation.owner?.fullName || __("Unassigned")}
</div>
</div>
<Badge variant={getObligationStatusVariant(props.obligation.status)}>
{getObligationStatusLabel(props.obligation.status)}
</Badge>
</div>
</div>
<Button
variant={isLinked ? "secondary" : "primary"}
icon={isLinked ? IconTrashCan : IconPlusLarge}
onClick={onToggle}
disabled={props.disabled}
className="ml-6"
>
{isLinked ? __("Unlink") : __("Link")}
</Button>
</div>
);
}

View File

@@ -0,0 +1,96 @@
/**
* @generated SignedSource<<1126620dba70ca7a331c00347217eaa8>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ReaderFragment } from 'relay-runtime';
export type ObligationStatus = "COMPLIANT" | "NON_COMPLIANT" | "PARTIALLY_COMPLIANT";
import { FragmentRefs } from "relay-runtime";
export type LinkedObligationsCardFragment$data = {
readonly area: string | null | undefined;
readonly id: string;
readonly owner: {
readonly fullName: string;
};
readonly requirement: string | null | undefined;
readonly source: string | null | undefined;
readonly status: ObligationStatus;
readonly " $fragmentType": "LinkedObligationsCardFragment";
};
export type LinkedObligationsCardFragment$key = {
readonly " $data"?: LinkedObligationsCardFragment$data;
readonly " $fragmentSpreads": FragmentRefs<"LinkedObligationsCardFragment">;
};
const node: ReaderFragment = {
"argumentDefinitions": [],
"kind": "Fragment",
"metadata": null,
"name": "LinkedObligationsCardFragment",
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "requirement",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "area",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "source",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "status",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "owner",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
}
],
"storageKey": null
}
],
"type": "Obligation",
"abstractKey": null
};
(node as any).hash = "67ae0e6b0df090bb5a708bf7e029f4c5";
export default node;

View File

@@ -0,0 +1,260 @@
/**
* @generated SignedSource<<4569a09dbc9fbf80fb787da46d0d058f>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ReaderFragment } from 'relay-runtime';
export type ObligationStatus = "COMPLIANT" | "NON_COMPLIANT" | "PARTIALLY_COMPLIANT";
import { FragmentRefs } from "relay-runtime";
export type LinkedObligationsDialogFragment$data = {
readonly id: string;
readonly obligations: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly area: string | null | undefined;
readonly id: string;
readonly owner: {
readonly fullName: string;
};
readonly requirement: string | null | undefined;
readonly source: string | null | undefined;
readonly status: ObligationStatus;
};
}>;
};
readonly " $fragmentType": "LinkedObligationsDialogFragment";
};
export type LinkedObligationsDialogFragment$key = {
readonly " $data"?: LinkedObligationsDialogFragment$data;
readonly " $fragmentSpreads": FragmentRefs<"LinkedObligationsDialogFragment">;
};
import LinkedObligationsDialogQuery_fragment_graphql from './LinkedObligationsDialogQuery_fragment.graphql';
const node: ReaderFragment = (function(){
var v0 = [
"obligations"
],
v1 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
};
return {
"argumentDefinitions": [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "after"
},
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "before"
},
{
"defaultValue": 20,
"kind": "LocalArgument",
"name": "first"
},
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "last"
},
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "order"
}
],
"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": LinkedObligationsDialogQuery_fragment_graphql,
"identifierInfo": {
"identifierField": "id",
"identifierQueryVariableName": "id"
}
}
},
"name": "LinkedObligationsDialogFragment",
"selections": [
{
"alias": "obligations",
"args": [
{
"kind": "Variable",
"name": "orderBy",
"variableName": "order"
}
],
"concreteType": "ObligationConnection",
"kind": "LinkedField",
"name": "__LinkedObligationsDialogQuery_obligations_connection",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "ObligationEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Obligation",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v1/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "requirement",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "area",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "source",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "status",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "owner",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
}
],
"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": "endCursor",
"storageKey": null
},
{
"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
}
],
"storageKey": null
}
],
"storageKey": null
},
(v1/*: any*/)
],
"type": "Organization",
"abstractKey": null
};
})();
(node as any).hash = "6e686f2a4bce776146b1985df2863e73";
export default node;

View File

@@ -0,0 +1,278 @@
/**
* @generated SignedSource<<44ee1c9c1b8d060d03736d1703d2a68a>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime";
export type LinkedObligationsDialogQuery$variables = {
organizationId: string;
};
export type LinkedObligationsDialogQuery$data = {
readonly organization: {
readonly id: string;
readonly " $fragmentSpreads": FragmentRefs<"LinkedObligationsDialogFragment">;
};
};
export type LinkedObligationsDialogQuery = {
response: LinkedObligationsDialogQuery$data;
variables: LinkedObligationsDialogQuery$variables;
};
const node: ConcreteRequest = (function(){
var v0 = [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "organizationId"
}
],
v1 = [
{
"kind": "Variable",
"name": "id",
"variableName": "organizationId"
}
],
v2 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
v3 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__typename",
"storageKey": null
},
v4 = [
{
"kind": "Literal",
"name": "first",
"value": 20
}
];
return {
"fragment": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "LinkedObligationsDialogQuery",
"selections": [
{
"alias": "organization",
"args": (v1/*: any*/),
"concreteType": null,
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v2/*: any*/),
{
"kind": "InlineFragment",
"selections": [
{
"args": null,
"kind": "FragmentSpread",
"name": "LinkedObligationsDialogFragment"
}
],
"type": "Organization",
"abstractKey": null
}
],
"storageKey": null
}
],
"type": "Query",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "LinkedObligationsDialogQuery",
"selections": [
{
"alias": "organization",
"args": (v1/*: any*/),
"concreteType": null,
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v3/*: any*/),
(v2/*: any*/),
{
"kind": "InlineFragment",
"selections": [
{
"alias": null,
"args": (v4/*: any*/),
"concreteType": "ObligationConnection",
"kind": "LinkedField",
"name": "obligations",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "ObligationEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Obligation",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v2/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "requirement",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "area",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "source",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "status",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "owner",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
},
(v2/*: any*/)
],
"storageKey": null
},
(v3/*: 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": "endCursor",
"storageKey": null
},
{
"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
}
],
"storageKey": null
}
],
"storageKey": "obligations(first:20)"
},
{
"alias": null,
"args": (v4/*: any*/),
"filters": [
"orderBy"
],
"handle": "connection",
"key": "LinkedObligationsDialogQuery_obligations",
"kind": "LinkedHandle",
"name": "obligations"
}
],
"type": "Organization",
"abstractKey": null
}
],
"storageKey": null
}
]
},
"params": {
"cacheID": "8d4a5e57f79ae207dd1e27c436e49bd5",
"id": null,
"metadata": {},
"name": "LinkedObligationsDialogQuery",
"operationKind": "query",
"text": "query LinkedObligationsDialogQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n ...LinkedObligationsDialogFragment\n }\n }\n}\n\nfragment LinkedObligationsDialogFragment on Organization {\n obligations(first: 20) {\n edges {\n node {\n id\n requirement\n area\n source\n status\n owner {\n fullName\n id\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
}
};
})();
(node as any).hash = "afd36a8a7dbe29044d2aefc3e3820fc8";
export default node;

View File

@@ -0,0 +1,351 @@
/**
* @generated SignedSource<<3d2709f51866093bcc78ec14501dae31>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime";
export type ObligationOrderField = "CREATED_AT" | "DUE_DATE" | "LAST_REVIEW_DATE" | "STATUS";
export type OrderDirection = "ASC" | "DESC";
export type ObligationOrder = {
direction: OrderDirection;
field: ObligationOrderField;
};
export type LinkedObligationsDialogQuery_fragment$variables = {
after?: any | null | undefined;
before?: any | null | undefined;
first?: number | null | undefined;
id: string;
last?: number | null | undefined;
order?: ObligationOrder | null | undefined;
};
export type LinkedObligationsDialogQuery_fragment$data = {
readonly node: {
readonly " $fragmentSpreads": FragmentRefs<"LinkedObligationsDialogFragment">;
};
};
export type LinkedObligationsDialogQuery_fragment = {
response: LinkedObligationsDialogQuery_fragment$data;
variables: LinkedObligationsDialogQuery_fragment$variables;
};
const node: ConcreteRequest = (function(){
var v0 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "after"
},
v1 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "before"
},
v2 = {
"defaultValue": 20,
"kind": "LocalArgument",
"name": "first"
},
v3 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "id"
},
v4 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "last"
},
v5 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "order"
},
v6 = [
{
"kind": "Variable",
"name": "id",
"variableName": "id"
}
],
v7 = {
"kind": "Variable",
"name": "after",
"variableName": "after"
},
v8 = {
"kind": "Variable",
"name": "before",
"variableName": "before"
},
v9 = {
"kind": "Variable",
"name": "first",
"variableName": "first"
},
v10 = {
"kind": "Variable",
"name": "last",
"variableName": "last"
},
v11 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__typename",
"storageKey": null
},
v12 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
v13 = [
(v7/*: any*/),
(v8/*: any*/),
(v9/*: any*/),
(v10/*: any*/),
{
"kind": "Variable",
"name": "orderBy",
"variableName": "order"
}
];
return {
"fragment": {
"argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/),
(v2/*: any*/),
(v3/*: any*/),
(v4/*: any*/),
(v5/*: any*/)
],
"kind": "Fragment",
"metadata": null,
"name": "LinkedObligationsDialogQuery_fragment",
"selections": [
{
"alias": null,
"args": (v6/*: any*/),
"concreteType": null,
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
{
"args": [
(v7/*: any*/),
(v8/*: any*/),
(v9/*: any*/),
(v10/*: any*/),
{
"kind": "Variable",
"name": "order",
"variableName": "order"
}
],
"kind": "FragmentSpread",
"name": "LinkedObligationsDialogFragment"
}
],
"storageKey": null
}
],
"type": "Query",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/),
(v2/*: any*/),
(v4/*: any*/),
(v5/*: any*/),
(v3/*: any*/)
],
"kind": "Operation",
"name": "LinkedObligationsDialogQuery_fragment",
"selections": [
{
"alias": null,
"args": (v6/*: any*/),
"concreteType": null,
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v11/*: any*/),
(v12/*: any*/),
{
"kind": "InlineFragment",
"selections": [
{
"alias": null,
"args": (v13/*: any*/),
"concreteType": "ObligationConnection",
"kind": "LinkedField",
"name": "obligations",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "ObligationEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Obligation",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v12/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "requirement",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "area",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "source",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "status",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "owner",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
},
(v12/*: any*/)
],
"storageKey": null
},
(v11/*: 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": "endCursor",
"storageKey": null
},
{
"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
}
],
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": (v13/*: any*/),
"filters": [
"orderBy"
],
"handle": "connection",
"key": "LinkedObligationsDialogQuery_obligations",
"kind": "LinkedHandle",
"name": "obligations"
}
],
"type": "Organization",
"abstractKey": null
}
],
"storageKey": null
}
]
},
"params": {
"cacheID": "a4640b163a373e0420a9fb1108ce7b3a",
"id": null,
"metadata": {},
"name": "LinkedObligationsDialogQuery_fragment",
"operationKind": "query",
"text": "query LinkedObligationsDialogQuery_fragment(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 20\n $last: Int = null\n $order: ObligationOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...LinkedObligationsDialogFragment_16fISc\n id\n }\n}\n\nfragment LinkedObligationsDialogFragment_16fISc on Organization {\n obligations(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n edges {\n node {\n id\n requirement\n area\n source\n status\n owner {\n fullName\n id\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
}
};
})();
(node as any).hash = "6e686f2a4bce776146b1985df2863e73";
export default node;