Add measures evidences tab
Signed-off-by: Bryan Frimin <bryan@getprobo.com> Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
committed by
Sacha Al Himdani
parent
b660c0ce7f
commit
140857bfb3
35
apps/console2/src/components/PageError.tsx
Normal file
35
apps/console2/src/components/PageError.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import { useRouteError } from "react-router";
|
||||
import { IconPageCross } from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
|
||||
const classNames = {
|
||||
wrapper: "py-10 text-center space-y-2 ",
|
||||
title: "text-2xl flex gap-2 font-semibold items-center justify-center",
|
||||
description: "text-base text-txt-tertiary",
|
||||
};
|
||||
|
||||
export function PageError() {
|
||||
const error = useRouteError();
|
||||
const { __ } = useTranslate();
|
||||
|
||||
if (!error) {
|
||||
return (
|
||||
<div className={classNames.wrapper}>
|
||||
<h1 className={classNames.title}>
|
||||
<IconPageCross size={26} />
|
||||
{__("Page not found")}
|
||||
</h1>
|
||||
<p className={classNames.description}>
|
||||
{__("The page you are looking for does not exist")}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classNames.wrapper}>
|
||||
<h1 className={classNames.title}>{__("Unexpected error :(")}</h1>
|
||||
<p className={classNames.description}>{error.toString()}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
123
apps/console2/src/components/controls/LinkedControlsCard.tsx
Normal file
123
apps/console2/src/components/controls/LinkedControlsCard.tsx
Normal file
@@ -0,0 +1,123 @@
|
||||
import { graphql } from "relay-runtime";
|
||||
import {
|
||||
Button,
|
||||
Tr,
|
||||
Td,
|
||||
Table,
|
||||
Thead,
|
||||
Tbody,
|
||||
Th,
|
||||
IconTrashCan,
|
||||
Badge,
|
||||
} from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import type { LinkedControlsCardFragment$key } from "./__generated__/LinkedControlsCardFragment.graphql";
|
||||
import { useFragment } from "react-relay";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
|
||||
const linkedControlFragment = graphql`
|
||||
fragment LinkedControlsCardFragment on Control {
|
||||
id
|
||||
name
|
||||
referenceId
|
||||
framework {
|
||||
name
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
type Mutation<Params> = (p: {
|
||||
variables: {
|
||||
input: {
|
||||
controlId: string;
|
||||
} & Params;
|
||||
connections: string[];
|
||||
};
|
||||
}) => void;
|
||||
|
||||
type Props<Params> = {
|
||||
// Controls linked to the element
|
||||
controls: (LinkedControlsCardFragment$key & { id: string })[];
|
||||
// Extra params to send to the mutation
|
||||
params: Params;
|
||||
// Disable (action when loading for instance)
|
||||
disabled?: boolean;
|
||||
// ID of the connection to update
|
||||
connectionId: string;
|
||||
// Mutation to detach a control (will receive {controlId, ...params})
|
||||
onDetach: Mutation<Params>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reusable component that displays a list of linked controls
|
||||
*/
|
||||
export function LinkedControlsCard<Params>(props: Props<Params>) {
|
||||
const { __ } = useTranslate();
|
||||
const controls = props.controls;
|
||||
|
||||
const onDetach = (controlId: string) => {
|
||||
props.onDetach({
|
||||
variables: {
|
||||
input: {
|
||||
controlId,
|
||||
...props.params,
|
||||
},
|
||||
connections: [props.connectionId],
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Table>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>{__("Reference")}</Th>
|
||||
<Th>{__("Name")}</Th>
|
||||
<Th></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{controls.length === 0 && (
|
||||
<Tr>
|
||||
<Td colSpan={4} className="text-center text-txt-secondary">
|
||||
{__("No controls linked")}
|
||||
</Td>
|
||||
</Tr>
|
||||
)}
|
||||
{controls.map((control) => (
|
||||
<ControlRow key={control.id} control={control} onClick={onDetach} />
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
|
||||
function ControlRow(props: {
|
||||
control: LinkedControlsCardFragment$key & { id: string };
|
||||
onClick: (controlId: string) => void;
|
||||
}) {
|
||||
const control = useFragment(linkedControlFragment, props.control);
|
||||
const organizationId = useOrganizationId();
|
||||
const { __ } = useTranslate();
|
||||
|
||||
return (
|
||||
<Tr to={`/organizations/${organizationId}/controls/${control.id}`}>
|
||||
<Td>
|
||||
<span className="inline-flex gap-2 items-center">
|
||||
{control.framework.name}{" "}
|
||||
<Badge size="md">{control.referenceId}</Badge>
|
||||
</span>
|
||||
</Td>
|
||||
<Td>{control.name}</Td>
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(control.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
</Tr>
|
||||
);
|
||||
}
|
||||
76
apps/console2/src/components/controls/__generated__/LinkedControlsCardFragment.graphql.ts
generated
Normal file
76
apps/console2/src/components/controls/__generated__/LinkedControlsCardFragment.graphql.ts
generated
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @generated SignedSource<<c922ab2420ac172a8d9c18948fc4f006>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type LinkedControlsCardFragment$data = {
|
||||
readonly framework: {
|
||||
readonly name: string;
|
||||
};
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly referenceId: string;
|
||||
readonly " $fragmentType": "LinkedControlsCardFragment";
|
||||
};
|
||||
export type LinkedControlsCardFragment$key = {
|
||||
readonly " $data"?: LinkedControlsCardFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedControlsCardFragment">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "LinkedControlsCardFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "referenceId",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Framework",
|
||||
"kind": "LinkedField",
|
||||
"name": "framework",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Control",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "1b72ca232511c698e0cbdc84cbc81c02";
|
||||
|
||||
export default node;
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
IconTrashCan,
|
||||
DocumentVersionBadge,
|
||||
DocumentTypeBadge,
|
||||
TrButton,
|
||||
} from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import type { LinkedDocumentsCardFragment$key } from "./__generated__/LinkedDocumentsCardFragment.graphql";
|
||||
@@ -20,7 +21,8 @@ import { useFragment } from "react-relay";
|
||||
import { useMemo, useState } from "react";
|
||||
import { sprintf } from "@probo/helpers";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import { DocumentLinkDialog } from "./DocumentLinkDialog";
|
||||
import { LinkedDocumentDialog } from "./LinkedDocumentsDialog.tsx";
|
||||
import clsx from "clsx";
|
||||
|
||||
const linkedDocumentFragment = graphql`
|
||||
fragment LinkedDocumentsCardFragment on Document {
|
||||
@@ -61,6 +63,7 @@ type Props<Params> = {
|
||||
onAttach: Mutation<Params>;
|
||||
// Mutation to detach a document (will receive {documentId, ...params})
|
||||
onDetach: Mutation<Params>;
|
||||
variant?: "card" | "table";
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -73,6 +76,7 @@ export function LinkedDocumentsCard<Params>(props: Props<Params>) {
|
||||
return limit ? props.documents.slice(0, limit) : props.documents;
|
||||
}, [props.documents, limit]);
|
||||
const showMoreButton = limit !== null && props.documents.length > limit;
|
||||
const variant = props.variant ?? "table";
|
||||
|
||||
const onAttach = (documentId: string) => {
|
||||
props.onAttach({
|
||||
@@ -98,47 +102,65 @@ export function LinkedDocumentsCard<Params>(props: Props<Params>) {
|
||||
});
|
||||
};
|
||||
|
||||
const Wrapper = variant === "card" ? Card : "div";
|
||||
|
||||
return (
|
||||
<Card padded className="space-y-[10px]">
|
||||
<div className="flex justify-between">
|
||||
<div className="text-lg font-semibold">{__("Documents")}</div>
|
||||
<DocumentLinkDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedDocuments={props.documents}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link document")}
|
||||
</Button>
|
||||
</DocumentLinkDialog>
|
||||
</div>
|
||||
{documents.length > 0 ? (
|
||||
<Table className="bg-invert">
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>{__("Name")}</Th>
|
||||
<Th>{__("Type")}</Th>
|
||||
<Th>{__("State")}</Th>
|
||||
<Th></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{documents.map((document) => (
|
||||
<DocumentRow
|
||||
key={document.id}
|
||||
document={document}
|
||||
onClick={onDetach}
|
||||
/>
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
) : (
|
||||
<div className="text-center text-sm text-txt-secondary">
|
||||
{__("No documents linked")}
|
||||
<Wrapper padded className="space-y-[10px]">
|
||||
{variant === "card" && (
|
||||
<div className="flex justify-between">
|
||||
<div className="text-lg font-semibold">{__("Documents")}</div>
|
||||
<LinkedDocumentDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedDocuments={props.documents}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link document")}
|
||||
</Button>
|
||||
</LinkedDocumentDialog>
|
||||
</div>
|
||||
)}
|
||||
<Table className={clsx(variant === "card" && "bg-invert")}>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>{__("Name")}</Th>
|
||||
<Th>{__("Type")}</Th>
|
||||
<Th>{__("State")}</Th>
|
||||
<Th></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{documents.length === 0 && (
|
||||
<Tr>
|
||||
<Td colSpan={4} className="text-center text-txt-secondary">
|
||||
{__("No documents linked")}
|
||||
</Td>
|
||||
</Tr>
|
||||
)}
|
||||
{documents.map((document) => (
|
||||
<DocumentRow
|
||||
key={document.id}
|
||||
document={document}
|
||||
onClick={onDetach}
|
||||
/>
|
||||
))}
|
||||
{variant === "table" && (
|
||||
<LinkedDocumentDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedDocuments={props.documents}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<TrButton colspan={4} icon={IconPlusLarge}>
|
||||
{__("Link document")}
|
||||
</TrButton>
|
||||
</LinkedDocumentDialog>
|
||||
)}
|
||||
</Tbody>
|
||||
</Table>
|
||||
{showMoreButton && (
|
||||
<Button
|
||||
variant="tertiary"
|
||||
@@ -149,7 +171,7 @@ export function LinkedDocumentsCard<Params>(props: Props<Params>) {
|
||||
{sprintf(__("Show %s more"), props.documents.length - limit)}
|
||||
</Button>
|
||||
)}
|
||||
</Card>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,33 +7,55 @@ import {
|
||||
IconMagnifyingGlass,
|
||||
IconPlusLarge,
|
||||
IconTrashCan,
|
||||
InfiniteScrollTrigger,
|
||||
Input,
|
||||
Spinner,
|
||||
} from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { Suspense, useMemo, useState, type ReactNode } from "react";
|
||||
import { graphql } from "relay-runtime";
|
||||
import { useLazyLoadQuery } from "react-relay";
|
||||
import type {
|
||||
DocumentLinkDialogQuery,
|
||||
DocumentLinkDialogQuery$data,
|
||||
} from "./__generated__/DocumentLinkDialogQuery.graphql";
|
||||
import { useLazyLoadQuery, usePaginationFragment } from "react-relay";
|
||||
import type { LinkedDocumentsDialogQuery } from "./__generated__/LinkedDocumentsDialogQuery.graphql";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import type { NodeOf } from "/types";
|
||||
import type {
|
||||
LinkedDocumentsDialogFragment$data,
|
||||
LinkedDocumentsDialogFragment$key,
|
||||
} from "./__generated__/LinkedDocumentsDialogFragment.graphql";
|
||||
|
||||
const documentsQuery = graphql`
|
||||
query DocumentLinkDialogQuery($organizationId: ID!) {
|
||||
query LinkedDocumentsDialogQuery($organizationId: ID!) {
|
||||
organization: node(id: $organizationId) {
|
||||
id
|
||||
... on Organization {
|
||||
documents(first: 100) @connection(key: "Organization__documents") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
title
|
||||
documentType
|
||||
}
|
||||
}
|
||||
...LinkedDocumentsDialogFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const documentsFragment = graphql`
|
||||
fragment LinkedDocumentsDialogFragment on Organization
|
||||
@refetchable(queryName: "LinkedDocumentsDialogQuery_fragment")
|
||||
@argumentDefinitions(
|
||||
first: { type: "Int", defaultValue: 20 }
|
||||
order: { type: "DocumentOrder", defaultValue: null }
|
||||
after: { type: "CursorKey", defaultValue: null }
|
||||
before: { type: "CursorKey", defaultValue: null }
|
||||
last: { type: "Int", defaultValue: null }
|
||||
) {
|
||||
documents(
|
||||
first: $first
|
||||
after: $after
|
||||
last: $last
|
||||
before: $before
|
||||
orderBy: $order
|
||||
) @connection(key: "LinkedDocumentsDialogQuery_documents") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
title
|
||||
documentType
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,14 +71,14 @@ type Props = {
|
||||
onUnlink: (documentId: string) => void;
|
||||
};
|
||||
|
||||
export function DocumentLinkDialog({ children, ...props }: Props) {
|
||||
export function LinkedDocumentDialog({ children, ...props }: Props) {
|
||||
const { __ } = useTranslate();
|
||||
|
||||
return (
|
||||
<Dialog trigger={children} title={__("Link documents")}>
|
||||
<DialogContent>
|
||||
<Suspense fallback={<Spinner centered />}>
|
||||
<DocumentLinkDialogContent {...props} />
|
||||
<LinkedDocumentsDialogContent {...props} />
|
||||
</Suspense>
|
||||
</DialogContent>
|
||||
<DialogFooter exitLabel={__("Close")} />
|
||||
@@ -64,15 +86,18 @@ export function DocumentLinkDialog({ children, ...props }: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
function DocumentLinkDialogContent(props: Omit<Props, "children">) {
|
||||
function LinkedDocumentsDialogContent(props: Omit<Props, "children">) {
|
||||
const organizationId = useOrganizationId();
|
||||
const data = useLazyLoadQuery<DocumentLinkDialogQuery>(documentsQuery, {
|
||||
const query = useLazyLoadQuery<LinkedDocumentsDialogQuery>(documentsQuery, {
|
||||
organizationId,
|
||||
});
|
||||
const { data, loadNext, hasNext, isLoadingNext } = usePaginationFragment(
|
||||
documentsFragment,
|
||||
query.organization as LinkedDocumentsDialogFragment$key
|
||||
);
|
||||
const { __ } = useTranslate();
|
||||
const [search, setSearch] = useState("");
|
||||
const documents =
|
||||
data.organization?.documents?.edges?.map((edge) => edge.node) ?? [];
|
||||
const documents = data.documents?.edges?.map((edge) => edge.node) ?? [];
|
||||
const linkedIds = useMemo(() => {
|
||||
return new Set(props.linkedDocuments?.map((m) => m.id) ?? []);
|
||||
}, [props.linkedDocuments]);
|
||||
@@ -103,14 +128,18 @@ function DocumentLinkDialogContent(props: Omit<Props, "children">) {
|
||||
disabled={props.disabled}
|
||||
/>
|
||||
))}
|
||||
{hasNext && (
|
||||
<InfiniteScrollTrigger
|
||||
loading={isLoadingNext}
|
||||
onView={() => loadNext(20)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
type Document = NodeOf<
|
||||
DocumentLinkDialogQuery$data["organization"]["documents"]
|
||||
>;
|
||||
type Document = NodeOf<LinkedDocumentsDialogFragment$data["documents"]>;
|
||||
|
||||
type RowProps = {
|
||||
document: Document;
|
||||
@@ -129,7 +158,7 @@ function DocumentRow(props: RowProps) {
|
||||
|
||||
return (
|
||||
<button
|
||||
className="py-4 flex items-center gap-4 hover:bg-subtle cursor-pointer px-6 w-full"
|
||||
className="py-4 flex items-center gap-4 hover:bg-subtle cursor-pointer px-6 w-full h-[100px]"
|
||||
onClick={() => onClick(props.document.id)}
|
||||
>
|
||||
{props.document.title}
|
||||
@@ -1,255 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<ec5910871c59f229db361be238007976>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type DocumentType = "ISMS" | "OTHER" | "POLICY";
|
||||
export type DocumentLinkDialogQuery$variables = {
|
||||
organizationId: string;
|
||||
};
|
||||
export type DocumentLinkDialogQuery$data = {
|
||||
readonly organization: {
|
||||
readonly documents?: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly documentType: DocumentType;
|
||||
readonly id: string;
|
||||
readonly title: string;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly id: string;
|
||||
};
|
||||
};
|
||||
export type DocumentLinkDialogQuery = {
|
||||
response: DocumentLinkDialogQuery$data;
|
||||
variables: DocumentLinkDialogQuery$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 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "DocumentEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Document",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "title",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "documentType",
|
||||
"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
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
v5 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "DocumentLinkDialogQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "documents",
|
||||
"args": null,
|
||||
"concreteType": "DocumentConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__Organization__documents_connection",
|
||||
"plural": false,
|
||||
"selections": (v4/*: any*/),
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "DocumentLinkDialogQuery",
|
||||
"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": (v5/*: any*/),
|
||||
"concreteType": "DocumentConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "documents",
|
||||
"plural": false,
|
||||
"selections": (v4/*: any*/),
|
||||
"storageKey": "documents(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v5/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "Organization__documents",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "documents"
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "0905fffe448540bf9c3d8abcbb5b7583",
|
||||
"id": null,
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": null,
|
||||
"cursor": null,
|
||||
"direction": "forward",
|
||||
"path": [
|
||||
"organization",
|
||||
"documents"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "DocumentLinkDialogQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query DocumentLinkDialogQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n documents(first: 100) {\n edges {\n node {\n id\n title\n documentType\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "6994e268de74f2102f48dc3e8156a797";
|
||||
|
||||
export default node;
|
||||
223
apps/console2/src/components/documents/__generated__/LinkedDocumentsDialogFragment.graphql.ts
generated
Normal file
223
apps/console2/src/components/documents/__generated__/LinkedDocumentsDialogFragment.graphql.ts
generated
Normal file
@@ -0,0 +1,223 @@
|
||||
/**
|
||||
* @generated SignedSource<<7b0ec493ab146db602cae612158407cb>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
export type DocumentType = "ISMS" | "OTHER" | "POLICY";
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type LinkedDocumentsDialogFragment$data = {
|
||||
readonly documents: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly documentType: DocumentType;
|
||||
readonly id: string;
|
||||
readonly title: string;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly id: string;
|
||||
readonly " $fragmentType": "LinkedDocumentsDialogFragment";
|
||||
};
|
||||
export type LinkedDocumentsDialogFragment$key = {
|
||||
readonly " $data"?: LinkedDocumentsDialogFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedDocumentsDialogFragment">;
|
||||
};
|
||||
|
||||
import LinkedDocumentsDialogQuery_fragment_graphql from './LinkedDocumentsDialogQuery_fragment.graphql';
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = [
|
||||
"documents"
|
||||
],
|
||||
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": LinkedDocumentsDialogQuery_fragment_graphql,
|
||||
"identifierInfo": {
|
||||
"identifierField": "id",
|
||||
"identifierQueryVariableName": "id"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "LinkedDocumentsDialogFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "documents",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "orderBy",
|
||||
"variableName": "order"
|
||||
}
|
||||
],
|
||||
"concreteType": "DocumentConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__LinkedDocumentsDialogQuery_documents_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "DocumentEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Document",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "title",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "documentType",
|
||||
"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 = "392d33b379a58cb3da08ab783c1cda5d";
|
||||
|
||||
export default node;
|
||||
245
apps/console2/src/components/documents/__generated__/LinkedDocumentsDialogQuery.graphql.ts
generated
Normal file
245
apps/console2/src/components/documents/__generated__/LinkedDocumentsDialogQuery.graphql.ts
generated
Normal file
@@ -0,0 +1,245 @@
|
||||
/**
|
||||
* @generated SignedSource<<6316cd819a27efb5989750b5f8de0444>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type LinkedDocumentsDialogQuery$variables = {
|
||||
organizationId: string;
|
||||
};
|
||||
export type LinkedDocumentsDialogQuery$data = {
|
||||
readonly organization: {
|
||||
readonly id: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedDocumentsDialogFragment">;
|
||||
};
|
||||
};
|
||||
export type LinkedDocumentsDialogQuery = {
|
||||
response: LinkedDocumentsDialogQuery$data;
|
||||
variables: LinkedDocumentsDialogQuery$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": "LinkedDocumentsDialogQuery",
|
||||
"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": "LinkedDocumentsDialogFragment"
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "LinkedDocumentsDialogQuery",
|
||||
"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": "DocumentConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "documents",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "DocumentEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Document",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "title",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "documentType",
|
||||
"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": "documents(first:20)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v4/*: any*/),
|
||||
"filters": [
|
||||
"orderBy"
|
||||
],
|
||||
"handle": "connection",
|
||||
"key": "LinkedDocumentsDialogQuery_documents",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "documents"
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "fd4ab41131ead5f74dceb4610ef3f2c5",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "LinkedDocumentsDialogQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query LinkedDocumentsDialogQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n ...LinkedDocumentsDialogFragment\n }\n }\n}\n\nfragment LinkedDocumentsDialogFragment on Organization {\n documents(first: 20) {\n edges {\n node {\n id\n title\n documentType\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 = "f97a3016285b1a39cc6925ac39d82acc";
|
||||
|
||||
export default node;
|
||||
318
apps/console2/src/components/documents/__generated__/LinkedDocumentsDialogQuery_fragment.graphql.ts
generated
Normal file
318
apps/console2/src/components/documents/__generated__/LinkedDocumentsDialogQuery_fragment.graphql.ts
generated
Normal file
@@ -0,0 +1,318 @@
|
||||
/**
|
||||
* @generated SignedSource<<29bf3465293095c44e826394c602cde1>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type DocumentOrderField = "CREATED_AT" | "TITLE";
|
||||
export type OrderDirection = "ASC" | "DESC";
|
||||
export type DocumentOrder = {
|
||||
direction: OrderDirection;
|
||||
field: DocumentOrderField;
|
||||
};
|
||||
export type LinkedDocumentsDialogQuery_fragment$variables = {
|
||||
after?: any | null | undefined;
|
||||
before?: any | null | undefined;
|
||||
first?: number | null | undefined;
|
||||
id: string;
|
||||
last?: number | null | undefined;
|
||||
order?: DocumentOrder | null | undefined;
|
||||
};
|
||||
export type LinkedDocumentsDialogQuery_fragment$data = {
|
||||
readonly node: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedDocumentsDialogFragment">;
|
||||
};
|
||||
};
|
||||
export type LinkedDocumentsDialogQuery_fragment = {
|
||||
response: LinkedDocumentsDialogQuery_fragment$data;
|
||||
variables: LinkedDocumentsDialogQuery_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": "LinkedDocumentsDialogQuery_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": "LinkedDocumentsDialogFragment"
|
||||
}
|
||||
],
|
||||
"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": "LinkedDocumentsDialogQuery_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": "DocumentConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "documents",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "DocumentEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Document",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v12/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "title",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "documentType",
|
||||
"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": "LinkedDocumentsDialogQuery_documents",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "documents"
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "e72639ede26aa4300b69ba3181de482b",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "LinkedDocumentsDialogQuery_fragment",
|
||||
"operationKind": "query",
|
||||
"text": "query LinkedDocumentsDialogQuery_fragment(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 20\n $last: Int = null\n $order: DocumentOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...LinkedDocumentsDialogFragment_16fISc\n id\n }\n}\n\nfragment LinkedDocumentsDialogFragment_16fISc on Organization {\n documents(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n edges {\n node {\n id\n title\n documentType\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 = "392d33b379a58cb3da08ab783c1cda5d";
|
||||
|
||||
export default node;
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
IconChevronDown,
|
||||
MeasureBadge,
|
||||
IconTrashCan,
|
||||
TrButton,
|
||||
} from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import type { LinkedMeasuresCardFragment$key } from "./__generated__/LinkedMeasuresCardFragment.graphql";
|
||||
@@ -19,7 +20,8 @@ import { useFragment } from "react-relay";
|
||||
import { useMemo, useState } from "react";
|
||||
import { sprintf } from "@probo/helpers";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import { MeasureLinkDialog } from "./MeasureLinkDialog";
|
||||
import { LinkedMeasureDialog } from "./LinkedMeasuresDialog.tsx";
|
||||
import clsx from "clsx";
|
||||
|
||||
const linkedMeasureFragment = graphql`
|
||||
fragment LinkedMeasuresCardFragment on Measure {
|
||||
@@ -51,6 +53,7 @@ type Props<Params> = {
|
||||
onAttach: Mutation<Params>;
|
||||
// Mutation to detach a measure (will receive {measureId, ...params})
|
||||
onDetach: Mutation<Params>;
|
||||
variant?: "card" | "table";
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -58,11 +61,14 @@ type Props<Params> = {
|
||||
*/
|
||||
export function LinkedMeasuresCard<Params>(props: Props<Params>) {
|
||||
const { __ } = useTranslate();
|
||||
const [limit, setLimit] = useState<number | null>(4);
|
||||
const [limit, setLimit] = useState<number | null>(
|
||||
props.variant === "card" ? 4 : null
|
||||
);
|
||||
const measures = useMemo(() => {
|
||||
return limit ? props.measures.slice(0, limit) : props.measures;
|
||||
}, [props.measures, limit]);
|
||||
const showMoreButton = limit !== null && props.measures.length > limit;
|
||||
const variant = props.variant ?? "table";
|
||||
|
||||
const onAttach = (measureId: string) => {
|
||||
props.onAttach({
|
||||
@@ -88,46 +94,60 @@ export function LinkedMeasuresCard<Params>(props: Props<Params>) {
|
||||
});
|
||||
};
|
||||
|
||||
const Wrapper = variant === "card" ? Card : "div";
|
||||
|
||||
return (
|
||||
<Card padded className="space-y-[10px]">
|
||||
<div className="flex justify-between">
|
||||
<div className="text-lg font-semibold">{__("Measures")}</div>
|
||||
<MeasureLinkDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedMeasures={props.measures}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link measure")}
|
||||
</Button>
|
||||
</MeasureLinkDialog>
|
||||
</div>
|
||||
{measures.length > 0 ? (
|
||||
<Table className="bg-invert">
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>{__("Name")}</Th>
|
||||
<Th>{__("State")}</Th>
|
||||
<Th></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{measures.map((measure) => (
|
||||
<MeasureRow
|
||||
key={measure.id}
|
||||
measure={measure}
|
||||
onClick={onDetach}
|
||||
/>
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
) : (
|
||||
<div className="text-center text-sm text-txt-secondary">
|
||||
{__("No measures linked")}
|
||||
<Wrapper padded className="space-y-[10px]">
|
||||
{variant === "card" && (
|
||||
<div className="flex justify-between">
|
||||
<div className="text-lg font-semibold">{__("Measures")}</div>
|
||||
<LinkedMeasureDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedMeasures={props.measures}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="tertiary" icon={IconPlusLarge}>
|
||||
{__("Link measure")}
|
||||
</Button>
|
||||
</LinkedMeasureDialog>
|
||||
</div>
|
||||
)}
|
||||
<Table className={clsx(variant === "card" && "bg-invert")}>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>{__("Name")}</Th>
|
||||
<Th>{__("State")}</Th>
|
||||
<Th></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{measures.length === 0 && (
|
||||
<Tr>
|
||||
<Td colSpan={3} className="text-center text-txt-secondary">
|
||||
{__("No measures linked")}
|
||||
</Td>
|
||||
</Tr>
|
||||
)}
|
||||
{measures.map((measure) => (
|
||||
<MeasureRow key={measure.id} measure={measure} onClick={onDetach} />
|
||||
))}
|
||||
{variant === "table" && (
|
||||
<LinkedMeasureDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedMeasures={props.measures}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<TrButton colspan={3} icon={IconPlusLarge}>
|
||||
{__("Link measure")}
|
||||
</TrButton>
|
||||
</LinkedMeasureDialog>
|
||||
)}
|
||||
</Tbody>
|
||||
</Table>
|
||||
{showMoreButton && (
|
||||
<Button
|
||||
variant="tertiary"
|
||||
@@ -138,7 +158,7 @@ export function LinkedMeasuresCard<Params>(props: Props<Params>) {
|
||||
{sprintf(__("Show %s more"), props.measures.length - limit)}
|
||||
</Button>
|
||||
)}
|
||||
</Card>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
IconMagnifyingGlass,
|
||||
IconPlusLarge,
|
||||
IconTrashCan,
|
||||
InfiniteScrollTrigger,
|
||||
Input,
|
||||
Option,
|
||||
Select,
|
||||
@@ -15,25 +16,46 @@ import {
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { Suspense, useMemo, useState, type ReactNode } from "react";
|
||||
import { graphql } from "relay-runtime";
|
||||
import { useLazyLoadQuery } from "react-relay";
|
||||
import type { MeasureLinkDialogQuery } from "./__generated__/MeasureLinkDialogQuery.graphql";
|
||||
import { useLazyLoadQuery, usePaginationFragment } from "react-relay";
|
||||
import type { LinkedMeasuresDialogQuery } from "./__generated__/LinkedMeasuresDialogQuery.graphql";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import type { LinkedMeasuresDialogFragment$key } from "./__generated__/LinkedMeasuresDialogFragment.graphql";
|
||||
|
||||
const measuresQuery = graphql`
|
||||
query MeasureLinkDialogQuery($organizationId: ID!) {
|
||||
query LinkedMeasuresDialogQuery($organizationId: ID!) {
|
||||
organization: node(id: $organizationId) {
|
||||
id
|
||||
... on Organization {
|
||||
measures(first: 100) @connection(key: "Organization__measures") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
state
|
||||
description
|
||||
category
|
||||
}
|
||||
}
|
||||
...LinkedMeasuresDialogFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const measuresFragment = graphql`
|
||||
fragment LinkedMeasuresDialogFragment on Organization
|
||||
@refetchable(queryName: "LinkedMeasuresDialogQuery_fragment")
|
||||
@argumentDefinitions(
|
||||
first: { type: "Int", defaultValue: 20 }
|
||||
order: { type: "MeasureOrder", defaultValue: null }
|
||||
after: { type: "CursorKey", defaultValue: null }
|
||||
before: { type: "CursorKey", defaultValue: null }
|
||||
last: { type: "Int", defaultValue: null }
|
||||
) {
|
||||
measures(
|
||||
first: $first
|
||||
after: $after
|
||||
last: $last
|
||||
before: $before
|
||||
orderBy: $order
|
||||
) @connection(key: "LinkedMeasuresDialogQuery_measures") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
state
|
||||
description
|
||||
category
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,14 +71,14 @@ type Props = {
|
||||
onUnlink: (measureId: string) => void;
|
||||
};
|
||||
|
||||
export function MeasureLinkDialog({ children, ...props }: Props) {
|
||||
export function LinkedMeasureDialog({ children, ...props }: Props) {
|
||||
const { __ } = useTranslate();
|
||||
|
||||
return (
|
||||
<Dialog trigger={children} title={__("Link measures")}>
|
||||
<DialogContent>
|
||||
<Suspense fallback={<Spinner centered />}>
|
||||
<MeasureLinkDialogContent {...props} />
|
||||
<LinkedMeasuresDialogContent {...props} />
|
||||
</Suspense>
|
||||
</DialogContent>
|
||||
<DialogFooter exitLabel={__("Close")} />
|
||||
@@ -64,16 +86,19 @@ export function MeasureLinkDialog({ children, ...props }: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
function MeasureLinkDialogContent(props: Omit<Props, "children">) {
|
||||
function LinkedMeasuresDialogContent(props: Omit<Props, "children">) {
|
||||
const organizationId = useOrganizationId();
|
||||
const data = useLazyLoadQuery<MeasureLinkDialogQuery>(measuresQuery, {
|
||||
const query = useLazyLoadQuery<LinkedMeasuresDialogQuery>(measuresQuery, {
|
||||
organizationId,
|
||||
});
|
||||
const { data, loadNext, hasNext, isLoadingNext } = usePaginationFragment(
|
||||
measuresFragment,
|
||||
query.organization as LinkedMeasuresDialogFragment$key
|
||||
);
|
||||
const { __ } = useTranslate();
|
||||
const [search, setSearch] = useState("");
|
||||
const [category, setCategory] = useState<string | null>(null);
|
||||
const measures =
|
||||
data.organization?.measures?.edges?.map((edge) => edge.node) ?? [];
|
||||
const measures = data.measures?.edges?.map((edge) => edge.node) ?? [];
|
||||
const linkedIds = useMemo(() => {
|
||||
return new Set(props.linkedMeasures?.map((m) => m.id) ?? []);
|
||||
}, [props.linkedMeasures]);
|
||||
@@ -124,6 +149,12 @@ function MeasureLinkDialogContent(props: Omit<Props, "children">) {
|
||||
disabled={props.disabled}
|
||||
/>
|
||||
))}
|
||||
{hasNext && (
|
||||
<InfiniteScrollTrigger
|
||||
loading={isLoadingNext}
|
||||
onView={() => loadNext(20)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
239
apps/console2/src/components/measures/__generated__/LinkedMeasuresDialogFragment.graphql.ts
generated
Normal file
239
apps/console2/src/components/measures/__generated__/LinkedMeasuresDialogFragment.graphql.ts
generated
Normal file
@@ -0,0 +1,239 @@
|
||||
/**
|
||||
* @generated SignedSource<<47d66bf5d9b99eb598728999a7b2ce85>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
export type MeasureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type LinkedMeasuresDialogFragment$data = {
|
||||
readonly id: string;
|
||||
readonly measures: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly category: string;
|
||||
readonly description: string;
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly state: MeasureState;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly " $fragmentType": "LinkedMeasuresDialogFragment";
|
||||
};
|
||||
export type LinkedMeasuresDialogFragment$key = {
|
||||
readonly " $data"?: LinkedMeasuresDialogFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedMeasuresDialogFragment">;
|
||||
};
|
||||
|
||||
import LinkedMeasuresDialogQuery_fragment_graphql from './LinkedMeasuresDialogQuery_fragment.graphql';
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = [
|
||||
"measures"
|
||||
],
|
||||
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": LinkedMeasuresDialogQuery_fragment_graphql,
|
||||
"identifierInfo": {
|
||||
"identifierField": "id",
|
||||
"identifierQueryVariableName": "id"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "LinkedMeasuresDialogFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "measures",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "orderBy",
|
||||
"variableName": "order"
|
||||
}
|
||||
],
|
||||
"concreteType": "MeasureConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__LinkedMeasuresDialogQuery_measures_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "MeasureEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Measure",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "category",
|
||||
"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 = "69458f9aed8aee19f69cd58090b68947";
|
||||
|
||||
export default node;
|
||||
259
apps/console2/src/components/measures/__generated__/LinkedMeasuresDialogQuery.graphql.ts
generated
Normal file
259
apps/console2/src/components/measures/__generated__/LinkedMeasuresDialogQuery.graphql.ts
generated
Normal file
@@ -0,0 +1,259 @@
|
||||
/**
|
||||
* @generated SignedSource<<d357c78d6043fd24cd4b9df8e6ba5057>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type LinkedMeasuresDialogQuery$variables = {
|
||||
organizationId: string;
|
||||
};
|
||||
export type LinkedMeasuresDialogQuery$data = {
|
||||
readonly organization: {
|
||||
readonly id: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedMeasuresDialogFragment">;
|
||||
};
|
||||
};
|
||||
export type LinkedMeasuresDialogQuery = {
|
||||
response: LinkedMeasuresDialogQuery$data;
|
||||
variables: LinkedMeasuresDialogQuery$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": "LinkedMeasuresDialogQuery",
|
||||
"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": "LinkedMeasuresDialogFragment"
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "LinkedMeasuresDialogQuery",
|
||||
"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": "MeasureConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "measures",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "MeasureEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Measure",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "category",
|
||||
"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": "measures(first:20)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v4/*: any*/),
|
||||
"filters": [
|
||||
"orderBy"
|
||||
],
|
||||
"handle": "connection",
|
||||
"key": "LinkedMeasuresDialogQuery_measures",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "measures"
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "ecb3ffb566c178a40f6ea72b1947b3ed",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "LinkedMeasuresDialogQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query LinkedMeasuresDialogQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n ...LinkedMeasuresDialogFragment\n }\n }\n}\n\nfragment LinkedMeasuresDialogFragment on Organization {\n measures(first: 20) {\n edges {\n node {\n id\n name\n state\n description\n category\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 = "8592f3602ea10f6c00f5eb32c3f6b638";
|
||||
|
||||
export default node;
|
||||
332
apps/console2/src/components/measures/__generated__/LinkedMeasuresDialogQuery_fragment.graphql.ts
generated
Normal file
332
apps/console2/src/components/measures/__generated__/LinkedMeasuresDialogQuery_fragment.graphql.ts
generated
Normal file
@@ -0,0 +1,332 @@
|
||||
/**
|
||||
* @generated SignedSource<<412b6fd2ef44aa7bc3c9e66ec2284c37>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type MeasureOrderField = "CREATED_AT";
|
||||
export type OrderDirection = "ASC" | "DESC";
|
||||
export type MeasureOrder = {
|
||||
direction: OrderDirection;
|
||||
field: MeasureOrderField;
|
||||
};
|
||||
export type LinkedMeasuresDialogQuery_fragment$variables = {
|
||||
after?: any | null | undefined;
|
||||
before?: any | null | undefined;
|
||||
first?: number | null | undefined;
|
||||
id: string;
|
||||
last?: number | null | undefined;
|
||||
order?: MeasureOrder | null | undefined;
|
||||
};
|
||||
export type LinkedMeasuresDialogQuery_fragment$data = {
|
||||
readonly node: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedMeasuresDialogFragment">;
|
||||
};
|
||||
};
|
||||
export type LinkedMeasuresDialogQuery_fragment = {
|
||||
response: LinkedMeasuresDialogQuery_fragment$data;
|
||||
variables: LinkedMeasuresDialogQuery_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": "LinkedMeasuresDialogQuery_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": "LinkedMeasuresDialogFragment"
|
||||
}
|
||||
],
|
||||
"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": "LinkedMeasuresDialogQuery_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": "MeasureConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "measures",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "MeasureEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Measure",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v12/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "category",
|
||||
"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": "LinkedMeasuresDialogQuery_measures",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "measures"
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "9de5e8b136a2952dbb169f6b27aade30",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "LinkedMeasuresDialogQuery_fragment",
|
||||
"operationKind": "query",
|
||||
"text": "query LinkedMeasuresDialogQuery_fragment(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 20\n $last: Int = null\n $order: MeasureOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...LinkedMeasuresDialogFragment_16fISc\n id\n }\n}\n\nfragment LinkedMeasuresDialogFragment_16fISc on Organization {\n measures(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n edges {\n node {\n id\n name\n state\n description\n category\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 = "69458f9aed8aee19f69cd58090b68947";
|
||||
|
||||
export default node;
|
||||
@@ -1,271 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<0b725ea8709fbf5da3f17545fcd2b8c4>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type MeasureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
|
||||
export type MeasureLinkDialogQuery$variables = {
|
||||
organizationId: string;
|
||||
};
|
||||
export type MeasureLinkDialogQuery$data = {
|
||||
readonly organization: {
|
||||
readonly id: string;
|
||||
readonly measures?: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly category: string;
|
||||
readonly description: string;
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly state: MeasureState;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
};
|
||||
};
|
||||
export type MeasureLinkDialogQuery = {
|
||||
response: MeasureLinkDialogQuery$data;
|
||||
variables: MeasureLinkDialogQuery$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 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "MeasureEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Measure",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "category",
|
||||
"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
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
v5 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "MeasureLinkDialogQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "measures",
|
||||
"args": null,
|
||||
"concreteType": "MeasureConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__Organization__measures_connection",
|
||||
"plural": false,
|
||||
"selections": (v4/*: any*/),
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "MeasureLinkDialogQuery",
|
||||
"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": (v5/*: any*/),
|
||||
"concreteType": "MeasureConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "measures",
|
||||
"plural": false,
|
||||
"selections": (v4/*: any*/),
|
||||
"storageKey": "measures(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v5/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "Organization__measures",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "measures"
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "54fff8a0c07ebe02ef34f3bb35e7582e",
|
||||
"id": null,
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": null,
|
||||
"cursor": null,
|
||||
"direction": "forward",
|
||||
"path": [
|
||||
"organization",
|
||||
"measures"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "MeasureLinkDialogQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query MeasureLinkDialogQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n measures(first: 100) {\n edges {\n node {\n id\n name\n state\n description\n category\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "cf01fa3a766badd4f6150e1a544403ba";
|
||||
|
||||
export default node;
|
||||
167
apps/console2/src/components/risks/LinkedRisksCard.tsx
Normal file
167
apps/console2/src/components/risks/LinkedRisksCard.tsx
Normal file
@@ -0,0 +1,167 @@
|
||||
import { graphql } from "relay-runtime";
|
||||
import {
|
||||
IconPlusLarge,
|
||||
Button,
|
||||
Tr,
|
||||
Td,
|
||||
Table,
|
||||
Thead,
|
||||
Tbody,
|
||||
Th,
|
||||
IconChevronDown,
|
||||
RiskBadge,
|
||||
IconTrashCan,
|
||||
} from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import type { LinkedRisksCardFragment$key } from "./__generated__/LinkedRisksCardFragment.graphql";
|
||||
import { useFragment } from "react-relay";
|
||||
import { useMemo, useState } from "react";
|
||||
import { sprintf } from "@probo/helpers";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import { LinkedRisksDialog } from "./LinkedRisksDialog.tsx";
|
||||
|
||||
const linkedRiskFragment = graphql`
|
||||
fragment LinkedRisksCardFragment on Risk {
|
||||
id
|
||||
name
|
||||
inherentRiskScore
|
||||
residualRiskScore
|
||||
}
|
||||
`;
|
||||
|
||||
type Mutation<Params> = (p: {
|
||||
variables: {
|
||||
input: {
|
||||
riskId: string;
|
||||
} & Params;
|
||||
connections: string[];
|
||||
};
|
||||
}) => void;
|
||||
|
||||
type Props<Params> = {
|
||||
// Risks linked to the element
|
||||
risks: (LinkedRisksCardFragment$key & { id: string })[];
|
||||
// Extra params to send to the mutation
|
||||
params: Params;
|
||||
// Disable (action when loading for instance)
|
||||
disabled?: boolean;
|
||||
// ID of the connection to update
|
||||
connectionId: string;
|
||||
// Mutation to attach a risk (will receive {riskId, ...params})
|
||||
onAttach: Mutation<Params>;
|
||||
// Mutation to detach a risk (will receive {riskId, ...params})
|
||||
onDetach: Mutation<Params>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reusable component that displays a list of linked risks
|
||||
*/
|
||||
export function LinkedRisksCard<Params>(props: Props<Params>) {
|
||||
const { __ } = useTranslate();
|
||||
const [limit, setLimit] = useState<number | null>(4);
|
||||
const risks = useMemo(() => {
|
||||
return limit ? props.risks.slice(0, limit) : props.risks;
|
||||
}, [props.risks, limit]);
|
||||
const showMoreButton = limit !== null && props.risks.length > limit;
|
||||
|
||||
const onAttach = (riskId: string) => {
|
||||
props.onAttach({
|
||||
variables: {
|
||||
input: {
|
||||
riskId,
|
||||
...props.params,
|
||||
},
|
||||
connections: [props.connectionId],
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const onDetach = (riskId: string) => {
|
||||
props.onDetach({
|
||||
variables: {
|
||||
input: {
|
||||
riskId,
|
||||
...props.params,
|
||||
},
|
||||
connections: [props.connectionId],
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4 relative">
|
||||
{risks.length > 0 ? (
|
||||
<Table>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>{__("Name")}</Th>
|
||||
<Th>{__("Inherent Risk")}</Th>
|
||||
<Th>{__("Residual Risk")}</Th>
|
||||
<Th></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{risks.map((risk) => (
|
||||
<RiskRow key={risk.id} risk={risk} onClick={onDetach} />
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
) : (
|
||||
<div className="text-center text-sm text-txt-secondary">
|
||||
{__("No risks linked")}
|
||||
</div>
|
||||
)}
|
||||
{showMoreButton && (
|
||||
<Button
|
||||
variant="tertiary"
|
||||
onClick={() => setLimit(null)}
|
||||
className="mt-3 mx-auto"
|
||||
icon={IconChevronDown}
|
||||
>
|
||||
{sprintf(__("Show %s more"), props.risks.length - limit)}
|
||||
</Button>
|
||||
)}
|
||||
<LinkedRisksDialog
|
||||
connectionId={props.connectionId}
|
||||
disabled={props.disabled}
|
||||
linkedRisks={props.risks}
|
||||
onLink={onAttach}
|
||||
onUnlink={onDetach}
|
||||
>
|
||||
<Button variant="secondary" icon={IconPlusLarge} className="ml-auto">
|
||||
{__("Link risk")}
|
||||
</Button>
|
||||
</LinkedRisksDialog>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function RiskRow(props: {
|
||||
risk: LinkedRisksCardFragment$key & { id: string };
|
||||
onClick: (riskId: string) => void;
|
||||
}) {
|
||||
const risk = useFragment(linkedRiskFragment, props.risk);
|
||||
const organizationId = useOrganizationId();
|
||||
const { __ } = useTranslate();
|
||||
|
||||
return (
|
||||
<Tr to={`/organizations/${organizationId}/risks/${risk.id}`}>
|
||||
<Td>{risk.name}</Td>
|
||||
<Td>
|
||||
<RiskBadge level={risk.inherentRiskScore} />
|
||||
</Td>
|
||||
<Td>
|
||||
<RiskBadge level={risk.residualRiskScore} />
|
||||
</Td>
|
||||
<Td noLink width={50} className="text-end">
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => props.onClick(risk.id)}
|
||||
icon={IconTrashCan}
|
||||
>
|
||||
{__("Unlink")}
|
||||
</Button>
|
||||
</Td>
|
||||
</Tr>
|
||||
);
|
||||
}
|
||||
172
apps/console2/src/components/risks/LinkedRisksDialog.tsx
Normal file
172
apps/console2/src/components/risks/LinkedRisksDialog.tsx
Normal file
@@ -0,0 +1,172 @@
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
IconMagnifyingGlass,
|
||||
IconPlusLarge,
|
||||
IconTrashCan,
|
||||
Input,
|
||||
Option,
|
||||
Select,
|
||||
Spinner,
|
||||
} from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { Suspense, useMemo, useState, type ReactNode } from "react";
|
||||
import { graphql } from "relay-runtime";
|
||||
import { useLazyLoadQuery } from "react-relay";
|
||||
import type { LinkedRisksDialogQuery } from "./__generated__/LinkedRisksDialogQuery.graphql";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
|
||||
const risksQuery = graphql`
|
||||
query LinkedRisksDialogQuery($organizationId: ID!) {
|
||||
organization: node(id: $organizationId) {
|
||||
id
|
||||
... on Organization {
|
||||
risks(first: 100) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
category
|
||||
description
|
||||
inherentRiskScore
|
||||
residualRiskScore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
children: ReactNode;
|
||||
connectionId: string;
|
||||
disabled?: boolean;
|
||||
linkedRisks?: { id: string }[];
|
||||
onLink: (riskId: string) => void;
|
||||
onUnlink: (riskId: string) => void;
|
||||
};
|
||||
|
||||
export function LinkedRisksDialog({ children, ...props }: Props) {
|
||||
const { __ } = useTranslate();
|
||||
|
||||
return (
|
||||
<Dialog trigger={children} title={__("Link risks")}>
|
||||
<DialogContent>
|
||||
<Suspense fallback={<Spinner centered />}>
|
||||
<LinkedRisksDialogContent {...props} />
|
||||
</Suspense>
|
||||
</DialogContent>
|
||||
<DialogFooter exitLabel={__("Close")} />
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
function LinkedRisksDialogContent(props: Omit<Props, "children">) {
|
||||
const organizationId = useOrganizationId();
|
||||
const data = useLazyLoadQuery<LinkedRisksDialogQuery>(risksQuery, {
|
||||
organizationId,
|
||||
});
|
||||
const { __ } = useTranslate();
|
||||
const [search, setSearch] = useState("");
|
||||
const [category, setCategory] = useState<string | null>(null);
|
||||
const risks = data.organization?.risks?.edges?.map((edge) => edge.node) ?? [];
|
||||
const linkedIds = useMemo(() => {
|
||||
return new Set(props.linkedRisks?.map((r) => r.id) ?? []);
|
||||
}, [props.linkedRisks]);
|
||||
|
||||
const filteredRisks = useMemo(() => {
|
||||
return risks.filter(
|
||||
(risk) =>
|
||||
(category === null || risk.category === category) &&
|
||||
(risk.name.toLowerCase().includes(search.toLowerCase()) ||
|
||||
risk.description?.toLowerCase().includes(search.toLowerCase()))
|
||||
);
|
||||
}, [risks, search, category]);
|
||||
|
||||
const categories = useMemo(
|
||||
() => Array.from(new Set(risks.map((r) => r.category))),
|
||||
[risks]
|
||||
);
|
||||
|
||||
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 risks...")}
|
||||
onValueChange={setSearch}
|
||||
/>
|
||||
<Select
|
||||
value={category ?? ""}
|
||||
placeholder={__("All categories")}
|
||||
onValueChange={setCategory}
|
||||
className="max-w-[180px]"
|
||||
>
|
||||
{categories.map((category) => (
|
||||
<Option key={category} value={category}>
|
||||
{category}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</div>
|
||||
<div className="divide-y divide-border-low">
|
||||
{filteredRisks.map((risk) => (
|
||||
<RiskRow
|
||||
key={risk.id}
|
||||
risk={risk}
|
||||
linkedRisks={linkedIds}
|
||||
onLink={props.onLink}
|
||||
onUnlink={props.onUnlink}
|
||||
disabled={props.disabled}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
type RowProps = {
|
||||
risk: {
|
||||
name: string;
|
||||
category: string;
|
||||
id: string;
|
||||
inherentRiskScore: number;
|
||||
residualRiskScore: number;
|
||||
};
|
||||
linkedRisks: Set<string>;
|
||||
disabled?: boolean;
|
||||
onLink: (riskId: string) => void;
|
||||
onUnlink: (riskId: string) => void;
|
||||
};
|
||||
|
||||
function RiskRow(props: RowProps) {
|
||||
const { __ } = useTranslate();
|
||||
|
||||
const isLinked = props.linkedRisks.has(props.risk.id);
|
||||
const onClick = isLinked ? props.onUnlink : props.onLink;
|
||||
const IconComponent = isLinked ? IconTrashCan : IconPlusLarge;
|
||||
|
||||
return (
|
||||
<button
|
||||
className="py-4 flex items-center gap-4 hover:bg-subtle cursor-pointer px-6 w-full"
|
||||
onClick={() => onClick(props.risk.id)}
|
||||
>
|
||||
<div className="text-left">{props.risk.name}</div>
|
||||
<Badge variant="neutral">{props.risk.category}</Badge>
|
||||
<Button
|
||||
disabled={props.disabled}
|
||||
className="ml-auto"
|
||||
variant={isLinked ? "secondary" : "primary"}
|
||||
asChild
|
||||
>
|
||||
<span>
|
||||
<IconComponent size={16} /> {isLinked ? __("Unlink") : __("Link")}
|
||||
</span>
|
||||
</Button>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
const attachMeasureMutation = graphql`
|
||||
mutation MeasureLinkDialogCreateMutation(
|
||||
$input: CreateRiskMeasureMappingInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
createRiskMeasureMapping(input: $input) {
|
||||
measureEdge @prependEdge(connections: $connections) {
|
||||
node {
|
||||
id
|
||||
name
|
||||
description
|
||||
category
|
||||
state
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const detachMeasureMutation = graphql`
|
||||
mutation MeasureLinkDialogDetachMutation(
|
||||
$input: DeleteRiskMeasureMappingInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
deleteRiskMeasureMapping(input: $input) {
|
||||
deletedMeasureId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
*/
|
||||
66
apps/console2/src/components/risks/__generated__/LinkedRisksCardFragment.graphql.ts
generated
Normal file
66
apps/console2/src/components/risks/__generated__/LinkedRisksCardFragment.graphql.ts
generated
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @generated SignedSource<<6e092be20526b76ee767836880803c34>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type LinkedRisksCardFragment$data = {
|
||||
readonly id: string;
|
||||
readonly inherentRiskScore: number;
|
||||
readonly name: string;
|
||||
readonly residualRiskScore: number;
|
||||
readonly " $fragmentType": "LinkedRisksCardFragment";
|
||||
};
|
||||
export type LinkedRisksCardFragment$key = {
|
||||
readonly " $data"?: LinkedRisksCardFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedRisksCardFragment">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "LinkedRisksCardFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "inherentRiskScore",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "residualRiskScore",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Risk",
|
||||
"abstractKey": null
|
||||
};
|
||||
|
||||
(node as any).hash = "32a84445ae1cc071f56139fa44d67690";
|
||||
|
||||
export default node;
|
||||
206
apps/console2/src/components/risks/__generated__/LinkedRisksDialogQuery.graphql.ts
generated
Normal file
206
apps/console2/src/components/risks/__generated__/LinkedRisksDialogQuery.graphql.ts
generated
Normal file
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
* @generated SignedSource<<ac10f3fa76fc76951f4c08e38ef0a185>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type LinkedRisksDialogQuery$variables = {
|
||||
organizationId: string;
|
||||
};
|
||||
export type LinkedRisksDialogQuery$data = {
|
||||
readonly organization: {
|
||||
readonly id: string;
|
||||
readonly risks?: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly category: string;
|
||||
readonly description: string;
|
||||
readonly id: string;
|
||||
readonly inherentRiskScore: number;
|
||||
readonly name: string;
|
||||
readonly residualRiskScore: number;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
};
|
||||
};
|
||||
export type LinkedRisksDialogQuery = {
|
||||
response: LinkedRisksDialogQuery$data;
|
||||
variables: LinkedRisksDialogQuery$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 = {
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
],
|
||||
"concreteType": "RiskConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "risks",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "RiskEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Risk",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "category",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "inherentRiskScore",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "residualRiskScore",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "risks(first:100)"
|
||||
}
|
||||
],
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "LinkedRisksDialogQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "LinkedRisksDialogQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "organization",
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "ccac9f72628186de135aeb2ee176207d",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "LinkedRisksDialogQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query LinkedRisksDialogQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ... on Organization {\n risks(first: 100) {\n edges {\n node {\n id\n name\n category\n description\n inherentRiskScore\n residualRiskScore\n }\n }\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "a0a7e39135cc4c1a4a74c4728902f944";
|
||||
|
||||
export default node;
|
||||
@@ -41,7 +41,7 @@ export const documentNodeQuery = graphql`
|
||||
query DocumentGraphNodeQuery($documentId: ID!) {
|
||||
node(id: $documentId) {
|
||||
... on Document {
|
||||
...DocumentPageDocumentFragment
|
||||
...DocumentDetailPageDocumentFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ const deleteMeasureMutation = graphql`
|
||||
}
|
||||
`;
|
||||
|
||||
export const MeasureConnectionKey = "MeasuresGraphListQuery__measures";
|
||||
|
||||
export function useDeleteMeasureMutation() {
|
||||
const { __ } = useTranslate();
|
||||
|
||||
@@ -34,3 +36,40 @@ export function useDeleteMeasureMutation() {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export const measureNodeQuery = graphql`
|
||||
query MeasureGraphNodeQuery($measureId: ID!) {
|
||||
node(id: $measureId) {
|
||||
... on Measure {
|
||||
id
|
||||
name
|
||||
description
|
||||
state
|
||||
category
|
||||
...MeasureRisksTabFragment
|
||||
...MeasureControlsTabFragment
|
||||
...MeasureFormDialogMeasureFragment
|
||||
...MeasureEvidencesTabFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const measureUpdateMutation = graphql`
|
||||
mutation MeasureGraphUpdateMutation($input: UpdateMeasureInput!) {
|
||||
updateMeasure(input: $input) {
|
||||
measure {
|
||||
...MeasureFormDialogMeasureFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const useUpdateMeasure = () => {
|
||||
const { __ } = useTranslate();
|
||||
|
||||
return useMutationWithToasts(measureUpdateMutation, {
|
||||
successMessage: __("Measure updated successfully."),
|
||||
errorMessage: __("Failed to update measure. Please try again."),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -12,7 +12,7 @@ import type { PeopleGraphPaginatedQuery } from "./__generated__/PeopleGraphPagin
|
||||
import type { PeopleGraphPaginatedFragment$key } from "./__generated__/PeopleGraphPaginatedFragment.graphql";
|
||||
import { useConfirm } from "@probo/ui";
|
||||
import type { PeopleGraphDeleteMutation } from "./__generated__/PeopleGraphDeleteMutation.graphql";
|
||||
import { sprintf } from "@probo/helpers";
|
||||
import { promisifyMutation, sprintf } from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
|
||||
const peopleQuery = graphql`
|
||||
@@ -130,16 +130,13 @@ export const useDeletePeople = (
|
||||
}
|
||||
confirm(
|
||||
() =>
|
||||
new Promise((resolve) => {
|
||||
mutate({
|
||||
variables: {
|
||||
input: {
|
||||
peopleId: people.id!,
|
||||
},
|
||||
connections: [connectionId],
|
||||
promisifyMutation(mutate)({
|
||||
variables: {
|
||||
input: {
|
||||
peopleId: people.id!,
|
||||
},
|
||||
onCompleted: () => resolve(),
|
||||
});
|
||||
connections: [connectionId],
|
||||
},
|
||||
}),
|
||||
{
|
||||
message: sprintf(
|
||||
|
||||
@@ -109,6 +109,7 @@ export const riskNodeQuery = graphql`
|
||||
...useRiskFormFragment
|
||||
...RiskOverviewTabFragment
|
||||
...RiskMeasuresTabFragment
|
||||
...RiskDocumentsTabFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { VendorGraphCreateMutation } from "./__generated__/VendorGraphCreat
|
||||
import type { VendorGraphDeleteMutation } from "./__generated__/VendorGraphDeleteMutation.graphql.ts";
|
||||
import { useMutation } from "react-relay";
|
||||
import { useConfirm } from "@probo/ui";
|
||||
import { sprintf } from "@probo/helpers";
|
||||
import { promisifyMutation, sprintf } from "@probo/helpers";
|
||||
|
||||
const createVendorMutation = graphql`
|
||||
mutation VendorGraphCreateMutation(
|
||||
@@ -64,16 +64,13 @@ export const useDeleteVendor = (
|
||||
}
|
||||
confirm(
|
||||
() =>
|
||||
new Promise((resolve) => {
|
||||
mutate({
|
||||
variables: {
|
||||
input: {
|
||||
vendorId: vendor.id!,
|
||||
},
|
||||
connections: [connectionId],
|
||||
promisifyMutation(mutate)({
|
||||
variables: {
|
||||
input: {
|
||||
vendorId: vendor.id!,
|
||||
},
|
||||
onCompleted: () => resolve(),
|
||||
});
|
||||
connections: [connectionId],
|
||||
},
|
||||
}),
|
||||
{
|
||||
message: sprintf(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<2cb115c83f67688124df197a8f944329>>
|
||||
* @generated SignedSource<<1c8d31af825eefa7bfb5d58a2534f190>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -15,7 +15,7 @@ export type DocumentGraphNodeQuery$variables = {
|
||||
};
|
||||
export type DocumentGraphNodeQuery$data = {
|
||||
readonly node: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"DocumentPageDocumentFragment">;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"DocumentDetailPageDocumentFragment">;
|
||||
};
|
||||
};
|
||||
export type DocumentGraphNodeQuery = {
|
||||
@@ -60,19 +60,19 @@ v4 = {
|
||||
"storageKey": null
|
||||
},
|
||||
v5 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 20
|
||||
}
|
||||
],
|
||||
v6 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
],
|
||||
v6 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
v7 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -116,7 +116,14 @@ v9 = {
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
};
|
||||
},
|
||||
v10 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 20
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
@@ -138,7 +145,7 @@ return {
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "DocumentPageDocumentFragment"
|
||||
"name": "DocumentDetailPageDocumentFragment"
|
||||
}
|
||||
],
|
||||
"type": "Document",
|
||||
@@ -193,6 +200,74 @@ return {
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v5/*: any*/),
|
||||
"concreteType": "ControlConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "controls",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ControlEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Control",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v6/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "referenceId",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Framework",
|
||||
"kind": "LinkedField",
|
||||
"name": "framework",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v6/*: any*/),
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v7/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v8/*: any*/),
|
||||
(v9/*: any*/)
|
||||
],
|
||||
"storageKey": "controls(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v5/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "DocumentDetailPage_controls",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "controls"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v10/*: any*/),
|
||||
"concreteType": "DocumentVersionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "versions",
|
||||
@@ -252,7 +327,7 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v6/*: any*/),
|
||||
"args": (v5/*: any*/),
|
||||
"concreteType": "DocumentVersionSignatureConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "signatures",
|
||||
@@ -331,10 +406,10 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v6/*: any*/),
|
||||
"args": (v5/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "DocumentPage_signatures",
|
||||
"key": "DocumentDetailPage_signatures",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "signatures"
|
||||
},
|
||||
@@ -373,10 +448,10 @@ return {
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v5/*: any*/),
|
||||
"args": (v10/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "DocumentPage_versions",
|
||||
"key": "DocumentDetailPage_versions",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "versions"
|
||||
}
|
||||
@@ -390,16 +465,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "671e1a9b133593847c68af3abd9a721f",
|
||||
"cacheID": "cc52945231b42fbaf4c86eba5c3ee433",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "DocumentGraphNodeQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query DocumentGraphNodeQuery(\n $documentId: ID!\n) {\n node(id: $documentId) {\n __typename\n ... on Document {\n ...DocumentPageDocumentFragment\n }\n id\n }\n}\n\nfragment DocumentPageDocumentFragment on Document {\n id\n title\n owner {\n id\n fullName\n }\n versions(first: 20) {\n edges {\n node {\n id\n content\n status\n publishedAt\n version\n updatedAt\n signatures(first: 100) {\n edges {\n node {\n id\n state\n signedBy {\n id\n }\n ...DocumentSignaturesDialog_signature\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n ...DocumentVersionHistoryDialogFragment\n ...DocumentSignaturesDialog_version\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment DocumentSignaturesDialog_signature on DocumentVersionSignature {\n id\n state\n signedAt\n requestedAt\n signedBy {\n fullName\n primaryEmailAddress\n id\n }\n}\n\nfragment DocumentSignaturesDialog_version on DocumentVersion {\n version\n status\n publishedAt\n updatedAt\n}\n\nfragment DocumentVersionHistoryDialogFragment on DocumentVersion {\n id\n version\n status\n content\n changelog\n publishedAt\n updatedAt\n publishedBy {\n fullName\n id\n }\n}\n"
|
||||
"text": "query DocumentGraphNodeQuery(\n $documentId: ID!\n) {\n node(id: $documentId) {\n __typename\n ... on Document {\n ...DocumentDetailPageDocumentFragment\n }\n id\n }\n}\n\nfragment DocumentDetailPageDocumentFragment on Document {\n id\n title\n owner {\n id\n fullName\n }\n controls(first: 100) {\n edges {\n node {\n id\n ...LinkedControlsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n versions(first: 20) {\n edges {\n node {\n id\n content\n status\n publishedAt\n version\n updatedAt\n signatures(first: 100) {\n edges {\n node {\n id\n state\n signedBy {\n id\n }\n ...DocumentSignaturesDialog_signature\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n ...DocumentVersionHistoryDialogFragment\n ...DocumentSignaturesDialog_version\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment DocumentSignaturesDialog_signature on DocumentVersionSignature {\n id\n state\n signedAt\n requestedAt\n signedBy {\n fullName\n primaryEmailAddress\n id\n }\n}\n\nfragment DocumentSignaturesDialog_version on DocumentVersion {\n version\n status\n publishedAt\n updatedAt\n}\n\nfragment DocumentVersionHistoryDialogFragment on DocumentVersion {\n id\n version\n status\n content\n changelog\n publishedAt\n updatedAt\n publishedBy {\n fullName\n id\n }\n}\n\nfragment LinkedControlsCardFragment on Control {\n id\n name\n referenceId\n framework {\n name\n id\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "d6f55d4636b86d853b97b44e68e435f2";
|
||||
(node as any).hash = "f7e5a8ebb67a7668627c01ca1c4c6b19";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<4d7510366af238f19e3bff7949776f0a>>
|
||||
* @generated SignedSource<<792fbba36453d167b7844222f287183e>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -153,6 +153,13 @@ return {
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
@@ -226,12 +233,12 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "876c92c41e08247a4900883b56ac6762",
|
||||
"cacheID": "aeaecdca869ba61b6602c2ebd701061d",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "MeasureGraphListQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query MeasureGraphListQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ...MeasuresPageFragment\n }\n}\n\nfragment MeasuresPageFragment on Organization {\n measures(first: 100) {\n edges {\n node {\n id\n name\n category\n state\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
|
||||
"text": "query MeasureGraphListQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ...MeasuresPageFragment\n }\n}\n\nfragment MeasureFormDialogMeasureFragment on Measure {\n id\n description\n name\n category\n state\n}\n\nfragment MeasuresPageFragment on Organization {\n measures(first: 100) {\n edges {\n node {\n id\n name\n category\n state\n ...MeasureFormDialogMeasureFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
495
apps/console2/src/hooks/graph/__generated__/MeasureGraphNodeQuery.graphql.ts
generated
Normal file
495
apps/console2/src/hooks/graph/__generated__/MeasureGraphNodeQuery.graphql.ts
generated
Normal file
@@ -0,0 +1,495 @@
|
||||
/**
|
||||
* @generated SignedSource<<3f0bf5e0e474802b13df43d692ee926d>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type MeasureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
|
||||
export type MeasureGraphNodeQuery$variables = {
|
||||
measureId: string;
|
||||
};
|
||||
export type MeasureGraphNodeQuery$data = {
|
||||
readonly node: {
|
||||
readonly category?: string;
|
||||
readonly description?: string;
|
||||
readonly id?: string;
|
||||
readonly name?: string;
|
||||
readonly state?: MeasureState;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"MeasureControlsTabFragment" | "MeasureEvidencesTabFragment" | "MeasureFormDialogMeasureFragment" | "MeasureRisksTabFragment">;
|
||||
};
|
||||
};
|
||||
export type MeasureGraphNodeQuery = {
|
||||
response: MeasureGraphNodeQuery$data;
|
||||
variables: MeasureGraphNodeQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "measureId"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "measureId"
|
||||
}
|
||||
],
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
v4 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
v5 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
},
|
||||
v6 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "category",
|
||||
"storageKey": null
|
||||
},
|
||||
v7 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v8 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
],
|
||||
v9 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
},
|
||||
v10 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
v11 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
},
|
||||
v12 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v10/*: any*/),
|
||||
(v11/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
v13 = {
|
||||
"kind": "ClientExtension",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__id",
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
v14 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 50
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "MeasureGraphNodeQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v5/*: any*/),
|
||||
(v6/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "MeasureRisksTabFragment"
|
||||
},
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "MeasureControlsTabFragment"
|
||||
},
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "MeasureFormDialogMeasureFragment"
|
||||
},
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "MeasureEvidencesTabFragment"
|
||||
}
|
||||
],
|
||||
"type": "Measure",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "MeasureGraphNodeQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v7/*: any*/),
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/),
|
||||
(v5/*: any*/),
|
||||
(v6/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v8/*: any*/),
|
||||
"concreteType": "RiskConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "risks",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "RiskEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Risk",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "inherentRiskScore",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "residualRiskScore",
|
||||
"storageKey": null
|
||||
},
|
||||
(v7/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v9/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v12/*: any*/),
|
||||
(v13/*: any*/)
|
||||
],
|
||||
"storageKey": "risks(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v8/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "Measure__risks",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "risks"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v8/*: any*/),
|
||||
"concreteType": "ControlConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "controls",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ControlEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Control",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "referenceId",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Framework",
|
||||
"kind": "LinkedField",
|
||||
"name": "framework",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v7/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v9/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v12/*: any*/),
|
||||
(v13/*: any*/)
|
||||
],
|
||||
"storageKey": "controls(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v8/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "MeasureControlsTabFragment_controls",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "controls"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v14/*: any*/),
|
||||
"concreteType": "EvidenceConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "evidences",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "EvidenceEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Evidence",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "filename",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "size",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "type",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fileUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "mimeType",
|
||||
"storageKey": null
|
||||
},
|
||||
(v7/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v9/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v10/*: any*/),
|
||||
(v11/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasPreviousPage",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "startCursor",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v13/*: any*/)
|
||||
],
|
||||
"storageKey": "evidences(first:50)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v14/*: any*/),
|
||||
"filters": [
|
||||
"orderBy"
|
||||
],
|
||||
"handle": "connection",
|
||||
"key": "MeasureEvidencesTabFragment_evidences",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "evidences"
|
||||
}
|
||||
],
|
||||
"type": "Measure",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "a4e9a325cbe97ad3b4846200c7e88a22",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "MeasureGraphNodeQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query MeasureGraphNodeQuery(\n $measureId: ID!\n) {\n node(id: $measureId) {\n __typename\n ... on Measure {\n id\n name\n description\n state\n category\n ...MeasureRisksTabFragment\n ...MeasureControlsTabFragment\n ...MeasureFormDialogMeasureFragment\n ...MeasureEvidencesTabFragment\n }\n id\n }\n}\n\nfragment LinkedControlsCardFragment on Control {\n id\n name\n referenceId\n framework {\n name\n id\n }\n}\n\nfragment LinkedRisksCardFragment on Risk {\n id\n name\n inherentRiskScore\n residualRiskScore\n}\n\nfragment MeasureControlsTabFragment on Measure {\n id\n controls(first: 100) {\n edges {\n node {\n id\n ...LinkedControlsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment MeasureEvidencesTabFragment on Measure {\n id\n evidences(first: 50) {\n edges {\n node {\n id\n ...MeasureEvidencesTabFragment_evidence\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment MeasureEvidencesTabFragment_evidence on Evidence {\n id\n filename\n size\n type\n createdAt\n fileUrl\n mimeType\n}\n\nfragment MeasureFormDialogMeasureFragment on Measure {\n id\n description\n name\n category\n state\n}\n\nfragment MeasureRisksTabFragment on Measure {\n id\n risks(first: 100) {\n edges {\n node {\n id\n ...LinkedRisksCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "5c4bd0699414117e0ed408348554ca7d";
|
||||
|
||||
export default node;
|
||||
167
apps/console2/src/hooks/graph/__generated__/MeasureGraphUpdateMutation.graphql.ts
generated
Normal file
167
apps/console2/src/hooks/graph/__generated__/MeasureGraphUpdateMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* @generated SignedSource<<0568c40c0caa32ce6daf11d414e2cc72>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type MeasureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
|
||||
export type UpdateMeasureInput = {
|
||||
category?: string | null | undefined;
|
||||
description?: string | null | undefined;
|
||||
id: string;
|
||||
name?: string | null | undefined;
|
||||
state?: MeasureState | null | undefined;
|
||||
};
|
||||
export type MeasureGraphUpdateMutation$variables = {
|
||||
input: UpdateMeasureInput;
|
||||
};
|
||||
export type MeasureGraphUpdateMutation$data = {
|
||||
readonly updateMeasure: {
|
||||
readonly measure: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"MeasureFormDialogMeasureFragment">;
|
||||
};
|
||||
};
|
||||
};
|
||||
export type MeasureGraphUpdateMutation = {
|
||||
response: MeasureGraphUpdateMutation$data;
|
||||
variables: MeasureGraphUpdateMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "MeasureGraphUpdateMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": "UpdateMeasurePayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "updateMeasure",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Measure",
|
||||
"kind": "LinkedField",
|
||||
"name": "measure",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "MeasureFormDialogMeasureFragment"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "MeasureGraphUpdateMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": "UpdateMeasurePayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "updateMeasure",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Measure",
|
||||
"kind": "LinkedField",
|
||||
"name": "measure",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "category",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "17d35db59a42796407f7f0d6bb4798ba",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "MeasureGraphUpdateMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation MeasureGraphUpdateMutation(\n $input: UpdateMeasureInput!\n) {\n updateMeasure(input: $input) {\n measure {\n ...MeasureFormDialogMeasureFragment\n id\n }\n }\n}\n\nfragment MeasureFormDialogMeasureFragment on Measure {\n id\n description\n name\n category\n state\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "9f74c8c6cea82050d077d26e6b7547f6";
|
||||
|
||||
export default node;
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<dfb9e4b341ccc895fce60e2de5287ec1>>
|
||||
* @generated SignedSource<<1fce2cc80e82f95488675ab257cb1087>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -24,7 +24,7 @@ export type RiskGraphNodeQuery$data = {
|
||||
readonly id: string;
|
||||
} | null | undefined;
|
||||
readonly treatment?: RiskTreatment;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"RiskMeasuresTabFragment" | "RiskOverviewTabFragment" | "useRiskFormFragment">;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"RiskDocumentsTabFragment" | "RiskMeasuresTabFragment" | "RiskOverviewTabFragment" | "useRiskFormFragment">;
|
||||
};
|
||||
};
|
||||
export type RiskGraphNodeQuery = {
|
||||
@@ -114,7 +114,51 @@ v9 = [
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
];
|
||||
],
|
||||
v10 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
},
|
||||
v11 = {
|
||||
"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
|
||||
},
|
||||
v12 = {
|
||||
"kind": "ClientExtension",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__id",
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
@@ -152,6 +196,11 @@ return {
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "RiskMeasuresTabFragment"
|
||||
},
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "RiskDocumentsTabFragment"
|
||||
}
|
||||
],
|
||||
"type": "Risk",
|
||||
@@ -274,53 +323,12 @@ return {
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
(v10/*: any*/)
|
||||
],
|
||||
"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
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"kind": "ClientExtension",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__id",
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
}
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/)
|
||||
],
|
||||
"storageKey": "measures(first:100)"
|
||||
},
|
||||
@@ -332,6 +340,121 @@ return {
|
||||
"key": "Risk__measures",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "measures"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v9/*: any*/),
|
||||
"concreteType": "DocumentConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "documents",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "DocumentEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Document",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v5/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "title",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "documentType",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 1
|
||||
}
|
||||
],
|
||||
"concreteType": "DocumentVersionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "versions",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "DocumentVersionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "DocumentVersion",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v5/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "versions(first:1)"
|
||||
},
|
||||
(v8/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v10/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/)
|
||||
],
|
||||
"storageKey": "documents(first:100)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v9/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "Risk__documents",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "documents"
|
||||
}
|
||||
],
|
||||
"type": "Risk",
|
||||
@@ -343,16 +466,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "295ecc0e99f46b7790fe04db0deed1d8",
|
||||
"cacheID": "bb52cb7161bdf1bbba40f782f5ff22c2",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "RiskGraphNodeQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query RiskGraphNodeQuery(\n $riskId: ID!\n) {\n node(id: $riskId) {\n __typename\n ... on Risk {\n name\n description\n treatment\n owner {\n id\n fullName\n }\n note\n ...useRiskFormFragment\n ...RiskOverviewTabFragment\n ...RiskMeasuresTabFragment\n }\n id\n }\n}\n\nfragment LinkedMeasuresCardFragment on Measure {\n id\n name\n state\n}\n\nfragment RiskMeasuresTabFragment on Risk {\n id\n measures(first: 100) {\n edges {\n node {\n id\n ...LinkedMeasuresCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment RiskOverviewTabFragment on Risk {\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n}\n\nfragment useRiskFormFragment on Risk {\n id\n name\n category\n description\n treatment\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n note\n owner {\n id\n }\n}\n"
|
||||
"text": "query RiskGraphNodeQuery(\n $riskId: ID!\n) {\n node(id: $riskId) {\n __typename\n ... on Risk {\n name\n description\n treatment\n owner {\n id\n fullName\n }\n note\n ...useRiskFormFragment\n ...RiskOverviewTabFragment\n ...RiskMeasuresTabFragment\n ...RiskDocumentsTabFragment\n }\n id\n }\n}\n\nfragment LinkedDocumentsCardFragment on Document {\n id\n title\n createdAt\n documentType\n versions(first: 1) {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n\nfragment LinkedMeasuresCardFragment on Measure {\n id\n name\n state\n}\n\nfragment RiskDocumentsTabFragment on Risk {\n id\n documents(first: 100) {\n edges {\n node {\n id\n ...LinkedDocumentsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment RiskMeasuresTabFragment on Risk {\n id\n measures(first: 100) {\n edges {\n node {\n id\n ...LinkedMeasuresCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment RiskOverviewTabFragment on Risk {\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n}\n\nfragment useRiskFormFragment on Risk {\n id\n name\n category\n description\n treatment\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n note\n owner {\n id\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "c742a5b3e536eabc8dca8b680f763a04";
|
||||
(node as any).hash = "fad84c61c3943be5d63e810325aa8f62";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -28,6 +28,8 @@ import { graphql } from "relay-runtime";
|
||||
import { useLazyLoadQuery } from "react-relay";
|
||||
import type { MainLayoutQuery as MainLayoutQueryType } from "./__generated__/MainLayoutQuery.graphql";
|
||||
import { Suspense } from "react";
|
||||
import { ErrorBoundary } from "react-error-boundary";
|
||||
import { PageError } from "/components/PageError";
|
||||
|
||||
const MainLayoutQuery = graphql`
|
||||
query MainLayoutQuery {
|
||||
@@ -123,7 +125,9 @@ export function MainLayout() {
|
||||
</ul>
|
||||
}
|
||||
>
|
||||
<Outlet />
|
||||
<ErrorBoundary FallbackComponent={PageError}>
|
||||
<Outlet />
|
||||
</ErrorBoundary>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,13 +13,12 @@ import {
|
||||
useDeleteDocumentMutation,
|
||||
} from "/hooks/graph/DocumentGraph";
|
||||
import { usePageTitle } from "@probo/hooks";
|
||||
import type { DocumentPageDocumentFragment$key } from "./__generated__/DocumentPageDocumentFragment.graphql";
|
||||
import type { DocumentDetailPageDocumentFragment$key } from "./__generated__/DocumentDetailPageDocumentFragment.graphql";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import {
|
||||
PageHeader,
|
||||
Breadcrumb,
|
||||
IconCheckmark1,
|
||||
Markdown,
|
||||
PropertyRow,
|
||||
Drawer,
|
||||
Badge,
|
||||
@@ -31,12 +30,15 @@ import {
|
||||
IconClock,
|
||||
IconSignature,
|
||||
useConfirm,
|
||||
Tabs,
|
||||
TabLink,
|
||||
TabBadge,
|
||||
} from "@probo/ui";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import { Button } from "@probo/ui";
|
||||
import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
|
||||
import { sprintf } from "@probo/helpers";
|
||||
import { useNavigate } from "react-router";
|
||||
import { Outlet, useNavigate } from "react-router";
|
||||
import UpdateVersionDialog from "./dialogs/UpdateVersionDialog";
|
||||
import { useRef } from "react";
|
||||
import { DocumentVersionHistoryDialog } from "./dialogs/DocumentVersionHistoryDialog";
|
||||
@@ -47,14 +49,23 @@ type Props = {
|
||||
};
|
||||
|
||||
const documentFragment = graphql`
|
||||
fragment DocumentPageDocumentFragment on Document {
|
||||
fragment DocumentDetailPageDocumentFragment on Document {
|
||||
id
|
||||
title
|
||||
owner {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
versions(first: 20) @connection(key: "DocumentPage_versions") {
|
||||
controls(first: 100) @connection(key: "DocumentDetailPage_controls") {
|
||||
__id
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
...LinkedControlsCardFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
versions(first: 20) @connection(key: "DocumentDetailPage_versions") {
|
||||
__id
|
||||
edges {
|
||||
node {
|
||||
@@ -64,7 +75,8 @@ const documentFragment = graphql`
|
||||
publishedAt
|
||||
version
|
||||
updatedAt
|
||||
signatures(first: 100) @connection(key: "DocumentPage_signatures") {
|
||||
signatures(first: 100)
|
||||
@connection(key: "DocumentDetailPage_signatures") {
|
||||
__id
|
||||
edges {
|
||||
node {
|
||||
@@ -86,7 +98,9 @@ const documentFragment = graphql`
|
||||
`;
|
||||
|
||||
const publishDocumentVersionMutation = graphql`
|
||||
mutation DocumentPagePublishMutation($input: PublishDocumentVersionInput!) {
|
||||
mutation DocumentDetailPagePublishMutation(
|
||||
$input: PublishDocumentVersionInput!
|
||||
) {
|
||||
publishDocumentVersion(input: $input) {
|
||||
document {
|
||||
id
|
||||
@@ -95,11 +109,11 @@ const publishDocumentVersionMutation = graphql`
|
||||
}
|
||||
`;
|
||||
|
||||
export default function DocumentPage(props: Props) {
|
||||
export default function DocumentDetailPage(props: Props) {
|
||||
const node = usePreloadedQuery(documentNodeQuery, props.queryRef).node;
|
||||
const document = useFragment(
|
||||
documentFragment,
|
||||
node as DocumentPageDocumentFragment$key
|
||||
node as DocumentDetailPageDocumentFragment$key
|
||||
);
|
||||
const { __, dateFormat } = useTranslate();
|
||||
const organizationId = useOrganizationId();
|
||||
@@ -229,7 +243,22 @@ export default function DocumentPage(props: Props) {
|
||||
</div>
|
||||
</div>
|
||||
<PageHeader title={document.title} />
|
||||
<Markdown content={lastVersion.content} />
|
||||
|
||||
<Tabs>
|
||||
<TabLink
|
||||
to={`/organizations/${organizationId}/documents/${document.id}/description`}
|
||||
>
|
||||
{__("Description")}
|
||||
</TabLink>
|
||||
<TabLink
|
||||
to={`/organizations/${organizationId}/documents/${document.id}/controls`}
|
||||
>
|
||||
{__("Controls")}
|
||||
<TabBadge>{document.controls.edges.length}</TabBadge>
|
||||
</TabLink>
|
||||
</Tabs>
|
||||
|
||||
<Outlet context={{ document, lastVersion }} />
|
||||
</div>
|
||||
<Drawer>
|
||||
<div className="text-base text-txt-primary font-medium mb-4">
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<c182ef1b9491681644676e99e0b07ee7>>
|
||||
* @generated SignedSource<<72689566d977ab4171c75ba9ce2c62f4>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -12,7 +12,16 @@ import { ReaderFragment } from 'relay-runtime';
|
||||
export type DocumentStatus = "DRAFT" | "PUBLISHED";
|
||||
export type DocumentVersionSignatureState = "REQUESTED" | "SIGNED";
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type DocumentPageDocumentFragment$data = {
|
||||
export type DocumentDetailPageDocumentFragment$data = {
|
||||
readonly controls: {
|
||||
readonly __id: string;
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedControlsCardFragment">;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly id: string;
|
||||
readonly owner: {
|
||||
readonly fullName: string;
|
||||
@@ -46,11 +55,11 @@ export type DocumentPageDocumentFragment$data = {
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly " $fragmentType": "DocumentPageDocumentFragment";
|
||||
readonly " $fragmentType": "DocumentDetailPageDocumentFragment";
|
||||
};
|
||||
export type DocumentPageDocumentFragment$key = {
|
||||
readonly " $data"?: DocumentPageDocumentFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"DocumentPageDocumentFragment">;
|
||||
export type DocumentDetailPageDocumentFragment$key = {
|
||||
readonly " $data"?: DocumentDetailPageDocumentFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"DocumentDetailPageDocumentFragment">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
@@ -117,6 +126,14 @@ return {
|
||||
"kind": "Fragment",
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": null,
|
||||
"cursor": null,
|
||||
"direction": "forward",
|
||||
"path": [
|
||||
"controls"
|
||||
]
|
||||
},
|
||||
{
|
||||
"count": null,
|
||||
"cursor": null,
|
||||
@@ -133,7 +150,7 @@ return {
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "DocumentPageDocumentFragment",
|
||||
"name": "DocumentDetailPageDocumentFragment",
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
@@ -162,12 +179,55 @@ return {
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "controls",
|
||||
"args": null,
|
||||
"concreteType": "ControlConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__DocumentDetailPage_controls_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ControlEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Control",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "LinkedControlsCardFragment"
|
||||
},
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": "versions",
|
||||
"args": null,
|
||||
"concreteType": "DocumentVersionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__DocumentPage_versions_connection",
|
||||
"name": "__DocumentDetailPage_versions_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
@@ -227,7 +287,7 @@ return {
|
||||
"args": null,
|
||||
"concreteType": "DocumentVersionSignatureConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__DocumentPage_signatures_connection",
|
||||
"name": "__DocumentDetailPage_signatures_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
@@ -313,6 +373,6 @@ return {
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "b42e98e8e26bc94a2d412bd73cd601f2";
|
||||
(node as any).hash = "df93b2fdd0ceea0637ddac2e4186181c";
|
||||
|
||||
export default node;
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<3ef23505e9378ce7ea92943b394ba290>>
|
||||
* @generated SignedSource<<ce29629a1c8d489463cc22edbd8b81de>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -10,21 +10,22 @@
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type PublishDocumentVersionInput = {
|
||||
changelog?: string | null | undefined;
|
||||
documentId: string;
|
||||
};
|
||||
export type DocumentPagePublishMutation$variables = {
|
||||
export type DocumentDetailPagePublishMutation$variables = {
|
||||
input: PublishDocumentVersionInput;
|
||||
};
|
||||
export type DocumentPagePublishMutation$data = {
|
||||
export type DocumentDetailPagePublishMutation$data = {
|
||||
readonly publishDocumentVersion: {
|
||||
readonly document: {
|
||||
readonly id: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
export type DocumentPagePublishMutation = {
|
||||
response: DocumentPagePublishMutation$data;
|
||||
variables: DocumentPagePublishMutation$variables;
|
||||
export type DocumentDetailPagePublishMutation = {
|
||||
response: DocumentDetailPagePublishMutation$data;
|
||||
variables: DocumentDetailPagePublishMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
@@ -77,7 +78,7 @@ return {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "DocumentPagePublishMutation",
|
||||
"name": "DocumentDetailPagePublishMutation",
|
||||
"selections": (v1/*: any*/),
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
@@ -86,20 +87,20 @@ return {
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "DocumentPagePublishMutation",
|
||||
"name": "DocumentDetailPagePublishMutation",
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "fad75c1a396f60d6d13e1605fe85f33e",
|
||||
"cacheID": "bbee8d20f444cdc0dbb012e8fecfa9c1",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "DocumentPagePublishMutation",
|
||||
"name": "DocumentDetailPagePublishMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation DocumentPagePublishMutation(\n $input: PublishDocumentVersionInput!\n) {\n publishDocumentVersion(input: $input) {\n document {\n id\n }\n }\n}\n"
|
||||
"text": "mutation DocumentDetailPagePublishMutation(\n $input: PublishDocumentVersionInput!\n) {\n publishDocumentVersion(input: $input) {\n document {\n id\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "488029ccd88b4c637b63cd11d1bef986";
|
||||
(node as any).hash = "2f5cc9855133b614896a1ac3768e669f";
|
||||
|
||||
export default node;
|
||||
@@ -13,7 +13,6 @@ import {
|
||||
} from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { useState, type ReactNode, Suspense } from "react";
|
||||
import type { DocumentPageDocumentFragment$data } from "../__generated__/DocumentPageDocumentFragment.graphql";
|
||||
import clsx from "clsx";
|
||||
import type { ItemOf, NodeOf } from "/types";
|
||||
import { graphql, useFragment } from "react-relay";
|
||||
@@ -23,13 +22,14 @@ import { usePeople } from "/hooks/graph/PeopleGraph.ts";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId.ts";
|
||||
import { useMutationWithToasts } from "/hooks/useMutationWithToasts.ts";
|
||||
import { sprintf } from "@probo/helpers";
|
||||
import type { DocumentDetailPageDocumentFragment$data } from "../__generated__/DocumentDetailPageDocumentFragment.graphql";
|
||||
|
||||
type Props = {
|
||||
document: DocumentPageDocumentFragment$data;
|
||||
document: DocumentDetailPageDocumentFragment$data;
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
type Version = NodeOf<DocumentPageDocumentFragment$data["versions"]>;
|
||||
type Version = NodeOf<DocumentDetailPageDocumentFragment$data["versions"]>;
|
||||
|
||||
export function DocumentSignaturesDialog(props: Props) {
|
||||
const { __ } = useTranslate();
|
||||
|
||||
@@ -9,11 +9,11 @@ import {
|
||||
import { graphql } from "relay-runtime";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { useState, type ReactNode } from "react";
|
||||
import type { DocumentPageDocumentFragment$data } from "../__generated__/DocumentPageDocumentFragment.graphql";
|
||||
import { useFragment } from "react-relay";
|
||||
import type { DocumentVersionHistoryDialogFragment$key } from "./__generated__/DocumentVersionHistoryDialogFragment.graphql";
|
||||
import clsx from "clsx";
|
||||
import type { NodeOf } from "/types";
|
||||
import type { DocumentDetailPageDocumentFragment$data } from "../__generated__/DocumentDetailPageDocumentFragment.graphql";
|
||||
|
||||
const historyFragment = graphql`
|
||||
fragment DocumentVersionHistoryDialogFragment on DocumentVersion {
|
||||
@@ -31,11 +31,11 @@ const historyFragment = graphql`
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
document: DocumentPageDocumentFragment$data;
|
||||
document: DocumentDetailPageDocumentFragment$data;
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
type Version = NodeOf<DocumentPageDocumentFragment$data["versions"]>;
|
||||
type Version = NodeOf<DocumentDetailPageDocumentFragment$data["versions"]>;
|
||||
|
||||
export function DocumentVersionHistoryDialog(props: Props) {
|
||||
const { __ } = useTranslate();
|
||||
@@ -68,7 +68,7 @@ export function DocumentVersionHistoryDialog(props: Props) {
|
||||
}
|
||||
|
||||
function VersionItem(props: {
|
||||
document: DocumentPageDocumentFragment$data;
|
||||
document: DocumentDetailPageDocumentFragment$data;
|
||||
version: Version;
|
||||
active?: boolean;
|
||||
onSelect: (v: Version) => void;
|
||||
|
||||
@@ -13,12 +13,12 @@ import {
|
||||
import { type RefObject } from "react";
|
||||
import { graphql } from "relay-runtime";
|
||||
import { useMutation } from "react-relay";
|
||||
import type { DocumentPageDocumentFragment$data } from "../__generated__/DocumentPageDocumentFragment.graphql";
|
||||
import type { UpdateVersionDialogCreateMutation } from "./__generated__/UpdateVersionDialogCreateMutation.graphql";
|
||||
import type { UpdateVersionDialogUpdateMutation } from "./__generated__/UpdateVersionDialogUpdateMutation.graphql";
|
||||
import { z } from "zod";
|
||||
import { useFormWithSchema } from "/hooks/useFormWithSchema";
|
||||
import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
|
||||
import type { DocumentDetailPageDocumentFragment$data } from "../__generated__/DocumentDetailPageDocumentFragment.graphql";
|
||||
|
||||
const createDraftDocument = graphql`
|
||||
mutation UpdateVersionDialogCreateMutation(
|
||||
@@ -62,7 +62,7 @@ const UpdateDocumentMutation = graphql`
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
document: DocumentPageDocumentFragment$data;
|
||||
document: DocumentDetailPageDocumentFragment$data;
|
||||
connectionId: string;
|
||||
ref: RefObject<{ open: () => void } | null>;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { LinkedControlsCard } from "/components/controls/LinkedControlsCard";
|
||||
import { useOutletContext } from "react-router";
|
||||
import type { DocumentDetailPageDocumentFragment$data } from "../__generated__/DocumentDetailPageDocumentFragment.graphql";
|
||||
import { graphql } from "relay-runtime";
|
||||
import { useMutation } from "react-relay";
|
||||
|
||||
const detachControlMutation = graphql`
|
||||
mutation DocumentControlsTab_detachControlMutation(
|
||||
$input: DeleteControlDocumentMappingInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
deleteControlDocumentMapping(input: $input) {
|
||||
deletedControlId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default function DocumentControlsTab() {
|
||||
const { document } = useOutletContext<{
|
||||
document: DocumentDetailPageDocumentFragment$data;
|
||||
}>();
|
||||
const controls = document.controls.edges.map((edge) => edge.node);
|
||||
const [detachControl] = useMutation(detachControlMutation);
|
||||
console.log(controls.map((c) => c.id));
|
||||
return (
|
||||
<LinkedControlsCard
|
||||
controls={controls}
|
||||
params={{ documentId: document.id }}
|
||||
connectionId={document.controls.__id}
|
||||
onDetach={detachControl}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { useOutletContext } from "react-router";
|
||||
import type { DocumentDetailPageDocumentFragment$data } from "../__generated__/DocumentDetailPageDocumentFragment.graphql";
|
||||
import type { NodeOf } from "/types";
|
||||
import { Markdown } from "@probo/ui";
|
||||
|
||||
export default function DocumentDescriptionTab() {
|
||||
const { lastVersion } = useOutletContext<{
|
||||
lastVersion: NodeOf<DocumentDetailPageDocumentFragment$data["versions"]>;
|
||||
}>();
|
||||
return (
|
||||
<div>
|
||||
<Markdown content={lastVersion.content} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* @generated SignedSource<<5c230fb025256fb7a5281ee5ecd3ccf4>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type DeleteControlDocumentMappingInput = {
|
||||
controlId: string;
|
||||
documentId: string;
|
||||
};
|
||||
export type DocumentControlsTab_detachControlMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: DeleteControlDocumentMappingInput;
|
||||
};
|
||||
export type DocumentControlsTab_detachControlMutation$data = {
|
||||
readonly deleteControlDocumentMapping: {
|
||||
readonly deletedControlId: string;
|
||||
};
|
||||
};
|
||||
export type DocumentControlsTab_detachControlMutation = {
|
||||
response: DocumentControlsTab_detachControlMutation$data;
|
||||
variables: DocumentControlsTab_detachControlMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deletedControlId",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "DocumentControlsTab_detachControlMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeleteControlDocumentMappingPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteControlDocumentMapping",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "DocumentControlsTab_detachControlMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeleteControlDocumentMappingPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteControlDocumentMapping",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "deleteEdge",
|
||||
"key": "",
|
||||
"kind": "ScalarHandle",
|
||||
"name": "deletedControlId",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "fce801689ab578a47c33a50c60fc4cd7",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "DocumentControlsTab_detachControlMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation DocumentControlsTab_detachControlMutation(\n $input: DeleteControlDocumentMappingInput!\n) {\n deleteControlDocumentMapping(input: $input) {\n deletedControlId\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "39c5b39c08ba37d06f5e0cfedc707a25";
|
||||
|
||||
export default node;
|
||||
@@ -205,7 +205,7 @@ export default function FrameworkDetailPage(props: Props) {
|
||||
key={control.id}
|
||||
id={control.referenceId}
|
||||
description={control.name ?? control.description}
|
||||
to={`/organizations/${organizationId}/frameworks/${framework.id}/${control.id}`}
|
||||
to={`/organizations/${organizationId}/frameworks/${framework.id}/controls/${control.id}`}
|
||||
active={selectedControl?.id === control.id}
|
||||
/>
|
||||
))}
|
||||
@@ -217,6 +217,7 @@ export default function FrameworkDetailPage(props: Props) {
|
||||
</div>
|
||||
<div className="text-base">{selectedControl.name}</div>
|
||||
<LinkedMeasuresCard
|
||||
variant="card"
|
||||
measures={
|
||||
selectedControl?.measures.edges.map((edge) => edge.node) ?? []
|
||||
}
|
||||
@@ -227,6 +228,7 @@ export default function FrameworkDetailPage(props: Props) {
|
||||
disabled={isAttachingMeasure || isDetachingMeasure}
|
||||
/>
|
||||
<LinkedDocumentsCard
|
||||
variant="card"
|
||||
documents={
|
||||
selectedControl?.documents.edges.map((edge) => edge.node) ?? []
|
||||
}
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
import { Outlet, useParams } from "react-router";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import {
|
||||
ActionDropdown,
|
||||
Breadcrumb,
|
||||
Button,
|
||||
Drawer,
|
||||
DropdownItem,
|
||||
IconCheckmark1,
|
||||
IconFrame2,
|
||||
IconPageTextLine,
|
||||
IconPencil,
|
||||
IconTrashCan,
|
||||
IconWarning,
|
||||
MeasureBadge,
|
||||
Option,
|
||||
PropertyRow,
|
||||
Select,
|
||||
TabLink,
|
||||
Tabs,
|
||||
useConfirm,
|
||||
} from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import {
|
||||
ConnectionHandler,
|
||||
usePreloadedQuery,
|
||||
type PreloadedQuery,
|
||||
} from "react-relay";
|
||||
import type { MeasureGraphNodeQuery } from "/hooks/graph/__generated__/MeasureGraphNodeQuery.graphql";
|
||||
import {
|
||||
MeasureConnectionKey,
|
||||
measureNodeQuery,
|
||||
useDeleteMeasureMutation,
|
||||
useUpdateMeasure,
|
||||
} from "/hooks/graph/MeasureGraph";
|
||||
import { PageHeader } from "@probo/ui";
|
||||
import { getMeasureStateLabel, measureStates, slugify } from "@probo/helpers";
|
||||
import MeasureFormDialog from "./dialog/MeasureFormDialog";
|
||||
import { sprintf } from "@probo/helpers";
|
||||
import { useNavigate } from "react-router";
|
||||
|
||||
type Props = {
|
||||
queryRef: PreloadedQuery<MeasureGraphNodeQuery>;
|
||||
};
|
||||
|
||||
export default function MeasureDetailPage(props: Props) {
|
||||
const { measureId } = useParams<{ measureId: string }>();
|
||||
const organizationId = useOrganizationId();
|
||||
const data = usePreloadedQuery(measureNodeQuery, props.queryRef);
|
||||
const measure = data.node;
|
||||
const { __ } = useTranslate();
|
||||
const [deleteMeasure] = useDeleteMeasureMutation();
|
||||
const navigate = useNavigate();
|
||||
const confirm = useConfirm();
|
||||
const [updateMeasure, isUpdating] = useUpdateMeasure();
|
||||
|
||||
if (!measureId) {
|
||||
throw new Error(
|
||||
"Cannot load measure detail page without measureId parameter"
|
||||
);
|
||||
}
|
||||
|
||||
const onDelete = () => {
|
||||
const connectionId = ConnectionHandler.getConnectionID(
|
||||
organizationId,
|
||||
MeasureConnectionKey
|
||||
);
|
||||
confirm(
|
||||
() =>
|
||||
new Promise<void>((resolve) => {
|
||||
deleteMeasure({
|
||||
variables: {
|
||||
input: { measureId },
|
||||
connections: [connectionId],
|
||||
},
|
||||
onSuccess() {
|
||||
navigate(`/organizations/${organizationId}/measures`);
|
||||
resolve();
|
||||
},
|
||||
});
|
||||
}),
|
||||
{
|
||||
message: sprintf(
|
||||
__(
|
||||
'This will permanently delete the measure "%s". This action cannot be undone.'
|
||||
),
|
||||
measure.name
|
||||
),
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const onStateChange = (state: string) => {
|
||||
updateMeasure({
|
||||
variables: {
|
||||
input: {
|
||||
id: measureId,
|
||||
state,
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* Header */}
|
||||
<Breadcrumb
|
||||
items={[
|
||||
{
|
||||
label: __("Measures"),
|
||||
to: `/organizations/${organizationId}/measures`,
|
||||
},
|
||||
...(measure.category
|
||||
? [
|
||||
{
|
||||
label: measure.category,
|
||||
to: `/organizations/${organizationId}/measures/category/${slugify(measure.category)}`,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
label: __("Measure detail"),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<PageHeader title={measure.name} description={measure.description}>
|
||||
<MeasureFormDialog measure={measure}>
|
||||
<Button variant="secondary" icon={IconPencil}>
|
||||
{__("Edit")}
|
||||
</Button>
|
||||
</MeasureFormDialog>
|
||||
<Select
|
||||
disabled={isUpdating}
|
||||
onValueChange={onStateChange}
|
||||
name="state"
|
||||
placeholder={__("Select state")}
|
||||
className="rounded-full"
|
||||
value={measure.state}
|
||||
>
|
||||
{measureStates.map((state) => (
|
||||
<Option key={state} value={state}>
|
||||
{getMeasureStateLabel(__, state)}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
<ActionDropdown variant="secondary">
|
||||
<DropdownItem variant="danger" icon={IconTrashCan} onClick={onDelete}>
|
||||
{__("Delete")}
|
||||
</DropdownItem>
|
||||
</ActionDropdown>
|
||||
</PageHeader>
|
||||
|
||||
<Tabs>
|
||||
<TabLink
|
||||
to={`/organizations/${organizationId}/measures/${measureId}/evidences`}
|
||||
>
|
||||
<IconPageTextLine size={20} />
|
||||
{__("Evidences")}
|
||||
</TabLink>
|
||||
<TabLink
|
||||
to={`/organizations/${organizationId}/measures/${measureId}/tasks`}
|
||||
>
|
||||
<IconCheckmark1 size={20} />
|
||||
{__("Tasks")}
|
||||
</TabLink>
|
||||
<TabLink
|
||||
to={`/organizations/${organizationId}/measures/${measureId}/controls`}
|
||||
>
|
||||
<IconFrame2 size={20} />
|
||||
{__("Controls")}
|
||||
</TabLink>
|
||||
<TabLink
|
||||
to={`/organizations/${organizationId}/measures/${measureId}/risks`}
|
||||
>
|
||||
<IconWarning size={20} />
|
||||
{__("Risks")}
|
||||
</TabLink>
|
||||
</Tabs>
|
||||
|
||||
<Outlet context={{ measure }} />
|
||||
|
||||
<Drawer>
|
||||
<PropertyRow label={__("State")}>
|
||||
<MeasureBadge state={measure.state!} />
|
||||
</PropertyRow>
|
||||
</Drawer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -44,6 +44,8 @@ import type { MeasuresPageImportMutation } from "./__generated__/MeasuresPageImp
|
||||
import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import { Link, useParams } from "react-router";
|
||||
import MeasureFormDialog from "./dialog/MeasureFormDialog";
|
||||
import { usePageTitle } from "@probo/hooks";
|
||||
|
||||
type Props = {
|
||||
queryRef: PreloadedQuery<MeasureGraphListQuery>;
|
||||
@@ -59,6 +61,7 @@ const measuresFragment = graphql`
|
||||
name
|
||||
category
|
||||
state
|
||||
...MeasureFormDialogMeasureFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,6 +109,7 @@ export default function MeasuresPage(props: Props) {
|
||||
}
|
||||
);
|
||||
const importFileRef = useRef<HTMLInputElement>(null);
|
||||
usePageTitle(__("Measures"));
|
||||
|
||||
const handleImport: ChangeEventHandler<HTMLInputElement> = (event) => {
|
||||
const file = event.target.files?.[0];
|
||||
@@ -145,9 +149,11 @@ export default function MeasuresPage(props: Props) {
|
||||
>
|
||||
{__("Import")}
|
||||
</FileButton>
|
||||
<Button variant="primary" icon={IconPlusLarge}>
|
||||
{__("New measure")}
|
||||
</Button>
|
||||
<MeasureFormDialog connection={connectionId}>
|
||||
<Button variant="primary" icon={IconPlusLarge}>
|
||||
{__("New measure")}
|
||||
</Button>
|
||||
</MeasureFormDialog>
|
||||
</PageHeader>
|
||||
<MeasureImplementation measures={measures} className="my-10" />
|
||||
{objectKeys(measuresPerCategory)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<d474691920e943cf5df04fa93c746b28>>
|
||||
* @generated SignedSource<<d2ea4d096aa13e35f9740af51ecd969f>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -20,6 +20,7 @@ export type MeasuresPageFragment$data = {
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly state: MeasureState;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"MeasureFormDialogMeasureFragment">;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
@@ -99,6 +100,11 @@ const node: ReaderFragment = {
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "MeasureFormDialogMeasureFragment"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -164,6 +170,6 @@ const node: ReaderFragment = {
|
||||
"abstractKey": null
|
||||
};
|
||||
|
||||
(node as any).hash = "6a45bee844bf79dc4540e20edf10ad78";
|
||||
(node as any).hash = "b9f66d2e9305aa568c33f708d4ce8fac";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
Input,
|
||||
Label,
|
||||
Option,
|
||||
PropertyRow,
|
||||
Textarea,
|
||||
useDialogRef,
|
||||
} from "@probo/ui";
|
||||
import type { ReactNode } from "react";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { Breadcrumb } from "@probo/ui";
|
||||
import { graphql } from "relay-runtime";
|
||||
import type { MeasureFormDialogMeasureFragment$key } from "./__generated__/MeasureFormDialogMeasureFragment.graphql";
|
||||
import { useFragment } from "react-relay";
|
||||
import { z } from "zod";
|
||||
import { useFormWithSchema } from "/hooks/useFormWithSchema";
|
||||
import { getMeasureStateLabel, measureStates } from "@probo/helpers";
|
||||
import { ControlledSelect } from "/components/form/ControlledField";
|
||||
import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import { useUpdateMeasure } from "/hooks/graph/MeasureGraph";
|
||||
|
||||
type Props = {
|
||||
children: ReactNode;
|
||||
measure?: MeasureFormDialogMeasureFragment$key;
|
||||
connection?: string;
|
||||
};
|
||||
|
||||
const measureFragment = graphql`
|
||||
fragment MeasureFormDialogMeasureFragment on Measure {
|
||||
id
|
||||
description
|
||||
name
|
||||
category
|
||||
state
|
||||
}
|
||||
`;
|
||||
|
||||
const measureCreateMutation = graphql`
|
||||
mutation MeasureFormDialogCreateMutation(
|
||||
$input: CreateMeasureInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
createMeasure(input: $input) {
|
||||
measureEdge @prependEdge(connections: $connections) {
|
||||
node {
|
||||
...MeasureFormDialogMeasureFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const measureSchema = z.object({
|
||||
name: z.string(),
|
||||
description: z.string(),
|
||||
category: z.string(),
|
||||
state: z.enum(measureStates),
|
||||
});
|
||||
|
||||
export default function MeasureFormDialog(props: Props) {
|
||||
const { __ } = useTranslate();
|
||||
const measure = useFragment(measureFragment, props.measure);
|
||||
const dialogRef = useDialogRef();
|
||||
const organizationId = useOrganizationId();
|
||||
const [mutate] = props.measure
|
||||
? useUpdateMeasure()
|
||||
: useMutationWithToasts(measureCreateMutation, {
|
||||
successMessage: __("Measure created successfully."),
|
||||
errorMessage: __("Failed to create measure. Please try again."),
|
||||
});
|
||||
|
||||
const { control, handleSubmit, register, formState } = useFormWithSchema(
|
||||
measureSchema,
|
||||
{
|
||||
defaultValues: {
|
||||
name: measure?.name ?? "",
|
||||
description: measure?.description ?? "",
|
||||
category: measure?.category ?? "",
|
||||
state: "NOT_STARTED",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const onSubmit = handleSubmit(async (data) => {
|
||||
if (measure) {
|
||||
await mutate({
|
||||
variables: {
|
||||
input: {
|
||||
id: measure.id,
|
||||
name: data.name,
|
||||
description: data.description,
|
||||
category: data.category,
|
||||
state: data.state,
|
||||
},
|
||||
},
|
||||
});
|
||||
} else {
|
||||
await mutate({
|
||||
variables: {
|
||||
input: {
|
||||
organizationId,
|
||||
name: data.name,
|
||||
description: data.description,
|
||||
category: data.category,
|
||||
},
|
||||
connections: [props.connection!],
|
||||
},
|
||||
});
|
||||
}
|
||||
dialogRef.current?.close();
|
||||
});
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
ref={dialogRef}
|
||||
trigger={props.children}
|
||||
title={
|
||||
<Breadcrumb
|
||||
items={[
|
||||
__("Measures"),
|
||||
measure ? __("Edit Measure") : __("New Measure"),
|
||||
]}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<form onSubmit={onSubmit}>
|
||||
<DialogContent className="grid grid-cols-[1fr_420px]">
|
||||
<div className="py-8 px-10 space-y-4">
|
||||
<Input
|
||||
id="title"
|
||||
required
|
||||
variant="title"
|
||||
placeholder={__("Document title")}
|
||||
{...register("name")}
|
||||
/>
|
||||
<Textarea
|
||||
id="content"
|
||||
variant="ghost"
|
||||
autogrow
|
||||
placeholder={__("Add description")}
|
||||
{...register("description")}
|
||||
/>
|
||||
</div>
|
||||
{/* Properties form */}
|
||||
<div className="py-5 px-6 bg-subtle">
|
||||
<Label>{__("Properties")}</Label>
|
||||
<PropertyRow
|
||||
label={__("Category")}
|
||||
error={formState.errors.category?.message}
|
||||
>
|
||||
<Input
|
||||
{...register("category")}
|
||||
required
|
||||
placeholder={__("Select category")}
|
||||
/>
|
||||
</PropertyRow>
|
||||
{measure && (
|
||||
<PropertyRow
|
||||
label={__("State")}
|
||||
error={formState.errors.state?.message}
|
||||
>
|
||||
<ControlledSelect
|
||||
control={control}
|
||||
name="state"
|
||||
placeholder={__("Select state")}
|
||||
>
|
||||
{measureStates.map((state) => (
|
||||
<Option key={state} value={state}>
|
||||
{getMeasureStateLabel(__, state)}
|
||||
</Option>
|
||||
))}
|
||||
</ControlledSelect>
|
||||
</PropertyRow>
|
||||
)}
|
||||
</div>
|
||||
</DialogContent>
|
||||
<DialogFooter>
|
||||
<Button type="submit">
|
||||
{measure ? __("Update measure") : __("Create measure")}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* @generated SignedSource<<09acdf5a03dd4ad1fab64c2c08564a2a>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type CreateMeasureInput = {
|
||||
category: string;
|
||||
description: string;
|
||||
name: string;
|
||||
organizationId: string;
|
||||
};
|
||||
export type MeasureFormDialogCreateMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: CreateMeasureInput;
|
||||
};
|
||||
export type MeasureFormDialogCreateMutation$data = {
|
||||
readonly createMeasure: {
|
||||
readonly measureEdge: {
|
||||
readonly node: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"MeasureFormDialogMeasureFragment">;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export type MeasureFormDialogCreateMutation = {
|
||||
response: MeasureFormDialogCreateMutation$data;
|
||||
variables: MeasureFormDialogCreateMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "MeasureFormDialogCreateMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "CreateMeasurePayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "createMeasure",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "MeasureEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "measureEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Measure",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "MeasureFormDialogMeasureFragment"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "MeasureFormDialogCreateMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "CreateMeasurePayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "createMeasure",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "MeasureEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "measureEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Measure",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "category",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "prependEdge",
|
||||
"key": "",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "measureEdge",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "6ee48b7249e180aafe2f40c120ec1195",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "MeasureFormDialogCreateMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation MeasureFormDialogCreateMutation(\n $input: CreateMeasureInput!\n) {\n createMeasure(input: $input) {\n measureEdge {\n node {\n ...MeasureFormDialogMeasureFragment\n id\n }\n }\n }\n}\n\nfragment MeasureFormDialogMeasureFragment on Measure {\n id\n description\n name\n category\n state\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "242f974b9926705919bf030281363dfc";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @generated SignedSource<<ad3cb8a5e721cd1d83d80540320b8313>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
export type MeasureState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED";
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type MeasureFormDialogMeasureFragment$data = {
|
||||
readonly category: string;
|
||||
readonly description: string;
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly state: MeasureState;
|
||||
readonly " $fragmentType": "MeasureFormDialogMeasureFragment";
|
||||
};
|
||||
export type MeasureFormDialogMeasureFragment$key = {
|
||||
readonly " $data"?: MeasureFormDialogMeasureFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"MeasureFormDialogMeasureFragment">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "MeasureFormDialogMeasureFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "category",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "state",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Measure",
|
||||
"abstractKey": null
|
||||
};
|
||||
|
||||
(node as any).hash = "4266d43b90952814d68b5425f65c10be";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,52 @@
|
||||
import { graphql, useFragment, useMutation } from "react-relay";
|
||||
import { useOutletContext } from "react-router";
|
||||
import { LinkedControlsCard } from "/components/controls/LinkedControlsCard";
|
||||
import type { MeasureControlsTabFragment$key } from "./__generated__/MeasureControlsTabFragment.graphql";
|
||||
|
||||
const ControlsFragment = graphql`
|
||||
fragment MeasureControlsTabFragment on Measure {
|
||||
id
|
||||
controls(first: 100)
|
||||
@connection(key: "MeasureControlsTabFragment_controls") {
|
||||
__id
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
...LinkedControlsCardFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const detachControlMutation = graphql`
|
||||
mutation MeasureControlsTabDetachMutation(
|
||||
$input: DeleteControlMeasureMappingInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
deleteControlMeasureMapping(input: $input) {
|
||||
deletedControlId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default function MeasureControlsTab() {
|
||||
const { measure } = useOutletContext<{
|
||||
measure: MeasureControlsTabFragment$key & { id: string };
|
||||
}>();
|
||||
const data = useFragment(ControlsFragment, measure);
|
||||
const connectionId = data.controls.__id;
|
||||
const controls = data.controls?.edges?.map((edge) => edge.node) ?? [];
|
||||
|
||||
const [detachControl, isDetaching] = useMutation(detachControlMutation);
|
||||
|
||||
return (
|
||||
<LinkedControlsCard
|
||||
disabled={isDetaching}
|
||||
controls={controls}
|
||||
onDetach={detachControl}
|
||||
params={{ measureId: data.id }}
|
||||
connectionId={connectionId}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
import { useOutletContext } from "react-router";
|
||||
import type { MeasureEvidencesTabFragment$key } from "./__generated__/MeasureEvidencesTabFragment.graphql";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { usePageTitle } from "@probo/hooks";
|
||||
import {
|
||||
Button,
|
||||
Dropzone,
|
||||
IconArrowInbox,
|
||||
IconTrashCan,
|
||||
Tbody,
|
||||
Td,
|
||||
Th,
|
||||
Thead,
|
||||
Tr,
|
||||
useConfirm,
|
||||
} from "@probo/ui";
|
||||
import { graphql } from "relay-runtime";
|
||||
import { useFragment, useMutation, useRefetchableFragment } from "react-relay";
|
||||
import { SortableTable } from "/components/SortableTable";
|
||||
import type { MeasureEvidencesTabFragment_evidence$key } from "./__generated__/MeasureEvidencesTabFragment_evidence.graphql";
|
||||
import { fileSize, fileType } from "@probo/helpers";
|
||||
import { promisifyMutation, sprintf } from "@probo/helpers";
|
||||
|
||||
const evidencesFragment = graphql`
|
||||
fragment MeasureEvidencesTabFragment on Measure
|
||||
@refetchable(queryName: "MeasureEvidencesTabQuery")
|
||||
@argumentDefinitions(
|
||||
first: { type: "Int", defaultValue: 50 }
|
||||
order: { type: "EvidenceOrder", defaultValue: null }
|
||||
after: { type: "CursorKey", defaultValue: null }
|
||||
before: { type: "CursorKey", defaultValue: null }
|
||||
last: { type: "Int", defaultValue: null }
|
||||
) {
|
||||
id
|
||||
evidences(
|
||||
first: $first
|
||||
after: $after
|
||||
last: $last
|
||||
before: $before
|
||||
orderBy: $order
|
||||
) @connection(key: "MeasureEvidencesTabFragment_evidences") {
|
||||
__id
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
...MeasureEvidencesTabFragment_evidence
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const evidenceFragment = graphql`
|
||||
fragment MeasureEvidencesTabFragment_evidence on Evidence {
|
||||
id
|
||||
filename
|
||||
size
|
||||
type
|
||||
createdAt
|
||||
fileUrl
|
||||
mimeType
|
||||
}
|
||||
`;
|
||||
|
||||
const uploadEvidenceMutation = graphql`
|
||||
mutation MeasureEvidencesTabUploadMutation(
|
||||
$input: UploadMeasureEvidenceInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
uploadMeasureEvidence(input: $input) {
|
||||
evidenceEdge @appendEdge(connections: $connections) {
|
||||
node {
|
||||
id
|
||||
...MeasureEvidencesTabFragment_evidence
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const deleteEvidenceMutation = graphql`
|
||||
mutation MeasureEvidencesTabDeleteMutation(
|
||||
$input: DeleteEvidenceInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
deleteEvidence(input: $input) {
|
||||
deletedEvidenceId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default function MeasureEvidencesTab() {
|
||||
const { measure } = useOutletContext<{
|
||||
measure: MeasureEvidencesTabFragment$key & { id: string; name: string };
|
||||
}>();
|
||||
const [data, refetch] = useRefetchableFragment(evidencesFragment, measure);
|
||||
const connectionId = data.evidences.__id;
|
||||
const evidences = data.evidences?.edges?.map((edge) => edge.node) ?? [];
|
||||
|
||||
const { __ } = useTranslate();
|
||||
const [mutate, isUpdating] = useMutation(uploadEvidenceMutation);
|
||||
|
||||
usePageTitle(measure.name + " - " + __("Evidences"));
|
||||
|
||||
const handleDrop = (files: File[]) => {
|
||||
for (const file of files) {
|
||||
mutate({
|
||||
variables: {
|
||||
connections: [connectionId],
|
||||
input: {
|
||||
measureId: measure.id,
|
||||
file: null,
|
||||
},
|
||||
},
|
||||
uploadables: {
|
||||
"input.file": file,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<Dropzone
|
||||
description={__("Only PDF files up to 10MB are allowed")}
|
||||
isUploading={isUpdating}
|
||||
onDrop={handleDrop}
|
||||
accept={{
|
||||
"application/pdf": [".pdf"],
|
||||
}}
|
||||
maxSize={10}
|
||||
/>
|
||||
<SortableTable refetch={refetch}>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>{__("Evidence name")}</Th>
|
||||
<Th>{__("Type")}</Th>
|
||||
<Th>{__("File size")}</Th>
|
||||
<Th>{__("Created at")}</Th>
|
||||
<Th width={50}></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{evidences.map((evidence) => (
|
||||
<EvidenceRow
|
||||
key={evidence.id}
|
||||
evidenceKey={evidence}
|
||||
connectionId={connectionId}
|
||||
/>
|
||||
))}
|
||||
</Tbody>
|
||||
</SortableTable>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function EvidenceRow(props: {
|
||||
evidenceKey: MeasureEvidencesTabFragment_evidence$key;
|
||||
connectionId: string;
|
||||
}) {
|
||||
const evidence = useFragment(evidenceFragment, props.evidenceKey);
|
||||
const { __, dateFormat } = useTranslate();
|
||||
|
||||
const [mutate, isDeleting] = useMutation(deleteEvidenceMutation);
|
||||
const confirm = useConfirm();
|
||||
|
||||
const handleDelete = () => {
|
||||
confirm(
|
||||
() => {
|
||||
return promisifyMutation(mutate)({
|
||||
variables: {
|
||||
connections: [props.connectionId],
|
||||
input: {
|
||||
evidenceId: evidence.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
{
|
||||
message: sprintf(
|
||||
__(
|
||||
'This will permanently delete the evidence "%s". This action cannot be undone.'
|
||||
),
|
||||
evidence.filename
|
||||
),
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Tr>
|
||||
<Td>{evidence.filename}</Td>
|
||||
<Td>{fileType(__, evidence)}</Td>
|
||||
<Td>{fileSize(__, evidence.size)}</Td>
|
||||
<Td>{dateFormat(evidence.createdAt)}</Td>
|
||||
<Td>
|
||||
<div className="flex gap-2">
|
||||
<Button asChild variant="secondary">
|
||||
<a href={evidence.fileUrl ?? ""} target="_blank">
|
||||
<IconArrowInbox size={16} />
|
||||
{__("Download")}
|
||||
</a>
|
||||
</Button>
|
||||
<Button
|
||||
variant="danger"
|
||||
icon={IconTrashCan}
|
||||
onClick={handleDelete}
|
||||
disabled={isDeleting}
|
||||
/>
|
||||
</div>
|
||||
</Td>
|
||||
</Tr>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import { graphql, useFragment, useMutation } from "react-relay";
|
||||
import type { MeasureRisksTabFragment$key } from "./__generated__/MeasureRisksTabFragment.graphql";
|
||||
import { useOutletContext } from "react-router";
|
||||
import { LinkedRisksCard } from "/components/risks/LinkedRisksCard";
|
||||
|
||||
const risksFragment = graphql`
|
||||
fragment MeasureRisksTabFragment on Measure {
|
||||
id
|
||||
risks(first: 100) @connection(key: "Measure__risks") {
|
||||
__id
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
...LinkedRisksCardFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const attachRiskMutation = graphql`
|
||||
mutation MeasureRisksTabCreateMutation(
|
||||
$input: CreateRiskMeasureMappingInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
createRiskMeasureMapping(input: $input) {
|
||||
riskEdge @prependEdge(connections: $connections) {
|
||||
node {
|
||||
id
|
||||
...LinkedRisksCardFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const detachRiskMutation = graphql`
|
||||
mutation MeasureRisksTabDetachMutation(
|
||||
$input: DeleteRiskMeasureMappingInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
deleteRiskMeasureMapping(input: $input) {
|
||||
deletedRiskId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default function MeasureRisksTab() {
|
||||
const { measure } = useOutletContext<{
|
||||
measure: MeasureRisksTabFragment$key & { id: string };
|
||||
}>();
|
||||
const data = useFragment(risksFragment, measure);
|
||||
const connectionId = data.risks.__id;
|
||||
const risks = data.risks?.edges?.map((edge) => edge.node) ?? [];
|
||||
|
||||
const [detachRisk, isDetaching] = useMutation(detachRiskMutation);
|
||||
const [attachRisk, isAttaching] = useMutation(attachRiskMutation);
|
||||
const isLoading = isDetaching || isAttaching;
|
||||
|
||||
return (
|
||||
<LinkedRisksCard
|
||||
disabled={isLoading}
|
||||
risks={risks}
|
||||
onAttach={attachRisk}
|
||||
onDetach={detachRisk}
|
||||
params={{ measureId: data.id }}
|
||||
connectionId={connectionId}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* @generated SignedSource<<63367052d20bc149e2d4f86adbf3c735>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type DeleteControlMeasureMappingInput = {
|
||||
controlId: string;
|
||||
measureId: string;
|
||||
};
|
||||
export type MeasureControlsTabDetachMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: DeleteControlMeasureMappingInput;
|
||||
};
|
||||
export type MeasureControlsTabDetachMutation$data = {
|
||||
readonly deleteControlMeasureMapping: {
|
||||
readonly deletedControlId: string;
|
||||
};
|
||||
};
|
||||
export type MeasureControlsTabDetachMutation = {
|
||||
response: MeasureControlsTabDetachMutation$data;
|
||||
variables: MeasureControlsTabDetachMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deletedControlId",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "MeasureControlsTabDetachMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeleteControlMeasureMappingPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteControlMeasureMapping",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "MeasureControlsTabDetachMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeleteControlMeasureMappingPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteControlMeasureMapping",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "deleteEdge",
|
||||
"key": "",
|
||||
"kind": "ScalarHandle",
|
||||
"name": "deletedControlId",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "158225e40cb2e95be134e59a4647ff69",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "MeasureControlsTabDetachMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation MeasureControlsTabDetachMutation(\n $input: DeleteControlMeasureMappingInput!\n) {\n deleteControlMeasureMapping(input: $input) {\n deletedControlId\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "d800ddbcf4b4c24ae945447d710be209";
|
||||
|
||||
export default node;
|
||||
155
apps/console2/src/pages/organizations/measures/tabs/__generated__/MeasureControlsTabFragment.graphql.ts
generated
Normal file
155
apps/console2/src/pages/organizations/measures/tabs/__generated__/MeasureControlsTabFragment.graphql.ts
generated
Normal file
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* @generated SignedSource<<ca62a85532feb9efd0d7489b36a5b017>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type MeasureControlsTabFragment$data = {
|
||||
readonly controls: {
|
||||
readonly __id: string;
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedControlsCardFragment">;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly id: string;
|
||||
readonly " $fragmentType": "MeasureControlsTabFragment";
|
||||
};
|
||||
export type MeasureControlsTabFragment$key = {
|
||||
readonly " $data"?: MeasureControlsTabFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"MeasureControlsTabFragment">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": null,
|
||||
"cursor": null,
|
||||
"direction": "forward",
|
||||
"path": [
|
||||
"controls"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "MeasureControlsTabFragment",
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"alias": "controls",
|
||||
"args": null,
|
||||
"concreteType": "ControlConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__MeasureControlsTabFragment_controls_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ControlEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Control",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "LinkedControlsCardFragment"
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"kind": "ClientExtension",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__id",
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Measure",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "ce7a8ffb4c5837e7b5f71a781f332064";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* @generated SignedSource<<1123080dba735de72e2440f5dec008b5>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type DeleteEvidenceInput = {
|
||||
evidenceId: string;
|
||||
};
|
||||
export type MeasureEvidencesTabDeleteMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: DeleteEvidenceInput;
|
||||
};
|
||||
export type MeasureEvidencesTabDeleteMutation$data = {
|
||||
readonly deleteEvidence: {
|
||||
readonly deletedEvidenceId: string;
|
||||
};
|
||||
};
|
||||
export type MeasureEvidencesTabDeleteMutation = {
|
||||
response: MeasureEvidencesTabDeleteMutation$data;
|
||||
variables: MeasureEvidencesTabDeleteMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deletedEvidenceId",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "MeasureEvidencesTabDeleteMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeleteEvidencePayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteEvidence",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "MeasureEvidencesTabDeleteMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeleteEvidencePayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteEvidence",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "deleteEdge",
|
||||
"key": "",
|
||||
"kind": "ScalarHandle",
|
||||
"name": "deletedEvidenceId",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "7c9ea7e14d3a342d9108026da877a854",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "MeasureEvidencesTabDeleteMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation MeasureEvidencesTabDeleteMutation(\n $input: DeleteEvidenceInput!\n) {\n deleteEvidence(input: $input) {\n deletedEvidenceId\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "5b78978395d1b8a165a078f60f6aa001";
|
||||
|
||||
export default node;
|
||||
225
apps/console2/src/pages/organizations/measures/tabs/__generated__/MeasureEvidencesTabFragment.graphql.ts
generated
Normal file
225
apps/console2/src/pages/organizations/measures/tabs/__generated__/MeasureEvidencesTabFragment.graphql.ts
generated
Normal file
@@ -0,0 +1,225 @@
|
||||
/**
|
||||
* @generated SignedSource<<70954edefec64fedbc4f8c1ec1c1efab>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type MeasureEvidencesTabFragment$data = {
|
||||
readonly evidences: {
|
||||
readonly __id: string;
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"MeasureEvidencesTabFragment_evidence">;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly id: string;
|
||||
readonly " $fragmentType": "MeasureEvidencesTabFragment";
|
||||
};
|
||||
export type MeasureEvidencesTabFragment$key = {
|
||||
readonly " $data"?: MeasureEvidencesTabFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"MeasureEvidencesTabFragment">;
|
||||
};
|
||||
|
||||
import MeasureEvidencesTabQuery_graphql from './MeasureEvidencesTabQuery.graphql';
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = [
|
||||
"evidences"
|
||||
],
|
||||
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": 50,
|
||||
"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": MeasureEvidencesTabQuery_graphql,
|
||||
"identifierInfo": {
|
||||
"identifierField": "id",
|
||||
"identifierQueryVariableName": "id"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "MeasureEvidencesTabFragment",
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": "evidences",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "orderBy",
|
||||
"variableName": "order"
|
||||
}
|
||||
],
|
||||
"concreteType": "EvidenceConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__MeasureEvidencesTabFragment_evidences_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "EvidenceEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Evidence",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "MeasureEvidencesTabFragment_evidence"
|
||||
},
|
||||
{
|
||||
"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
|
||||
},
|
||||
{
|
||||
"kind": "ClientExtension",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__id",
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Measure",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "619655a768981a51a00a71887dbcb227";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* @generated SignedSource<<aa88116272684a0ebbca38e57c798eee>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
export type EvidenceType = "FILE" | "LINK";
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type MeasureEvidencesTabFragment_evidence$data = {
|
||||
readonly createdAt: any;
|
||||
readonly fileUrl: string | null | undefined;
|
||||
readonly filename: string;
|
||||
readonly id: string;
|
||||
readonly mimeType: string;
|
||||
readonly size: number;
|
||||
readonly type: EvidenceType;
|
||||
readonly " $fragmentType": "MeasureEvidencesTabFragment_evidence";
|
||||
};
|
||||
export type MeasureEvidencesTabFragment_evidence$key = {
|
||||
readonly " $data"?: MeasureEvidencesTabFragment_evidence$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"MeasureEvidencesTabFragment_evidence">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "MeasureEvidencesTabFragment_evidence",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "filename",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "size",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "type",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fileUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "mimeType",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Evidence",
|
||||
"abstractKey": null
|
||||
};
|
||||
|
||||
(node as any).hash = "4fa5951157f130a8ed644151ef5facd6";
|
||||
|
||||
export default node;
|
||||
358
apps/console2/src/pages/organizations/measures/tabs/__generated__/MeasureEvidencesTabQuery.graphql.ts
generated
Normal file
358
apps/console2/src/pages/organizations/measures/tabs/__generated__/MeasureEvidencesTabQuery.graphql.ts
generated
Normal file
@@ -0,0 +1,358 @@
|
||||
/**
|
||||
* @generated SignedSource<<65fd5218c9365e00e3127dfca328ad10>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type EvidenceOrderField = "CREATED_AT";
|
||||
export type OrderDirection = "ASC" | "DESC";
|
||||
export type EvidenceOrder = {
|
||||
direction: OrderDirection;
|
||||
field: EvidenceOrderField;
|
||||
};
|
||||
export type MeasureEvidencesTabQuery$variables = {
|
||||
after?: any | null | undefined;
|
||||
before?: any | null | undefined;
|
||||
first?: number | null | undefined;
|
||||
id: string;
|
||||
last?: number | null | undefined;
|
||||
order?: EvidenceOrder | null | undefined;
|
||||
};
|
||||
export type MeasureEvidencesTabQuery$data = {
|
||||
readonly node: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"MeasureEvidencesTabFragment">;
|
||||
};
|
||||
};
|
||||
export type MeasureEvidencesTabQuery = {
|
||||
response: MeasureEvidencesTabQuery$data;
|
||||
variables: MeasureEvidencesTabQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "after"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "before"
|
||||
},
|
||||
v2 = {
|
||||
"defaultValue": 50,
|
||||
"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": "MeasureEvidencesTabQuery",
|
||||
"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": "MeasureEvidencesTabFragment"
|
||||
}
|
||||
],
|
||||
"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": "MeasureEvidencesTabQuery",
|
||||
"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": "EvidenceConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "evidences",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "EvidenceEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Evidence",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v12/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "filename",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "size",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "type",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fileUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "mimeType",
|
||||
"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
|
||||
},
|
||||
{
|
||||
"kind": "ClientExtension",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__id",
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v13/*: any*/),
|
||||
"filters": [
|
||||
"orderBy"
|
||||
],
|
||||
"handle": "connection",
|
||||
"key": "MeasureEvidencesTabFragment_evidences",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "evidences"
|
||||
}
|
||||
],
|
||||
"type": "Measure",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "28755a6b97ad50d18c25dea1b383d062",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "MeasureEvidencesTabQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query MeasureEvidencesTabQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 50\n $last: Int = null\n $order: EvidenceOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...MeasureEvidencesTabFragment_16fISc\n id\n }\n}\n\nfragment MeasureEvidencesTabFragment_16fISc on Measure {\n id\n evidences(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n edges {\n node {\n id\n ...MeasureEvidencesTabFragment_evidence\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment MeasureEvidencesTabFragment_evidence on Evidence {\n id\n filename\n size\n type\n createdAt\n fileUrl\n mimeType\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "619655a768981a51a00a71887dbcb227";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,230 @@
|
||||
/**
|
||||
* @generated SignedSource<<dd129ccf57ef541ce24672d4b55d708f>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type UploadMeasureEvidenceInput = {
|
||||
file: any;
|
||||
measureId: string;
|
||||
};
|
||||
export type MeasureEvidencesTabUploadMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: UploadMeasureEvidenceInput;
|
||||
};
|
||||
export type MeasureEvidencesTabUploadMutation$data = {
|
||||
readonly uploadMeasureEvidence: {
|
||||
readonly evidenceEdge: {
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"MeasureEvidencesTabFragment_evidence">;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export type MeasureEvidencesTabUploadMutation = {
|
||||
response: MeasureEvidencesTabUploadMutation$data;
|
||||
variables: MeasureEvidencesTabUploadMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "MeasureEvidencesTabUploadMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "UploadMeasureEvidencePayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "uploadMeasureEvidence",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "EvidenceEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "evidenceEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Evidence",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "MeasureEvidencesTabFragment_evidence"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "MeasureEvidencesTabUploadMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "UploadMeasureEvidencePayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "uploadMeasureEvidence",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "EvidenceEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "evidenceEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Evidence",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "filename",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "size",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "type",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fileUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "mimeType",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "appendEdge",
|
||||
"key": "",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "evidenceEdge",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "facbff238f3ee10c220a5c80883836da",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "MeasureEvidencesTabUploadMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation MeasureEvidencesTabUploadMutation(\n $input: UploadMeasureEvidenceInput!\n) {\n uploadMeasureEvidence(input: $input) {\n evidenceEdge {\n node {\n id\n ...MeasureEvidencesTabFragment_evidence\n }\n }\n }\n}\n\nfragment MeasureEvidencesTabFragment_evidence on Evidence {\n id\n filename\n size\n type\n createdAt\n fileUrl\n mimeType\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "37283c7d6f25ed8c768ba9e0f93ebafb";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* @generated SignedSource<<9af67842ec7b635682d0c10d86385b88>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type CreateRiskMeasureMappingInput = {
|
||||
measureId: string;
|
||||
riskId: string;
|
||||
};
|
||||
export type MeasureRisksTabCreateMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: CreateRiskMeasureMappingInput;
|
||||
};
|
||||
export type MeasureRisksTabCreateMutation$data = {
|
||||
readonly createRiskMeasureMapping: {
|
||||
readonly riskEdge: {
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedRisksCardFragment">;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export type MeasureRisksTabCreateMutation = {
|
||||
response: MeasureRisksTabCreateMutation$data;
|
||||
variables: MeasureRisksTabCreateMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "MeasureRisksTabCreateMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "CreateRiskMeasureMappingPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "createRiskMeasureMapping",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "RiskEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "riskEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Risk",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "LinkedRisksCardFragment"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "MeasureRisksTabCreateMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "CreateRiskMeasureMappingPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "createRiskMeasureMapping",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "RiskEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "riskEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Risk",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "inherentRiskScore",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "residualRiskScore",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "prependEdge",
|
||||
"key": "",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "riskEdge",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "53097378652dfdfc8505535921234ade",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "MeasureRisksTabCreateMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation MeasureRisksTabCreateMutation(\n $input: CreateRiskMeasureMappingInput!\n) {\n createRiskMeasureMapping(input: $input) {\n riskEdge {\n node {\n id\n ...LinkedRisksCardFragment\n }\n }\n }\n}\n\nfragment LinkedRisksCardFragment on Risk {\n id\n name\n inherentRiskScore\n residualRiskScore\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "c167b300964866d886760968abaa014f";
|
||||
|
||||
export default node;
|
||||
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* @generated SignedSource<<f9c0e3868814f7247aee411c93d7a5eb>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type DeleteRiskMeasureMappingInput = {
|
||||
measureId: string;
|
||||
riskId: string;
|
||||
};
|
||||
export type MeasureRisksTabDetachMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: DeleteRiskMeasureMappingInput;
|
||||
};
|
||||
export type MeasureRisksTabDetachMutation$data = {
|
||||
readonly deleteRiskMeasureMapping: {
|
||||
readonly deletedRiskId: string;
|
||||
};
|
||||
};
|
||||
export type MeasureRisksTabDetachMutation = {
|
||||
response: MeasureRisksTabDetachMutation$data;
|
||||
variables: MeasureRisksTabDetachMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deletedRiskId",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "MeasureRisksTabDetachMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeleteRiskMeasureMappingPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteRiskMeasureMapping",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "MeasureRisksTabDetachMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeleteRiskMeasureMappingPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteRiskMeasureMapping",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "deleteEdge",
|
||||
"key": "",
|
||||
"kind": "ScalarHandle",
|
||||
"name": "deletedRiskId",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "ac75591b5e166b2ee994bd99a0afc29a",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "MeasureRisksTabDetachMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation MeasureRisksTabDetachMutation(\n $input: DeleteRiskMeasureMappingInput!\n) {\n deleteRiskMeasureMapping(input: $input) {\n deletedRiskId\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "5b42a2d7e8a78ff4c674ce6612df537c";
|
||||
|
||||
export default node;
|
||||
155
apps/console2/src/pages/organizations/measures/tabs/__generated__/MeasureRisksTabFragment.graphql.ts
generated
Normal file
155
apps/console2/src/pages/organizations/measures/tabs/__generated__/MeasureRisksTabFragment.graphql.ts
generated
Normal file
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* @generated SignedSource<<caa6c09d5f08c92e9e1083e0e6691713>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type MeasureRisksTabFragment$data = {
|
||||
readonly id: string;
|
||||
readonly risks: {
|
||||
readonly __id: string;
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedRisksCardFragment">;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly " $fragmentType": "MeasureRisksTabFragment";
|
||||
};
|
||||
export type MeasureRisksTabFragment$key = {
|
||||
readonly " $data"?: MeasureRisksTabFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"MeasureRisksTabFragment">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": null,
|
||||
"cursor": null,
|
||||
"direction": "forward",
|
||||
"path": [
|
||||
"risks"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "MeasureRisksTabFragment",
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"alias": "risks",
|
||||
"args": null,
|
||||
"concreteType": "RiskConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__Measure__risks_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "RiskEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Risk",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "LinkedRisksCardFragment"
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"kind": "ClientExtension",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__id",
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Measure",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "1d73bd64b1a01fed76eac68d83d4d4c1";
|
||||
|
||||
export default node;
|
||||
@@ -129,6 +129,11 @@ export default function RiskDetailPage(props: Props) {
|
||||
>
|
||||
{__("Measures")}
|
||||
</TabLink>
|
||||
<TabLink
|
||||
to={`/organizations/${organizationId}/risks/${riskId}/documents`}
|
||||
>
|
||||
{__("Documents")}
|
||||
</TabLink>
|
||||
</Tabs>
|
||||
|
||||
<Outlet context={{ risk }} />
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import { graphql, useFragment, useMutation } from "react-relay";
|
||||
import { useOutletContext } from "react-router";
|
||||
import { LinkedDocumentsCard } from "/components/documents/LinkedDocumentsCard";
|
||||
import type { RiskDocumentsTabFragment$key } from "./__generated__/RiskDocumentsTabFragment.graphql";
|
||||
|
||||
const documentsFragment = graphql`
|
||||
fragment RiskDocumentsTabFragment on Risk {
|
||||
id
|
||||
documents(first: 100) @connection(key: "Risk__documents") {
|
||||
__id
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
...LinkedDocumentsCardFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const attachDocumentMutation = graphql`
|
||||
mutation RiskDocumentsTabCreateMutation(
|
||||
$input: CreateRiskDocumentMappingInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
createRiskDocumentMapping(input: $input) {
|
||||
documentEdge @prependEdge(connections: $connections) {
|
||||
node {
|
||||
id
|
||||
...LinkedDocumentsCardFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const detachDocumentMutation = graphql`
|
||||
mutation RiskDocumentsTabDetachMutation(
|
||||
$input: DeleteRiskDocumentMappingInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
deleteRiskDocumentMapping(input: $input) {
|
||||
deletedDocumentId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default function RiskDocumentsTab() {
|
||||
const { risk } = useOutletContext<{
|
||||
risk: RiskDocumentsTabFragment$key & { id: string };
|
||||
}>();
|
||||
const data = useFragment(documentsFragment, risk);
|
||||
const connectionId = data.documents.__id;
|
||||
const documents = data.documents?.edges?.map((edge) => edge.node) ?? [];
|
||||
|
||||
const [detachDocument, isDetaching] = useMutation(detachDocumentMutation);
|
||||
const [attachDocument, isAttaching] = useMutation(attachDocumentMutation);
|
||||
const isLoading = isDetaching || isAttaching;
|
||||
|
||||
return (
|
||||
<LinkedDocumentsCard
|
||||
disabled={isLoading}
|
||||
documents={documents}
|
||||
onAttach={attachDocument}
|
||||
onDetach={detachDocument}
|
||||
params={{ riskId: data.id }}
|
||||
connectionId={connectionId}
|
||||
/>
|
||||
);
|
||||
}
|
||||
256
apps/console2/src/pages/organizations/risks/tabs/__generated__/RiskDocumentsTabCreateMutation.graphql.ts
generated
Normal file
256
apps/console2/src/pages/organizations/risks/tabs/__generated__/RiskDocumentsTabCreateMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,256 @@
|
||||
/**
|
||||
* @generated SignedSource<<81e7ff7299c6b5f9e46fa08ee731be12>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type CreateRiskDocumentMappingInput = {
|
||||
documentId: string;
|
||||
riskId: string;
|
||||
};
|
||||
export type RiskDocumentsTabCreateMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: CreateRiskDocumentMappingInput;
|
||||
};
|
||||
export type RiskDocumentsTabCreateMutation$data = {
|
||||
readonly createRiskDocumentMapping: {
|
||||
readonly documentEdge: {
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedDocumentsCardFragment">;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export type RiskDocumentsTabCreateMutation = {
|
||||
response: RiskDocumentsTabCreateMutation$data;
|
||||
variables: RiskDocumentsTabCreateMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "RiskDocumentsTabCreateMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "CreateRiskDocumentMappingPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "createRiskDocumentMapping",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "DocumentEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "documentEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Document",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "LinkedDocumentsCardFragment"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "RiskDocumentsTabCreateMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "CreateRiskDocumentMappingPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "createRiskDocumentMapping",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "DocumentEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "documentEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Document",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "title",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "documentType",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 1
|
||||
}
|
||||
],
|
||||
"concreteType": "DocumentVersionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "versions",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "DocumentVersionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "DocumentVersion",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "status",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "versions(first:1)"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "prependEdge",
|
||||
"key": "",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "documentEdge",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "e2844d2884a2d7d2c648fea4888fbfc5",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "RiskDocumentsTabCreateMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation RiskDocumentsTabCreateMutation(\n $input: CreateRiskDocumentMappingInput!\n) {\n createRiskDocumentMapping(input: $input) {\n documentEdge {\n node {\n id\n ...LinkedDocumentsCardFragment\n }\n }\n }\n}\n\nfragment LinkedDocumentsCardFragment on Document {\n id\n title\n createdAt\n documentType\n versions(first: 1) {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "0847d69d95edfec177a03175e227ced6";
|
||||
|
||||
export default node;
|
||||
133
apps/console2/src/pages/organizations/risks/tabs/__generated__/RiskDocumentsTabDetachMutation.graphql.ts
generated
Normal file
133
apps/console2/src/pages/organizations/risks/tabs/__generated__/RiskDocumentsTabDetachMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* @generated SignedSource<<ae02449f816da7f2b79f16edbe2f7066>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type DeleteRiskDocumentMappingInput = {
|
||||
documentId: string;
|
||||
riskId: string;
|
||||
};
|
||||
export type RiskDocumentsTabDetachMutation$variables = {
|
||||
connections: ReadonlyArray<string>;
|
||||
input: DeleteRiskDocumentMappingInput;
|
||||
};
|
||||
export type RiskDocumentsTabDetachMutation$data = {
|
||||
readonly deleteRiskDocumentMapping: {
|
||||
readonly deletedDocumentId: string;
|
||||
};
|
||||
};
|
||||
export type RiskDocumentsTabDetachMutation = {
|
||||
response: RiskDocumentsTabDetachMutation$data;
|
||||
variables: RiskDocumentsTabDetachMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "connections"
|
||||
},
|
||||
v1 = {
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
},
|
||||
v2 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deletedDocumentId",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "RiskDocumentsTabDetachMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeleteRiskDocumentMappingPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteRiskDocumentMapping",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v1/*: any*/),
|
||||
(v0/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "RiskDocumentsTabDetachMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v2/*: any*/),
|
||||
"concreteType": "DeleteRiskDocumentMappingPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteRiskDocumentMapping",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"filters": null,
|
||||
"handle": "deleteEdge",
|
||||
"key": "",
|
||||
"kind": "ScalarHandle",
|
||||
"name": "deletedDocumentId",
|
||||
"handleArgs": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "connections",
|
||||
"variableName": "connections"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "a8dc5064c650c498193904e16790df6e",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "RiskDocumentsTabDetachMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation RiskDocumentsTabDetachMutation(\n $input: DeleteRiskDocumentMappingInput!\n) {\n deleteRiskDocumentMapping(input: $input) {\n deletedDocumentId\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "0aa4bf52197d033dfc3aabca9288aad4";
|
||||
|
||||
export default node;
|
||||
155
apps/console2/src/pages/organizations/risks/tabs/__generated__/RiskDocumentsTabFragment.graphql.ts
generated
Normal file
155
apps/console2/src/pages/organizations/risks/tabs/__generated__/RiskDocumentsTabFragment.graphql.ts
generated
Normal file
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* @generated SignedSource<<1ccd9664c4fb02eb50e1284ed64372fb>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type RiskDocumentsTabFragment$data = {
|
||||
readonly documents: {
|
||||
readonly __id: string;
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"LinkedDocumentsCardFragment">;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly id: string;
|
||||
readonly " $fragmentType": "RiskDocumentsTabFragment";
|
||||
};
|
||||
export type RiskDocumentsTabFragment$key = {
|
||||
readonly " $data"?: RiskDocumentsTabFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"RiskDocumentsTabFragment">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": null,
|
||||
"cursor": null,
|
||||
"direction": "forward",
|
||||
"path": [
|
||||
"documents"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "RiskDocumentsTabFragment",
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"alias": "documents",
|
||||
"args": null,
|
||||
"concreteType": "DocumentConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__Risk__documents_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "DocumentEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Document",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "LinkedDocumentsCardFragment"
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"kind": "ClientExtension",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__id",
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Risk",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "91792e693e6326b25ceb70c14fdc154e";
|
||||
|
||||
export default node;
|
||||
@@ -12,7 +12,9 @@ import {
|
||||
import {
|
||||
ActionDropdown,
|
||||
Breadcrumb,
|
||||
Button,
|
||||
DropdownItem,
|
||||
IconPageTextLine,
|
||||
IconTrashCan,
|
||||
TabLink,
|
||||
Tabs,
|
||||
@@ -21,6 +23,7 @@ import { useTranslate } from "@probo/i18n";
|
||||
import { useOrganizationId } from "/hooks/useOrganizationId";
|
||||
import { Outlet } from "react-router";
|
||||
import { faviconUrl } from "@probo/helpers";
|
||||
import { ImportAssessmentDialog } from "./dialogs/ImportAssessmentDialog";
|
||||
|
||||
type Props = {
|
||||
queryRef: PreloadedQuery<VendorGraphNodeQuery>;
|
||||
@@ -50,7 +53,7 @@ export default function VendorDetailPage(props: Props) {
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<div className="flex justify-between">
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="space-y-4">
|
||||
{logo && (
|
||||
<img
|
||||
@@ -61,15 +64,22 @@ export default function VendorDetailPage(props: Props) {
|
||||
)}
|
||||
<div className="text-2xl">{vendor.name}</div>
|
||||
</div>
|
||||
<ActionDropdown variant="secondary">
|
||||
<DropdownItem
|
||||
variant="danger"
|
||||
icon={IconTrashCan}
|
||||
onClick={deleteVendor}
|
||||
>
|
||||
{__("Delete")}
|
||||
</DropdownItem>
|
||||
</ActionDropdown>
|
||||
<div className="flex gap-2 items-center">
|
||||
<ImportAssessmentDialog vendorId={vendor.id!}>
|
||||
<Button icon={IconPageTextLine} variant="secondary">
|
||||
{__("Assessment From Website")}
|
||||
</Button>
|
||||
</ImportAssessmentDialog>
|
||||
<ActionDropdown variant="secondary">
|
||||
<DropdownItem
|
||||
variant="danger"
|
||||
icon={IconTrashCan}
|
||||
onClick={deleteVendor}
|
||||
>
|
||||
{__("Delete")}
|
||||
</DropdownItem>
|
||||
</ActionDropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Tabs>
|
||||
|
||||
99
apps/console2/src/pages/organizations/vendors/dialogs/ImportAssessmentDialog.tsx
vendored
Normal file
99
apps/console2/src/pages/organizations/vendors/dialogs/ImportAssessmentDialog.tsx
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
Field,
|
||||
useDialogRef,
|
||||
} from "@probo/ui";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { z } from "zod";
|
||||
import { useFormWithSchema } from "/hooks/useFormWithSchema";
|
||||
import { graphql } from "relay-runtime";
|
||||
import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
const schema = z.object({
|
||||
url: z.string().url(),
|
||||
});
|
||||
|
||||
const importAssessmentMutation = graphql`
|
||||
mutation ImportAssessmentDialogMutation($input: AssessVendorInput!) {
|
||||
assessVendor(input: $input) {
|
||||
vendor {
|
||||
id
|
||||
name
|
||||
websiteUrl
|
||||
...useVendorFormFragment
|
||||
...VendorComplianceTabFragment
|
||||
...VendorRiskAssessmentTabFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
vendorId: string;
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export function ImportAssessmentDialog({ vendorId, children }: Props) {
|
||||
const { __ } = useTranslate();
|
||||
const dialogRef = useDialogRef();
|
||||
const { register, handleSubmit, reset, formState } = useFormWithSchema(
|
||||
schema,
|
||||
{
|
||||
defaultValues: {
|
||||
url: "",
|
||||
},
|
||||
}
|
||||
);
|
||||
const [assess, isAssessing] = useMutationWithToasts(
|
||||
importAssessmentMutation,
|
||||
{
|
||||
successMessage: __("Vendor assessed successfully."),
|
||||
errorMessage: __("Failed to assess vendor. Please try again."),
|
||||
}
|
||||
);
|
||||
|
||||
const onSubmit = handleSubmit((data) => {
|
||||
assess({
|
||||
variables: {
|
||||
input: {
|
||||
id: vendorId,
|
||||
websiteUrl: data.url,
|
||||
},
|
||||
},
|
||||
onSuccess: () => {
|
||||
dialogRef.current?.close();
|
||||
reset();
|
||||
},
|
||||
});
|
||||
});
|
||||
return (
|
||||
<Dialog
|
||||
ref={dialogRef}
|
||||
defaultOpen
|
||||
trigger={children}
|
||||
title={__("Assessment from website")}
|
||||
className="max-w-lg"
|
||||
>
|
||||
<form onSubmit={onSubmit}>
|
||||
<DialogContent padded>
|
||||
<Field
|
||||
required
|
||||
label={__("URL")}
|
||||
type="text"
|
||||
{...register("url")}
|
||||
error={formState.errors.url?.message}
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogFooter>
|
||||
<Button type="submit" disabled={isAssessing}>
|
||||
{__("Assess")}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
543
apps/console2/src/pages/organizations/vendors/dialogs/__generated__/ImportAssessmentDialogMutation.graphql.ts
generated
vendored
Normal file
543
apps/console2/src/pages/organizations/vendors/dialogs/__generated__/ImportAssessmentDialogMutation.graphql.ts
generated
vendored
Normal file
@@ -0,0 +1,543 @@
|
||||
/**
|
||||
* @generated SignedSource<<a0f6e47aa4001c2a99c02b7eabe5c99a>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type AssessVendorInput = {
|
||||
id: string;
|
||||
websiteUrl: string;
|
||||
};
|
||||
export type ImportAssessmentDialogMutation$variables = {
|
||||
input: AssessVendorInput;
|
||||
};
|
||||
export type ImportAssessmentDialogMutation$data = {
|
||||
readonly assessVendor: {
|
||||
readonly vendor: {
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
readonly websiteUrl: string | null | undefined;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"VendorComplianceTabFragment" | "VendorRiskAssessmentTabFragment" | "useVendorFormFragment">;
|
||||
};
|
||||
};
|
||||
};
|
||||
export type ImportAssessmentDialogMutation = {
|
||||
response: ImportAssessmentDialogMutation$data;
|
||||
variables: ImportAssessmentDialogMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"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
|
||||
},
|
||||
v4 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "websiteUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
v5 = [
|
||||
(v2/*: any*/)
|
||||
],
|
||||
v6 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 50
|
||||
}
|
||||
],
|
||||
v7 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v8 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
},
|
||||
v9 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
v10 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
},
|
||||
v11 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasPreviousPage",
|
||||
"storageKey": null
|
||||
},
|
||||
v12 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "startCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
v13 = {
|
||||
"kind": "ClientExtension",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__id",
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
v14 = [
|
||||
"orderBy"
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "ImportAssessmentDialogMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": "AssessVendorPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "assessVendor",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Vendor",
|
||||
"kind": "LinkedField",
|
||||
"name": "vendor",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "useVendorFormFragment"
|
||||
},
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "VendorComplianceTabFragment"
|
||||
},
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "VendorRiskAssessmentTabFragment"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "ImportAssessmentDialogMutation",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": "AssessVendorPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "assessVendor",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Vendor",
|
||||
"kind": "LinkedField",
|
||||
"name": "vendor",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "description",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "statusPageUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "termsOfServiceUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "privacyPolicyUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "serviceLevelAgreementUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "dataProcessingAgreementUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "legalName",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "headquarterAddress",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "certifications",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "securityPageUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "trustPageUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "businessOwner",
|
||||
"plural": false,
|
||||
"selections": (v5/*: any*/),
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "securityOwner",
|
||||
"plural": false,
|
||||
"selections": (v5/*: any*/),
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v6/*: any*/),
|
||||
"concreteType": "VendorComplianceReportConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "complianceReports",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "VendorComplianceReportEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "VendorComplianceReport",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "reportDate",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "validUntil",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "reportName",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fileUrl",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fileSize",
|
||||
"storageKey": null
|
||||
},
|
||||
(v7/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v8/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v9/*: any*/),
|
||||
(v10/*: any*/),
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v13/*: any*/)
|
||||
],
|
||||
"storageKey": "complianceReports(first:50)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v6/*: any*/),
|
||||
"filters": (v14/*: any*/),
|
||||
"handle": "connection",
|
||||
"key": "VendorComplianceTabFragment_complianceReports",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "complianceReports"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v6/*: any*/),
|
||||
"concreteType": "VendorRiskAssessmentConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "riskAssessments",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "VendorRiskAssessmentEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "VendorRiskAssessment",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "assessedAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "People",
|
||||
"kind": "LinkedField",
|
||||
"name": "assessedBy",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "fullName",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "expiresAt",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "dataSensitivity",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "businessImpact",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "notes",
|
||||
"storageKey": null
|
||||
},
|
||||
(v7/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v8/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v10/*: any*/),
|
||||
(v9/*: any*/),
|
||||
(v11/*: any*/),
|
||||
(v12/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v13/*: any*/)
|
||||
],
|
||||
"storageKey": "riskAssessments(first:50)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v6/*: any*/),
|
||||
"filters": (v14/*: any*/),
|
||||
"handle": "connection",
|
||||
"key": "VendorRiskAssessmentTabFragment_riskAssessments",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "riskAssessments"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "dbe0c3ef0f5d4d36436224603629d30a",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "ImportAssessmentDialogMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation ImportAssessmentDialogMutation(\n $input: AssessVendorInput!\n) {\n assessVendor(input: $input) {\n vendor {\n id\n name\n websiteUrl\n ...useVendorFormFragment\n ...VendorComplianceTabFragment\n ...VendorRiskAssessmentTabFragment\n }\n }\n}\n\nfragment VendorComplianceTabFragment on Vendor {\n complianceReports(first: 50) {\n edges {\n node {\n id\n ...VendorComplianceTabFragment_report\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorComplianceTabFragment_report on VendorComplianceReport {\n id\n reportDate\n validUntil\n reportName\n fileUrl\n fileSize\n}\n\nfragment VendorRiskAssessmentTabFragment on Vendor {\n id\n riskAssessments(first: 50) {\n edges {\n node {\n id\n ...VendorRiskAssessmentTabFragment_assessment\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment VendorRiskAssessmentTabFragment_assessment on VendorRiskAssessment {\n id\n assessedAt\n assessedBy {\n id\n fullName\n }\n expiresAt\n dataSensitivity\n businessImpact\n notes\n}\n\nfragment useVendorFormFragment on Vendor {\n id\n name\n description\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n websiteUrl\n legalName\n headquarterAddress\n certifications\n securityPageUrl\n trustPageUrl\n businessOwner {\n id\n }\n securityOwner {\n id\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "d740639450b37e427fad42d04c4aef70";
|
||||
|
||||
export default node;
|
||||
@@ -18,8 +18,7 @@ import {
|
||||
import { useFragment, useMutation, useRefetchableFragment } from "react-relay";
|
||||
import type { VendorComplianceTabFragment_report$key } from "./__generated__/VendorComplianceTabFragment_report.graphql";
|
||||
import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
|
||||
import { sprintf } from "@probo/helpers";
|
||||
import { fileSize } from "@probo/helpers/src/file.ts";
|
||||
import { sprintf, fileSize } from "@probo/helpers";
|
||||
import { SortableTable, SortableTh } from "/components/SortableTable";
|
||||
|
||||
const complianceReportsFragment = graphql`
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
IconPlusLarge,
|
||||
RiskBadge,
|
||||
Badge,
|
||||
TrButton,
|
||||
} from "@probo/ui";
|
||||
import { useFragment, useRefetchableFragment } from "react-relay";
|
||||
import type { VendorRiskAssessmentTabFragment_assessment$key } from "./__generated__/VendorRiskAssessmentTabFragment_assessment.graphql";
|
||||
@@ -104,17 +105,7 @@ export default function VendorRiskAssessmentTab() {
|
||||
|
||||
return (
|
||||
<div className="space-y-6 relative">
|
||||
<div className="flex justify-end">
|
||||
<CreateRiskAssessmentDialog
|
||||
vendorId={vendor.id}
|
||||
connection={data.riskAssessments.__id}
|
||||
peopleId={peopleId}
|
||||
>
|
||||
<Button icon={IconPlusLarge} variant="primary">
|
||||
{__("Add Risk Assessment")}
|
||||
</Button>
|
||||
</CreateRiskAssessmentDialog>
|
||||
</div>
|
||||
<div className="flex justify-end"></div>
|
||||
<div className="overflow-x-auto">
|
||||
<SortableTable refetch={refetch}>
|
||||
<Thead>
|
||||
@@ -126,6 +117,15 @@ export default function VendorRiskAssessmentTab() {
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
<CreateRiskAssessmentDialog
|
||||
vendorId={vendor.id}
|
||||
connection={data.riskAssessments.__id}
|
||||
peopleId={peopleId}
|
||||
>
|
||||
<TrButton colspan={5} onClick={() => {}}>
|
||||
{__("Add Risk Assessment")}
|
||||
</TrButton>
|
||||
</CreateRiskAssessmentDialog>
|
||||
{assessments.map((assessment) => (
|
||||
<AssessmentRow
|
||||
key={assessment.id}
|
||||
|
||||
@@ -22,6 +22,7 @@ import { vendorRoutes } from "./routes/vendorRoutes.ts";
|
||||
import { organizationViewQuery } from "./hooks/graph/OrganizationGraph.ts";
|
||||
import { peopleRoutes } from "./routes/peopleRoutes.ts";
|
||||
import { frameworkRoutes } from "./routes/frameworkRoutes.ts";
|
||||
import { PageError } from "./components/PageError.tsx";
|
||||
|
||||
function ErrorBoundary() {
|
||||
const error = useRouteError();
|
||||
@@ -87,6 +88,10 @@ const routes = [
|
||||
...peopleRoutes,
|
||||
...vendorRoutes,
|
||||
...frameworkRoutes,
|
||||
{
|
||||
path: "*",
|
||||
Component: PageError,
|
||||
},
|
||||
],
|
||||
},
|
||||
] satisfies AppRoute[];
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { lazy } from "react";
|
||||
import { Fragment, lazy } from "react";
|
||||
import { loadQuery } from "react-relay";
|
||||
import type { AppRoute } from "/routes.tsx";
|
||||
import { relayEnvironment } from "/providers/RelayProviders";
|
||||
import { documentsQuery } from "/hooks/graph/DocumentGraph";
|
||||
import { documentNodeQuery } from "/hooks/graph/DocumentGraph";
|
||||
import { PageSkeleton } from "/components/skeletons/PageSkeleton";
|
||||
import { redirect } from "react-router";
|
||||
|
||||
export const documentsRoutes = [
|
||||
{
|
||||
@@ -22,7 +23,34 @@ export const documentsRoutes = [
|
||||
queryLoader: ({ documentId }) =>
|
||||
loadQuery(relayEnvironment, documentNodeQuery, { documentId }),
|
||||
Component: lazy(
|
||||
() => import("/pages/organizations/documents/DocumentPage")
|
||||
() => import("../pages/organizations/documents/DocumentDetailPage")
|
||||
),
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
queryLoader: ({ organizationId, documentId }) => {
|
||||
throw redirect(
|
||||
`/organizations/${organizationId}/documents/${documentId}/description`
|
||||
);
|
||||
},
|
||||
Component: Fragment,
|
||||
},
|
||||
{
|
||||
path: "description",
|
||||
Component: lazy(
|
||||
() =>
|
||||
import(
|
||||
"../pages/organizations/documents/tabs/DocumentDescriptionTab"
|
||||
)
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "controls",
|
||||
Component: lazy(
|
||||
() =>
|
||||
import("../pages/organizations/documents/tabs/DocumentControlsTab")
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
] satisfies AppRoute[];
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
frameworkNodeQuery,
|
||||
} from "/hooks/graph/FrameworkGraph";
|
||||
import type { AppRoute } from "/routes";
|
||||
import { lazy } from "react";
|
||||
import { Fragment, lazy } from "react";
|
||||
|
||||
export const frameworkRoutes = [
|
||||
{
|
||||
@@ -19,12 +19,22 @@ export const frameworkRoutes = [
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "frameworks/:frameworkId/:controlId?",
|
||||
path: "frameworks/:frameworkId",
|
||||
fallback: PageSkeleton,
|
||||
queryLoader: ({ frameworkId }) =>
|
||||
loadQuery(relayEnvironment, frameworkNodeQuery, { frameworkId }),
|
||||
Component: lazy(
|
||||
() => import("/pages/organizations/frameworks/FrameworkDetailPage")
|
||||
),
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
Component: Fragment,
|
||||
},
|
||||
{
|
||||
path: "controls/:controlId",
|
||||
Component: Fragment,
|
||||
},
|
||||
],
|
||||
},
|
||||
] satisfies AppRoute[];
|
||||
|
||||
@@ -2,8 +2,9 @@ import { Fragment, lazy } from "react";
|
||||
import { loadQuery } from "react-relay";
|
||||
import type { AppRoute } from "/routes.tsx";
|
||||
import { relayEnvironment } from "/providers/RelayProviders";
|
||||
import { measuresQuery } from "/hooks/graph/MeasureGraph";
|
||||
import { measureNodeQuery, measuresQuery } from "/hooks/graph/MeasureGraph";
|
||||
import { PageSkeleton } from "/components/skeletons/PageSkeleton";
|
||||
import { redirect } from "react-router";
|
||||
|
||||
export const measureRoutes = [
|
||||
{
|
||||
@@ -22,6 +23,39 @@ export const measureRoutes = [
|
||||
{
|
||||
path: "measures/:measureId",
|
||||
fallback: PageSkeleton,
|
||||
Component: Fragment,
|
||||
queryLoader: ({ measureId }) =>
|
||||
loadQuery(relayEnvironment, measureNodeQuery, { measureId }),
|
||||
Component: lazy(
|
||||
() => import("/pages/organizations/measures/MeasureDetailPage")
|
||||
),
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
loader: () => {
|
||||
throw redirect("evidences");
|
||||
},
|
||||
Component: Fragment,
|
||||
},
|
||||
{
|
||||
path: "risks",
|
||||
Component: lazy(
|
||||
() => import("/pages/organizations/measures/tabs/MeasureRisksTab.tsx")
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "controls",
|
||||
Component: lazy(
|
||||
() =>
|
||||
import("/pages/organizations/measures/tabs/MeasureControlsTab.tsx")
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "evidences",
|
||||
Component: lazy(
|
||||
() =>
|
||||
import("/pages/organizations/measures/tabs/MeasureEvidencesTab.tsx")
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
] satisfies AppRoute[];
|
||||
|
||||
@@ -41,6 +41,12 @@ export const riskRoutes = [
|
||||
() => import("/pages/organizations/risks/tabs/RiskMeasuresTab.tsx")
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "documents",
|
||||
Component: lazy(
|
||||
() => import("/pages/organizations/risks/tabs/RiskDocumentsTab.tsx")
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
] satisfies AppRoute[];
|
||||
|
||||
2
graphql.config.yml
Normal file
2
graphql.config.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
schema: "pkg/server/api/console/v1/schema.graphql"
|
||||
documents: []
|
||||
@@ -17,3 +17,18 @@ export function fileSize(__: (s: string) => string, size: number): string {
|
||||
|
||||
return `${formattedSize} ${units[unitIndex]}`;
|
||||
}
|
||||
|
||||
type FileInfo = {
|
||||
type: string;
|
||||
mimeType: string;
|
||||
};
|
||||
|
||||
export function fileType(__: (s: string) => string, info: FileInfo): string {
|
||||
if (
|
||||
info.type !== "FILE" ||
|
||||
(info.mimeType !== "text/uri-list" && info.mimeType !== "text/uri")
|
||||
) {
|
||||
return __("Document");
|
||||
}
|
||||
return __("Link");
|
||||
}
|
||||
|
||||
@@ -14,3 +14,5 @@ export { getRole, getRoles, peopleRoles } from "./people";
|
||||
export { certificationCategoryLabel, certifications } from "./certifications";
|
||||
export { availableFrameworks } from "./frameworks";
|
||||
export { getDocumentTypeLabel, documentTypes } from "./documents";
|
||||
export { promisifyMutation } from "./relay";
|
||||
export { fileType, fileSize } from "./file";
|
||||
|
||||
37
packages/helpers/src/relay.ts
Normal file
37
packages/helpers/src/relay.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
export function promisifyMutation<Response, Error, Args>(
|
||||
mutationFn: (
|
||||
args: {
|
||||
onCompleted?: (response: Response, error: Error) => void;
|
||||
onError?: (error: Error) => void;
|
||||
} & Args,
|
||||
) => void,
|
||||
): (
|
||||
args: {
|
||||
onCompleted?: (response: Response, error: Error) => void;
|
||||
onError?: (error: Error) => void;
|
||||
} & Args,
|
||||
) => Promise<Response> {
|
||||
return (opts) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
mutationFn({
|
||||
...opts,
|
||||
onCompleted: (response, error) => {
|
||||
if (opts.onCompleted) {
|
||||
opts.onCompleted(response, error);
|
||||
}
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(response);
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
if (opts.onError) {
|
||||
opts.onError(error);
|
||||
}
|
||||
reject(error);
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
"@tailwindcss/vite": "^4.1.7",
|
||||
"clsx": "^2.1.1",
|
||||
"react-dropzone": "^14.3.8",
|
||||
"react-intersection-observer": "^9.16.0",
|
||||
"react-markdown": "^10.1.0",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"remark-gfm": "^4.0.1",
|
||||
|
||||
@@ -9,7 +9,7 @@ import { tv, type VariantProps } from "tailwind-variants";
|
||||
import { Slot } from "../Slot";
|
||||
|
||||
export const button = tv({
|
||||
base: "flex items-center justify-center gap-[6px] px-3 py-2 rounded-full cursor-pointer text-sm font-medium h-8 focus:outline-none whitespace-nowrap",
|
||||
base: "flex items-center justify-center gap-[6px] px-3 py-2 rounded-full cursor-pointer text-sm font-medium h-8 focus:outline-none whitespace-nowrap w-max",
|
||||
variants: {
|
||||
variant: {
|
||||
primary:
|
||||
|
||||
5
packages/ui/src/Atoms/Icons/IconWarning.tsx
Normal file
5
packages/ui/src/Atoms/Icons/IconWarning.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
import type {IconProps} from "./type.ts";
|
||||
|
||||
export function IconWarning({size = 24, className}: IconProps) {
|
||||
return <svg className={className} xmlns="http://www.w3.org/2000/svg" width={size} height={size} fill="currentColor" viewBox="0 0 24 24"><path fill="currentColor" d="M12.188 1.993a3.001 3.001 0 0 1 2.41 1.51L22.596 17.5l.093.174A3 3 0 0 1 20.001 22H4v-.001a2.999 2.999 0 0 1-2.618-4.495l8-14a3 3 0 0 1 2.608-1.518l.198.007Zm-.33 2.002a1 1 0 0 0-.738.498l-.001.003-8 14-.003.004A1.002 1.002 0 0 0 3.99 20h16.008a1.001 1.001 0 0 0 .999-1 1 1 0 0 0-.134-.5l-.002-.004-8-14-.002-.003a1 1 0 0 0-.87-.507l-.132.009ZM12.01 16a1 1 0 0 1 0 2H12a1 1 0 0 1 0-2h.01ZM11 13V9a1 1 0 0 1 2 0v4a1 1 0 1 1-2 0Z"/></svg>
|
||||
}
|
||||
@@ -71,6 +71,7 @@ export { IconSettingsGear2 } from "./IconSettingsGear2.tsx";
|
||||
export { IconBook } from "./IconBook.tsx";
|
||||
export { IconCircleQuestionmarkSolid } from "./IconCircleQuestionmarkSolid.tsx";
|
||||
export { IconBlock1 } from "./IconBlock1.tsx";
|
||||
export { IconWarning } from "./IconWarning.tsx";
|
||||
export { IconChevronUp } from "./IconChevronUp.tsx";
|
||||
export { IconBlock } from "./IconBlock.tsx";
|
||||
export { IconChevronDown } from "./IconChevronDown.tsx";
|
||||
|
||||
1
packages/ui/src/Atoms/Icons/warning.svg
Normal file
1
packages/ui/src/Atoms/Icons/warning.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" d="M12.188 1.993a3.001 3.001 0 0 1 2.41 1.51L22.596 17.5l.093.174A3 3 0 0 1 20.001 22H4v-.001a2.999 2.999 0 0 1-2.618-4.495l8-14a3 3 0 0 1 2.608-1.518l.198.007Zm-.33 2.002a1 1 0 0 0-.738.498l-.001.003-8 14-.003.004A1.002 1.002 0 0 0 3.99 20h16.008a1.001 1.001 0 0 0 .999-1 1 1 0 0 0-.134-.5l-.002-.004-8-14-.002-.003a1 1 0 0 0-.87-.507l-.132.009ZM12.01 16a1 1 0 0 1 0 2H12a1 1 0 0 1 0-2h.01ZM11 13V9a1 1 0 0 1 2 0v4a1 1 0 1 1-2 0Z"/></svg>
|
||||
|
After Width: | Height: | Size: 560 B |
@@ -0,0 +1,16 @@
|
||||
import { InfiniteScrollTrigger } from "./InfiniteScrollTrigger";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
|
||||
export default {
|
||||
title: "Atoms/InfiniteScrollTrigger",
|
||||
component: InfiniteScrollTrigger,
|
||||
argTypes: {},
|
||||
} satisfies Meta<typeof InfiniteScrollTrigger>;
|
||||
|
||||
type Story = StoryObj<typeof InfiniteScrollTrigger>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
onView: () => {},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
import { useEffect, type ReactNode } from "react";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { useRefSync } from "@probo/hooks";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
import { Spinner } from "../Spinner/Spinner";
|
||||
|
||||
type Props = {
|
||||
children?: ReactNode;
|
||||
onView: () => void;
|
||||
loading?: boolean;
|
||||
};
|
||||
|
||||
export function InfiniteScrollTrigger({ children, onView, loading }: Props) {
|
||||
const { __ } = useTranslate();
|
||||
const { ref, inView } = useInView({
|
||||
threshold: 0,
|
||||
});
|
||||
const onViewRef = useRefSync(onView);
|
||||
console.log(inView);
|
||||
useEffect(() => {
|
||||
if (inView && !loading) onViewRef.current();
|
||||
}, [inView, loading]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex gap-2 items-center justify-center text-xs text-txt-secondary"
|
||||
ref={ref}
|
||||
>
|
||||
{children ?? (
|
||||
<>
|
||||
<Spinner size={16} />
|
||||
{__("Loading")}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Table } from "./Table";
|
||||
import { Table, Tbody, Td, Th, Thead, Tr, TrButton } from "./Table";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
|
||||
export default {
|
||||
@@ -9,4 +9,33 @@ export default {
|
||||
|
||||
type Story = StoryObj<typeof Table>;
|
||||
|
||||
export const Default: Story = {};
|
||||
export const Default: Story = {
|
||||
render: () => {
|
||||
return (
|
||||
<Table>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>Header 1</Th>
|
||||
<Th>Header 2</Th>
|
||||
<Th>Header 3</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
<Tr>
|
||||
<Td>Row 1, Cell 1</Td>
|
||||
<Td>Row 1, Cell 2</Td>
|
||||
<Td>Row 1, Cell 3</Td>
|
||||
</Tr>
|
||||
<Tr>
|
||||
<Td>Row 2, Cell 1</Td>
|
||||
<Td>Row 2, Cell 2</Td>
|
||||
<Td>Row 2, Cell 3</Td>
|
||||
</Tr>
|
||||
<TrButton onClick={() => {}} colspan={3}>
|
||||
Add row
|
||||
</TrButton>
|
||||
</Tbody>
|
||||
</Table>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
type FC,
|
||||
type HTMLAttributes,
|
||||
type PropsWithChildren,
|
||||
type ReactNode,
|
||||
} from "react";
|
||||
import { Card } from "../Card/Card";
|
||||
import { Link } from "react-router";
|
||||
import clsx from "clsx";
|
||||
import { IconPlusLarge } from "../Icons";
|
||||
|
||||
export function Table({
|
||||
children,
|
||||
@@ -34,7 +37,10 @@ export function Th({
|
||||
}: PropsWithChildren<{ className?: string; width?: number }>) {
|
||||
return (
|
||||
<th
|
||||
className={clsx("first:pl-6 last:pr-6 py-3", className)}
|
||||
className={clsx(
|
||||
"first:pl-6 last:pr-6 py-3 whitespace-nowrap",
|
||||
className,
|
||||
)}
|
||||
style={{ width }}
|
||||
>
|
||||
{children}
|
||||
@@ -98,12 +104,35 @@ export function Td({
|
||||
<td
|
||||
{...props}
|
||||
width={width}
|
||||
className={clsx(
|
||||
"first:*:pl-6 *:block last:*:pr-6 *:py-3",
|
||||
className,
|
||||
)}
|
||||
className={clsx("first:*:pl-6 *:pr-6 *:block *:py-3", className)}
|
||||
>
|
||||
<Link to={to}>{children}</Link>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
export function TrButton({
|
||||
icon = IconPlusLarge,
|
||||
children,
|
||||
colspan,
|
||||
...props
|
||||
}: {
|
||||
colspan?: number;
|
||||
children: ReactNode;
|
||||
icon?: FC<{ size: number; className?: string }>;
|
||||
} & HTMLAttributes<HTMLButtonElement>) {
|
||||
const IconComponent = icon;
|
||||
return (
|
||||
<tr>
|
||||
<td colSpan={colspan}>
|
||||
<button
|
||||
{...props}
|
||||
className="py-2 bg-highlight hover:bg-highlight-hover active:bg-highlight-pressed cursor-pointer w-full flex gap-2 items-center justify-center"
|
||||
>
|
||||
<IconComponent size={16} />
|
||||
{children}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Tabs, TabLink } from "./Tabs";
|
||||
import { Tabs, TabLink, TabBadge } from "./Tabs";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
|
||||
export default {
|
||||
@@ -13,8 +13,10 @@ export const Default: Story = {
|
||||
render: () => (
|
||||
<Tabs>
|
||||
<TabLink to="#">Tab 1</TabLink>
|
||||
<TabLink to="#">Tab 2</TabLink>
|
||||
<TabLink to="#">Tab 3</TabLink>
|
||||
<TabLink to="/demo">Tab 2</TabLink>
|
||||
<TabLink to="/demo2">
|
||||
Tab 3 <TabBadge>3</TabBadge>
|
||||
</TabLink>
|
||||
</Tabs>
|
||||
),
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ export function TabLink(props: PropsWithChildren<{ to: string }>) {
|
||||
<NavLink
|
||||
className={(params) =>
|
||||
clsx(
|
||||
"py-4 hover:text-txt-primary border-b-2 active:border-border-active -mb-[1px] active:text-txt-primary",
|
||||
"py-4 hover:text-txt-primary border-b-2 active:border-border-active -mb-[1px] active:text-txt-primary flex items-center gap-1",
|
||||
params.isActive
|
||||
? "border-border-active text-txt-primary"
|
||||
: "border-transparent",
|
||||
@@ -31,3 +31,11 @@ export function TabLink(props: PropsWithChildren<{ to: string }>) {
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function TabBadge(props: PropsWithChildren) {
|
||||
return (
|
||||
<span className="py-1 px-2 text-txt-secondary text-xs font-semibold rounded-lg bg-highlight text-primary">
|
||||
{props.children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ type State = {
|
||||
message: string | null;
|
||||
variant?: ComponentProps<typeof Button>["variant"];
|
||||
label?: string;
|
||||
onConfirm: () => Promise<void>;
|
||||
onConfirm: () => Promise<unknown>;
|
||||
};
|
||||
|
||||
const useConfirmStore = create(
|
||||
|
||||
@@ -29,11 +29,12 @@ export { Textarea } from "./Atoms/Textarea/Textarea.tsx";
|
||||
export { Select, Option } from "./Atoms/Select/Select.tsx";
|
||||
export { Label } from "./Atoms/Label/Label";
|
||||
export { PropertyRow } from "./Atoms/PropertyRow/PropertyRow";
|
||||
export { Table, Thead, Tr, Tbody, Td, Th } from "./Atoms/Table/Table";
|
||||
export { Tabs, TabLink } from "./Atoms/Tabs/Tabs";
|
||||
export { Table, Thead, Tr, Tbody, Td, Th, TrButton } from "./Atoms/Table/Table";
|
||||
export { Tabs, TabLink, TabBadge } from "./Atoms/Tabs/Tabs";
|
||||
export { Markdown } from "./Atoms/Markdown/Markdown";
|
||||
export { Dropzone } from "./Atoms/Dropzone/Dropzone";
|
||||
export { ControlItem } from "./Atoms/ControlItem/ControlItem";
|
||||
export { InfiniteScrollTrigger } from "./Atoms/InfiniteScrollTrigger/InfiniteScrollTrigger";
|
||||
|
||||
// Molecules
|
||||
export {
|
||||
|
||||
Reference in New Issue
Block a user