Use relay and refacto public trust center

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-08-20 23:34:50 +02:00
parent 5db9b9f787
commit d31f611e63
19 changed files with 982 additions and 498 deletions

View File

@@ -0,0 +1,139 @@
import { useState } from "react";
import {
Dialog,
DialogFooter,
DialogContent,
Button,
Field,
useToast,
useDialogRef,
} from "@probo/ui";
import { useTranslate } from "@probo/i18n";
import { sprintf } from "@probo/helpers";
import { useFormWithSchema } from "/hooks/useFormWithSchema";
import { z } from "zod";
import { useMutation, graphql } from "react-relay";
import type { PublicTrustCenterAccessRequestDialogMutation } from "./__generated__/PublicTrustCenterAccessRequestDialogMutation.graphql";
const CreateTrustCenterAccessMutation = graphql`
mutation PublicTrustCenterAccessRequestDialogMutation(
$input: CreateTrustCenterAccessInput!
) {
createTrustCenterAccess(input: $input) {
trustCenterAccess {
id
email
name
}
}
}
`;
type Props = {
trigger: React.ReactNode;
trustCenterId: string;
organizationName: string;
};
export function PublicTrustCenterAccessRequestDialog({
trigger,
trustCenterId,
organizationName
}: Props) {
const { __ } = useTranslate();
const { toast } = useToast();
const [isSubmitting, setIsSubmitting] = useState(false);
const dialogRef = useDialogRef();
const [commitMutation] = useMutation<PublicTrustCenterAccessRequestDialogMutation>(CreateTrustCenterAccessMutation);
const schema = z.object({
name: z.string().min(1, __("Name is required")).min(2, __("Name must be at least 2 characters long")),
email: z.string().min(1, __("Email is required")).email(__("Please enter a valid email address")),
});
const { register, handleSubmit, formState, reset } = useFormWithSchema(schema, {
defaultValues: { name: "", email: "" },
});
const onSubmit = handleSubmit(async (data) => {
setIsSubmitting(true);
commitMutation({
variables: {
input: {
trustCenterId,
email: data.email,
name: data.name,
},
},
onCompleted: (response) => {
if (response.createTrustCenterAccess) {
toast({
title: __("Request Submitted"),
description: __("Your access request has been submitted. You will receive an email if your request is approved."),
variant: "success",
});
reset();
dialogRef.current?.close();
}
setIsSubmitting(false);
},
onError: (error) => {
const errorMessage = error.message || __("An error occurred while submitting your request.");
toast({
title: __("Request Failed"),
description: errorMessage,
variant: "error",
});
setIsSubmitting(false);
},
});
});
return (
<Dialog
ref={dialogRef}
trigger={trigger}
title={__("Request Access")}
>
<form onSubmit={onSubmit}>
<DialogContent padded className="space-y-4">
<div className="text-sm text-txt-secondary">
{sprintf(__("Request access to %s's Trust Center. Your request will be reviewed and you will receive an email notification with access instructions if approved."), organizationName)}
</div>
<Field
label={__("Your Name")}
required
error={formState.errors.name?.message}
{...register("name")}
placeholder={__("Enter your full name")}
disabled={isSubmitting}
/>
<Field
label={__("Email Address")}
required
type="email"
error={formState.errors.email?.message}
{...register("email")}
placeholder={__("Enter your email address")}
disabled={isSubmitting}
/>
</DialogContent>
<DialogFooter>
<Button
type="submit"
disabled={isSubmitting}
>
{isSubmitting ? __("Submitting...") : __("Submit Request")}
</Button>
</DialogFooter>
</form>
</Dialog>
);
}

View File

