Add compliance frameworks

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2026-03-03 08:56:39 +01:00
parent 4d882e37b0
commit c17c53e80f
36 changed files with 5303 additions and 90 deletions

View File

@@ -0,0 +1,32 @@
import { FrameworkLogo } from "@probo/ui";
import { useFragment } from "react-relay";
import { graphql } from "relay-runtime";
import type { FrameworkBadgeFragment$key } from "./__generated__/FrameworkBadgeFragment.graphql";
const frameworkFragment = graphql`
fragment FrameworkBadgeFragment on Framework {
id
name
lightLogoURL
darkLogoURL
}
`;
export function FrameworkBadge(props: { framework: FrameworkBadgeFragment$key }) {
const framework = useFragment(frameworkFragment, props.framework);
return (
<div className="flex flex-col gap-2 items-center w-19">
<FrameworkLogo
className="size-19"
lightLogoURL={framework.lightLogoURL}
darkLogoURL={framework.darkLogoURL}
name={framework.name}
/>
<div className="txt-primary text-sm max-w-19 overflow-hidden min-w-0 whitespace-nowrap text-ellipsis">
{framework.name}
</div>
</div>
);
}

View File

@@ -19,7 +19,7 @@ import type { TrustGraphCurrentQuery$data } from "#/queries/__generated__/TrustG
import { getPathPrefix } from "#/utils/pathPrefix";
import type { OrganizationSidebar_requestAllAccessesMutation } from "./__generated__/OrganizationSidebar_requestAllAccessesMutation.graphql";
import { AuditRowAvatar } from "./AuditRow";
import { FrameworkBadge } from "./FrameworkBadge";
const requestAllAccessesMutation = graphql`
mutation OrganizationSidebar_requestAllAccessesMutation {
@@ -154,7 +154,7 @@ export function OrganizationSidebar({
<hr className="my-6 -mx-6 h-px bg-border-low border-none" />
{/* Certifications */}
{trustCenter.audits.edges.length > 0 && (
{trustCenter.complianceFrameworks.edges.length > 0 && (
<>
<div className="space-y-4">
<h2 className="text-xs text-txt-secondary flex gap-1 items-center">
@@ -167,8 +167,8 @@ export function OrganizationSidebar({
gridTemplateColumns: "repeat(auto-fit, 75px",
}}
>
{trustCenter.audits.edges.map(audit => (
<AuditRowAvatar key={audit.node.id} audit={audit.node} />
{trustCenter.complianceFrameworks.edges.map(edge => (
<FrameworkBadge key={edge.node.id} framework={edge.node.framework} />
))}
</div>
</div>

View File

@@ -0,0 +1,66 @@
/**
* @generated SignedSource<<f13ba91513aa9a472ab62c4c6a93b6bb>>
* @lightSyntaxTransform
* @nogrep
*/
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ReaderFragment } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime";
export type FrameworkBadgeFragment$data = {
readonly darkLogoURL: string | null | undefined;
readonly id: string;
readonly lightLogoURL: string | null | undefined;
readonly name: string;
readonly " $fragmentType": "FrameworkBadgeFragment";
};
export type FrameworkBadgeFragment$key = {
readonly " $data"?: FrameworkBadgeFragment$data;
readonly " $fragmentSpreads": FragmentRefs<"FrameworkBadgeFragment">;
};
const node: ReaderFragment = {
"argumentDefinitions": [],
"kind": "Fragment",
"metadata": null,
"name": "FrameworkBadgeFragment",
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "lightLogoURL",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "darkLogoURL",
"storageKey": null
}
],
"type": "Framework",
"abstractKey": null
};
(node as any).hash = "cdfaf9a4a0e2cb667a5ef8d3e7db1f99";
export default node;

View File

@@ -34,6 +34,16 @@ export const currentTrustGraphQuery = graphql`
}
}
}
complianceFrameworks(first: 50) {
edges {
node {
id
framework {
...FrameworkBadgeFragment
}
}
}
}
}
}
`;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<47a6e80d3532b4c93d18495c2be7676d>>
* @generated SignedSource<<4eef287e3e3152affa1b16189a504c36>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -22,6 +22,16 @@ export type TrustGraphCurrentQuery$data = {
};
}>;
};
readonly complianceFrameworks: {
readonly edges: ReadonlyArray<{
readonly node: {
readonly framework: {
readonly " $fragmentSpreads": FragmentRefs<"FrameworkBadgeFragment">;
};
readonly id: string;
};
}>;
};
readonly darkLogoFileUrl: string | null | undefined;
readonly id: string;
readonly logoFileUrl: string | null | undefined;
@@ -193,6 +203,33 @@ v16 = {
(v6/*: any*/)
],
"storageKey": null
},
v17 = {
"alias": null,
"args": null,
"concreteType": "Framework",
"kind": "LinkedField",
"name": "framework",
"plural": false,
"selections": [
(v0/*: any*/),
(v7/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "lightLogoURL",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "darkLogoURL",
"storageKey": null
}
],
"storageKey": null
};
return {
"fragment": {
@@ -300,6 +337,56 @@ return {
}
],
"storageKey": "audits(first:50)"
},
{
"alias": null,
"args": (v13/*: any*/),
"concreteType": "ComplianceFrameworkConnection",
"kind": "LinkedField",
"name": "complianceFrameworks",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "ComplianceFrameworkEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "ComplianceFramework",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v0/*: any*/),
{
"alias": null,
"args": null,
"concreteType": "Framework",
"kind": "LinkedField",
"name": "framework",
"plural": false,
"selections": [
{
"args": null,
"kind": "FragmentSpread",
"name": "FrameworkBadgeFragment"
}
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": "complianceFrameworks(first:50)"
}
],
"storageKey": null
@@ -612,33 +699,7 @@ return {
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "Framework",
"kind": "LinkedField",
"name": "framework",
"plural": false,
"selections": [
(v0/*: any*/),
(v7/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "lightLogoURL",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "darkLogoURL",
"storageKey": null
}
],
"storageKey": null
}
(v17/*: any*/)
],
"storageKey": null
}
@@ -647,6 +708,41 @@ return {
}
],
"storageKey": "audits(first:50)"
},
{
"alias": null,
"args": (v13/*: any*/),
"concreteType": "ComplianceFrameworkConnection",
"kind": "LinkedField",
"name": "complianceFrameworks",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "ComplianceFrameworkEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "ComplianceFramework",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v0/*: any*/),
(v17/*: any*/)
],
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": "complianceFrameworks(first:50)"
}
],
"storageKey": null
@@ -654,16 +750,16 @@ return {
]
},
"params": {
"cacheID": "42b477429f092f97b0f444433a78c6d1",
"cacheID": "e64b984bdcf5a5fb2f19e69c6205ba9a",
"id": null,
"metadata": {},
"name": "TrustGraphCurrentQuery",
"operationKind": "query",
"text": "query TrustGraphCurrentQuery {\n currentTrustCenter {\n id\n slug\n logoFileUrl\n darkLogoFileUrl\n nonDisclosureAgreement {\n fileName\n fileUrl\n viewerSignature {\n status\n id\n }\n }\n organization {\n name\n description\n websiteUrl\n email\n headquarterAddress\n id\n }\n ...OverviewPageFragment\n vendorInfo: vendors(first: 0) {\n totalCount\n }\n audits(first: 50) {\n edges {\n node {\n id\n ...AuditRowFragment\n }\n }\n }\n }\n}\n\nfragment AuditRowFragment on Audit {\n name\n report {\n id\n filename\n isUserAuthorized\n access {\n id\n status\n }\n }\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n}\n\nfragment DocumentRowFragment on Document {\n id\n title\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment OverviewPageFragment on TrustCenter {\n references(first: 14) {\n edges {\n node {\n id\n name\n logoUrl\n websiteUrl\n }\n }\n }\n vendors(first: 3) {\n edges {\n node {\n id\n countries\n ...VendorRowFragment\n }\n }\n }\n documents(first: 5) {\n edges {\n node {\n id\n ...DocumentRowFragment\n documentType\n }\n }\n }\n trustCenterFiles(first: 5) {\n edges {\n node {\n id\n category\n ...TrustCenterFileRowFragment\n }\n }\n }\n}\n\nfragment TrustCenterFileRowFragment on TrustCenterFile {\n id\n name\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment VendorRowFragment on Vendor {\n name\n description\n websiteUrl\n countries\n}\n"
"text": "query TrustGraphCurrentQuery {\n currentTrustCenter {\n id\n slug\n logoFileUrl\n darkLogoFileUrl\n nonDisclosureAgreement {\n fileName\n fileUrl\n viewerSignature {\n status\n id\n }\n }\n organization {\n name\n description\n websiteUrl\n email\n headquarterAddress\n id\n }\n ...OverviewPageFragment\n vendorInfo: vendors(first: 0) {\n totalCount\n }\n audits(first: 50) {\n edges {\n node {\n id\n ...AuditRowFragment\n }\n }\n }\n complianceFrameworks(first: 50) {\n edges {\n node {\n id\n framework {\n ...FrameworkBadgeFragment\n id\n }\n }\n }\n }\n }\n}\n\nfragment AuditRowFragment on Audit {\n name\n report {\n id\n filename\n isUserAuthorized\n access {\n id\n status\n }\n }\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n}\n\nfragment DocumentRowFragment on Document {\n id\n title\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment FrameworkBadgeFragment on Framework {\n id\n name\n lightLogoURL\n darkLogoURL\n}\n\nfragment OverviewPageFragment on TrustCenter {\n references(first: 14) {\n edges {\n node {\n id\n name\n logoUrl\n websiteUrl\n }\n }\n }\n vendors(first: 3) {\n edges {\n node {\n id\n countries\n ...VendorRowFragment\n }\n }\n }\n documents(first: 5) {\n edges {\n node {\n id\n ...DocumentRowFragment\n documentType\n }\n }\n }\n trustCenterFiles(first: 5) {\n edges {\n node {\n id\n category\n ...TrustCenterFileRowFragment\n }\n }\n }\n}\n\nfragment TrustCenterFileRowFragment on TrustCenterFile {\n id\n name\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment VendorRowFragment on Vendor {\n name\n description\n websiteUrl\n countries\n}\n"
}
};
})();
(node as any).hash = "41cf8e5383cefdd5b3b7b85263eccb1f";
(node as any).hash = "d1ce7e38b42fad48e9f38bf00bb34d56";
export default node;