Rename portal and trust frontends

Update visitor-facing apps to Compliance Portal
types, hooks, and resolvers so they match the
backend GraphQL rename.

Signed-off-by: Bryan Frimin <bryan@probo.com>
This commit is contained in:
Bryan Frimin
2026-07-20 18:08:35 +02:00
parent 53cc6c487e
commit d914cb9ac7
42 changed files with 295 additions and 295 deletions

View File

@@ -25,14 +25,14 @@ import { graphql, useFragment } from "react-relay";
import { InlineErrorCard } from "#/components/errors/InlineErrorCard"; import { InlineErrorCard } from "#/components/errors/InlineErrorCard";
import { HomeSection } from "#/components/HomeSection/HomeSection"; import { HomeSection } from "#/components/HomeSection/HomeSection";
import type { ComplianceFrameworksSection_trustCenter$key } from "./__generated__/ComplianceFrameworksSection_trustCenter.graphql"; import type { ComplianceFrameworksSection_compliancePortal$key } from "./__generated__/ComplianceFrameworksSection_compliancePortal.graphql";
import { ComplianceFrameworkListItem } from "./ComplianceFrameworkListItem"; import { ComplianceFrameworkListItem } from "./ComplianceFrameworkListItem";
// @throwOnFieldError makes a field error in this fragment throw at the read // @throwOnFieldError makes a field error in this fragment throw at the read
// below, where the section's ErrorBoundary contains it. See // below, where the section's ErrorBoundary contains it. See
// contrib/claude/error-handling.md. // contrib/claude/error-handling.md.
const complianceFrameworksSectionFragment = graphql` const complianceFrameworksSectionFragment = graphql`
fragment ComplianceFrameworksSection_trustCenter on TrustCenter @throwOnFieldError { fragment ComplianceFrameworksSection_compliancePortal on CompliancePortal @throwOnFieldError {
complianceFrameworks(first: 8) { complianceFrameworks(first: 8) {
edges { edges {
node { node {
@@ -45,13 +45,13 @@ const complianceFrameworksSectionFragment = graphql`
`; `;
interface ComplianceFrameworksSectionProps { interface ComplianceFrameworksSectionProps {
trustCenterKey: ComplianceFrameworksSection_trustCenter$key; compliancePortalKey: ComplianceFrameworksSection_compliancePortal$key;
} }
// "Compliance" section: the grid of certification frameworks the trust center // "Compliance" section: the grid of certification frameworks the compliance portal
// covers. Wraps its data-reading content in a boundary so a load failure // covers. Wraps its data-reading content in a boundary so a load failure
// degrades to an inline error instead of taking down the page. // degrades to an inline error instead of taking down the page.
export function ComplianceFrameworksSection({ trustCenterKey }: ComplianceFrameworksSectionProps) { export function ComplianceFrameworksSection({ compliancePortalKey }: ComplianceFrameworksSectionProps) {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
@@ -64,14 +64,14 @@ export function ComplianceFrameworksSection({ trustCenterKey }: ComplianceFramew
</HomeSection> </HomeSection>
)} )}
> >
<ComplianceFrameworksSectionContent trustCenterKey={trustCenterKey} /> <ComplianceFrameworksSectionContent compliancePortalKey={compliancePortalKey} />
</ErrorBoundary> </ErrorBoundary>
); );
} }
function ComplianceFrameworksSectionContent({ trustCenterKey }: ComplianceFrameworksSectionProps) { function ComplianceFrameworksSectionContent({ compliancePortalKey }: ComplianceFrameworksSectionProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const data = useFragment(complianceFrameworksSectionFragment, trustCenterKey); const data = useFragment(complianceFrameworksSectionFragment, compliancePortalKey);
const frameworks = data.complianceFrameworks.edges.map(edge => edge.node); const frameworks = data.complianceFrameworks.edges.map(edge => edge.node);
if (frameworks.length === 0) { if (frameworks.length === 0) {

View File

@@ -24,29 +24,29 @@ import { graphql, useFragment } from "react-relay";
import { externalHref, hostnameOf } from "#/lib/url/hostname"; import { externalHref, hostnameOf } from "#/lib/url/hostname";
import type { TrustCenterContactInfo_trustCenter$key } from "./__generated__/TrustCenterContactInfo_trustCenter.graphql"; import type { CompliancePortalContactInfo_compliancePortal$key } from "./__generated__/CompliancePortalContactInfo_compliancePortal.graphql";
import { organizationContactInfo } from "./variants"; import { organizationContactInfo } from "./variants";
const trustCenterContactInfoFragment = graphql` const compliancePortalContactInfoFragment = graphql`
fragment TrustCenterContactInfo_trustCenter on TrustCenter { fragment CompliancePortalContactInfo_compliancePortal on CompliancePortal {
websiteUrl websiteUrl
email email
headquarterAddress headquarterAddress
} }
`; `;
interface TrustCenterContactInfoProps { interface CompliancePortalContactInfoProps {
trustCenterKey: TrustCenterContactInfo_trustCenter$key; compliancePortalKey: CompliancePortalContactInfo_compliancePortal$key;
} }
// Trust center contact details (website, email, HQ) rendered as an icon + label // Compliance portal contact details (website, email, HQ) rendered as an icon +
// row. Owns its fragment so it can be reused wherever the trust center is in scope. // label row. Owns its fragment so it can be reused wherever the portal is in scope.
export function TrustCenterContactInfo({ trustCenterKey }: TrustCenterContactInfoProps) { export function CompliancePortalContactInfo({ compliancePortalKey }: CompliancePortalContactInfoProps) {
const trustCenter = useFragment(trustCenterContactInfoFragment, trustCenterKey); const compliancePortal = useFragment(compliancePortalContactInfoFragment, compliancePortalKey);
const hasWebsite = trustCenter.websiteUrl != null && trustCenter.websiteUrl !== ""; const hasWebsite = compliancePortal.websiteUrl != null && compliancePortal.websiteUrl !== "";
const hasEmail = trustCenter.email != null && trustCenter.email !== ""; const hasEmail = compliancePortal.email != null && compliancePortal.email !== "";
const hasAddress = trustCenter.headquarterAddress != null && trustCenter.headquarterAddress !== ""; const hasAddress = compliancePortal.headquarterAddress != null && compliancePortal.headquarterAddress !== "";
// Nothing to show — render no row (and therefore no divider) at all. // Nothing to show — render no row (and therefore no divider) at all.
if (!hasWebsite && !hasEmail && !hasAddress) { if (!hasWebsite && !hasEmail && !hasAddress) {
@@ -60,21 +60,21 @@ export function TrustCenterContactInfo({ trustCenterKey }: TrustCenterContactInf
{hasWebsite && ( {hasWebsite && (
<a <a
className={link()} className={link()}
href={externalHref(trustCenter.websiteUrl)} href={externalHref(compliancePortal.websiteUrl)}
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
<GlobeSimpleIcon /> <GlobeSimpleIcon />
<Text size={2} color="neutral"> <Text size={2} color="neutral">
{hostnameOf(trustCenter.websiteUrl)} {hostnameOf(compliancePortal.websiteUrl)}
</Text> </Text>
</a> </a>
)} )}
{hasEmail && ( {hasEmail && (
<a className={link()} href={`mailto:${trustCenter.email}`}> <a className={link()} href={`mailto:${compliancePortal.email}`}>
<EnvelopeIcon /> <EnvelopeIcon />
<Text size={2} color="neutral"> <Text size={2} color="neutral">
{trustCenter.email} {compliancePortal.email}
</Text> </Text>
</a> </a>
)} )}
@@ -82,7 +82,7 @@ export function TrustCenterContactInfo({ trustCenterKey }: TrustCenterContactInf
<div className={item()}> <div className={item()}>
<MapPinSimpleIcon /> <MapPinSimpleIcon />
<Text size={2} color="neutral"> <Text size={2} color="neutral">
{trustCenter.headquarterAddress} {compliancePortal.headquarterAddress}
</Text> </Text>
</div> </div>
)} )}

View File

@@ -38,7 +38,7 @@ export interface PageHeaderProps {
flushBottomSpace?: boolean; flushBottomSpace?: boolean;
} }
// Page header for the Trust Center nav pages: a size-7 title in the shared white // Page header for the Compliance Portal nav pages: a size-7 title in the shared white
// band, with an optional count, inline actions, and a toolbar slot below. // band, with an optional count, inline actions, and a toolbar slot below.
export function PageHeader({ title, count, actions, children, flushBottomSpace }: PageHeaderProps) { export function PageHeader({ title, count, actions, children, flushBottomSpace }: PageHeaderProps) {
const { content, titleRow, count: countSlot } = pageHeader(); const { content, titleRow, count: countSlot } = pageHeader();

View File

@@ -28,12 +28,12 @@ import { HomeSection } from "#/components/HomeSection/HomeSection";
import { MailingListUpdateListItem } from "#/components/MailingListUpdateListItem/MailingListUpdateListItem"; import { MailingListUpdateListItem } from "#/components/MailingListUpdateListItem/MailingListUpdateListItem";
import { dotPatternStyle } from "#/components/MediaTile/variants"; import { dotPatternStyle } from "#/components/MediaTile/variants";
import type { RecentUpdatesSection_trustCenter$key } from "./__generated__/RecentUpdatesSection_trustCenter.graphql"; import type { RecentUpdatesSection_compliancePortal$key } from "./__generated__/RecentUpdatesSection_compliancePortal.graphql";
// @throwOnFieldError surfaces a field error at the read below so the section // @throwOnFieldError surfaces a field error at the read below so the section
// ErrorBoundary contains it. See contrib/claude/error-handling.md. // ErrorBoundary contains it. See contrib/claude/error-handling.md.
const recentUpdatesSectionFragment = graphql` const recentUpdatesSectionFragment = graphql`
fragment RecentUpdatesSection_trustCenter on TrustCenter @throwOnFieldError { fragment RecentUpdatesSection_compliancePortal on CompliancePortal @throwOnFieldError {
updates(first: 5) { updates(first: 5) {
edges { edges {
node { node {
@@ -46,12 +46,12 @@ const recentUpdatesSectionFragment = graphql`
`; `;
interface RecentUpdatesSectionProps { interface RecentUpdatesSectionProps {
trustCenterKey: RecentUpdatesSection_trustCenter$key; compliancePortalKey: RecentUpdatesSection_compliancePortal$key;
} }
// "Recent updates" section: the latest mailing-list updates as a list, with a // "Recent updates" section: the latest mailing-list updates as a list, with a
// link to the full updates page. A load failure degrades to an inline error. // link to the full updates page. A load failure degrades to an inline error.
export function RecentUpdatesSection({ trustCenterKey }: RecentUpdatesSectionProps) { export function RecentUpdatesSection({ compliancePortalKey }: RecentUpdatesSectionProps) {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
@@ -64,14 +64,14 @@ export function RecentUpdatesSection({ trustCenterKey }: RecentUpdatesSectionPro
</HomeSection> </HomeSection>
)} )}
> >
<RecentUpdatesSectionContent trustCenterKey={trustCenterKey} /> <RecentUpdatesSectionContent compliancePortalKey={compliancePortalKey} />
</ErrorBoundary> </ErrorBoundary>
); );
} }
function RecentUpdatesSectionContent({ trustCenterKey }: RecentUpdatesSectionProps) { function RecentUpdatesSectionContent({ compliancePortalKey }: RecentUpdatesSectionProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const data = useFragment(recentUpdatesSectionFragment, trustCenterKey); const data = useFragment(recentUpdatesSectionFragment, compliancePortalKey);
const updates = data.updates.edges.map(edge => edge.node); const updates = data.updates.edges.map(edge => edge.node);
if (updates.length === 0) { if (updates.length === 0) {

View File

@@ -23,7 +23,7 @@ import { graphql, useFragment } from "react-relay";
import { InlineErrorCard } from "#/components/errors/InlineErrorCard"; import { InlineErrorCard } from "#/components/errors/InlineErrorCard";
import type { SecurityCommitmentsSection_trustCenter$key } from "./__generated__/SecurityCommitmentsSection_trustCenter.graphql"; import type { SecurityCommitmentsSection_compliancePortal$key } from "./__generated__/SecurityCommitmentsSection_compliancePortal.graphql";
import { SecurityCommitmentGroupListItem } from "./SecurityCommitmentGroupListItem"; import { SecurityCommitmentGroupListItem } from "./SecurityCommitmentGroupListItem";
import { securityCommitments } from "./variants"; import { securityCommitments } from "./variants";
@@ -31,7 +31,7 @@ import { securityCommitments } from "./variants";
// below, where the section's ErrorBoundary contains it. See // below, where the section's ErrorBoundary contains it. See
// contrib/claude/error-handling.md. // contrib/claude/error-handling.md.
const securityCommitmentsSectionFragment = graphql` const securityCommitmentsSectionFragment = graphql`
fragment SecurityCommitmentsSection_trustCenter on TrustCenter @throwOnFieldError { fragment SecurityCommitmentsSection_compliancePortal on CompliancePortal @throwOnFieldError {
commitmentGroups(first: 100) { commitmentGroups(first: 100) {
edges { edges {
node { node {
@@ -53,13 +53,13 @@ const securityCommitmentsSectionFragment = graphql`
`; `;
interface SecurityCommitmentsSectionProps { interface SecurityCommitmentsSectionProps {
trustCenterKey: SecurityCommitmentsSection_trustCenter$key; compliancePortalKey: SecurityCommitmentsSection_compliancePortal$key;
} }
// "Security Commitments" section: stacked groups, each a header above a grid of // "Security Commitments" section: stacked groups, each a header above a grid of
// commitment cards. Wraps its data-reading content in a boundary so a load // commitment cards. Wraps its data-reading content in a boundary so a load
// failure degrades to an inline error instead of taking down the page. // failure degrades to an inline error instead of taking down the page.
export function SecurityCommitmentsSection({ trustCenterKey }: SecurityCommitmentsSectionProps) { export function SecurityCommitmentsSection({ compliancePortalKey }: SecurityCommitmentsSectionProps) {
return ( return (
<ErrorBoundary <ErrorBoundary
fallback={( fallback={(
@@ -68,13 +68,13 @@ export function SecurityCommitmentsSection({ trustCenterKey }: SecurityCommitmen
</div> </div>
)} )}
> >
<SecurityCommitmentsSectionContent trustCenterKey={trustCenterKey} /> <SecurityCommitmentsSectionContent compliancePortalKey={compliancePortalKey} />
</ErrorBoundary> </ErrorBoundary>
); );
} }
function SecurityCommitmentsSectionContent({ trustCenterKey }: SecurityCommitmentsSectionProps) { function SecurityCommitmentsSectionContent({ compliancePortalKey }: SecurityCommitmentsSectionProps) {
const data = useFragment(securityCommitmentsSectionFragment, trustCenterKey); const data = useFragment(securityCommitmentsSectionFragment, compliancePortalKey);
const slots = securityCommitments(); const slots = securityCommitments();
// Groups with no cards render nothing, so filter them out here to keep the // Groups with no cards render nothing, so filter them out here to keep the

View File

@@ -41,7 +41,7 @@ const topBarFragment = graphql`
...TopBarUserMenu_identity ...TopBarUserMenu_identity
...TopBarMobileNav_identity ...TopBarMobileNav_identity
} }
currentTrustCenter @required(action: THROW) { currentCompliancePortal @required(action: THROW) {
themedLogoUrl themedLogoUrl
title title
} }
@@ -62,9 +62,9 @@ export function TopBar({ queryKey }: TopBarProps) {
const location = useLocation(); const location = useLocation();
const { pathname } = location; const { pathname } = location;
const { currentTrustCenter } = data; const { currentCompliancePortal } = data;
const title = currentTrustCenter.title; const title = currentCompliancePortal.title;
const logoUrl = currentTrustCenter.themedLogoUrl ?? undefined; const logoUrl = currentCompliancePortal.themedLogoUrl ?? undefined;
const slots = topBar(); const slots = topBar();

View File

@@ -20,7 +20,7 @@
import { tv } from "tailwind-variants/lite"; import { tv } from "tailwind-variants/lite";
// Trust Center top navigation bar. Slots are shared by the live TopBar and its // Compliance Portal top navigation bar. Slots are shared by the live TopBar and its
// skeleton so the loading placeholder is structurally identical. Desktop-first: // skeleton so the loading placeholder is structurally identical. Desktop-first:
// unprefixed classes are the desktop layout; max-md: collapses into the burger. // unprefixed classes are the desktop layout; max-md: collapses into the burger.
export const topBar = tv({ export const topBar = tv({

View File

@@ -24,10 +24,10 @@ import { graphql, useFragment } from "react-relay";
import { MediaTile } from "#/components/MediaTile/MediaTile"; import { MediaTile } from "#/components/MediaTile/MediaTile";
import { externalHref } from "#/lib/url/hostname"; import { externalHref } from "#/lib/url/hostname";
import type { TrustCenterReferenceListItem_reference$key } from "./__generated__/TrustCenterReferenceListItem_reference.graphql"; import type { CompliancePortalReferenceListItem_reference$key } from "./__generated__/CompliancePortalReferenceListItem_reference.graphql";
const trustCenterReferenceListItemFragment = graphql` const compliancePortalReferenceListItemFragment = graphql`
fragment TrustCenterReferenceListItem_reference on TrustCenterReference @throwOnFieldError { fragment CompliancePortalReferenceListItem_reference on CompliancePortalReference @throwOnFieldError {
name name
websiteUrl websiteUrl
logo { logo {
@@ -36,13 +36,13 @@ const trustCenterReferenceListItemFragment = graphql`
} }
`; `;
interface TrustCenterReferenceListItemProps { interface CompliancePortalReferenceListItemProps {
referenceKey: TrustCenterReferenceListItem_reference$key; referenceKey: CompliancePortalReferenceListItem_reference$key;
} }
// A single "Trusted by" logo tile, linking to the reference's website. // A single "Trusted by" logo tile, linking to the reference's website.
export function TrustCenterReferenceListItem({ referenceKey }: TrustCenterReferenceListItemProps) { export function CompliancePortalReferenceListItem({ referenceKey }: CompliancePortalReferenceListItemProps) {
const reference = useFragment(trustCenterReferenceListItemFragment, referenceKey); const reference = useFragment(compliancePortalReferenceListItemFragment, referenceKey);
return ( return (
<a <a

View File

@@ -25,18 +25,18 @@ import { graphql, useFragment } from "react-relay";
import { InlineErrorCard } from "#/components/errors/InlineErrorCard"; import { InlineErrorCard } from "#/components/errors/InlineErrorCard";
import { HomeSection } from "#/components/HomeSection/HomeSection"; import { HomeSection } from "#/components/HomeSection/HomeSection";
import type { TrustedBySection_trustCenter$key } from "./__generated__/TrustedBySection_trustCenter.graphql"; import type { TrustedBySection_compliancePortal$key } from "./__generated__/TrustedBySection_compliancePortal.graphql";
import { TrustCenterReferenceListItem } from "./TrustCenterReferenceListItem"; import { CompliancePortalReferenceListItem } from "./CompliancePortalReferenceListItem";
// @throwOnFieldError surfaces a field error at the read below so the section // @throwOnFieldError surfaces a field error at the read below so the section
// ErrorBoundary contains it. See contrib/claude/error-handling.md. // ErrorBoundary contains it. See contrib/claude/error-handling.md.
const trustedBySectionFragment = graphql` const trustedBySectionFragment = graphql`
fragment TrustedBySection_trustCenter on TrustCenter @throwOnFieldError { fragment TrustedBySection_compliancePortal on CompliancePortal @throwOnFieldError {
references(first: 12) { references(first: 12) {
edges { edges {
node { node {
id id
...TrustCenterReferenceListItem_reference ...CompliancePortalReferenceListItem_reference
} }
} }
} }
@@ -44,12 +44,12 @@ const trustedBySectionFragment = graphql`
`; `;
interface TrustedBySectionProps { interface TrustedBySectionProps {
trustCenterKey: TrustedBySection_trustCenter$key; compliancePortalKey: TrustedBySection_compliancePortal$key;
} }
// "Trusted by" section: a grid of customer / reference logos. A load failure // "Trusted by" section: a grid of customer / reference logos. A load failure
// degrades to an inline error instead of taking down the page. // degrades to an inline error instead of taking down the page.
export function TrustedBySection({ trustCenterKey }: TrustedBySectionProps) { export function TrustedBySection({ compliancePortalKey }: TrustedBySectionProps) {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
@@ -62,14 +62,14 @@ export function TrustedBySection({ trustCenterKey }: TrustedBySectionProps) {
</HomeSection> </HomeSection>
)} )}
> >
<TrustedBySectionContent trustCenterKey={trustCenterKey} /> <TrustedBySectionContent compliancePortalKey={compliancePortalKey} />
</ErrorBoundary> </ErrorBoundary>
); );
} }
function TrustedBySectionContent({ trustCenterKey }: TrustedBySectionProps) { function TrustedBySectionContent({ compliancePortalKey }: TrustedBySectionProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const data = useFragment(trustedBySectionFragment, trustCenterKey); const data = useFragment(trustedBySectionFragment, compliancePortalKey);
const references = data.references.edges.map(edge => edge.node); const references = data.references.edges.map(edge => edge.node);
if (references.length === 0) { if (references.length === 0) {
@@ -80,7 +80,7 @@ function TrustedBySectionContent({ trustCenterKey }: TrustedBySectionProps) {
<HomeSection title={t("home.sections.trustedBy")}> <HomeSection title={t("home.sections.trustedBy")}>
<div className="grid grid-cols-6 gap-4 max-lg:grid-cols-3 max-sm:grid-cols-2"> <div className="grid grid-cols-6 gap-4 max-lg:grid-cols-3 max-sm:grid-cols-2">
{references.map(reference => ( {references.map(reference => (
<TrustCenterReferenceListItem key={reference.id} referenceKey={reference} /> <CompliancePortalReferenceListItem key={reference.id} referenceKey={reference} />
))} ))}
</div> </div>
</HomeSection> </HomeSection>

View File

@@ -44,7 +44,7 @@ import type { useResumeAccessRequestMutation } from "./__generated__/useResumeAc
const requestAllAccessesMutation = graphql` const requestAllAccessesMutation = graphql`
mutation useResumeAccessRequestMutation { mutation useResumeAccessRequestMutation {
requestAllAccesses { requestAllAccesses {
trustCenterAccess { compliancePortalAccess {
id id
} }
} }
@@ -83,8 +83,8 @@ const requestReportMutation = graphql`
`; `;
const requestFileMutation = graphql` const requestFileMutation = graphql`
mutation useResumeAccessRequest_fileMutation($input: RequestTrustCenterFileAccessInput!) { mutation useResumeAccessRequest_fileMutation($input: RequestCompliancePortalFileAccessInput!) {
requestTrustCenterFileAccess(input: $input) { requestCompliancePortalFileAccess(input: $input) {
file { file {
id id
access { access {
@@ -194,7 +194,7 @@ export function useResumeAccessRequest(isAuthenticated: boolean) {
const continueUrl = buildRequestAccessContinueUrl(REQUEST_FILE_PARAM, fileId); const continueUrl = buildRequestAccessContinueUrl(REQUEST_FILE_PARAM, fileId);
clear(REQUEST_FILE_PARAM); clear(REQUEST_FILE_PARAM);
void requestFileAccess({ void requestFileAccess({
variables: { input: { trustCenterFileId: fileId } }, variables: { input: { compliancePortalFileId: fileId } },
...makeHandlers(continueUrl), ...makeHandlers(continueUrl),
}).catch(() => {}); }).catch(() => {});
return; return;

View File

@@ -21,7 +21,7 @@
import { graphql } from "react-relay"; import { graphql } from "react-relay";
import { type LiveState, readFragment } from "relay-runtime"; import { type LiveState, readFragment } from "relay-runtime";
import type { TrustCenterLogoResolverFragment$key } from "./__generated__/TrustCenterLogoResolverFragment.graphql"; import type { CompliancePortalLogoResolverFragment$key } from "./__generated__/CompliancePortalLogoResolverFragment.graphql";
function prefersDark(): boolean { function prefersDark(): boolean {
return typeof window !== "undefined" return typeof window !== "undefined"
@@ -30,21 +30,21 @@ function prefersDark(): boolean {
} }
/** /**
* @relayField TrustCenter.themedLogoUrl: String * @relayField CompliancePortal.themedLogoUrl: String
* @rootFragment TrustCenterLogoResolverFragment * @rootFragment CompliancePortalLogoResolverFragment
* @live * @live
* *
* Resolves the trust center logo download URL for the current system color * Resolves the compliance portal logo download URL for the current system color
* scheme: the dark logo (falling back to the light one) when the OS prefers * scheme: the dark logo (falling back to the light one) when the OS prefers
* dark, otherwise the light logo. Lives in the graph so consumers select a * dark, otherwise the light logo. Lives in the graph so consumers select a
* single field instead of threading `useSystemTheme` through URL selection. * single field instead of threading `useSystemTheme` through URL selection.
*/ */
export function themedLogoUrl( export function themedLogoUrl(
key: TrustCenterLogoResolverFragment$key, key: CompliancePortalLogoResolverFragment$key,
): LiveState<string | null> { ): LiveState<string | null> {
const data = readFragment( const data = readFragment(
graphql` graphql`
fragment TrustCenterLogoResolverFragment on TrustCenter { fragment CompliancePortalLogoResolverFragment on CompliancePortal {
logo { logo {
downloadUrl downloadUrl
} }

View File

@@ -24,7 +24,7 @@ import { graphql, usePreloadedQuery } from "react-relay";
import { ComplianceFrameworksSection } from "#/components/ComplianceFrameworks/ComplianceFrameworksSection"; import { ComplianceFrameworksSection } from "#/components/ComplianceFrameworks/ComplianceFrameworksSection";
import { Hero } from "#/components/Hero/Hero"; import { Hero } from "#/components/Hero/Hero";
import { TrustCenterContactInfo } from "#/components/Hero/TrustCenterContactInfo"; import { CompliancePortalContactInfo } from "#/components/Hero/CompliancePortalContactInfo";
import { RecentUpdatesSection } from "#/components/RecentUpdates/RecentUpdatesSection"; import { RecentUpdatesSection } from "#/components/RecentUpdates/RecentUpdatesSection";
import { SecurityCommitmentsSection } from "#/components/SecurityCommitments/SecurityCommitmentsSection"; import { SecurityCommitmentsSection } from "#/components/SecurityCommitments/SecurityCommitmentsSection";
import { TrustedBySection } from "#/components/TrustedBy/TrustedBySection"; import { TrustedBySection } from "#/components/TrustedBy/TrustedBySection";
@@ -33,13 +33,13 @@ import type { HomePageQuery } from "./__generated__/HomePageQuery.graphql";
export const homePageQuery = graphql` export const homePageQuery = graphql`
query HomePageQuery @throwOnFieldError { query HomePageQuery @throwOnFieldError {
currentTrustCenter @required(action: THROW) { currentCompliancePortal @required(action: THROW) {
title title
...TrustCenterContactInfo_trustCenter ...CompliancePortalContactInfo_compliancePortal
...ComplianceFrameworksSection_trustCenter ...ComplianceFrameworksSection_compliancePortal
...SecurityCommitmentsSection_trustCenter ...SecurityCommitmentsSection_compliancePortal
...TrustedBySection_trustCenter ...TrustedBySection_compliancePortal
...RecentUpdatesSection_trustCenter ...RecentUpdatesSection_compliancePortal
} }
} }
`; `;
@@ -51,8 +51,8 @@ interface HomePageProps {
export function HomePage({ queryRef }: HomePageProps) { export function HomePage({ queryRef }: HomePageProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const data = usePreloadedQuery<HomePageQuery>(homePageQuery, queryRef); const data = usePreloadedQuery<HomePageQuery>(homePageQuery, queryRef);
const { currentTrustCenter } = data; const { currentCompliancePortal } = data;
const { title } = currentTrustCenter; const { title } = currentCompliancePortal;
return ( return (
<> <>
@@ -60,14 +60,14 @@ export function HomePage({ queryRef }: HomePageProps) {
title={t("home.heroTitle", { name: title })} title={t("home.heroTitle", { name: title })}
description={t("home.heroDescription")} description={t("home.heroDescription")}
> >
<TrustCenterContactInfo trustCenterKey={currentTrustCenter} /> <CompliancePortalContactInfo compliancePortalKey={currentCompliancePortal} />
</Hero> </Hero>
<div className="flex w-full flex-col items-center px-8 max-md:px-4"> <div className="flex w-full flex-col items-center px-8 max-md:px-4">
<div className="flex w-full max-w-5xl flex-col"> <div className="flex w-full max-w-5xl flex-col">
<ComplianceFrameworksSection trustCenterKey={currentTrustCenter} /> <ComplianceFrameworksSection compliancePortalKey={currentCompliancePortal} />
<SecurityCommitmentsSection trustCenterKey={currentTrustCenter} /> <SecurityCommitmentsSection compliancePortalKey={currentCompliancePortal} />
<TrustedBySection trustCenterKey={currentTrustCenter} /> <TrustedBySection compliancePortalKey={currentCompliancePortal} />
<RecentUpdatesSection trustCenterKey={currentTrustCenter} /> <RecentUpdatesSection compliancePortalKey={currentCompliancePortal} />
</div> </div>
</div> </div>
</> </>

View File

@@ -37,7 +37,7 @@ export const documentViewerPageQuery = graphql`
title title
isUserAuthorized isUserAuthorized
} }
... on TrustCenterFile { ... on CompliancePortalFile {
id id
name name
isUserAuthorized isUserAuthorized
@@ -66,8 +66,8 @@ function resolveNode(node: DocumentViewerPageQuery["response"]["aliasedNode"]):
switch (node.__typename) { switch (node.__typename) {
case "Document": case "Document":
return { kind: "Document", id: node.id, title: node.title, isAuthorized: node.isUserAuthorized }; return { kind: "Document", id: node.id, title: node.title, isAuthorized: node.isUserAuthorized };
case "TrustCenterFile": case "CompliancePortalFile":
return { kind: "TrustCenterFile", id: node.id, title: node.name, isAuthorized: node.isUserAuthorized }; return { kind: "CompliancePortalFile", id: node.id, title: node.name, isAuthorized: node.isUserAuthorized };
case "AuditReport": case "AuditReport":
return { kind: "AuditReport", id: node.id, title: node.fileName, isAuthorized: node.isUserAuthorized }; return { kind: "AuditReport", id: node.id, title: node.fileName, isAuthorized: node.isUserAuthorized };
default: default:

View File

@@ -35,13 +35,13 @@ import { DocumentListItem } from "./_components/DocumentListItem";
import { DocumentSection } from "./_components/DocumentSection"; import { DocumentSection } from "./_components/DocumentSection";
import { DocumentsEmpty } from "./_components/DocumentsEmpty"; import { DocumentsEmpty } from "./_components/DocumentsEmpty";
import { DocumentsToolbar } from "./_components/DocumentsToolbar"; import { DocumentsToolbar } from "./_components/DocumentsToolbar";
import { TrustCenterFileListItem } from "./_components/TrustCenterFileListItem"; import { CompliancePortalFileListItem } from "./_components/CompliancePortalFileListItem";
import { toQueryVariables } from "./_lib/toQueryVariables"; import { toQueryVariables } from "./_lib/toQueryVariables";
import { useDocumentTab } from "./_lib/useDocumentTab"; import { useDocumentTab } from "./_lib/useDocumentTab";
import { documentsLayout } from "./variants"; import { documentsLayout } from "./variants";
export const documentsPageQuery = graphql` export const documentsPageQuery = graphql`
query DocumentsPageQuery($visibility: TrustCenterVisibility) { query DocumentsPageQuery($visibility: CompliancePortalVisibility) {
...DocumentsPage_query @arguments(visibility: $visibility) ...DocumentsPage_query @arguments(visibility: $visibility)
} }
`; `;
@@ -49,8 +49,8 @@ export const documentsPageQuery = graphql`
const documentsPageFragment = graphql` const documentsPageFragment = graphql`
fragment DocumentsPage_query on Query fragment DocumentsPage_query on Query
@refetchable(queryName: "DocumentsPageRefetchQuery") @refetchable(queryName: "DocumentsPageRefetchQuery")
@argumentDefinitions(visibility: { type: "TrustCenterVisibility" }) { @argumentDefinitions(visibility: { type: "CompliancePortalVisibility" }) {
currentTrustCenter @required(action: THROW) { currentCompliancePortal @required(action: THROW) {
documents(first: 250, filter: { visibility: $visibility }) { documents(first: 250, filter: { visibility: $visibility }) {
edges { edges {
node { node {
@@ -71,12 +71,12 @@ const documentsPageFragment = graphql`
} }
} }
} }
trustCenterFiles(first: 250, filter: { visibility: $visibility }) { compliancePortalFiles(first: 250, filter: { visibility: $visibility }) {
edges { edges {
node { node {
id id
category category
...TrustCenterFileListItem_file ...CompliancePortalFileListItem_file
} }
} }
} }
@@ -88,7 +88,7 @@ interface DocumentsPageProps {
queryRef: PreloadedQuery<DocumentsPageQuery>; queryRef: PreloadedQuery<DocumentsPageQuery>;
} }
// Trust Center documents page: a unified list of published documents, uploaded // Compliance Portal documents page: a unified list of published documents, uploaded
// files, and audit reports, grouped into category sections. The All/Public/ // files, and audit reports, grouped into category sections. The All/Public/
// Private tabs are backed by a server-side visibility filter. // Private tabs are backed by a server-side visibility filter.
export function DocumentsPage({ queryRef }: DocumentsPageProps) { export function DocumentsPage({ queryRef }: DocumentsPageProps) {
@@ -140,10 +140,10 @@ export function DocumentsPage({ queryRef }: DocumentsPageProps) {
}); });
}, [refetch, tab]); }, [refetch, tab]);
const { currentTrustCenter } = data; const { currentCompliancePortal } = data;
const documentNodes = currentTrustCenter.documents.edges.map(edge => edge.node); const documentNodes = currentCompliancePortal.documents.edges.map(edge => edge.node);
const fileNodes = currentTrustCenter.trustCenterFiles.edges.map(edge => edge.node); const fileNodes = currentCompliancePortal.compliancePortalFiles.edges.map(edge => edge.node);
const auditNodes = currentTrustCenter.audits.edges const auditNodes = currentCompliancePortal.audits.edges
.map(edge => edge.node) .map(edge => edge.node)
.filter(node => node.reportFile != null); .filter(node => node.reportFile != null);
@@ -191,7 +191,7 @@ export function DocumentsPage({ queryRef }: DocumentsPageProps) {
{fileGroups.map(group => ( {fileGroups.map(group => (
<DocumentSection key={`category:${group.key}`} title={group.key}> <DocumentSection key={`category:${group.key}`} title={group.key}>
{group.nodes.map(node => ( {group.nodes.map(node => (
<TrustCenterFileListItem key={node.id} fileKey={node} /> <CompliancePortalFileListItem key={node.id} fileKey={node} />
))} ))}
</DocumentSection> </DocumentSection>
))} ))}

View File

@@ -22,11 +22,11 @@ import { graphql, useFragment } from "react-relay";
import { useRequestFileAccess } from "../_lib/useAccessRequest"; import { useRequestFileAccess } from "../_lib/useAccessRequest";
import type { TrustCenterFileListItem_file$key } from "./__generated__/TrustCenterFileListItem_file.graphql"; import type { CompliancePortalFileListItem_file$key } from "./__generated__/CompliancePortalFileListItem_file.graphql";
import { DocumentEntry } from "./DocumentEntry"; import { DocumentEntry } from "./DocumentEntry";
const trustCenterFileListItemFragment = graphql` const compliancePortalFileListItemFragment = graphql`
fragment TrustCenterFileListItem_file on TrustCenterFile @throwOnFieldError { fragment CompliancePortalFileListItem_file on CompliancePortalFile @throwOnFieldError {
id id
alias alias
name name
@@ -38,14 +38,14 @@ const trustCenterFileListItemFragment = graphql`
} }
`; `;
interface TrustCenterFileListItemProps { interface CompliancePortalFileListItemProps {
fileKey: TrustCenterFileListItem_file$key; fileKey: CompliancePortalFileListItem_file$key;
} }
// A single uploaded trust-center file entry: name, its category, and an access // A single uploaded trust-center file entry: name, its category, and an access
// action linking to the viewer when authorized. // action linking to the viewer when authorized.
export function TrustCenterFileListItem({ fileKey }: TrustCenterFileListItemProps) { export function CompliancePortalFileListItem({ fileKey }: CompliancePortalFileListItemProps) {
const file = useFragment(trustCenterFileListItemFragment, fileKey); const file = useFragment(compliancePortalFileListItemFragment, fileKey);
const { requestAccess, isRequesting } = useRequestFileAccess(file.id); const { requestAccess, isRequesting } = useRequestFileAccess(file.id);
return ( return (

View File

@@ -26,7 +26,7 @@ import { EmptyState } from "#/components/EmptyState/EmptyState";
import { useDocumentTab } from "../_lib/useDocumentTab"; import { useDocumentTab } from "../_lib/useDocumentTab";
// Empty state for the documents list. When a Public/Private tab is active it // Empty state for the documents list. When a Public/Private tab is active it
// notes the filter; otherwise it states the trust center publishes no documents. // notes the filter; otherwise it states the compliance portal publishes no documents.
export function DocumentsEmpty() { export function DocumentsEmpty() {
const { t } = useTranslation("documents"); const { t } = useTranslation("documents");
const { tab } = useDocumentTab(); const { tab } = useDocumentTab();

View File

@@ -80,8 +80,8 @@ const reportMutation = graphql`
`; `;
const fileMutation = graphql` const fileMutation = graphql`
mutation useAccessRequestFileMutation($input: RequestTrustCenterFileAccessInput!) { mutation useAccessRequestFileMutation($input: RequestCompliancePortalFileAccessInput!) {
requestTrustCenterFileAccess(input: $input) { requestCompliancePortalFileAccess(input: $input) {
file { file {
id id
access { access {
@@ -171,7 +171,7 @@ export function useRequestFileAccess(id: string): AccessRequest {
); );
const requestAccess = useCallback(() => { const requestAccess = useCallback(() => {
void mutate({ variables: { input: { trustCenterFileId: id } }, ...handlers }).catch(() => {}); void mutate({ variables: { input: { compliancePortalFileId: id } }, ...handlers }).catch(() => {});
}, [mutate, id, handlers]); }, [mutate, id, handlers]);
return { requestAccess, isRequesting }; return { requestAccess, isRequesting };
@@ -189,7 +189,7 @@ export function useAccessRequest(kind: DocumentKind, id: string): AccessRequest
return document; return document;
case "AuditReport": case "AuditReport":
return report; return report;
case "TrustCenterFile": case "CompliancePortalFile":
return file; return file;
} }
} }

View File

@@ -27,7 +27,7 @@ import type { useDocumentExportDocumentMutation } from "./__generated__/useDocum
import type { useDocumentExportFileMutation } from "./__generated__/useDocumentExportFileMutation.graphql"; import type { useDocumentExportFileMutation } from "./__generated__/useDocumentExportFileMutation.graphql";
import type { useDocumentExportReportMutation } from "./__generated__/useDocumentExportReportMutation.graphql"; import type { useDocumentExportReportMutation } from "./__generated__/useDocumentExportReportMutation.graphql";
export type DocumentKind = "Document" | "TrustCenterFile" | "AuditReport"; export type DocumentKind = "Document" | "CompliancePortalFile" | "AuditReport";
const exportDocumentMutation = graphql` const exportDocumentMutation = graphql`
mutation useDocumentExportDocumentMutation($input: ExportDocumentPDFInput!) { mutation useDocumentExportDocumentMutation($input: ExportDocumentPDFInput!) {
@@ -38,8 +38,8 @@ const exportDocumentMutation = graphql`
`; `;
const exportFileMutation = graphql` const exportFileMutation = graphql`
mutation useDocumentExportFileMutation($input: ExportTrustCenterFileInput!) { mutation useDocumentExportFileMutation($input: ExportCompliancePortalFileInput!) {
exportTrustCenterFile(input: $input) { exportCompliancePortalFile(input: $input) {
data data
} }
} }
@@ -102,10 +102,10 @@ export function useDocumentExport(kind: DocumentKind, id: string, enabled: boole
onCompleted: response => apply(id, response.exportDocumentPDF.data), onCompleted: response => apply(id, response.exportDocumentPDF.data),
}).catch(() => {}); }).catch(() => {});
break; break;
case "TrustCenterFile": case "CompliancePortalFile":
exportFile({ exportFile({
variables: { input: { trustCenterFileId: id } }, variables: { input: { compliancePortalFileId: id } },
onCompleted: response => apply(id, response.exportTrustCenterFile.data), onCompleted: response => apply(id, response.exportCompliancePortalFile.data),
}).catch(() => {}); }).catch(() => {});
break; break;
case "AuditReport": case "AuditReport":

View File

@@ -61,7 +61,7 @@ export const ndaPageQuery = graphql`
viewer { viewer {
id id
} }
currentTrustCenter @required(action: THROW) { currentCompliancePortal @required(action: THROW) {
title title
nonDisclosureAgreement { nonDisclosureAgreement {
fileUrl fileUrl
@@ -72,7 +72,7 @@ export const ndaPageQuery = graphql`
`; `;
const ndaPageFragment = graphql` const ndaPageFragment = graphql`
fragment NDAPageFragment on TrustCenter fragment NDAPageFragment on CompliancePortal
@refetchable(queryName: "NDAPageRefetchQuery") { @refetchable(queryName: "NDAPageRefetchQuery") {
nonDisclosureAgreement @required(action: THROW) { nonDisclosureAgreement @required(action: THROW) {
viewerSignature { viewerSignature {
@@ -122,13 +122,13 @@ export function NDAPage({ queryRef }: NDAPageProps) {
const [scale, setScale] = useState(1); const [scale, setScale] = useState(1);
const data = usePreloadedQuery<NDAPageQueryType>(ndaPageQuery, queryRef); const data = usePreloadedQuery<NDAPageQueryType>(ndaPageQuery, queryRef);
const trustCenter = data.currentTrustCenter; const compliancePortal = data.currentCompliancePortal;
const [fragment, refetch] = useRefetchableFragment<NDAPageRefetchQuery, NDAPageFragment$key>( const [fragment, refetch] = useRefetchableFragment<NDAPageRefetchQuery, NDAPageFragment$key>(
ndaPageFragment, ndaPageFragment,
trustCenter, compliancePortal,
); );
const nda = trustCenter.nonDisclosureAgreement; const nda = compliancePortal.nonDisclosureAgreement;
const signature = fragment.nonDisclosureAgreement.viewerSignature; const signature = fragment.nonDisclosureAgreement.viewerSignature;
const safeContinueUrl = getSafeContinueUrl(searchParams.get("continue")); const safeContinueUrl = getSafeContinueUrl(searchParams.get("continue"));
@@ -236,7 +236,7 @@ export function NDAPage({ queryRef }: NDAPageProps) {
{t("title")} {t("title")}
</Heading> </Heading>
<Text size={2} color="neutral"> <Text size={2} color="neutral">
{t("subtitle", { name: trustCenter.title })} {t("subtitle", { name: compliancePortal.title })}
</Text> </Text>
{signature.consentText != null && ( {signature.consentText != null && (
<Text size={1} color="faint" className={slots.consent()}> <Text size={1} color="faint" className={slots.consent()}>

View File

@@ -52,7 +52,7 @@ const subprocessorsPageFragment = graphql`
category: { type: "SubprocessorCategory" } category: { type: "SubprocessorCategory" }
country: { type: "CountryCode" } country: { type: "CountryCode" }
) { ) {
currentTrustCenter @required(action: THROW) { currentCompliancePortal @required(action: THROW) {
subprocessors(first: 250, filter: { query: $query, category: $category, country: $country }) { subprocessors(first: 250, filter: { query: $query, category: $category, country: $country }) {
totalCount totalCount
edges { edges {
@@ -98,7 +98,7 @@ export function SubprocessorsPage({ queryRef }: SubprocessorsPageProps) {
}); });
}, [refetch, query, category, country]); }, [refetch, query, category, country]);
const { subprocessors } = data.currentTrustCenter; const { subprocessors } = data.currentCompliancePortal;
const nodes: SubprocessorNode[] = subprocessors.edges.map(edge => edge.node); const nodes: SubprocessorNode[] = subprocessors.edges.map(edge => edge.node);
const groups = groupByCategory(nodes, value => t(`categories.${value}.label`)); const groups = groupByCategory(nodes, value => t(`categories.${value}.label`));

View File

@@ -27,7 +27,7 @@ import { EmptyState } from "#/components/EmptyState/EmptyState";
import { useSubprocessorFilters } from "../_lib/useSubprocessorFilters"; import { useSubprocessorFilters } from "../_lib/useSubprocessorFilters";
// Empty state for the subprocessor list. When filters are active it offers to // Empty state for the subprocessor list. When filters are active it offers to
// clear them; otherwise it states the trust center lists no subprocessors. // clear them; otherwise it states the compliance portal lists no subprocessors.
export function SubprocessorsEmpty() { export function SubprocessorsEmpty() {
const { t } = useTranslation("subprocessors"); const { t } = useTranslation("subprocessors");
const { hasActiveFilters, clear } = useSubprocessorFilters(); const { hasActiveFilters, clear } = useSubprocessorFilters();

View File

@@ -34,11 +34,11 @@ import { useSubprocessorSearch } from "../_lib/useSubprocessorSearch";
import type { SubprocessorsToolbar_query$key } from "./__generated__/SubprocessorsToolbar_query.graphql"; import type { SubprocessorsToolbar_query$key } from "./__generated__/SubprocessorsToolbar_query.graphql";
// Facet data: the distinct categories and countries actually present across the // Facet data: the distinct categories and countries actually present across the
// trust center's published subprocessors, used to populate the filter dropdowns // compliance portal's published subprocessors, used to populate the filter dropdowns
// (server-computed so the options never dead-end on an empty result). // (server-computed so the options never dead-end on an empty result).
const subprocessorsToolbarFragment = graphql` const subprocessorsToolbarFragment = graphql`
fragment SubprocessorsToolbar_query on Query { fragment SubprocessorsToolbar_query on Query {
currentTrustCenter @required(action: THROW) { currentCompliancePortal @required(action: THROW) {
subprocessorCategories subprocessorCategories
subprocessorCountries subprocessorCountries
} }
@@ -58,7 +58,7 @@ export function SubprocessorsToolbar({ queryKey }: SubprocessorsToolbarProps) {
const { category, country, setCategory, setCountry } = useSubprocessorFilters(); const { category, country, setCategory, setCountry } = useSubprocessorFilters();
const [queryInput, setQueryInput] = useSubprocessorSearch(); const [queryInput, setQueryInput] = useSubprocessorSearch();
const { subprocessorCategories, subprocessorCountries } = data.currentTrustCenter; const { subprocessorCategories, subprocessorCountries } = data.currentCompliancePortal;
const categoryOptions = useMemo(() => { const categoryOptions = useMemo(() => {
return [...subprocessorCategories].sort((a, b) => t(`categories.${a}.label`).localeCompare(t(`categories.${b}.label`))); return [...subprocessorCategories].sort((a, b) => t(`categories.${a}.label`).localeCompare(t(`categories.${b}.label`)));

View File

@@ -53,7 +53,7 @@ const updatesPageFragment = graphql`
last: { type: "Int" } last: { type: "Int" }
before: { type: "CursorKey" } before: { type: "CursorKey" }
) { ) {
currentTrustCenter @required(action: THROW) { currentCompliancePortal @required(action: THROW) {
updates(first: $first, after: $after, last: $last, before: $before) { updates(first: $first, after: $after, last: $last, before: $before) {
pageInfo { pageInfo {
hasNextPage hasNextPage
@@ -96,7 +96,7 @@ export function UpdatesPage({ queryRef }: UpdatesPageProps) {
}); });
}, [refetch]); }, [refetch]);
const { updates } = data.currentTrustCenter; const { updates } = data.currentCompliancePortal;
const { pageInfo } = updates; const { pageInfo } = updates;
const { isPending, goPrevious, goNext } = useCursorPagination(refetchUpdates, pageInfo, UPDATES_PAGE_SIZE); const { isPending, goPrevious, goNext } = useCursorPagination(refetchUpdates, pageInfo, UPDATES_PAGE_SIZE);

View File

@@ -25,7 +25,7 @@ import { EmptyState } from "#/components/EmptyState/EmptyState";
import { UpdatesSubscribeButton } from "./UpdatesSubscribeButton"; import { UpdatesSubscribeButton } from "./UpdatesSubscribeButton";
// Empty state for the updates list: shown when the trust center has published no // Empty state for the updates list: shown when the compliance portal has published no
// updates yet, inviting the visitor to subscribe. // updates yet, inviting the visitor to subscribe.
export function UpdatesEmpty() { export function UpdatesEmpty() {
const { t } = useTranslation("updates"); const { t } = useTranslation("updates");

View File

@@ -1,2 +1,2 @@
# TrustCenter app # Trust app (compliance portal)

View File

@@ -32,14 +32,14 @@ import { useFragment, useMutation } from "react-relay";
import { useLocation, useNavigate, useSearchParams } from "react-router"; import { useLocation, useNavigate, useSearchParams } from "react-router";
import { graphql } from "relay-runtime"; import { graphql } from "relay-runtime";
import type { TrustCenterFileRow_requestAccessMutation } from "./__generated__/TrustCenterFileRow_requestAccessMutation.graphql"; import type { CompliancePortalFileRow_requestAccessMutation } from "./__generated__/CompliancePortalFileRow_requestAccessMutation.graphql";
import type { TrustCenterFileRowFragment$key } from "./__generated__/TrustCenterFileRowFragment.graphql"; import type { CompliancePortalFileRowFragment$key } from "./__generated__/CompliancePortalFileRowFragment.graphql";
const requestAccessMutation = graphql` const requestAccessMutation = graphql`
mutation TrustCenterFileRow_requestAccessMutation( mutation CompliancePortalFileRow_requestAccessMutation(
$input: RequestTrustCenterFileAccessInput! $input: RequestCompliancePortalFileAccessInput!
) { ) {
requestTrustCenterFileAccess(input: $input) { requestCompliancePortalFileAccess(input: $input) {
file { file {
access { access {
id id
@@ -50,8 +50,8 @@ const requestAccessMutation = graphql`
} }
`; `;
const trustCenterFileRowFragment = graphql` const compliancePortalFileRowFragment = graphql`
fragment TrustCenterFileRowFragment on TrustCenterFile { fragment CompliancePortalFileRowFragment on CompliancePortalFile {
id id
alias alias
name name
@@ -63,8 +63,8 @@ const trustCenterFileRowFragment = graphql`
} }
`; `;
export function TrustCenterFileRow(props: { export function CompliancePortalFileRow(props: {
file: TrustCenterFileRowFragment$key; file: CompliancePortalFileRowFragment$key;
}) { }) {
const { __ } = useTranslate(); const { __ } = useTranslate();
const { toast } = useToast(); const { toast } = useToast();
@@ -72,12 +72,12 @@ export function TrustCenterFileRow(props: {
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const navigate = useNavigate(); const navigate = useNavigate();
const file = useFragment(trustCenterFileRowFragment, props.file); const file = useFragment(compliancePortalFileRowFragment, props.file);
const filePath = file.alias ?? file.id; const filePath = file.alias ?? file.id;
const hasRequested = file.access?.status === "REQUESTED"; const hasRequested = file.access?.status === "REQUESTED";
const [requestAccess, isRequestingAccess] const [requestAccess, isRequestingAccess]
= useMutation<TrustCenterFileRow_requestAccessMutation>( = useMutation<CompliancePortalFileRow_requestAccessMutation>(
requestAccessMutation, requestAccessMutation,
); );
@@ -85,7 +85,7 @@ export function TrustCenterFileRow(props: {
requestAccess({ requestAccess({
variables: { variables: {
input: { input: {
trustCenterFileId: file.id, compliancePortalFileId: file.id,
}, },
}, },
onCompleted: (_, errors) => { onCompleted: (_, errors) => {

View File

@@ -37,7 +37,7 @@ import { useMutation } from "react-relay";
import { useLocation, useNavigate, useSearchParams } from "react-router"; import { useLocation, useNavigate, useSearchParams } from "react-router";
import { graphql } from "relay-runtime"; import { graphql } from "relay-runtime";
import type { TrustGraphCurrentQuery$data } from "#/queries/__generated__/TrustGraphCurrentQuery.graphql"; import type { CompliancePortalGraphCurrentQuery$data } from "#/queries/__generated__/CompliancePortalGraphCurrentQuery.graphql";
import type { OrganizationSidebar_requestAllAccessesMutation } from "./__generated__/OrganizationSidebar_requestAllAccessesMutation.graphql"; import type { OrganizationSidebar_requestAllAccessesMutation } from "./__generated__/OrganizationSidebar_requestAllAccessesMutation.graphql";
import type { OrganizationSidebar_subscribeToMailingListMutation } from "./__generated__/OrganizationSidebar_subscribeToMailingListMutation.graphql"; import type { OrganizationSidebar_subscribeToMailingListMutation } from "./__generated__/OrganizationSidebar_subscribeToMailingListMutation.graphql";
@@ -47,7 +47,7 @@ import { FrameworkBadge } from "./FrameworkBadge";
const requestAllAccessesMutation = graphql` const requestAllAccessesMutation = graphql`
mutation OrganizationSidebar_requestAllAccessesMutation { mutation OrganizationSidebar_requestAllAccessesMutation {
requestAllAccesses { requestAllAccesses {
trustCenterAccess { compliancePortalAccess {
id id
} }
} }
@@ -76,13 +76,13 @@ const unsubscribeFromMailingListMutation = graphql`
`; `;
export function OrganizationSidebar({ export function OrganizationSidebar({
trustCenter, compliancePortal,
isAuthenticated, isAuthenticated,
}: { }: {
trustCenter: TrustGraphCurrentQuery$data["currentTrustCenter"]; compliancePortal: CompliancePortalGraphCurrentQuery$data["currentCompliancePortal"];
isAuthenticated: boolean; isAuthenticated: boolean;
}) { }) {
const trustCenterId = trustCenter?.id; const compliancePortalId = compliancePortal?.id;
const { __ } = useTranslate(); const { __ } = useTranslate();
const { toast } = useToast(); const { toast } = useToast();
const theme = useSystemTheme(); const theme = useSystemTheme();
@@ -91,8 +91,8 @@ export function OrganizationSidebar({
const location = useLocation(); const location = useLocation();
const logoFileUrl = theme === "dark" const logoFileUrl = theme === "dark"
? (trustCenter?.darkLogo?.downloadUrl ?? trustCenter?.logo?.downloadUrl) ? (compliancePortal?.darkLogo?.downloadUrl ?? compliancePortal?.logo?.downloadUrl)
: trustCenter?.logo?.downloadUrl; : compliancePortal?.logo?.downloadUrl;
const [requestAllAccesses, isRequestingAccess] const [requestAllAccesses, isRequestingAccess]
= useMutation<OrganizationSidebar_requestAllAccessesMutation>( = useMutation<OrganizationSidebar_requestAllAccessesMutation>(
@@ -155,12 +155,12 @@ export function OrganizationSidebar({
variables: {}, variables: {},
updater: (store, data) => { updater: (store, data) => {
const subscription = data?.subscribeToMailingList?.subscription; const subscription = data?.subscribeToMailingList?.subscription;
if (!subscription?.id || !trustCenterId) return; if (!subscription?.id || !compliancePortalId) return;
const trustCenterRecord = store.get(trustCenterId); const compliancePortalRecord = store.get(compliancePortalId);
if (!trustCenterRecord) return; if (!compliancePortalRecord) return;
const subscriptionRecord = store.get(subscription.id); const subscriptionRecord = store.get(subscription.id);
if (!subscriptionRecord) return; if (!subscriptionRecord) return;
trustCenterRecord.setLinkedRecord(subscriptionRecord, "viewerSubscription"); compliancePortalRecord.setLinkedRecord(subscriptionRecord, "viewerSubscription");
}, },
onCompleted: (_, errors) => { onCompleted: (_, errors) => {
if (errors?.length) { if (errors?.length) {
@@ -215,7 +215,7 @@ export function OrganizationSidebar({
}); });
}; };
if (!trustCenter) { if (!compliancePortal) {
return null; return null;
} }
@@ -233,9 +233,9 @@ export function OrganizationSidebar({
: ( : (
<div className="size-24 rounded-2xl border border-border-mid shadow-mid bg-level-1" /> <div className="size-24 rounded-2xl border border-border-mid shadow-mid bg-level-1" />
)} )}
<h1 className="text-2xl mt-6">{trustCenter.title}</h1> <h1 className="text-2xl mt-6">{compliancePortal.title}</h1>
<p className="text-sm text-txt-secondary mt-1"> <p className="text-sm text-txt-secondary mt-1">
{trustCenter.description} {compliancePortal.description}
</p> </p>
<hr className="my-6 -mx-6 h-px bg-border-low border-none" /> <hr className="my-6 -mx-6 h-px bg-border-low border-none" />
@@ -246,32 +246,32 @@ export function OrganizationSidebar({
<IconBlock size={16} /> <IconBlock size={16} />
{__("Business information")} {__("Business information")}
</h2> </h2>
{trustCenter.websiteUrl && ( {compliancePortal.websiteUrl && (
<BusinessInfo label={__("Website")}> <BusinessInfo label={__("Website")}>
<a {...externalLinkProps(trustCenter.websiteUrl)}> <a {...externalLinkProps(compliancePortal.websiteUrl)}>
<span className="text-txt-info hover:underline "> <span className="text-txt-info hover:underline ">
{new URL(trustCenter.websiteUrl).host} {new URL(compliancePortal.websiteUrl).host}
</span> </span>
</a> </a>
</BusinessInfo> </BusinessInfo>
)} )}
{trustCenter.email && ( {compliancePortal.email && (
<BusinessInfo label={__("Contact")}> <BusinessInfo label={__("Contact")}>
<a href={`mailto:${trustCenter.email}`}> <a href={`mailto:${compliancePortal.email}`}>
<span className="text-txt-info hover:underline "> <span className="text-txt-info hover:underline ">
{trustCenter.email} {compliancePortal.email}
</span> </span>
</a> </a>
</BusinessInfo> </BusinessInfo>
)} )}
{trustCenter.headquarterAddress && ( {compliancePortal.headquarterAddress && (
<BusinessInfo label={__("HQ address")}> <BusinessInfo label={__("HQ address")}>
{trustCenter.headquarterAddress} {compliancePortal.headquarterAddress}
</BusinessInfo> </BusinessInfo>
)} )}
{trustCenter.customLinks.edges.length > 0 && ( {compliancePortal.customLinks.edges.length > 0 && (
<div className="flex flex-wrap gap-x-4 gap-y-2"> <div className="flex flex-wrap gap-x-4 gap-y-2">
{trustCenter.customLinks.edges.map(({ node }) => ( {compliancePortal.customLinks.edges.map(({ node }) => (
<a <a
key={node.id} key={node.id}
{...externalLinkProps(node.url)} {...externalLinkProps(node.url)}
@@ -287,7 +287,7 @@ export function OrganizationSidebar({
<hr className="my-6 -mx-6 h-px bg-border-low border-none" /> <hr className="my-6 -mx-6 h-px bg-border-low border-none" />
{/* Certifications */} {/* Certifications */}
{trustCenter.complianceFrameworks.edges.length > 0 && ( {compliancePortal.complianceFrameworks.edges.length > 0 && (
<> <>
<div className="space-y-4"> <div className="space-y-4">
<h2 className="text-xs text-txt-secondary flex gap-1 items-center"> <h2 className="text-xs text-txt-secondary flex gap-1 items-center">
@@ -300,7 +300,7 @@ export function OrganizationSidebar({
gridTemplateColumns: "repeat(auto-fit, 75px", gridTemplateColumns: "repeat(auto-fit, 75px",
}} }}
> >
{trustCenter.complianceFrameworks.edges.map(edge => ( {compliancePortal.complianceFrameworks.edges.map(edge => (
<FrameworkBadge key={edge.node.id} framework={edge.node.framework} /> <FrameworkBadge key={edge.node.id} framework={edge.node.framework} />
))} ))}
</div> </div>
@@ -322,7 +322,7 @@ export function OrganizationSidebar({
{__("Request access")} {__("Request access")}
</Button> </Button>
{isAuthenticated && ( {isAuthenticated && (
trustCenter.viewerSubscription compliancePortal.viewerSubscription
? ( ? (
<Button <Button
disabled={isUnsubscribing} disabled={isUnsubscribing}

View File

@@ -18,7 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE. // SOFTWARE.
import { getTrustCenterUrl } from "@probo/helpers"; import { getCompliancePortalUrl } from "@probo/helpers";
import { useTranslate } from "@probo/i18n"; import { useTranslate } from "@probo/i18n";
import { Skeleton, TabLink, Tabs } from "@probo/ui"; import { Skeleton, TabLink, Tabs } from "@probo/ui";
@@ -31,12 +31,12 @@ export function MainSkeleton() {
<Skeleton className="w-full h-300" /> <Skeleton className="w-full h-300" />
<main> <main>
<Tabs className="mb-8"> <Tabs className="mb-8">
<TabLink to={getTrustCenterUrl("overview")}>{__("Overview")}</TabLink> <TabLink to={getCompliancePortalUrl("overview")}>{__("Overview")}</TabLink>
<TabLink to={getTrustCenterUrl("documents")}>{__("Documents")}</TabLink> <TabLink to={getCompliancePortalUrl("documents")}>{__("Documents")}</TabLink>
<TabLink to={getTrustCenterUrl("subprocessors")}> <TabLink to={getCompliancePortalUrl("subprocessors")}>
{__("Subprocessors")} {__("Subprocessors")}
</TabLink> </TabLink>
<TabLink to={getTrustCenterUrl("updates")}>{__("Updates")}</TabLink> <TabLink to={getCompliancePortalUrl("updates")}>{__("Updates")}</TabLink>
</Tabs> </Tabs>
<TabSkeleton /> <TabSkeleton />
</main> </main>

View File

@@ -20,15 +20,15 @@
import { useContext } from "react"; import { useContext } from "react";
import { TrustCenterContext } from "#/providers/TrustCenterProvider"; import { CompliancePortalContext } from "#/providers/CompliancePortalProvider";
export function useTrustCenter(): { export function useCompliancePortal(): {
id: string; id: string;
title: string; title: string;
} { } {
const context = useContext(TrustCenterContext); const context = useContext(CompliancePortalContext);
if (!context) { if (!context) {
throw new Error("useTrustCenter must be used within a TrustCenterProvider"); throw new Error("useCompliancePortal must be used within a CompliancePortalProvider");
} }
return context; return context;
} }

View File

@@ -65,9 +65,9 @@ const reportMutation = graphql`
const fileMutation = graphql` const fileMutation = graphql`
mutation useRequestAccessCallback_fileMutation( mutation useRequestAccessCallback_fileMutation(
$input: RequestTrustCenterFileAccessInput! $input: RequestCompliancePortalFileAccessInput!
) { ) {
requestTrustCenterFileAccess(input: $input) { requestCompliancePortalFileAccess(input: $input) {
file { file {
access { access {
id id
@@ -81,7 +81,7 @@ const fileMutation = graphql`
const allMutation = graphql` const allMutation = graphql`
mutation useRequestAccessCallback_allMutation { mutation useRequestAccessCallback_allMutation {
requestAllAccesses { requestAllAccesses {
trustCenterAccess { compliancePortalAccess {
id id
} }
} }
@@ -164,7 +164,7 @@ export function useRequestAccessCallback() {
searchParams.delete("request-file-id"); searchParams.delete("request-file-id");
void requestFileAccess({ void requestFileAccess({
variables: { variables: {
input: { trustCenterFileId: fileId }, input: { compliancePortalFileId: fileId },
}, },
onCompleted: (_, errors) => { onCompleted: (_, errors) => {
if (errors?.length) { if (errors?.length) {

View File

@@ -26,42 +26,42 @@ import { Outlet } from "react-router";
import { OrganizationSidebar } from "#/components/OrganizationSidebar"; import { OrganizationSidebar } from "#/components/OrganizationSidebar";
import { useRequestAccessCallback } from "#/hooks/useRequestAccessCallback"; import { useRequestAccessCallback } from "#/hooks/useRequestAccessCallback";
import { TrustCenterProvider } from "#/providers/TrustCenterProvider"; import { CompliancePortalProvider } from "#/providers/CompliancePortalProvider";
import type { TrustGraphCurrentQuery } from "#/queries/__generated__/TrustGraphCurrentQuery.graphql"; import type { CompliancePortalGraphCurrentQuery } from "#/queries/__generated__/CompliancePortalGraphCurrentQuery.graphql";
import { currentTrustGraphQuery } from "#/queries/TrustGraph"; import { currentCompliancePortalGraphQuery } from "#/queries/CompliancePortalGraph";
type Props = { type Props = {
queryRef: PreloadedQuery<TrustGraphCurrentQuery>; queryRef: PreloadedQuery<CompliancePortalGraphCurrentQuery>;
}; };
export function MainLayout(props: Props) { export function MainLayout(props: Props) {
const { __ } = useTranslate(); const { __ } = useTranslate();
const data = usePreloadedQuery<TrustGraphCurrentQuery>(currentTrustGraphQuery, props.queryRef); const data = usePreloadedQuery<CompliancePortalGraphCurrentQuery>(currentCompliancePortalGraphQuery, props.queryRef);
const trustCenter = data.currentTrustCenter; const compliancePortal = data.currentCompliancePortal;
const isAuthenticated = data.viewer != null; const isAuthenticated = data.viewer != null;
const theme = useSystemTheme(); const theme = useSystemTheme();
useFavicon( useFavicon(
theme === "dark" theme === "dark"
? (trustCenter?.darkLogo?.downloadUrl ?? trustCenter?.logo?.downloadUrl) ? (compliancePortal?.darkLogo?.downloadUrl ?? compliancePortal?.logo?.downloadUrl)
: trustCenter?.logo?.downloadUrl, : compliancePortal?.logo?.downloadUrl,
); );
useRequestAccessCallback(); useRequestAccessCallback();
return ( return (
<TrustCenterProvider trustCenter={trustCenter}> <CompliancePortalProvider compliancePortal={compliancePortal}>
<div className="grid grid-cols-1 max-w-[1280px] mx-4 pt-6 gap-4 lg:mx-auto lg:gap-10 lg:pt-20 lg:grid-cols-[400px_1fr] lg:items-start "> <div className="grid grid-cols-1 max-w-[1280px] mx-4 pt-6 gap-4 lg:mx-auto lg:gap-10 lg:pt-20 lg:grid-cols-[400px_1fr] lg:items-start ">
<OrganizationSidebar trustCenter={trustCenter} isAuthenticated={isAuthenticated} /> <OrganizationSidebar compliancePortal={compliancePortal} isAuthenticated={isAuthenticated} />
<main> <main>
<Tabs className="mb-8"> <Tabs className="mb-8">
<TabLink to="/overview">{__("Overview")}</TabLink> <TabLink to="/overview">{__("Overview")}</TabLink>
<TabLink to="/documents">{__("Documents")}</TabLink> <TabLink to="/documents">{__("Documents")}</TabLink>
{trustCenter.subprocessorInfo.totalCount > 0 {compliancePortal.subprocessorInfo.totalCount > 0
&& <TabLink to="/subprocessors">{__("Subprocessors")}</TabLink>} && <TabLink to="/subprocessors">{__("Subprocessors")}</TabLink>}
<TabLink to="/updates">{__("Updates")}</TabLink> <TabLink to="/updates">{__("Updates")}</TabLink>
</Tabs> </Tabs>
<Outlet context={{ trustCenter }} /> <Outlet context={{ compliancePortal }} />
</main> </main>
</div> </div>
@@ -73,6 +73,6 @@ export function MainLayout(props: Props) {
{" "} {" "}
<Logo withPicto className="h-6" /> <Logo withPicto className="h-6" />
</a> </a>
</TrustCenterProvider> </CompliancePortalProvider>
); );
} }

View File

@@ -43,15 +43,15 @@ import { PDFPreview } from "#/components/PDFPreview";
import type { DocumentPageExportDocumentMutation } from "./__generated__/DocumentPageExportDocumentMutation.graphql"; import type { DocumentPageExportDocumentMutation } from "./__generated__/DocumentPageExportDocumentMutation.graphql";
import type { DocumentPageExportReportMutation } from "./__generated__/DocumentPageExportReportMutation.graphql"; import type { DocumentPageExportReportMutation } from "./__generated__/DocumentPageExportReportMutation.graphql";
import type { DocumentPageExportTrustCenterFileMutation } from "./__generated__/DocumentPageExportTrustCenterFileMutation.graphql"; import type { DocumentPageExportCompliancePortalFileMutation } from "./__generated__/DocumentPageExportCompliancePortalFileMutation.graphql";
import type { DocumentPageQuery as DocumentPageQueryType } from "./__generated__/DocumentPageQuery.graphql"; import type { DocumentPageQuery as DocumentPageQueryType } from "./__generated__/DocumentPageQuery.graphql";
import type { DocumentPageRequestDocumentAccessMutation } from "./__generated__/DocumentPageRequestDocumentAccessMutation.graphql"; import type { DocumentPageRequestDocumentAccessMutation } from "./__generated__/DocumentPageRequestDocumentAccessMutation.graphql";
import type { DocumentPageRequestReportAccessMutation } from "./__generated__/DocumentPageRequestReportAccessMutation.graphql"; import type { DocumentPageRequestReportAccessMutation } from "./__generated__/DocumentPageRequestReportAccessMutation.graphql";
import type { DocumentPageRequestTrustCenterFileAccessMutation } from "./__generated__/DocumentPageRequestTrustCenterFileAccessMutation.graphql"; import type { DocumentPageRequestCompliancePortalFileAccessMutation } from "./__generated__/DocumentPageRequestCompliancePortalFileAccessMutation.graphql";
export const documentPageQuery = graphql` export const documentPageQuery = graphql`
query DocumentPageQuery($alias: String!) { query DocumentPageQuery($alias: String!) {
currentTrustCenter { currentCompliancePortal {
logo { logo {
downloadUrl downloadUrl
} }
@@ -70,7 +70,7 @@ export const documentPageQuery = graphql`
status status
} }
} }
... on TrustCenterFile { ... on CompliancePortalFile {
id id
name name
isUserAuthorized isUserAuthorized
@@ -102,11 +102,11 @@ const exportDocumentMutation = graphql`
} }
`; `;
const exportTrustCenterFileMutation = graphql` const exportCompliancePortalFileMutation = graphql`
mutation DocumentPageExportTrustCenterFileMutation( mutation DocumentPageExportCompliancePortalFileMutation(
$input: ExportTrustCenterFileInput! $input: ExportCompliancePortalFileInput!
) { ) {
exportTrustCenterFile(input: $input) { exportCompliancePortalFile(input: $input) {
data data
} }
} }
@@ -137,11 +137,11 @@ const requestDocumentAccessMutation = graphql`
} }
`; `;
const requestTrustCenterFileAccessMutation = graphql` const requestCompliancePortalFileAccessMutation = graphql`
mutation DocumentPageRequestTrustCenterFileAccessMutation( mutation DocumentPageRequestCompliancePortalFileAccessMutation(
$input: RequestTrustCenterFileAccessInput! $input: RequestCompliancePortalFileAccessInput!
) { ) {
requestTrustCenterFileAccess(input: $input) { requestCompliancePortalFileAccess(input: $input) {
file { file {
access { access {
id id
@@ -192,7 +192,7 @@ function getNodeTitle(node: DocumentPageQueryType["response"]["aliasedNode"]): s
switch (node.__typename) { switch (node.__typename) {
case "Document": case "Document":
return node.title; return node.title;
case "TrustCenterFile": case "CompliancePortalFile":
return node.name; return node.name;
case "AuditReport": case "AuditReport":
return node.fileName; return node.fileName;
@@ -204,7 +204,7 @@ function getNodeTitle(node: DocumentPageQueryType["response"]["aliasedNode"]): s
function getNodeId(node: DocumentPageQueryType["response"]["aliasedNode"]): string | undefined { function getNodeId(node: DocumentPageQueryType["response"]["aliasedNode"]): string | undefined {
switch (node.__typename) { switch (node.__typename) {
case "Document": case "Document":
case "TrustCenterFile": case "CompliancePortalFile":
case "AuditReport": case "AuditReport":
return node.id; return node.id;
default: default:
@@ -224,12 +224,12 @@ export function DocumentPage({ queryRef }: Props) {
const [exportError, setExportError] = useState<string | null>(null); const [exportError, setExportError] = useState<string | null>(null);
const data = usePreloadedQuery<DocumentPageQueryType>(documentPageQuery, queryRef); const data = usePreloadedQuery<DocumentPageQueryType>(documentPageQuery, queryRef);
const trustCenter = data.currentTrustCenter; const compliancePortal = data.currentCompliancePortal;
const node = data.aliasedNode; const node = data.aliasedNode;
if ( if (
node.__typename !== "Document" node.__typename !== "Document"
&& node.__typename !== "TrustCenterFile" && node.__typename !== "CompliancePortalFile"
&& node.__typename !== "AuditReport" && node.__typename !== "AuditReport"
) { ) {
throw new Error(`Unexpected node type: ${node.__typename}`); throw new Error(`Unexpected node type: ${node.__typename}`);
@@ -239,19 +239,19 @@ export function DocumentPage({ queryRef }: Props) {
const nodeId = getNodeId(node); const nodeId = getNodeId(node);
const logoFileUrl = theme === "dark" const logoFileUrl = theme === "dark"
? (trustCenter?.darkLogo?.downloadUrl ?? trustCenter?.logo?.downloadUrl) ? (compliancePortal?.darkLogo?.downloadUrl ?? compliancePortal?.logo?.downloadUrl)
: trustCenter?.logo?.downloadUrl; : compliancePortal?.logo?.downloadUrl;
const [exportDocument, isExportingDocument] const [exportDocument, isExportingDocument]
= useMutation<DocumentPageExportDocumentMutation>(exportDocumentMutation); = useMutation<DocumentPageExportDocumentMutation>(exportDocumentMutation);
const [exportFile, isExportingFile] const [exportFile, isExportingFile]
= useMutation<DocumentPageExportTrustCenterFileMutation>(exportTrustCenterFileMutation); = useMutation<DocumentPageExportCompliancePortalFileMutation>(exportCompliancePortalFileMutation);
const [exportReport, isExportingReport] const [exportReport, isExportingReport]
= useMutation<DocumentPageExportReportMutation>(exportReportMutation); = useMutation<DocumentPageExportReportMutation>(exportReportMutation);
const [requestAccess, isRequestingAccess] const [requestAccess, isRequestingAccess]
= useMutation<DocumentPageRequestDocumentAccessMutation>(requestDocumentAccessMutation); = useMutation<DocumentPageRequestDocumentAccessMutation>(requestDocumentAccessMutation);
const [requestFileAccess, isRequestingFileAccess] const [requestFileAccess, isRequestingFileAccess]
= useMutation<DocumentPageRequestTrustCenterFileAccessMutation>(requestTrustCenterFileAccessMutation); = useMutation<DocumentPageRequestCompliancePortalFileAccessMutation>(requestCompliancePortalFileAccessMutation);
const [requestReportAccess, isRequestingReportAccess] const [requestReportAccess, isRequestingReportAccess]
= useMutation<DocumentPageRequestReportAccessMutation>(requestReportAccessMutation); = useMutation<DocumentPageRequestReportAccessMutation>(requestReportAccessMutation);
@@ -291,15 +291,15 @@ export function DocumentPage({ queryRef }: Props) {
onError, onError,
}); });
break; break;
case "TrustCenterFile": case "CompliancePortalFile":
exportFile({ exportFile({
variables: { input: { trustCenterFileId: node.id } }, variables: { input: { compliancePortalFileId: node.id } },
onCompleted: (response, errors) => { onCompleted: (response, errors) => {
if (onCompletedErrors(errors)) return; if (onCompletedErrors(errors)) return;
if (isPdfDataUri(response.exportTrustCenterFile.data)) { if (isPdfDataUri(response.exportCompliancePortalFile.data)) {
setPdfData(response.exportTrustCenterFile.data); setPdfData(response.exportCompliancePortalFile.data);
} else { } else {
setFileData(response.exportTrustCenterFile.data); setFileData(response.exportCompliancePortalFile.data);
} }
}, },
onError, onError,
@@ -359,9 +359,9 @@ export function DocumentPage({ queryRef }: Props) {
onError, onError,
}); });
break; break;
case "TrustCenterFile": case "CompliancePortalFile":
requestFileAccess({ requestFileAccess({
variables: { input: { trustCenterFileId: node.id } }, variables: { input: { compliancePortalFileId: node.id } },
onCompleted, onCompleted,
onError, onError,
}); });
@@ -378,7 +378,7 @@ export function DocumentPage({ queryRef }: Props) {
const isRequesting = isRequestingAccess || isRequestingFileAccess || isRequestingReportAccess; const isRequesting = isRequestingAccess || isRequestingFileAccess || isRequestingReportAccess;
const hasRequested = node.access?.status === "REQUESTED"; const hasRequested = node.access?.status === "REQUESTED";
const isPdf = node.__typename === "Document" || node.__typename === "AuditReport" || (node.__typename === "TrustCenterFile" && pdfData !== null); const isPdf = node.__typename === "Document" || node.__typename === "AuditReport" || (node.__typename === "CompliancePortalFile" && pdfData !== null);
const handleDownload = () => { const handleDownload = () => {
if (!fileData || !nodeTitle) return; if (!fileData || !nodeTitle) return;

View File

@@ -26,25 +26,25 @@ import { type PreloadedQuery, usePreloadedQuery } from "react-relay";
import { DocumentRow } from "#/components/DocumentRow"; import { DocumentRow } from "#/components/DocumentRow";
import { RowHeader } from "#/components/RowHeader"; import { RowHeader } from "#/components/RowHeader";
import { Rows } from "#/components/Rows"; import { Rows } from "#/components/Rows";
import { TrustCenterFileRow } from "#/components/TrustCenterFileRow"; import { CompliancePortalFileRow } from "#/components/CompliancePortalFileRow";
import { documentTypeLabel } from "#/helpers/documents"; import { documentTypeLabel } from "#/helpers/documents";
import type { TrustGraphCurrentDocumentsQuery } from "#/queries/__generated__/TrustGraphCurrentDocumentsQuery.graphql"; import type { CompliancePortalGraphCurrentDocumentsQuery } from "#/queries/__generated__/CompliancePortalGraphCurrentDocumentsQuery.graphql";
import { currentTrustDocumentsQuery } from "#/queries/TrustGraph"; import { currentTrustDocumentsQuery } from "#/queries/CompliancePortalGraph";
type Props = { type Props = {
queryRef: PreloadedQuery<TrustGraphCurrentDocumentsQuery>; queryRef: PreloadedQuery<CompliancePortalGraphCurrentDocumentsQuery>;
}; };
export function DocumentsPage({ queryRef }: Props) { export function DocumentsPage({ queryRef }: Props) {
const { __ } = useTranslate(); const { __ } = useTranslate();
const data = usePreloadedQuery<TrustGraphCurrentDocumentsQuery>( const data = usePreloadedQuery<CompliancePortalGraphCurrentDocumentsQuery>(
currentTrustDocumentsQuery, currentTrustDocumentsQuery,
queryRef, queryRef,
); );
const documents const documents
= data.currentTrustCenter?.documents.edges.map(edge => edge.node) ?? []; = data.currentCompliancePortal?.documents.edges.map(edge => edge.node) ?? [];
const files const files
= data.currentTrustCenter?.trustCenterFiles.edges.map(edge => edge.node) ?? []; = data.currentCompliancePortal?.compliancePortalFiles.edges.map(edge => edge.node) ?? [];
const documentsPerType = groupBy(documents, document => const documentsPerType = groupBy(documents, document =>
documentTypeLabel(document.documentType, __), documentTypeLabel(document.documentType, __),
); );
@@ -68,7 +68,7 @@ export function DocumentsPage({ queryRef }: Props) {
<Fragment key={category}> <Fragment key={category}>
<RowHeader>{category}</RowHeader> <RowHeader>{category}</RowHeader>
{files.map(file => ( {files.map(file => (
<TrustCenterFileRow key={file.id} file={file} /> <CompliancePortalFileRow key={file.id} file={file} />
))} ))}
</Fragment> </Fragment>
))} ))}

View File

@@ -46,7 +46,7 @@ export const ndaPageQuery = graphql`
# eslint-disable-next-line relay/unused-fields # eslint-disable-next-line relay/unused-fields
id id
} }
currentTrustCenter @required(action: THROW) { currentCompliancePortal @required(action: THROW) {
title title
nonDisclosureAgreement { nonDisclosureAgreement {
fileName fileName
@@ -61,7 +61,7 @@ export const ndaPageQuery = graphql`
`; `;
const ndaPageFragment = graphql` const ndaPageFragment = graphql`
fragment NDAPageFragment on TrustCenter fragment NDAPageFragment on CompliancePortal
@refetchable(queryName: "NDAPageRefetchQuery") { @refetchable(queryName: "NDAPageRefetchQuery") {
nonDisclosureAgreement @required(action: THROW) { nonDisclosureAgreement @required(action: THROW) {
viewerSignature { viewerSignature {
@@ -108,12 +108,12 @@ export function NDAPage(props: {
const isDesktop = !isMobile; const isDesktop = !isMobile;
const queryData = usePreloadedQuery<NDAPageQueryType>(ndaPageQuery, props.queryRef); const queryData = usePreloadedQuery<NDAPageQueryType>(ndaPageQuery, props.queryRef);
const trustCenter = queryData.currentTrustCenter; const compliancePortal = queryData.currentCompliancePortal;
const viewer = queryData.viewer; const viewer = queryData.viewer;
const [data, refetch] = useRefetchableFragment<NDAPageRefetchQuery, NDAPageFragment$key>( const [data, refetch] = useRefetchableFragment<NDAPageRefetchQuery, NDAPageFragment$key>(
ndaPageFragment, ndaPageFragment,
trustCenter, compliancePortal,
); );
const ndaSignature = data.nonDisclosureAgreement.viewerSignature; const ndaSignature = data.nonDisclosureAgreement.viewerSignature;
@@ -217,7 +217,7 @@ export function NDAPage(props: {
}); });
}; };
const nda = trustCenter.nonDisclosureAgreement; const nda = compliancePortal.nonDisclosureAgreement;
if (!viewer) { if (!viewer) {
return <Navigate to="/connect" replace />; return <Navigate to="/connect" replace />;
} }
@@ -244,7 +244,7 @@ export function NDAPage(props: {
__( __(
"%s requires you to sign an NDA before accessing compliance documents.", "%s requires you to sign an NDA before accessing compliance documents.",
), ),
trustCenter.title, compliancePortal.title,
)} )}
</p> </p>
{isMobile && nda?.fileUrl && ( {isMobile && nda?.fileUrl && (

View File

@@ -19,7 +19,7 @@
// SOFTWARE. // SOFTWARE.
import { import {
getTrustCenterUrl, getCompliancePortalUrl,
groupBy, groupBy,
objectEntries, objectEntries,
sprintf, sprintf,
@@ -36,9 +36,9 @@ import { DocumentRow } from "#/components/DocumentRow";
import { RowHeader } from "#/components/RowHeader"; import { RowHeader } from "#/components/RowHeader";
import { Rows } from "#/components/Rows"; import { Rows } from "#/components/Rows";
import { SubprocessorRow } from "#/components/SubprocessorRow"; import { SubprocessorRow } from "#/components/SubprocessorRow";
import { TrustCenterFileRow } from "#/components/TrustCenterFileRow"; import { CompliancePortalFileRow } from "#/components/CompliancePortalFileRow";
import { documentTypeLabel } from "#/helpers/documents"; import { documentTypeLabel } from "#/helpers/documents";
import type { TrustGraphCurrentQuery$data } from "#/queries/__generated__/TrustGraphCurrentQuery.graphql"; import type { CompliancePortalGraphCurrentQuery$data } from "#/queries/__generated__/CompliancePortalGraphCurrentQuery.graphql";
import type { import type {
OverviewPageFragment$data, OverviewPageFragment$data,
@@ -46,7 +46,7 @@ import type {
} from "./__generated__/OverviewPageFragment.graphql"; } from "./__generated__/OverviewPageFragment.graphql";
const overviewFragment = graphql` const overviewFragment = graphql`
fragment OverviewPageFragment on TrustCenter { fragment OverviewPageFragment on CompliancePortal {
references(first: 14) { references(first: 14) {
edges { edges {
node { node {
@@ -77,12 +77,12 @@ const overviewFragment = graphql`
} }
} }
} }
trustCenterFiles(first: 5) { compliancePortalFiles(first: 5) {
edges { edges {
node { node {
id id
category category
...TrustCenterFileRowFragment ...CompliancePortalFileRowFragment
} }
} }
} }
@@ -90,26 +90,26 @@ const overviewFragment = graphql`
`; `;
export function OverviewPage() { export function OverviewPage() {
const { trustCenter } = useOutletContext<{ const { compliancePortal } = useOutletContext<{
trustCenter: OverviewPageFragment$key compliancePortal: OverviewPageFragment$key
& TrustGraphCurrentQuery$data["currentTrustCenter"]; & CompliancePortalGraphCurrentQuery$data["currentCompliancePortal"];
}>(); }>();
const fragment = useFragment(overviewFragment, trustCenter); const fragment = useFragment(overviewFragment, compliancePortal);
return ( return (
<div> <div>
<References <References
references={fragment.references.edges.map(edge => edge.node)} references={fragment.references.edges.map(edge => edge.node)}
/> />
<Documents <Documents
audits={trustCenter.audits.edges} audits={compliancePortal.audits.edges}
documents={fragment.documents.edges} documents={fragment.documents.edges}
files={fragment.trustCenterFiles.edges} files={fragment.compliancePortalFiles.edges}
url={getTrustCenterUrl("documents")} url={getCompliancePortalUrl("documents")}
/> />
<Subprocessors <Subprocessors
title={trustCenter.title} title={compliancePortal.title}
subprocessors={fragment.subprocessors.edges} subprocessors={fragment.subprocessors.edges}
url={getTrustCenterUrl("subprocessors")} url={getCompliancePortalUrl("subprocessors")}
/> />
</div> </div>
); );
@@ -122,9 +122,9 @@ function Documents({
url, url,
}: { }: {
documents: OverviewPageFragment$data["documents"]["edges"]; documents: OverviewPageFragment$data["documents"]["edges"];
files: OverviewPageFragment$data["trustCenterFiles"]["edges"]; files: OverviewPageFragment$data["compliancePortalFiles"]["edges"];
audits: NonNullable< audits: NonNullable<
TrustGraphCurrentQuery$data["currentTrustCenter"] CompliancePortalGraphCurrentQuery$data["currentCompliancePortal"]
>["audits"]["edges"]; >["audits"]["edges"];
url: string; url: string;
}) { }) {
@@ -171,7 +171,7 @@ function Documents({
<Fragment key={category}> <Fragment key={category}>
<RowHeader>{category}</RowHeader> <RowHeader>{category}</RowHeader>
{files.map(file => ( {files.map(file => (
<TrustCenterFileRow key={file.id} file={file} /> <CompliancePortalFileRow key={file.id} file={file} />
))} ))}
</Fragment> </Fragment>
))} ))}

View File

@@ -24,18 +24,18 @@ import { type PreloadedQuery, usePreloadedQuery } from "react-relay";
import { Rows } from "#/components/Rows"; import { Rows } from "#/components/Rows";
import { SubprocessorRow } from "#/components/SubprocessorRow"; import { SubprocessorRow } from "#/components/SubprocessorRow";
import type { TrustGraphCurrentSubprocessorsQuery } from "#/queries/__generated__/TrustGraphCurrentSubprocessorsQuery.graphql"; import type { CompliancePortalGraphCurrentSubprocessorsQuery } from "#/queries/__generated__/CompliancePortalGraphCurrentSubprocessorsQuery.graphql";
import { currentTrustSubprocessorsQuery } from "#/queries/TrustGraph"; import { currentTrustSubprocessorsQuery } from "#/queries/CompliancePortalGraph";
type Props = { type Props = {
queryRef: PreloadedQuery<TrustGraphCurrentSubprocessorsQuery>; queryRef: PreloadedQuery<CompliancePortalGraphCurrentSubprocessorsQuery>;
}; };
export function SubprocessorsPage({ queryRef }: Props) { export function SubprocessorsPage({ queryRef }: Props) {
const { __ } = useTranslate(); const { __ } = useTranslate();
const data = usePreloadedQuery<TrustGraphCurrentSubprocessorsQuery>(currentTrustSubprocessorsQuery, queryRef); const data = usePreloadedQuery<CompliancePortalGraphCurrentSubprocessorsQuery>(currentTrustSubprocessorsQuery, queryRef);
const subprocessors const subprocessors
= data.currentTrustCenter?.subprocessors.edges.map(edge => edge.node) ?? []; = data.currentCompliancePortal?.subprocessors.edges.map(edge => edge.node) ?? [];
const hasAnyCountries = subprocessors.some(subprocessor => subprocessor.countries.length > 0); const hasAnyCountries = subprocessors.some(subprocessor => subprocessor.countries.length > 0);
@@ -45,7 +45,7 @@ export function SubprocessorsPage({ queryRef }: Props) {
<p className="text-sm text-txt-secondary mb-4"> <p className="text-sm text-txt-secondary mb-4">
{sprintf( {sprintf(
__("Third-party subprocessors %s work with:"), __("Third-party subprocessors %s work with:"),
data.currentTrustCenter?.title ?? "", data.currentCompliancePortal?.title ?? "",
)} )}
</p> </p>
<Rows> <Rows>

View File

@@ -29,7 +29,7 @@ import type { UpdatesPageQuery } from "#/pages/__generated__/UpdatesPageQuery.gr
export const currentTrustUpdatesQuery = graphql` export const currentTrustUpdatesQuery = graphql`
query UpdatesPageQuery { query UpdatesPageQuery {
currentTrustCenter { currentCompliancePortal {
id id
updates(first: 50) { updates(first: 50) {
edges { edges {
@@ -57,7 +57,7 @@ export function UpdatesPage({ queryRef }: Props) {
); );
const items const items
= data.currentTrustCenter?.updates.edges.map(e => e.node) ?? []; = data.currentCompliancePortal?.updates.edges.map(e => e.node) ?? [];
return ( return (
<div> <div>

View File

@@ -28,7 +28,7 @@ import type { AuthLayoutQuery } from "./__generated__/AuthLayoutQuery.graphql";
export const authLayoutQuery = graphql` export const authLayoutQuery = graphql`
query AuthLayoutQuery { query AuthLayoutQuery {
currentTrustCenter @required(action: THROW) { currentCompliancePortal @required(action: THROW) {
logo { logo {
downloadUrl downloadUrl
} }
@@ -42,7 +42,7 @@ export const authLayoutQuery = graphql`
export function AuthLayout(props: { queryRef: PreloadedQuery<AuthLayoutQuery> }) { export function AuthLayout(props: { queryRef: PreloadedQuery<AuthLayoutQuery> }) {
const { queryRef } = props; const { queryRef } = props;
const { currentTrustCenter: compliancePage } = usePreloadedQuery<AuthLayoutQuery>(authLayoutQuery, queryRef); const { currentCompliancePortal: compliancePage } = usePreloadedQuery<AuthLayoutQuery>(authLayoutQuery, queryRef);
const theme = useSystemTheme(); const theme = useSystemTheme();
const logoFileUrl = theme === "dark" const logoFileUrl = theme === "dark"

View File

@@ -30,7 +30,7 @@ import type { ConnectPageQuery } from "./__generated__/ConnectPageQuery.graphql"
export const connectPageQuery = graphql` export const connectPageQuery = graphql`
query ConnectPageQuery { query ConnectPageQuery {
currentTrustCenter @required(action: THROW) { currentCompliancePortal @required(action: THROW) {
title title
} }
} }
@@ -45,7 +45,7 @@ export function ConnectPage(props: {
const safeContinueUrl = useSafeContinueUrl(); const safeContinueUrl = useSafeContinueUrl();
const { const {
currentTrustCenter: { title }, currentCompliancePortal: { title },
} = usePreloadedQuery<ConnectPageQuery>(connectPageQuery, queryRef); } = usePreloadedQuery<ConnectPageQuery>(connectPageQuery, queryRef);
usePageTitle(__(`Connect to ${title}'s Compliance Page`)); usePageTitle(__(`Connect to ${title}'s Compliance Page`));

View File

@@ -20,22 +20,22 @@
import { createContext, type ReactNode } from "react"; import { createContext, type ReactNode } from "react";
import type { TrustGraphCurrentQuery$data } from "#/queries/__generated__/TrustGraphCurrentQuery.graphql"; import type { CompliancePortalGraphCurrentQuery$data } from "#/queries/__generated__/CompliancePortalGraphCurrentQuery.graphql";
export const TrustCenterContext = createContext< export const CompliancePortalContext = createContext<
TrustGraphCurrentQuery$data["currentTrustCenter"] | null CompliancePortalGraphCurrentQuery$data["currentCompliancePortal"] | null
>(null); >(null);
export const TrustCenterProvider = ({ export const CompliancePortalProvider = ({
children, children,
trustCenter, compliancePortal,
}: { }: {
children: ReactNode; children: ReactNode;
trustCenter: TrustGraphCurrentQuery$data["currentTrustCenter"]; compliancePortal: CompliancePortalGraphCurrentQuery$data["currentCompliancePortal"];
}) => { }) => {
return ( return (
<TrustCenterContext.Provider value={trustCenter}> <CompliancePortalContext.Provider value={compliancePortal}>
{children} {children}
</TrustCenterContext.Provider> </CompliancePortalContext.Provider>
); );
}; };

View File

@@ -23,12 +23,12 @@ import { graphql } from "relay-runtime";
/* eslint-disable relay/unused-fields, relay/must-colocate-fragment-spreads */ /* eslint-disable relay/unused-fields, relay/must-colocate-fragment-spreads */
// Queries for custom domain (subdomain) approach // Queries for custom domain (subdomain) approach
export const currentTrustGraphQuery = graphql` export const currentCompliancePortalGraphQuery = graphql`
query TrustGraphCurrentQuery { query CompliancePortalGraphCurrentQuery {
viewer { viewer {
id id
} }
currentTrustCenter @required(action: THROW) { currentCompliancePortal @required(action: THROW) {
id id
slug slug
title title
@@ -91,8 +91,8 @@ export const currentTrustGraphQuery = graphql`
`; `;
export const currentTrustDocumentsQuery = graphql` export const currentTrustDocumentsQuery = graphql`
query TrustGraphCurrentDocumentsQuery { query CompliancePortalGraphCurrentDocumentsQuery {
currentTrustCenter { currentCompliancePortal {
id id
documents(first: 50) { documents(first: 50) {
edges { edges {
@@ -103,12 +103,12 @@ export const currentTrustDocumentsQuery = graphql`
} }
} }
} }
trustCenterFiles(first: 50) { compliancePortalFiles(first: 50) {
edges { edges {
node { node {
id id
category category
...TrustCenterFileRowFragment ...CompliancePortalFileRowFragment
} }
} }
} }
@@ -117,8 +117,8 @@ export const currentTrustDocumentsQuery = graphql`
`; `;
export const currentTrustSubprocessorsQuery = graphql` export const currentTrustSubprocessorsQuery = graphql`
query TrustGraphCurrentSubprocessorsQuery { query CompliancePortalGraphCurrentSubprocessorsQuery {
currentTrustCenter { currentCompliancePortal {
id id
subprocessors(first: 50) { subprocessors(first: 50) {
edges { edges {

View File

@@ -36,9 +36,9 @@ import { SubprocessorsPage } from "#/pages/SubprocessorsPage";
import { currentTrustUpdatesQuery, UpdatesPage } from "#/pages/UpdatesPage"; import { currentTrustUpdatesQuery, UpdatesPage } from "#/pages/UpdatesPage";
import { import {
currentTrustDocumentsQuery, currentTrustDocumentsQuery,
currentTrustGraphQuery, currentCompliancePortalGraphQuery,
currentTrustSubprocessorsQuery, currentTrustSubprocessorsQuery,
} from "#/queries/TrustGraph"; } from "#/queries/CompliancePortalGraph";
import { DocumentPageErrorBoundary } from "./components/DocumentPageErrorBoundary"; import { DocumentPageErrorBoundary } from "./components/DocumentPageErrorBoundary";
import { PageError } from "./components/PageError"; import { PageError } from "./components/PageError";
@@ -79,7 +79,7 @@ const routes = [
{ {
path: "/overview", path: "/overview",
loader: loaderFromQueryLoader(() => loader: loaderFromQueryLoader(() =>
loadQuery(consoleEnvironment, currentTrustGraphQuery, {}), loadQuery(consoleEnvironment, currentCompliancePortalGraphQuery, {}),
), ),
Component: withQueryRef(MainLayout), Component: withQueryRef(MainLayout),
Fallback: MainSkeleton, Fallback: MainSkeleton,
@@ -100,7 +100,7 @@ const routes = [
{ {
path: "/documents", path: "/documents",
loader: loaderFromQueryLoader(() => loader: loaderFromQueryLoader(() =>
loadQuery(consoleEnvironment, currentTrustGraphQuery, {}), loadQuery(consoleEnvironment, currentCompliancePortalGraphQuery, {}),
), ),
Component: withQueryRef(MainLayout), Component: withQueryRef(MainLayout),
Fallback: MainSkeleton, Fallback: MainSkeleton,
@@ -119,7 +119,7 @@ const routes = [
{ {
path: "/subprocessors", path: "/subprocessors",
loader: loaderFromQueryLoader(() => loader: loaderFromQueryLoader(() =>
loadQuery(consoleEnvironment, currentTrustGraphQuery, {}), loadQuery(consoleEnvironment, currentCompliancePortalGraphQuery, {}),
), ),
Component: withQueryRef(MainLayout), Component: withQueryRef(MainLayout),
Fallback: MainSkeleton, Fallback: MainSkeleton,
@@ -138,7 +138,7 @@ const routes = [
{ {
path: "/updates", path: "/updates",
loader: loaderFromQueryLoader(() => loader: loaderFromQueryLoader(() =>
loadQuery(consoleEnvironment, currentTrustGraphQuery, {}), loadQuery(consoleEnvironment, currentCompliancePortalGraphQuery, {}),
), ),
Component: withQueryRef(MainLayout), Component: withQueryRef(MainLayout),
Fallback: MainSkeleton, Fallback: MainSkeleton,