@@ -0,0 +1,133 @@
import {
Card,
Tr,
Td,
Table,
Thead,
Tbody,
Th,
Button,
IconArrowDown,
IconLock,
} from "@probo/ui";
import { useTranslate } from "@probo/i18n";
import { sprintf } from "@probo/helpers";
import { FrameworkLogo } from "/components/FrameworkLogo";
import { PublicTrustCenterAccessRequestDialog } from "./PublicTrustCenterAccessRequestDialog";
import type { TrustCenterAudit } from "../pages/PublicTrustCenterPage";
type Props = {
audits: TrustCenterAudit[];
organizationName: string;
isAuthenticated: boolean;
trustCenterId: string;
};
export function PublicTrustCenterAudits({
audits,
organizationName,
isAuthenticated,
trustCenterId
}: Props) {
const { __ } = useTranslate();
if (audits.length === 0) {
return (
<Card padded>
<div className="text-center py-8">
<h2 className="text-xl font-semibold text-txt-primary mb-2">
{__("Compliance")}
</h2>
<p className="text-txt-secondary">
{__("No compliance reports are currently available.")}
</p>
</div>
</Card>
);
}
return (
<Card padded className="space-y-4">
<div>
<h2 className="text-xl font-semibold text-txt-primary">
{__("Compliance")}
</h2>
<p className="text-sm text-txt-secondary mt-1">
{sprintf(__("%s is compliant with the following frameworks"), organizationName)}
</p>
</div>
<Table>
<Thead>
<Tr>
<Th>{__("Framework")}</Th>
<Th>{__("Report")}</Th>
</Tr>
</Thead>
<Tbody>
{audits.map((audit) => {
const hasReport = audit.report !== null;
const downloadUrl = audit.report?.downloadUrl;
const reportName = audit.report?.filename || __("Compliance Report");
return (
<Tr key={audit.id}>
<Td>
<div className="flex items-center gap-3">
<div className="flex-shrink-0">
<div className="w-8 h-8 [&>img]:w-8 [&>img]:h-8 [&>div]:w-8 [&>div]:h-8">
<FrameworkLogo name={audit.framework.name} />
</div>
</div>
<div className="font-medium">
{audit.framework.name}
</div>
</div>
</Td>
<Td>
{!hasReport ? (
<span className="text-txt-tertiary text-sm">
{__("No report")}
</span>
) : !isAuthenticated ? (
<PublicTrustCenterAccessRequestDialog
trigger={
<Button
variant="secondary"
icon={IconLock}
>
{__("Request Access")}
</Button>
}
trustCenterId={trustCenterId}
organizationName={organizationName}
/>
) : downloadUrl ? (
<Button
variant="secondary"
icon={IconArrowDown}
onClick={() => {
const link = document.createElement('a');
link.href = downloadUrl;
link.download = reportName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}}
>
{__("Download")}
</Button>
) : (
<span className="text-txt-tertiary text-sm">
{__("Not available")}
</span>
)}
</Td>
</Tr>
);
})}
</Tbody>
</Table>
</Card>
);
}

View File

@@ -0,0 +1,151 @@
import {
Card,
Tr,
Td,
Table,
Thead,
Tbody,
Th,
DocumentTypeBadge,
Button,
IconArrowDown,
IconLock,
useToast,
} from "@probo/ui";
import { useTranslate } from "@probo/i18n";
import { useMutation, graphql } from "react-relay";
import { PublicTrustCenterAccessRequestDialog } from "./PublicTrustCenterAccessRequestDialog";
import type { PublicTrustCenterDocumentsExportPDFMutation } from "./__generated__/PublicTrustCenterDocumentsExportPDFMutation.graphql";
import type { TrustCenterDocument } from "../pages/PublicTrustCenterPage";
const ExportDocumentPDFMutation = graphql`
mutation PublicTrustCenterDocumentsExportPDFMutation(
$input: ExportDocumentPDFInput!
) {
exportDocumentPDF(input: $input) {
data
}
}
`;
type Props = {
documents: TrustCenterDocument[];
isAuthenticated: boolean;
trustCenterId: string;
organizationName: string;
};
export function PublicTrustCenterDocuments({
documents,
isAuthenticated,
trustCenterId,
organizationName
}: Props) {
const { __ } = useTranslate();
const { toast } = useToast();
const [commitMutation] = useMutation<PublicTrustCenterDocumentsExportPDFMutation>(ExportDocumentPDFMutation);
const handleDownload = async (document: TrustCenterDocument) => {
commitMutation({
variables: {
input: { documentId: document.id }
},
onCompleted: (response) => {
if (response.exportDocumentPDF?.data) {
const link = window.document.createElement("a");
link.href = response.exportDocumentPDF.data;
link.download = `${document.title}.pdf`;
window.document.body.appendChild(link);
link.click();
window.document.body.removeChild(link);
}
},
onError: () => {
toast({
title: __("Download Failed"),
description: __("Unable to download the document. Please try again."),
variant: "error",
});
},
});
};
if (documents.length === 0) {
return (
<Card padded>
<div className="text-center py-8">
<h2 className="text-xl font-semibold text-txt-primary mb-2">
{__("Documents")}
</h2>
<p className="text-txt-secondary">
{__("No documents are currently available.")}
</p>
</div>
</Card>
);
}
return (
<Card padded className="space-y-4">
<div>
<h2 className="text-xl font-semibold text-txt-primary">
{__("Documents")}
</h2>
<p className="text-sm text-txt-secondary mt-1">
{__("Security and compliance documentation")}
</p>
</div>
<Table>
<Thead>
<Tr>
<Th className="w-1/2">{__("Document")}</Th>
<Th className="w-1/4">{__("Type")}</Th>
<Th className="w-1/4">{__("Download")}</Th>
</Tr>
</Thead>
<Tbody>
{documents.map((document) => {
return (
<Tr key={document.id}>
<Td>
<div className="font-medium">
{document.title}
</div>
</Td>
<Td>
<DocumentTypeBadge type={document.documentType} />
</Td>
<Td>
{!isAuthenticated ? (
<PublicTrustCenterAccessRequestDialog
trigger={
<Button
variant="secondary"
icon={IconLock}
>
{__("Request Access")}
</Button>
}
trustCenterId={trustCenterId}
organizationName={organizationName}
/>
) : (
<Button
variant="secondary"
icon={IconArrowDown}
onClick={() => handleDownload(document)}
>
{__("Download")}
</Button>
)}
</Td>
</Tr>
);
})}
</Tbody>
</Table>
</Card>
);
}

View File

@@ -0,0 +1,108 @@
import {
Card,
Tr,
Td,
Table,
Thead,
Tbody,
Th,
} from "@probo/ui";
import { useTranslate } from "@probo/i18n";
import { faviconUrl, sprintf } from "@probo/helpers";
import type { TrustCenterVendor } from "../pages/PublicTrustCenterPage";
type Props = {
vendors: TrustCenterVendor[];
organizationName: string;
};
export function PublicTrustCenterVendors({ vendors, organizationName }: Props) {
const { __ } = useTranslate();
if (vendors.length === 0) {
return (
<Card padded>
<div className="text-center py-8">
<h2 className="text-xl font-semibold text-txt-primary mb-2">
{__("Subcontractors")}
</h2>
<p className="text-txt-secondary">
{__("No subcontractor information is currently available.")}
</p>
</div>
</Card>
);
}
return (
<Card padded className="space-y-4">
<div>
<h2 className="text-xl font-semibold text-txt-primary">
{__("Subcontractors")}
</h2>
<p className="text-sm text-txt-secondary mt-1">
{sprintf(__("Third-party subcontractors %s work with"), organizationName)}
</p>
</div>
<Table>
<Thead>
<Tr>
<Th>{__("Company")}</Th>
<Th>{__("Website")}</Th>
</Tr>
</Thead>
<Tbody>
{vendors.map((vendor) => {
const url = vendor.privacyPolicyUrl || vendor.websiteUrl;
const logo = faviconUrl(vendor.websiteUrl);
const getCleanUrl = (url: string) => {
try {
const parsedUrl = new URL(url);
return parsedUrl.hostname + parsedUrl.pathname + parsedUrl.search;
} catch {
return url.replace(/^https?:\/\//, '');
}
};
return (
<Tr key={vendor.id}>
<Td>
<div className="flex items-center space-x-3">
{logo && (
<img
src={logo}
alt={`${vendor.name} logo`}
className="w-8 h-8 object-contain rounded-full"
/>
)}
<div className="font-medium">
{vendor.name}
</div>
</div>
</Td>
<Td>
{url ? (
<a
href={url}
target="_blank"
rel="noopener noreferrer"
className="text-txt-info hover:opacity-80 underline transition-opacity"
>
{getCleanUrl(url)}
</a>
) : (
<span className="text-txt-secondary text-sm">
{__("No website available")}
</span>
)}
</Td>
</Tr>
);
})}
</Tbody>
</Table>
</Card>
);
}

View File

@@ -0,0 +1,123 @@
/**
* @generated SignedSource<<4ce5109725ad53ad77aedf4d39bf463b>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type CreateTrustCenterAccessInput = {
email: string;
name: string;
trustCenterId: string;
};
export type PublicTrustCenterAccessRequestDialogMutation$variables = {
input: CreateTrustCenterAccessInput;
};
export type PublicTrustCenterAccessRequestDialogMutation$data = {
readonly createTrustCenterAccess: {
readonly trustCenterAccess: {
readonly email: string;
readonly id: string;
readonly name: string;
};
};
};
export type PublicTrustCenterAccessRequestDialogMutation = {
response: PublicTrustCenterAccessRequestDialogMutation$data;
variables: PublicTrustCenterAccessRequestDialogMutation$variables;
};
const node: ConcreteRequest = (function(){
var v0 = [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "input"
}
],
v1 = [
{
"alias": null,
"args": [
{
"kind": "Variable",
"name": "input",
"variableName": "input"
}
],
"concreteType": "CreateTrustCenterAccessPayload",
"kind": "LinkedField",
"name": "createTrustCenterAccess",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "TrustCenterAccess",
"kind": "LinkedField",
"name": "trustCenterAccess",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "email",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
];
return {
"fragment": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "PublicTrustCenterAccessRequestDialogMutation",
"selections": (v1/*: any*/),
"type": "Mutation",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "PublicTrustCenterAccessRequestDialogMutation",
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "bdc03aeaa40a243db4af3886abffb1a0",
"id": null,
"metadata": {},
"name": "PublicTrustCenterAccessRequestDialogMutation",
"operationKind": "mutation",
"text": "mutation PublicTrustCenterAccessRequestDialogMutation(\n $input: CreateTrustCenterAccessInput!\n) {\n createTrustCenterAccess(input: $input) {\n trustCenterAccess {\n id\n email\n name\n }\n }\n}\n"
}
};
})();
(node as any).hash = "d895df22aae3dcc8438bb794910cbfcc";
export default node;

View File

@@ -0,0 +1,92 @@
/**
* @generated SignedSource<<e737361b21a8767acd6a604702875029>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type ExportDocumentPDFInput = {
documentId: string;
};
export type PublicTrustCenterDocumentsExportPDFMutation$variables = {
input: ExportDocumentPDFInput;
};
export type PublicTrustCenterDocumentsExportPDFMutation$data = {
readonly exportDocumentPDF: {
readonly data: string;
};
};
export type PublicTrustCenterDocumentsExportPDFMutation = {
response: PublicTrustCenterDocumentsExportPDFMutation$data;
variables: PublicTrustCenterDocumentsExportPDFMutation$variables;
};
const node: ConcreteRequest = (function(){
var v0 = [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "input"
}
],
v1 = [
{
"alias": null,
"args": [
{
"kind": "Variable",
"name": "input",
"variableName": "input"
}
],
"concreteType": "ExportDocumentPDFPayload",
"kind": "LinkedField",
"name": "exportDocumentPDF",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "data",
"storageKey": null
}
],
"storageKey": null
}
];
return {
"fragment": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "PublicTrustCenterDocumentsExportPDFMutation",
"selections": (v1/*: any*/),
"type": "Mutation",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "PublicTrustCenterDocumentsExportPDFMutation",
"selections": (v1/*: any*/)
},
"params": {
"cacheID": "bb7c09ea21c22c0a728b18dde2449f72",
"id": null,
"metadata": {},
"name": "PublicTrustCenterDocumentsExportPDFMutation",
"operationKind": "mutation",
"text": "mutation PublicTrustCenterDocumentsExportPDFMutation(\n $input: ExportDocumentPDFInput!\n) {\n exportDocumentPDF(input: $input) {\n data\n }\n}\n"
}
};
})();
(node as any).hash = "00a3f3d260fe38b35fe33a0033cf2400";
export default node;

View File

@@ -0,0 +1,166 @@
import { useParams, Navigate } from "react-router";
import { usePageTitle } from "@probo/hooks";
import { useTranslate } from "@probo/i18n";
import { PublicTrustCenterLayout } from "/layouts/PublicTrustCenterLayout";
import { PublicTrustCenterAudits } from "../components/PublicTrustCenterAudits";
import { PublicTrustCenterVendors } from "../components/PublicTrustCenterVendors";
import { PublicTrustCenterDocuments } from "../components/PublicTrustCenterDocuments";
import { TrustRelayProvider, useTrustAuth } from "/providers/TrustRelayProvider";
import { Suspense } from "react";
import { useLazyLoadQuery } from "react-relay";
import { graphql } from "react-relay";
import { Spinner } from "@probo/ui";
import type { PublicTrustCenterPageQuery } from "./__generated__/PublicTrustCenterPageQuery.graphql";
export interface TrustCenterDocument {
id: string;
title: string;
documentType: string;
}
export interface TrustCenterAudit {
id: string;
framework: {
name: string;
};
report: {
id: string;
filename: string;
downloadUrl: string | null;
} | null;
}
export interface TrustCenterVendor {
id: string;
name: string;
category: string;
privacyPolicyUrl?: string | null;
websiteUrl?: string | null;
}
const PublicTrustCenterQuery = graphql`
query PublicTrustCenterPageQuery($slug: String!) {
trustCenterBySlug(slug: $slug) {
id
active
slug
organization {
id
name
logoUrl
}
documents(first: 100) {
edges {
node {
id
title
documentType
}
}
}
audits(first: 100) {
edges {
node {
id
framework {
name
}
report {
id
filename
downloadUrl
}
}
}
}
vendors(first: 100) {
edges {
node {
id
name
category
websiteUrl
privacyPolicyUrl
}
}
}
}
}
`;
function PublicTrustCenterContent() {
const { __ } = useTranslate();
const { slug } = useParams<{ slug: string }>();
const { isAuthenticated } = useTrustAuth();
if (!slug) {
return <Navigate to="/" replace />;
}
const data = useLazyLoadQuery<PublicTrustCenterPageQuery>(PublicTrustCenterQuery, { slug });
const organization = data?.trustCenterBySlug?.organization;
const organizationName = organization?.name || "";
usePageTitle(
organizationName ? `${organizationName} - Trust Center` : "Trust Center"
);
if (!data?.trustCenterBySlug) {
return (
<div className="flex items-center justify-center min-h-screen">
<div className="text-center">
<h1 className="text-2xl font-bold text-gray-900 mb-2">
{__("Trust Center Not Found")}
</h1>
<p className="text-gray-600">
{__("The trust center you're looking for doesn't exist.")}
</p>
</div>
</div>
);
}
const { documents, audits, vendors } = data.trustCenterBySlug;
const trustCenterDocuments = documents.edges.map((edge) => edge.node) as TrustCenterDocument[];
const trustCenterAudits = audits.edges.map((edge) => edge.node) as TrustCenterAudit[];
const trustCenterVendors = vendors.edges.map((edge) => edge.node) as TrustCenterVendor[];
return (
<PublicTrustCenterLayout
organizationName={organizationName}
organizationLogo={organization?.logoUrl}
isAuthenticated={isAuthenticated}
>
<div className="space-y-12">
<PublicTrustCenterAudits
audits={trustCenterAudits}
organizationName={organizationName}
isAuthenticated={isAuthenticated}
trustCenterId={data.trustCenterBySlug.id}
/>
<PublicTrustCenterDocuments
documents={trustCenterDocuments}
organizationName={organizationName}
isAuthenticated={isAuthenticated}
trustCenterId={data.trustCenterBySlug.id}
/>
<PublicTrustCenterVendors
vendors={trustCenterVendors}
organizationName={organizationName}
/>
</div>
</PublicTrustCenterLayout>
);
}
export default function PublicTrustCenterPage() {
return (
<TrustRelayProvider>
<Suspense fallback={<Spinner />}>
<PublicTrustCenterContent />
</Suspense>
</TrustRelayProvider>
);
}

View File

@@ -0,0 +1,430 @@
/**
* @generated SignedSource<<7510cf085d283274b579e0571eb503c4>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from 'relay-runtime';
export type DocumentType = "ISMS" | "OTHER" | "POLICY";
export type VendorCategory = "ANALYTICS" | "CLOUD_MONITORING" | "CLOUD_PROVIDER" | "COLLABORATION" | "CUSTOMER_SUPPORT" | "DATA_STORAGE_AND_PROCESSING" | "DOCUMENT_MANAGEMENT" | "EMPLOYEE_MANAGEMENT" | "ENGINEERING" | "FINANCE" | "IDENTITY_PROVIDER" | "IT" | "MARKETING" | "OFFICE_OPERATIONS" | "OTHER" | "PASSWORD_MANAGEMENT" | "PRODUCT_AND_DESIGN" | "PROFESSIONAL_SERVICES" | "RECRUITING" | "SALES" | "SECURITY" | "VERSION_CONTROL";
export type PublicTrustCenterPageQuery$variables = {
slug: string;
};
export type PublicTrustCenterPageQuery$data = {
readonly trustCenterBySlug: {
readonly active: boolean;
readonly audits: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly framework: {
readonly name: string;
};
readonly id: string;
readonly report: {
readonly downloadUrl: string | null | undefined;
readonly filename: string;
readonly id: string;
} | null | undefined;
};
}>;
};
readonly documents: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly documentType: DocumentType;
readonly id: string;
readonly title: string;
};
}>;
};
readonly id: string;
readonly organization: {
readonly id: string;
readonly logoUrl: string | null | undefined;
readonly name: string;
};
readonly slug: string;
readonly vendors: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly category: VendorCategory;
readonly id: string;
readonly name: string;
readonly privacyPolicyUrl: string | null | undefined;
readonly websiteUrl: string | null | undefined;
};
}>;
};
} | null | undefined;
};
export type PublicTrustCenterPageQuery = {
response: PublicTrustCenterPageQuery$data;
variables: PublicTrustCenterPageQuery$variables;
};
const node: ConcreteRequest = (function(){
var v0 = [
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "slug"
}
],
v1 = [
{
"kind": "Variable",
"name": "slug",
"variableName": "slug"
}
],
v2 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
v3 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "active",
"storageKey": null
},
v4 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "slug",
"storageKey": null
},
v5 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
},
v6 = {
"alias": null,
"args": null,
"concreteType": "Organization",
"kind": "LinkedField",
"name": "organization",
"plural": false,
"selections": [
(v2/*: any*/),
(v5/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "logoUrl",
"storageKey": null
}
],
"storageKey": null
},
v7 = [
{
"kind": "Literal",
"name": "first",
"value": 100
}
],
v8 = {
"alias": null,
"args": (v7/*: 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
}
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": "documents(first:100)"
},
v9 = {
"alias": null,
"args": null,
"concreteType": "Report",
"kind": "LinkedField",
"name": "report",
"plural": false,
"selections": [
(v2/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "filename",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "downloadUrl",
"storageKey": null
}
],
"storageKey": null
},
v10 = {
"alias": null,
"args": (v7/*: any*/),
"concreteType": "VendorConnection",
"kind": "LinkedField",
"name": "vendors",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "VendorEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Vendor",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v2/*: any*/),
(v5/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "category",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "websiteUrl",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "privacyPolicyUrl",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": "vendors(first:100)"
};
return {
"fragment": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Fragment",
"metadata": null,
"name": "PublicTrustCenterPageQuery",
"selections": [
{
"alias": null,
"args": (v1/*: any*/),
"concreteType": "TrustCenter",
"kind": "LinkedField",
"name": "trustCenterBySlug",
"plural": false,
"selections": [
(v2/*: any*/),
(v3/*: any*/),
(v4/*: any*/),
(v6/*: any*/),
(v8/*: any*/),
{
"alias": null,
"args": (v7/*: any*/),
"concreteType": "AuditConnection",
"kind": "LinkedField",
"name": "audits",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "AuditEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Audit",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v2/*: any*/),
{
"alias": null,
"args": null,
"concreteType": "Framework",
"kind": "LinkedField",
"name": "framework",
"plural": false,
"selections": [
(v5/*: any*/)
],
"storageKey": null
},
(v9/*: any*/)
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": "audits(first:100)"
},
(v10/*: any*/)
],
"storageKey": null
}
],
"type": "Query",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "PublicTrustCenterPageQuery",
"selections": [
{
"alias": null,
"args": (v1/*: any*/),
"concreteType": "TrustCenter",
"kind": "LinkedField",
"name": "trustCenterBySlug",
"plural": false,
"selections": [
(v2/*: any*/),
(v3/*: any*/),
(v4/*: any*/),
(v6/*: any*/),
(v8/*: any*/),
{
"alias": null,
"args": (v7/*: any*/),
"concreteType": "AuditConnection",
"kind": "LinkedField",
"name": "audits",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "AuditEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "Audit",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v2/*: any*/),
{
"alias": null,
"args": null,
"concreteType": "Framework",
"kind": "LinkedField",
"name": "framework",
"plural": false,
"selections": [
(v5/*: any*/),
(v2/*: any*/)
],
"storageKey": null
},
(v9/*: any*/)
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": "audits(first:100)"
},
(v10/*: any*/)
],
"storageKey": null
}
]
},
"params": {
"cacheID": "9d0437e87c7c88083619611892bcc422",
"id": null,
"metadata": {},
"name": "PublicTrustCenterPageQuery",
"operationKind": "query",
"text": "query PublicTrustCenterPageQuery(\n $slug: String!\n) {\n trustCenterBySlug(slug: $slug) {\n id\n active\n slug\n organization {\n id\n name\n logoUrl\n }\n documents(first: 100) {\n edges {\n node {\n id\n title\n documentType\n }\n }\n }\n audits(first: 100) {\n edges {\n node {\n id\n framework {\n name\n id\n }\n report {\n id\n filename\n downloadUrl\n }\n }\n }\n }\n vendors(first: 100) {\n edges {\n node {\n id\n name\n category\n websiteUrl\n privacyPolicyUrl\n }\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "7fc4b49f2a965be237cf3d51baa815bd";
export default node;