Add vendor business and security owner

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-04-12 14:53:16 -07:00
parent 8261e13857
commit 9b868220f6
19 changed files with 908 additions and 240 deletions

View File

@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
## [Unreleased] ## [Unreleased]
### Added
- Added business owner and security owner fields to vendors
### Changed
- Improved vendor detail page with organized sections
- Split information into logical sections (Basic Information, Ownership, Risk & Service, Documentation)
- Better visual organization of vendor information
## [0.8.0] - 2025-04-12 ## [0.8.0] - 2025-04-12
### Added ### Added

View File

@@ -26,7 +26,7 @@ import { EditRiskPage } from "./risks/EditRiskPage";
import { NewRiskPage } from "./risks/NewRiskPage"; import { NewRiskPage } from "./risks/NewRiskPage";
import { ListRiskPage } from "./risks/ListRiskPage"; import { ListRiskPage } from "./risks/ListRiskPage";
import ShowRiskView from "./risks/ShowRiskView"; import ShowRiskView from "./risks/ShowRiskView";
import { VendorListPage } from "./vendors/VendorListPage"; import { ListVendorPage } from "./vendors/ListVendorPage";
import { VendorPage } from "./vendors/VendorPage"; import { VendorPage } from "./vendors/VendorPage";
export function OrganizationsRoutes() { export function OrganizationsRoutes() {
@@ -37,7 +37,7 @@ export function OrganizationsRoutes() {
<Route path="people" element={<PeopleListPage />} /> <Route path="people" element={<PeopleListPage />} />
<Route path="people/new" element={<NewPeoplePage />} /> <Route path="people/new" element={<NewPeoplePage />} />
<Route path="people/:peopleId" element={<PeoplePage />} /> <Route path="people/:peopleId" element={<PeoplePage />} />
<Route path="vendors" element={<VendorListPage />} /> <Route path="vendors" element={<ListVendorPage />} />
<Route path="frameworks" element={<FrameworkListPage />} /> <Route path="frameworks" element={<FrameworkListPage />} />
<Route path="frameworks/new" element={<NewFrameworkPage />} /> <Route path="frameworks/new" element={<NewFrameworkPage />} />
<Route path="frameworks/:frameworkId/*"> <Route path="frameworks/:frameworkId/*">

View File

@@ -4,9 +4,9 @@ import { lazy } from "@probo/react-lazy";
import { useLocation } from "react-router"; import { useLocation } from "react-router";
import { ErrorBoundaryWithLocation } from "../ErrorBoundary"; import { ErrorBoundaryWithLocation } from "../ErrorBoundary";
const VendorListView = lazy(() => import("./VendorListView")); const VendorListView = lazy(() => import("./ListVendorView"));
export function VendorListViewSkeleton() { export function ListVendorViewSkeleton() {
return ( return (
<PageTemplateSkeleton <PageTemplateSkeleton
title="Vendors" title="Vendors"
@@ -34,11 +34,11 @@ export function VendorListViewSkeleton() {
); );
} }
export function VendorListPage() { export function ListVendorPage() {
const location = useLocation(); const location = useLocation();
return ( return (
<Suspense key={location.pathname} fallback={<VendorListViewSkeleton />}> <Suspense key={location.pathname} fallback={<ListVendorViewSkeleton />}>
<ErrorBoundaryWithLocation> <ErrorBoundaryWithLocation>
<VendorListView /> <VendorListView />
</ErrorBoundaryWithLocation> </ErrorBoundaryWithLocation>

View File

@@ -17,12 +17,12 @@ import { Link } from "react-router";
import Fuse from "fuse.js"; import Fuse from "fuse.js";
import { useToast } from "@/hooks/use-toast"; import { useToast } from "@/hooks/use-toast";
import { PageTemplate } from "@/components/PageTemplate"; import { PageTemplate } from "@/components/PageTemplate";
import { VendorListViewSkeleton } from "./VendorListPage"; import { ListVendorViewSkeleton } from "./ListVendorPage";
import { VendorListViewQuery as VendorListViewQueryType } from "./__generated__/VendorListViewQuery.graphql"; import { ListVendorViewCreateVendorMutation } from "./__generated__/ListVendorViewCreateVendorMutation.graphql";
import { VendorListViewCreateVendorMutation } from "./__generated__/VendorListViewCreateVendorMutation.graphql"; import { ListVendorViewPaginationQuery } from "./__generated__/ListVendorViewPaginationQuery.graphql";
import { VendorListViewDeleteVendorMutation } from "./__generated__/VendorListViewDeleteVendorMutation.graphql"; import { ListVendorView_vendors$key } from "./__generated__/ListVendorView_vendors.graphql";
import { VendorListViewPaginationQuery } from "./__generated__/VendorListViewPaginationQuery.graphql"; import { ListVendorViewQuery } from "./__generated__/ListVendorViewQuery.graphql";
import { VendorListView_vendors$key } from "./__generated__/VendorListView_vendors.graphql"; import { ListVendorViewDeleteVendorMutation } from "./__generated__/ListVendorViewDeleteVendorMutation.graphql";
interface VendorData { interface VendorData {
name: string; name: string;
@@ -44,8 +44,8 @@ interface VendorData {
const ITEMS_PER_PAGE = 25; const ITEMS_PER_PAGE = 25;
const vendorListViewQuery = graphql` const listVendorViewQuery = graphql`
query VendorListViewQuery( query ListVendorViewQuery(
$organizationId: ID! $organizationId: ID!
$first: Int $first: Int
$after: CursorKey $after: CursorKey
@@ -55,15 +55,15 @@ const vendorListViewQuery = graphql`
organization: node(id: $organizationId) { organization: node(id: $organizationId) {
id id
...VendorListView_vendors ...ListVendorView_vendors
@arguments(first: $first, after: $after, last: $last, before: $before) @arguments(first: $first, after: $after, last: $last, before: $before)
} }
} }
`; `;
const vendorListFragment = graphql` const vendorListFragment = graphql`
fragment VendorListView_vendors on Organization fragment ListVendorView_vendors on Organization
@refetchable(queryName: "VendorListViewPaginationQuery") @refetchable(queryName: "ListVendorViewPaginationQuery")
@argumentDefinitions( @argumentDefinitions(
first: { type: "Int" } first: { type: "Int" }
after: { type: "CursorKey" } after: { type: "CursorKey" }
@@ -99,7 +99,7 @@ const vendorListFragment = graphql`
`; `;
const createVendorMutation = graphql` const createVendorMutation = graphql`
mutation VendorListViewCreateVendorMutation( mutation ListVendorViewCreateVendorMutation(
$input: CreateVendorInput! $input: CreateVendorInput!
$connections: [ID!]! $connections: [ID!]!
) { ) {
@@ -119,7 +119,7 @@ const createVendorMutation = graphql`
`; `;
const deleteVendorMutation = graphql` const deleteVendorMutation = graphql`
mutation VendorListViewDeleteVendorMutation( mutation ListVendorViewDeleteVendorMutation(
$input: DeleteVendorInput! $input: DeleteVendorInput!
$connections: [ID!]! $connections: [ID!]!
) { ) {
@@ -183,14 +183,14 @@ function LoadBelowButton({
); );
} }
function VendorListContent({ function ListVendorContent({
queryRef, queryRef,
}: { }: {
queryRef: PreloadedQuery<VendorListViewQueryType>; queryRef: PreloadedQuery<ListVendorViewQuery>;
}) { }) {
const { toast } = useToast(); const { toast } = useToast();
const data = usePreloadedQuery<VendorListViewQueryType>( const data = usePreloadedQuery<ListVendorViewQuery>(
vendorListViewQuery, listVendorViewQuery,
queryRef queryRef
); );
const [, setSearchParams] = useSearchParams(); const [, setSearchParams] = useSearchParams();
@@ -200,9 +200,9 @@ function VendorListContent({
const [vendorsData, setVendorsData] = useState<VendorData[]>([]); const [vendorsData, setVendorsData] = useState<VendorData[]>([]);
const [isLoadingVendors, setIsLoadingVendors] = useState(false); const [isLoadingVendors, setIsLoadingVendors] = useState(false);
const [createVendor] = const [createVendor] =
useMutation<VendorListViewCreateVendorMutation>(createVendorMutation); useMutation<ListVendorViewCreateVendorMutation>(createVendorMutation);
const [deleteVendor] = const [deleteVendor] =
useMutation<VendorListViewDeleteVendorMutation>(deleteVendorMutation); useMutation<ListVendorViewDeleteVendorMutation>(deleteVendorMutation);
const { organizationId } = useParams(); const { organizationId } = useParams();
useEffect(() => { useEffect(() => {
@@ -239,8 +239,8 @@ function VendorListContent({
isLoadingNext, isLoadingNext,
isLoadingPrevious, isLoadingPrevious,
} = usePaginationFragment< } = usePaginationFragment<
VendorListViewPaginationQuery, ListVendorViewPaginationQuery,
VendorListView_vendors$key ListVendorView_vendors$key
>(vendorListFragment, data.organization); >(vendorListFragment, data.organization);
const vendors = const vendors =
@@ -390,14 +390,6 @@ function VendorListContent({
</Avatar> </Avatar>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<p className="font-medium">{vendor?.name}</p> <p className="font-medium">{vendor?.name}</p>
{vendor?.description && (
<>
<span className="text-tertiary">•</span>
<p className="text-sm text-tertiary">
{vendor.description}
</p>
</>
)}
</div> </div>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
@@ -484,10 +476,10 @@ function VendorListContent({
); );
} }
export default function VendorListView() { export default function ListVendorView() {
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const [queryRef, loadQuery] = const [queryRef, loadQuery] =
useQueryLoader<VendorListViewQueryType>(vendorListViewQuery); useQueryLoader<ListVendorViewQuery>(listVendorViewQuery);
const { organizationId } = useParams(); const { organizationId } = useParams();
@@ -505,12 +497,12 @@ export default function VendorListView() {
}, [loadQuery, organizationId]); }, [loadQuery, organizationId]);
if (!queryRef) { if (!queryRef) {
return <VendorListViewSkeleton />; return <ListVendorViewSkeleton />;
} }
return ( return (
<Suspense fallback={<VendorListViewSkeleton />}> <Suspense fallback={<ListVendorViewSkeleton />}>
<VendorListContent queryRef={queryRef} /> <ListVendorContent queryRef={queryRef} />
</Suspense> </Suspense>
); );
} }

View File

@@ -5,7 +5,7 @@ import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { useToast } from "@/hooks/use-toast"; import { useToast } from "@/hooks/use-toast";
import { HelpCircle, X } from "lucide-react"; import { HelpCircle, X, User } from "lucide-react";
import { import {
graphql, graphql,
PreloadedQuery, PreloadedQuery,
@@ -23,9 +23,10 @@ import { useParams } from "react-router";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { PageTemplate } from "@/components/PageTemplate"; import { PageTemplate } from "@/components/PageTemplate";
import { VendorViewSkeleton } from "./VendorPage"; import { VendorViewSkeleton } from "./VendorPage";
import PeopleSelector from "@/components/PeopleSelector";
const vendorViewQuery = graphql` const vendorViewQuery = graphql`
query VendorViewQuery($vendorId: ID!) { query VendorViewQuery($vendorId: ID!, $organizationId: ID!) {
node(id: $vendorId) { node(id: $vendorId) {
... on Vendor { ... on Vendor {
id id
@@ -46,6 +47,14 @@ const vendorViewQuery = graphql`
headquarterAddress headquarterAddress
legalName legalName
websiteUrl websiteUrl
businessOwner {
id
fullName
}
securityOwner {
id
fullName
}
createdAt createdAt
updatedAt updatedAt
complianceReports(first: 100) complianceReports(first: 100)
@@ -64,6 +73,9 @@ const vendorViewQuery = graphql`
} }
} }
} }
organization: node(id: $organizationId) {
...PeopleSelector_organization
}
} }
`; `;
@@ -89,6 +101,14 @@ const updateVendorMutation = graphql`
headquarterAddress headquarterAddress
legalName legalName
websiteUrl websiteUrl
businessOwner {
id
fullName
}
securityOwner {
id
fullName
}
updatedAt updatedAt
} }
} }
@@ -133,12 +153,14 @@ function EditableField({
onChange, onChange,
type = "text", type = "text",
helpText, helpText,
disabled = false,
}: { }: {
label: string; label: string;
value: string; value: string;
onChange: (value: string) => void; onChange: (value: string) => void;
type?: string; type?: string;
helpText?: string; helpText?: string;
disabled?: boolean;
}) { }) {
return ( return (
<div className="space-y-2"> <div className="space-y-2">
@@ -151,6 +173,7 @@ function EditableField({
type={type} type={type}
value={value} value={value}
onChange={(e) => onChange(e.target.value)} onChange={(e) => onChange(e.target.value)}
disabled={disabled}
/> />
{helpText && <p className="text-sm text-secondary">{helpText}</p>} {helpText && <p className="text-sm text-secondary">{helpText}</p>}
</div> </div>
@@ -348,6 +371,7 @@ function VendorViewContent({
}: { }: {
queryRef: PreloadedQuery<VendorViewQueryType>; queryRef: PreloadedQuery<VendorViewQueryType>;
}) { }) {
const { organizationId } = useParams();
const data = usePreloadedQuery(vendorViewQuery, queryRef); const data = usePreloadedQuery(vendorViewQuery, queryRef);
const [editedFields, setEditedFields] = useState<Set<string>>(new Set()); const [editedFields, setEditedFields] = useState<Set<string>>(new Set());
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
@@ -368,6 +392,8 @@ function VendorViewContent({
headquarterAddress: data.node.headquarterAddress || "", headquarterAddress: data.node.headquarterAddress || "",
legalName: data.node.legalName || "", legalName: data.node.legalName || "",
websiteUrl: data.node.websiteUrl || "", websiteUrl: data.node.websiteUrl || "",
businessOwnerId: data.node.businessOwner?.id || null,
securityOwnerId: data.node.securityOwner?.id || null,
}); });
const [updateVendor] = const [updateVendor] =
useMutation<VendorViewUpdateVendorMutation>(updateVendorMutation); useMutation<VendorViewUpdateVendorMutation>(updateVendorMutation);
@@ -391,6 +417,8 @@ function VendorViewContent({
serviceTerminationAt: formData.serviceTerminationAt serviceTerminationAt: formData.serviceTerminationAt
? formatDateForAPI(formData.serviceTerminationAt) ? formatDateForAPI(formData.serviceTerminationAt)
: null, : null,
businessOwnerId: formData.businessOwnerId || undefined,
securityOwnerId: formData.securityOwnerId || undefined,
}; };
updateVendor({ updateVendor({
@@ -407,6 +435,7 @@ function VendorViewContent({
variant: "default", variant: "default",
}); });
setEditedFields(new Set()); setEditedFields(new Set());
loadQuery({ vendorId: data.node.id!, organizationId: organizationId! });
}, },
onError: (error) => { onError: (error) => {
if (error.message?.includes("concurrent modification")) { if (error.message?.includes("concurrent modification")) {
@@ -417,7 +446,10 @@ function VendorViewContent({
variant: "destructive", variant: "destructive",
}); });
loadQuery({ vendorId: data.node.id! }); loadQuery({
vendorId: data.node.id!,
organizationId: organizationId!,
});
} else { } else {
toast({ toast({
title: "Error", title: "Error",
@@ -427,7 +459,7 @@ function VendorViewContent({
} }
}, },
}); });
}, [updateVendor, data.node.id, formData, loadQuery, toast]); }, [updateVendor, data.node.id, formData, loadQuery, toast, organizationId]);
const handleFieldChange = (field: keyof typeof formData, value: unknown) => { const handleFieldChange = (field: keyof typeof formData, value: unknown) => {
setFormData((prev) => ({ setFormData((prev) => ({
@@ -456,6 +488,8 @@ function VendorViewContent({
headquarterAddress: data.node.headquarterAddress || "", headquarterAddress: data.node.headquarterAddress || "",
legalName: data.node.legalName || "", legalName: data.node.legalName || "",
websiteUrl: data.node.websiteUrl || "", websiteUrl: data.node.websiteUrl || "",
businessOwnerId: data.node.businessOwner?.id || null,
securityOwnerId: data.node.securityOwner?.id || null,
}); });
setEditedFields(new Set()); setEditedFields(new Set());
}; };
@@ -480,7 +514,10 @@ function VendorViewContent({
description: "Compliance report deleted successfully", description: "Compliance report deleted successfully",
variant: "default", variant: "default",
}); });
loadQuery({ vendorId: data.node.id! }); loadQuery({
vendorId: data.node.id!,
organizationId: organizationId!,
});
}, },
onError: (error) => { onError: (error) => {
toast({ toast({
@@ -491,7 +528,13 @@ function VendorViewContent({
}, },
}); });
}, },
[deleteVendorComplianceReport, data.node.id, loadQuery, toast] [
deleteVendorComplianceReport,
data.node.id,
loadQuery,
toast,
organizationId,
]
); );
const handleUploadReport = useCallback( const handleUploadReport = useCallback(
@@ -547,7 +590,10 @@ function VendorViewContent({
description: "Compliance report uploaded successfully", description: "Compliance report uploaded successfully",
variant: "default", variant: "default",
}); });
loadQuery({ vendorId: data.node.id! }); loadQuery({
vendorId: data.node.id!,
organizationId: organizationId!,
});
}, },
onError: (error) => { onError: (error) => {
toast({ toast({
@@ -561,12 +607,28 @@ function VendorViewContent({
}; };
reader.readAsDataURL(file); reader.readAsDataURL(file);
}, },
[uploadVendorComplianceReport, data.node.id, loadQuery, toast] [
uploadVendorComplianceReport,
data.node.id,
loadQuery,
toast,
organizationId,
]
); );
return ( return (
<PageTemplate title={formData.name}> <PageTemplate title={formData.name}>
<div className="max-w-2xl space-y-6"> <div className="max-w-2xl space-y-6">
<Card className="p-6">
<div className="space-y-4">
<div className="space-y-2">
<h2 className="text-lg font-medium">Basic Information</h2>
<p className="text-sm text-secondary">
General information about the vendor
</p>
</div>
<div className="space-y-4">
<EditableField <EditableField
label="Name" label="Name"
value={formData.name} value={formData.name}
@@ -588,7 +650,9 @@ function VendorViewContent({
<EditableField <EditableField
label="Headquarter Address" label="Headquarter Address"
value={formData.headquarterAddress} value={formData.headquarterAddress}
onChange={(value) => handleFieldChange("headquarterAddress", value)} onChange={(value) =>
handleFieldChange("headquarterAddress", value)
}
/> />
<EditableField <EditableField
@@ -596,13 +660,68 @@ function VendorViewContent({
value={formData.websiteUrl} value={formData.websiteUrl}
onChange={(value) => handleFieldChange("websiteUrl", value)} onChange={(value) => handleFieldChange("websiteUrl", value)}
/> />
</div>
</div>
</Card>
<Card className="p-6"> <Card className="p-6">
<div className="space-y-4"> <div className="space-y-4">
<div className="space-y-2"> <div className="space-y-2">
<h2 className="text-lg font-medium">Service Information</h2> <h2 className="text-lg font-medium">Ownership Information</h2>
<p className="text-sm text-secondary"> <p className="text-sm text-secondary">
Basic information about the vendor service Individuals responsible for this vendor
</p>
</div>
<div className="space-y-4">
<div className="space-y-2">
<div className="flex items-center gap-2">
<User className="h-4 w-4 text-tertiary" />
<Label className="text-sm">Business Owner</Label>
</div>
<PeopleSelector
organizationRef={data.organization}
selectedPersonId={formData.businessOwnerId}
onSelect={(value) =>
handleFieldChange("businessOwnerId", value)
}
placeholder="Select business owner (optional)"
/>
<p className="text-sm text-secondary">
The person responsible for business decisions related to this
vendor
</p>
</div>
<div className="space-y-2">
<div className="flex items-center gap-2">
<User className="h-4 w-4 text-tertiary" />
<Label className="text-sm">Security Owner</Label>
</div>
<PeopleSelector
organizationRef={data.organization}
selectedPersonId={formData.securityOwnerId}
onSelect={(value) =>
handleFieldChange("securityOwnerId", value)
}
placeholder="Select security owner (optional)"
/>
<p className="text-sm text-secondary">
The person responsible for security oversight of this vendor
</p>
</div>
</div>
</div>
</Card>
<Card className="p-6">
<div className="space-y-4">
<div className="space-y-2">
<h2 className="text-lg font-medium">
Risk & Service Information
</h2>
<p className="text-sm text-secondary">
Information about service criticality and risk
</p> </p>
</div> </div>
@@ -735,7 +854,7 @@ function VendorViewContent({
<Card className="p-6"> <Card className="p-6">
<div className="space-y-4"> <div className="space-y-4">
<div className="space-y-2"> <div className="space-y-2">
<h2 className="text-lg font-medium">URLs</h2> <h2 className="text-lg font-medium">Documentation & Links</h2>
<p className="text-sm text-secondary"> <p className="text-sm text-secondary">
Important URLs related to the vendor Important URLs related to the vendor
</p> </p>
@@ -860,13 +979,13 @@ function VendorViewContent({
} }
export default function VendorView() { export default function VendorView() {
const { vendorId } = useParams(); const { vendorId, organizationId } = useParams();
const [queryRef, loadQuery] = const [queryRef, loadQuery] =
useQueryLoader<VendorViewQueryType>(vendorViewQuery); useQueryLoader<VendorViewQueryType>(vendorViewQuery);
useEffect(() => { useEffect(() => {
loadQuery({ vendorId: vendorId! }); loadQuery({ vendorId: vendorId!, organizationId: organizationId! });
}, [loadQuery, vendorId]); }, [loadQuery, vendorId, organizationId]);
if (!queryRef) { if (!queryRef) {
return <VendorViewSkeleton />; return <VendorViewSkeleton />;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<d8ebd7f4de7a9e2e314f93e5e6b61e25>> * @generated SignedSource<<178462391e73ba2adb212005c3813f33>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -12,6 +12,7 @@ import { ConcreteRequest } from 'relay-runtime';
export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT"; export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT";
export type ServiceCriticality = "HIGH" | "LOW" | "MEDIUM"; export type ServiceCriticality = "HIGH" | "LOW" | "MEDIUM";
export type CreateVendorInput = { export type CreateVendorInput = {
businessOwnerId?: string | null | undefined;
category?: string | null | undefined; category?: string | null | undefined;
certifications?: ReadonlyArray<string> | null | undefined; certifications?: ReadonlyArray<string> | null | undefined;
dataProcessingAgreementUrl?: string | null | undefined; dataProcessingAgreementUrl?: string | null | undefined;
@@ -22,6 +23,7 @@ export type CreateVendorInput = {
organizationId: string; organizationId: string;
privacyPolicyUrl?: string | null | undefined; privacyPolicyUrl?: string | null | undefined;
riskTier: RiskTier; riskTier: RiskTier;
securityOwnerId?: string | null | undefined;
securityPageUrl?: string | null | undefined; securityPageUrl?: string | null | undefined;
serviceCriticality: ServiceCriticality; serviceCriticality: ServiceCriticality;
serviceLevelAgreementUrl?: string | null | undefined; serviceLevelAgreementUrl?: string | null | undefined;
@@ -32,11 +34,11 @@ export type CreateVendorInput = {
trustPageUrl?: string | null | undefined; trustPageUrl?: string | null | undefined;
websiteUrl?: string | null | undefined; websiteUrl?: string | null | undefined;
}; };
export type VendorListViewCreateVendorMutation$variables = { export type ListVendorViewCreateVendorMutation$variables = {
connections: ReadonlyArray<string>; connections: ReadonlyArray<string>;
input: CreateVendorInput; input: CreateVendorInput;
}; };
export type VendorListViewCreateVendorMutation$data = { export type ListVendorViewCreateVendorMutation$data = {
readonly createVendor: { readonly createVendor: {
readonly vendorEdge: { readonly vendorEdge: {
readonly node: { readonly node: {
@@ -50,9 +52,9 @@ export type VendorListViewCreateVendorMutation$data = {
}; };
}; };
}; };
export type VendorListViewCreateVendorMutation = { export type ListVendorViewCreateVendorMutation = {
response: VendorListViewCreateVendorMutation$data; response: ListVendorViewCreateVendorMutation$data;
variables: VendorListViewCreateVendorMutation$variables; variables: ListVendorViewCreateVendorMutation$variables;
}; };
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
@@ -145,7 +147,7 @@ return {
], ],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "VendorListViewCreateVendorMutation", "name": "ListVendorViewCreateVendorMutation",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -170,7 +172,7 @@ return {
(v0/*: any*/) (v0/*: any*/)
], ],
"kind": "Operation", "kind": "Operation",
"name": "VendorListViewCreateVendorMutation", "name": "ListVendorViewCreateVendorMutation",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -203,16 +205,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "cedd0394889a1b00d329ed9f30dcb3b9", "cacheID": "6b3c93935ce5b90fead6aadd70992667",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "VendorListViewCreateVendorMutation", "name": "ListVendorViewCreateVendorMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation VendorListViewCreateVendorMutation(\n $input: CreateVendorInput!\n) {\n createVendor(input: $input) {\n vendorEdge {\n node {\n id\n name\n description\n createdAt\n updatedAt\n riskTier\n }\n }\n }\n}\n" "text": "mutation ListVendorViewCreateVendorMutation(\n $input: CreateVendorInput!\n) {\n createVendor(input: $input) {\n vendorEdge {\n node {\n id\n name\n description\n createdAt\n updatedAt\n riskTier\n }\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "9be60a8a66ae0214cf280252be1c6b7b"; (node as any).hash = "d75423060ceec238c1cc6b38f79be4e1";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<a46552774a4d24ce7d1849d7485fb323>> * @generated SignedSource<<c376281753e99a7cada0872375288f35>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -12,18 +12,18 @@ import { ConcreteRequest } from 'relay-runtime';
export type DeleteVendorInput = { export type DeleteVendorInput = {
vendorId: string; vendorId: string;
}; };
export type VendorListViewDeleteVendorMutation$variables = { export type ListVendorViewDeleteVendorMutation$variables = {
connections: ReadonlyArray<string>; connections: ReadonlyArray<string>;
input: DeleteVendorInput; input: DeleteVendorInput;
}; };
export type VendorListViewDeleteVendorMutation$data = { export type ListVendorViewDeleteVendorMutation$data = {
readonly deleteVendor: { readonly deleteVendor: {
readonly deletedVendorId: string; readonly deletedVendorId: string;
}; };
}; };
export type VendorListViewDeleteVendorMutation = { export type ListVendorViewDeleteVendorMutation = {
response: VendorListViewDeleteVendorMutation$data; response: ListVendorViewDeleteVendorMutation$data;
variables: VendorListViewDeleteVendorMutation$variables; variables: ListVendorViewDeleteVendorMutation$variables;
}; };
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
@@ -59,7 +59,7 @@ return {
], ],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "VendorListViewDeleteVendorMutation", "name": "ListVendorViewDeleteVendorMutation",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -84,7 +84,7 @@ return {
(v0/*: any*/) (v0/*: any*/)
], ],
"kind": "Operation", "kind": "Operation",
"name": "VendorListViewDeleteVendorMutation", "name": "ListVendorViewDeleteVendorMutation",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -117,16 +117,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "7edee61297200dec1695f6b2325cd7f0", "cacheID": "7aa26c31ccb2b601700560ad66e84b6f",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "VendorListViewDeleteVendorMutation", "name": "ListVendorViewDeleteVendorMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation VendorListViewDeleteVendorMutation(\n $input: DeleteVendorInput!\n) {\n deleteVendor(input: $input) {\n deletedVendorId\n }\n}\n" "text": "mutation ListVendorViewDeleteVendorMutation(\n $input: DeleteVendorInput!\n) {\n deleteVendor(input: $input) {\n deletedVendorId\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "85387685fd75c8b99fb9e9195d4a903f"; (node as any).hash = "9d443dea5c3e78e04dbfc6632b063c8d";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<e166844caf05e2dfc32321c2547cbf32>> * @generated SignedSource<<49f537ed24daee25a89fb244341ba874>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -10,21 +10,21 @@
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type VendorListViewPaginationQuery$variables = { export type ListVendorViewPaginationQuery$variables = {
after?: string | null | undefined; after?: string | null | undefined;
before?: string | null | undefined; before?: string | null | undefined;
first?: number | null | undefined; first?: number | null | undefined;
id: string; id: string;
last?: number | null | undefined; last?: number | null | undefined;
}; };
export type VendorListViewPaginationQuery$data = { export type ListVendorViewPaginationQuery$data = {
readonly node: { readonly node: {
readonly " $fragmentSpreads": FragmentRefs<"VendorListView_vendors">; readonly " $fragmentSpreads": FragmentRefs<"ListVendorView_vendors">;
}; };
}; };
export type VendorListViewPaginationQuery = { export type ListVendorViewPaginationQuery = {
response: VendorListViewPaginationQuery$data; response: ListVendorViewPaginationQuery$data;
variables: VendorListViewPaginationQuery$variables; variables: ListVendorViewPaginationQuery$variables;
}; };
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
@@ -119,7 +119,7 @@ return {
], ],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "VendorListViewPaginationQuery", "name": "ListVendorViewPaginationQuery",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -137,7 +137,7 @@ return {
(v9/*: any*/) (v9/*: any*/)
], ],
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "VendorListView_vendors" "name": "ListVendorView_vendors"
} }
], ],
"storageKey": null "storageKey": null
@@ -156,7 +156,7 @@ return {
(v3/*: any*/) (v3/*: any*/)
], ],
"kind": "Operation", "kind": "Operation",
"name": "VendorListViewPaginationQuery", "name": "ListVendorViewPaginationQuery",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -320,16 +320,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "f447e5171c495d86e5132c58b2afc8c8", "cacheID": "f48cd9d88c871edac4c400dc2fa20e9a",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "VendorListViewPaginationQuery", "name": "ListVendorViewPaginationQuery",
"operationKind": "query", "operationKind": "query",
"text": "query VendorListViewPaginationQuery(\n $after: CursorKey\n $before: CursorKey\n $first: Int\n $last: Int\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...VendorListView_vendors_pbnwq\n id\n }\n}\n\nfragment VendorListView_vendors_pbnwq on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: {direction: ASC, field: NAME}) {\n edges {\n node {\n id\n name\n description\n createdAt\n updatedAt\n riskTier\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n" "text": "query ListVendorViewPaginationQuery(\n $after: CursorKey\n $before: CursorKey\n $first: Int\n $last: Int\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...ListVendorView_vendors_pbnwq\n id\n }\n}\n\nfragment ListVendorView_vendors_pbnwq on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: {direction: ASC, field: NAME}) {\n edges {\n node {\n id\n name\n description\n createdAt\n updatedAt\n riskTier\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n"
} }
}; };
})(); })();
(node as any).hash = "96466253eae17f60ffdf08ad59719e83"; (node as any).hash = "6e3badec3308017fd318d4bd1dc41b44";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<843c11acfe2ed3f07fe2e05237f4cb08>> * @generated SignedSource<<faaaba37922ca105627be876b05672a7>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -10,22 +10,22 @@
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type VendorListViewQuery$variables = { export type ListVendorViewQuery$variables = {
after?: string | null | undefined; after?: string | null | undefined;
before?: string | null | undefined; before?: string | null | undefined;
first?: number | null | undefined; first?: number | null | undefined;
last?: number | null | undefined; last?: number | null | undefined;
organizationId: string; organizationId: string;
}; };
export type VendorListViewQuery$data = { export type ListVendorViewQuery$data = {
readonly organization: { readonly organization: {
readonly id: string; readonly id: string;
readonly " $fragmentSpreads": FragmentRefs<"VendorListView_vendors">; readonly " $fragmentSpreads": FragmentRefs<"ListVendorView_vendors">;
}; };
}; };
export type VendorListViewQuery = { export type ListVendorViewQuery = {
response: VendorListViewQuery$data; response: ListVendorViewQuery$data;
variables: VendorListViewQuery$variables; variables: ListVendorViewQuery$variables;
}; };
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
@@ -120,7 +120,7 @@ return {
], ],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "VendorListViewQuery", "name": "ListVendorViewQuery",
"selections": [ "selections": [
{ {
"alias": "organization", "alias": "organization",
@@ -139,7 +139,7 @@ return {
(v10/*: any*/) (v10/*: any*/)
], ],
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "VendorListView_vendors" "name": "ListVendorView_vendors"
} }
], ],
"storageKey": null "storageKey": null
@@ -158,7 +158,7 @@ return {
(v1/*: any*/) (v1/*: any*/)
], ],
"kind": "Operation", "kind": "Operation",
"name": "VendorListViewQuery", "name": "ListVendorViewQuery",
"selections": [ "selections": [
{ {
"alias": "organization", "alias": "organization",
@@ -322,16 +322,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "4bef9b4458b57ed70122d2bcbb205788", "cacheID": "f0f91262680529a635110382be5a2b03",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "VendorListViewQuery", "name": "ListVendorViewQuery",
"operationKind": "query", "operationKind": "query",
"text": "query VendorListViewQuery(\n $organizationId: ID!\n $first: Int\n $after: CursorKey\n $last: Int\n $before: CursorKey\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ...VendorListView_vendors_pbnwq\n }\n}\n\nfragment VendorListView_vendors_pbnwq on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: {direction: ASC, field: NAME}) {\n edges {\n node {\n id\n name\n description\n createdAt\n updatedAt\n riskTier\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n" "text": "query ListVendorViewQuery(\n $organizationId: ID!\n $first: Int\n $after: CursorKey\n $last: Int\n $before: CursorKey\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ...ListVendorView_vendors_pbnwq\n }\n}\n\nfragment ListVendorView_vendors_pbnwq on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: {direction: ASC, field: NAME}) {\n edges {\n node {\n id\n name\n description\n createdAt\n updatedAt\n riskTier\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n id\n}\n"
} }
}; };
})(); })();
(node as any).hash = "ea4b2e523cecb2f3200afb17b4bd505a"; (node as any).hash = "184bbebfe8fea44e62091de8165d0683";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<dce76b1271e95cbf0d70b18be492a389>> * @generated SignedSource<<b85fbf05b6b7f76bd8ceb87383bfd4b3>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -11,7 +11,7 @@
import { ReaderFragment } from 'relay-runtime'; import { ReaderFragment } from 'relay-runtime';
export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT"; export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type VendorListView_vendors$data = { export type ListVendorView_vendors$data = {
readonly id: string; readonly id: string;
readonly vendors: { readonly vendors: {
readonly __id: string; readonly __id: string;
@@ -32,11 +32,11 @@ export type VendorListView_vendors$data = {
readonly startCursor: string | null | undefined; readonly startCursor: string | null | undefined;
}; };
}; };
readonly " $fragmentType": "VendorListView_vendors"; readonly " $fragmentType": "ListVendorView_vendors";
}; };
export type VendorListView_vendors$key = { export type ListVendorView_vendors$key = {
readonly " $data"?: VendorListView_vendors$data; readonly " $data"?: ListVendorView_vendors$data;
readonly " $fragmentSpreads": FragmentRefs<"VendorListView_vendors">; readonly " $fragmentSpreads": FragmentRefs<"ListVendorView_vendors">;
}; };
const node: ReaderFragment = (function(){ const node: ReaderFragment = (function(){
@@ -98,14 +98,14 @@ return {
"fragmentPathInResult": [ "fragmentPathInResult": [
"node" "node"
], ],
"operation": require('./VendorListViewPaginationQuery.graphql'), "operation": require('./ListVendorViewPaginationQuery.graphql'),
"identifierInfo": { "identifierInfo": {
"identifierField": "id", "identifierField": "id",
"identifierQueryVariableName": "id" "identifierQueryVariableName": "id"
} }
} }
}, },
"name": "VendorListView_vendors", "name": "ListVendorView_vendors",
"selections": [ "selections": [
{ {
"alias": "vendors", "alias": "vendors",
@@ -257,6 +257,6 @@ return {
}; };
})(); })();
(node as any).hash = "96466253eae17f60ffdf08ad59719e83"; (node as any).hash = "6e3badec3308017fd318d4bd1dc41b44";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<f69485d1f583f57e60850e2bc6428763>> * @generated SignedSource<<62c3cb3473246b0326ff4cbd4cc4f940>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,13 +9,19 @@
// @ts-nocheck // @ts-nocheck
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime";
export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT"; export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT";
export type ServiceCriticality = "HIGH" | "LOW" | "MEDIUM"; export type ServiceCriticality = "HIGH" | "LOW" | "MEDIUM";
export type VendorViewQuery$variables = { export type VendorViewQuery$variables = {
organizationId: string;
vendorId: string; vendorId: string;
}; };
export type VendorViewQuery$data = { export type VendorViewQuery$data = {
readonly node: { readonly node: {
readonly businessOwner?: {
readonly fullName: string;
readonly id: string;
} | null | undefined;
readonly certifications?: ReadonlyArray<string>; readonly certifications?: ReadonlyArray<string>;
readonly complianceReports?: { readonly complianceReports?: {
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
@@ -39,6 +45,10 @@ export type VendorViewQuery$data = {
readonly name?: string; readonly name?: string;
readonly privacyPolicyUrl?: string | null | undefined; readonly privacyPolicyUrl?: string | null | undefined;
readonly riskTier?: RiskTier; readonly riskTier?: RiskTier;
readonly securityOwner?: {
readonly fullName: string;
readonly id: string;
} | null | undefined;
readonly securityPageUrl?: string | null | undefined; readonly securityPageUrl?: string | null | undefined;
readonly serviceCriticality?: ServiceCriticality; readonly serviceCriticality?: ServiceCriticality;
readonly serviceLevelAgreementUrl?: string | null | undefined; readonly serviceLevelAgreementUrl?: string | null | undefined;
@@ -50,6 +60,9 @@ export type VendorViewQuery$data = {
readonly updatedAt?: string; readonly updatedAt?: string;
readonly websiteUrl?: string | null | undefined; readonly websiteUrl?: string | null | undefined;
}; };
readonly organization: {
readonly " $fragmentSpreads": FragmentRefs<"PeopleSelector_organization">;
};
}; };
export type VendorViewQuery = { export type VendorViewQuery = {
response: VendorViewQuery$data; response: VendorViewQuery$data;
@@ -57,168 +70,234 @@ export type VendorViewQuery = {
}; };
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
var v0 = [ var v0 = {
{ "defaultValue": null,
"kind": "LocalArgument",
"name": "organizationId"
},
v1 = {
"defaultValue": null, "defaultValue": null,
"kind": "LocalArgument", "kind": "LocalArgument",
"name": "vendorId" "name": "vendorId"
} },
], v2 = [
v1 = [
{ {
"kind": "Variable", "kind": "Variable",
"name": "id", "name": "id",
"variableName": "vendorId" "variableName": "vendorId"
} }
], ],
v2 = { v3 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "id", "name": "id",
"storageKey": null "storageKey": null
}, },
v3 = { v4 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "name", "name": "name",
"storageKey": null "storageKey": null
}, },
v4 = { v5 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "description", "name": "description",
"storageKey": null "storageKey": null
}, },
v5 = { v6 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "serviceStartAt", "name": "serviceStartAt",
"storageKey": null "storageKey": null
}, },
v6 = { v7 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "serviceTerminationAt", "name": "serviceTerminationAt",
"storageKey": null "storageKey": null
}, },
v7 = { v8 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "serviceCriticality", "name": "serviceCriticality",
"storageKey": null "storageKey": null
}, },
v8 = { v9 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "riskTier", "name": "riskTier",
"storageKey": null "storageKey": null
}, },
v9 = { v10 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "statusPageUrl", "name": "statusPageUrl",
"storageKey": null "storageKey": null
}, },
v10 = { v11 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "termsOfServiceUrl", "name": "termsOfServiceUrl",
"storageKey": null "storageKey": null
}, },
v11 = { v12 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "privacyPolicyUrl", "name": "privacyPolicyUrl",
"storageKey": null "storageKey": null
}, },
v12 = { v13 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "serviceLevelAgreementUrl", "name": "serviceLevelAgreementUrl",
"storageKey": null "storageKey": null
}, },
v13 = { v14 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "dataProcessingAgreementUrl", "name": "dataProcessingAgreementUrl",
"storageKey": null "storageKey": null
}, },
v14 = { v15 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "securityPageUrl", "name": "securityPageUrl",
"storageKey": null "storageKey": null
}, },
v15 = { v16 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "trustPageUrl", "name": "trustPageUrl",
"storageKey": null "storageKey": null
}, },
v16 = { v17 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "certifications", "name": "certifications",
"storageKey": null "storageKey": null
}, },
v17 = { v18 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "headquarterAddress", "name": "headquarterAddress",
"storageKey": null "storageKey": null
}, },
v18 = { v19 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "legalName", "name": "legalName",
"storageKey": null "storageKey": null
}, },
v19 = { v20 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "websiteUrl", "name": "websiteUrl",
"storageKey": null "storageKey": null
}, },
v20 = { v21 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
},
v22 = [
(v3/*: any*/),
(v21/*: any*/)
],
v23 = {
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "businessOwner",
"plural": false,
"selections": (v22/*: any*/),
"storageKey": null
},
v24 = {
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "securityOwner",
"plural": false,
"selections": (v22/*: any*/),
"storageKey": null
},
v25 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "createdAt", "name": "createdAt",
"storageKey": null "storageKey": null
}, },
v21 = { v26 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "storageKey": null
}, },
v22 = { v27 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "__typename", "name": "__typename",
"storageKey": null "storageKey": null
}, },
v23 = [ v28 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cursor",
"storageKey": null
},
v29 = {
"alias": null,
"args": null,
"concreteType": "PageInfo",
"kind": "LinkedField",
"name": "pageInfo",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "endCursor",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasNextPage",
"storageKey": null
}
],
"storageKey": null
},
v30 = [
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -235,7 +314,7 @@ v23 = [
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v2/*: any*/), (v3/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -271,64 +350,56 @@ v23 = [
"name": "fileSize", "name": "fileSize",
"storageKey": null "storageKey": null
}, },
(v20/*: any*/), (v25/*: any*/),
(v22/*: any*/) (v27/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
{ (v28/*: any*/)
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "cursor",
"storageKey": null
}
], ],
"storageKey": null "storageKey": null
}, },
(v29/*: any*/)
],
v31 = [
{ {
"alias": null, "kind": "Variable",
"args": null, "name": "id",
"concreteType": "PageInfo", "variableName": "organizationId"
"kind": "LinkedField",
"name": "pageInfo",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "endCursor",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "hasNextPage",
"storageKey": null
} }
], ],
"storageKey": null v32 = {
}
],
v24 = [
{
"kind": "Literal", "kind": "Literal",
"name": "first", "name": "first",
"value": 100 "value": 100
},
v33 = [
(v32/*: any*/)
],
v34 = [
(v32/*: any*/),
{
"kind": "Literal",
"name": "orderBy",
"value": {
"direction": "ASC",
"field": "FULL_NAME"
}
} }
]; ];
return { return {
"fragment": { "fragment": {
"argumentDefinitions": (v0/*: any*/), "argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/)
],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "VendorViewQuery", "name": "VendorViewQuery",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": (v1/*: any*/), "args": (v2/*: any*/),
"concreteType": null, "concreteType": null,
"kind": "LinkedField", "kind": "LinkedField",
"name": "node", "name": "node",
@@ -337,7 +408,6 @@ return {
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
(v2/*: any*/),
(v3/*: any*/), (v3/*: any*/),
(v4/*: any*/), (v4/*: any*/),
(v5/*: any*/), (v5/*: any*/),
@@ -356,7 +426,10 @@ return {
(v18/*: any*/), (v18/*: any*/),
(v19/*: any*/), (v19/*: any*/),
(v20/*: any*/), (v20/*: any*/),
(v21/*: any*/), (v23/*: any*/),
(v24/*: any*/),
(v25/*: any*/),
(v26/*: any*/),
{ {
"alias": "complianceReports", "alias": "complianceReports",
"args": null, "args": null,
@@ -364,7 +437,7 @@ return {
"kind": "LinkedField", "kind": "LinkedField",
"name": "__VendorView_complianceReports_connection", "name": "__VendorView_complianceReports_connection",
"plural": false, "plural": false,
"selections": (v23/*: any*/), "selections": (v30/*: any*/),
"storageKey": null "storageKey": null
} }
], ],
@@ -373,6 +446,22 @@ return {
} }
], ],
"storageKey": null "storageKey": null
},
{
"alias": "organization",
"args": (v31/*: any*/),
"concreteType": null,
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
{
"args": null,
"kind": "FragmentSpread",
"name": "PeopleSelector_organization"
}
],
"storageKey": null
} }
], ],
"type": "Query", "type": "Query",
@@ -380,24 +469,26 @@ return {
}, },
"kind": "Request", "kind": "Request",
"operation": { "operation": {
"argumentDefinitions": (v0/*: any*/), "argumentDefinitions": [
(v1/*: any*/),
(v0/*: any*/)
],
"kind": "Operation", "kind": "Operation",
"name": "VendorViewQuery", "name": "VendorViewQuery",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": (v1/*: any*/), "args": (v2/*: any*/),
"concreteType": null, "concreteType": null,
"kind": "LinkedField", "kind": "LinkedField",
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v22/*: any*/), (v27/*: any*/),
(v2/*: any*/), (v3/*: any*/),
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
(v3/*: any*/),
(v4/*: any*/), (v4/*: any*/),
(v5/*: any*/), (v5/*: any*/),
(v6/*: any*/), (v6/*: any*/),
@@ -415,20 +506,23 @@ return {
(v18/*: any*/), (v18/*: any*/),
(v19/*: any*/), (v19/*: any*/),
(v20/*: any*/), (v20/*: any*/),
(v21/*: any*/), (v23/*: any*/),
(v24/*: any*/),
(v25/*: any*/),
(v26/*: any*/),
{ {
"alias": null, "alias": null,
"args": (v24/*: any*/), "args": (v33/*: any*/),
"concreteType": "VendorComplianceReportConnection", "concreteType": "VendorComplianceReportConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "complianceReports", "name": "complianceReports",
"plural": false, "plural": false,
"selections": (v23/*: any*/), "selections": (v30/*: any*/),
"storageKey": "complianceReports(first:100)" "storageKey": "complianceReports(first:100)"
}, },
{ {
"alias": null, "alias": null,
"args": (v24/*: any*/), "args": (v33/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "VendorView_complianceReports", "key": "VendorView_complianceReports",
@@ -441,11 +535,87 @@ return {
} }
], ],
"storageKey": null "storageKey": null
},
{
"alias": "organization",
"args": (v31/*: any*/),
"concreteType": null,
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v27/*: any*/),
(v3/*: any*/),
{
"kind": "InlineFragment",
"selections": [
{
"alias": null,
"args": (v34/*: any*/),
"concreteType": "PeopleConnection",
"kind": "LinkedField",
"name": "peoples",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "PeopleEdge",
"kind": "LinkedField",
"name": "edges",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "node",
"plural": false,
"selections": [
(v3/*: any*/),
(v21/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "primaryEmailAddress",
"storageKey": null
},
(v27/*: any*/)
],
"storageKey": null
},
(v28/*: any*/)
],
"storageKey": null
},
(v29/*: any*/)
],
"storageKey": "peoples(first:100,orderBy:{\"direction\":\"ASC\",\"field\":\"FULL_NAME\"})"
},
{
"alias": null,
"args": (v34/*: any*/),
"filters": [
"orderBy"
],
"handle": "connection",
"key": "PeopleSelector_organization_peoples",
"kind": "LinkedHandle",
"name": "peoples"
}
],
"type": "Organization",
"abstractKey": null
}
],
"storageKey": null
} }
] ]
}, },
"params": { "params": {
"cacheID": "2bef9911b76d74ced85cf4430410a297", "cacheID": "337beb9fa1d1d29bcd974229385d8e7a",
"id": null, "id": null,
"metadata": { "metadata": {
"connection": [ "connection": [
@@ -462,11 +632,11 @@ return {
}, },
"name": "VendorViewQuery", "name": "VendorViewQuery",
"operationKind": "query", "operationKind": "query",
"text": "query VendorViewQuery(\n $vendorId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n securityPageUrl\n trustPageUrl\n certifications\n headquarterAddress\n legalName\n websiteUrl\n createdAt\n updatedAt\n complianceReports(first: 100) {\n edges {\n node {\n id\n reportName\n reportDate\n validUntil\n fileUrl\n fileSize\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n}\n" "text": "query VendorViewQuery(\n $vendorId: ID!\n $organizationId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n securityPageUrl\n trustPageUrl\n certifications\n headquarterAddress\n legalName\n websiteUrl\n businessOwner {\n id\n fullName\n }\n securityOwner {\n id\n fullName\n }\n createdAt\n updatedAt\n complianceReports(first: 100) {\n edges {\n node {\n id\n reportName\n reportDate\n validUntil\n fileUrl\n fileSize\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n organization: node(id: $organizationId) {\n __typename\n ...PeopleSelector_organization\n id\n }\n}\n\nfragment PeopleSelector_organization on Organization {\n id\n peoples(first: 100, orderBy: {direction: ASC, field: FULL_NAME}) {\n edges {\n node {\n id\n fullName\n primaryEmailAddress\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "f3f95bc0c893b61e83940c1cc0c33922"; (node as any).hash = "4a621712e4dfaebf9ad42232ba7f713a";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<0e66de0cfba2c27bbf78dcb8e846ad8d>> * @generated SignedSource<<e8b13d28eed7587f5fbefcc073c53dc4>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -12,6 +12,7 @@ import { ConcreteRequest } from 'relay-runtime';
export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT"; export type RiskTier = "CRITICAL" | "GENERAL" | "SIGNIFICANT";
export type ServiceCriticality = "HIGH" | "LOW" | "MEDIUM"; export type ServiceCriticality = "HIGH" | "LOW" | "MEDIUM";
export type UpdateVendorInput = { export type UpdateVendorInput = {
businessOwnerId?: string | null | undefined;
category?: string | null | undefined; category?: string | null | undefined;
certifications?: ReadonlyArray<string> | null | undefined; certifications?: ReadonlyArray<string> | null | undefined;
dataProcessingAgreementUrl?: string | null | undefined; dataProcessingAgreementUrl?: string | null | undefined;
@@ -22,6 +23,7 @@ export type UpdateVendorInput = {
name?: string | null | undefined; name?: string | null | undefined;
privacyPolicyUrl?: string | null | undefined; privacyPolicyUrl?: string | null | undefined;
riskTier?: RiskTier | null | undefined; riskTier?: RiskTier | null | undefined;
securityOwnerId?: string | null | undefined;
securityPageUrl?: string | null | undefined; securityPageUrl?: string | null | undefined;
serviceCriticality?: ServiceCriticality | null | undefined; serviceCriticality?: ServiceCriticality | null | undefined;
serviceLevelAgreementUrl?: string | null | undefined; serviceLevelAgreementUrl?: string | null | undefined;
@@ -38,6 +40,10 @@ export type VendorViewUpdateVendorMutation$variables = {
export type VendorViewUpdateVendorMutation$data = { export type VendorViewUpdateVendorMutation$data = {
readonly updateVendor: { readonly updateVendor: {
readonly vendor: { readonly vendor: {
readonly businessOwner: {
readonly fullName: string;
readonly id: string;
} | null | undefined;
readonly certifications: ReadonlyArray<string>; readonly certifications: ReadonlyArray<string>;
readonly dataProcessingAgreementUrl: string | null | undefined; readonly dataProcessingAgreementUrl: string | null | undefined;
readonly description: string | null | undefined; readonly description: string | null | undefined;
@@ -47,6 +53,10 @@ export type VendorViewUpdateVendorMutation$data = {
readonly name: string; readonly name: string;
readonly privacyPolicyUrl: string | null | undefined; readonly privacyPolicyUrl: string | null | undefined;
readonly riskTier: RiskTier; readonly riskTier: RiskTier;
readonly securityOwner: {
readonly fullName: string;
readonly id: string;
} | null | undefined;
readonly securityPageUrl: string | null | undefined; readonly securityPageUrl: string | null | undefined;
readonly serviceCriticality: ServiceCriticality; readonly serviceCriticality: ServiceCriticality;
readonly serviceLevelAgreementUrl: string | null | undefined; readonly serviceLevelAgreementUrl: string | null | undefined;
@@ -73,7 +83,24 @@ var v0 = [
"name": "input" "name": "input"
} }
], ],
v1 = [ v1 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
v2 = [
(v1/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
}
],
v3 = [
{ {
"alias": null, "alias": null,
"args": [ "args": [
@@ -96,13 +123,7 @@ v1 = [
"name": "vendor", "name": "vendor",
"plural": false, "plural": false,
"selections": [ "selections": [
{ (v1/*: any*/),
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -222,6 +243,26 @@ v1 = [
"name": "websiteUrl", "name": "websiteUrl",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "businessOwner",
"plural": false,
"selections": (v2/*: any*/),
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "securityOwner",
"plural": false,
"selections": (v2/*: any*/),
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -242,7 +283,7 @@ return {
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "VendorViewUpdateVendorMutation", "name": "VendorViewUpdateVendorMutation",
"selections": (v1/*: any*/), "selections": (v3/*: any*/),
"type": "Mutation", "type": "Mutation",
"abstractKey": null "abstractKey": null
}, },
@@ -251,19 +292,19 @@ return {
"argumentDefinitions": (v0/*: any*/), "argumentDefinitions": (v0/*: any*/),
"kind": "Operation", "kind": "Operation",
"name": "VendorViewUpdateVendorMutation", "name": "VendorViewUpdateVendorMutation",
"selections": (v1/*: any*/) "selections": (v3/*: any*/)
}, },
"params": { "params": {
"cacheID": "8ed69675626a00cac2cc79aa570f123d", "cacheID": "d582aaaddaa73ef8e0fdef172364c64e",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "VendorViewUpdateVendorMutation", "name": "VendorViewUpdateVendorMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation VendorViewUpdateVendorMutation(\n $input: UpdateVendorInput!\n) {\n updateVendor(input: $input) {\n vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n securityPageUrl\n trustPageUrl\n certifications\n headquarterAddress\n legalName\n websiteUrl\n updatedAt\n }\n }\n}\n" "text": "mutation VendorViewUpdateVendorMutation(\n $input: UpdateVendorInput!\n) {\n updateVendor(input: $input) {\n vendor {\n id\n name\n description\n serviceStartAt\n serviceTerminationAt\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n securityPageUrl\n trustPageUrl\n certifications\n headquarterAddress\n legalName\n websiteUrl\n businessOwner {\n id\n fullName\n }\n securityOwner {\n id\n fullName\n }\n updatedAt\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "517efd79b3eb1781ed562368a2ed1ecc"; (node as any).hash = "627ef1694ebc04845b019bb65dd72c97";
export default node; export default node;

View File

@@ -0,0 +1,2 @@
ALTER TABLE vendors ADD COLUMN business_owner_id TEXT REFERENCES peoples(id) ON DELETE SET NULL;
ALTER TABLE vendors ADD COLUMN security_owner_id TEXT REFERENCES peoples(id) ON DELETE SET NULL;

View File

@@ -47,6 +47,8 @@ type (
Certifications []string `db:"certifications"` Certifications []string `db:"certifications"`
ServiceCriticality ServiceCriticality `db:"service_criticality"` ServiceCriticality ServiceCriticality `db:"service_criticality"`
RiskTier RiskTier `db:"risk_tier"` RiskTier RiskTier `db:"risk_tier"`
BusinessOwnerID *gid.GID `db:"business_owner_id"`
SecurityOwnerID *gid.GID `db:"security_owner_id"`
StatusPageURL *string `db:"status_page_url"` StatusPageURL *string `db:"status_page_url"`
TermsOfServiceURL *string `db:"terms_of_service_url"` TermsOfServiceURL *string `db:"terms_of_service_url"`
SecurityPageURL *string `db:"security_page_url"` SecurityPageURL *string `db:"security_page_url"`
@@ -93,6 +95,8 @@ SELECT
certifications, certifications,
service_criticality, service_criticality,
risk_tier, risk_tier,
business_owner_id,
security_owner_id,
status_page_url, status_page_url,
terms_of_service_url, terms_of_service_url,
security_page_url, security_page_url,
@@ -153,6 +157,8 @@ INSERT INTO
service_termination_at, service_termination_at,
service_criticality, service_criticality,
risk_tier, risk_tier,
business_owner_id,
security_owner_id,
status_page_url, status_page_url,
terms_of_service_url, terms_of_service_url,
security_page_url, security_page_url,
@@ -178,6 +184,8 @@ VALUES (
@service_termination_at, @service_termination_at,
@service_criticality, @service_criticality,
@risk_tier, @risk_tier,
@business_owner_id,
@security_owner_id,
@status_page_url, @status_page_url,
@terms_of_service_url, @terms_of_service_url,
@security_page_url, @security_page_url,
@@ -205,6 +213,8 @@ VALUES (
"service_termination_at": v.ServiceTerminationAt, "service_termination_at": v.ServiceTerminationAt,
"service_criticality": v.ServiceCriticality, "service_criticality": v.ServiceCriticality,
"risk_tier": v.RiskTier, "risk_tier": v.RiskTier,
"business_owner_id": v.BusinessOwnerID,
"security_owner_id": v.SecurityOwnerID,
"status_page_url": v.StatusPageURL, "status_page_url": v.StatusPageURL,
"terms_of_service_url": v.TermsOfServiceURL, "terms_of_service_url": v.TermsOfServiceURL,
"security_page_url": v.SecurityPageURL, "security_page_url": v.SecurityPageURL,
@@ -259,6 +269,8 @@ SELECT
service_termination_at, service_termination_at,
service_criticality, service_criticality,
risk_tier, risk_tier,
business_owner_id,
security_owner_id,
status_page_url, status_page_url,
terms_of_service_url, terms_of_service_url,
security_page_url, security_page_url,
@@ -319,6 +331,8 @@ SET
terms_of_service_url = @terms_of_service_url, terms_of_service_url = @terms_of_service_url,
security_page_url = @security_page_url, security_page_url = @security_page_url,
trust_page_url = @trust_page_url, trust_page_url = @trust_page_url,
business_owner_id = @business_owner_id,
security_owner_id = @security_owner_id,
updated_at = @updated_at updated_at = @updated_at
WHERE %s WHERE %s
AND id = @vendor_id AND id = @vendor_id
@@ -346,6 +360,8 @@ WHERE %s
"terms_of_service_url": v.TermsOfServiceURL, "terms_of_service_url": v.TermsOfServiceURL,
"security_page_url": v.SecurityPageURL, "security_page_url": v.SecurityPageURL,
"trust_page_url": v.TrustPageURL, "trust_page_url": v.TrustPageURL,
"business_owner_id": v.BusinessOwnerID,
"security_owner_id": v.SecurityOwnerID,
} }
maps.Copy(args, scope.SQLArguments()) maps.Copy(args, scope.SQLArguments())

View File

@@ -50,6 +50,8 @@ type (
ServiceTerminationAt *time.Time ServiceTerminationAt *time.Time
ServiceCriticality coredata.ServiceCriticality ServiceCriticality coredata.ServiceCriticality
RiskTier coredata.RiskTier RiskTier coredata.RiskTier
BusinessOwnerID *gid.GID
SecurityOwnerID *gid.GID
} }
UpdateVendorRequest struct { UpdateVendorRequest struct {
@@ -72,6 +74,8 @@ type (
ServiceTerminationAt *time.Time ServiceTerminationAt *time.Time
ServiceCriticality *coredata.ServiceCriticality ServiceCriticality *coredata.ServiceCriticality
RiskTier *coredata.RiskTier RiskTier *coredata.RiskTier
BusinessOwnerID *gid.GID
SecurityOwnerID *gid.GID
} }
) )
@@ -203,6 +207,14 @@ func (s VendorService) Update(
vendor.TrustPageURL = req.TrustPageURL vendor.TrustPageURL = req.TrustPageURL
} }
if req.BusinessOwnerID != nil {
vendor.BusinessOwnerID = req.BusinessOwnerID
}
if req.SecurityOwnerID != nil {
vendor.SecurityOwnerID = req.SecurityOwnerID
}
vendor.UpdatedAt = time.Now() vendor.UpdatedAt = time.Now()
if err := vendor.Update(ctx, conn, s.svc.scope); err != nil { if err := vendor.Update(ctx, conn, s.svc.scope); err != nil {

View File

@@ -457,6 +457,9 @@ type Vendor implements Node {
orderBy: VendorComplianceReportOrder orderBy: VendorComplianceReportOrder
): VendorComplianceReportConnection! @goField(forceResolver: true) ): VendorComplianceReportConnection! @goField(forceResolver: true)
businessOwner: People @goField(forceResolver: true)
securityOwner: People @goField(forceResolver: true)
serviceStartAt: Datetime! serviceStartAt: Datetime!
serviceTerminationAt: Datetime serviceTerminationAt: Datetime
serviceCriticality: ServiceCriticality! serviceCriticality: ServiceCriticality!
@@ -943,6 +946,8 @@ input CreateVendorInput {
serviceTerminationAt: Datetime serviceTerminationAt: Datetime
serviceCriticality: ServiceCriticality! serviceCriticality: ServiceCriticality!
riskTier: RiskTier! riskTier: RiskTier!
businessOwnerId: ID
securityOwnerId: ID
} }
input UpdateVendorInput { input UpdateVendorInput {
@@ -965,6 +970,8 @@ input UpdateVendorInput {
certifications: [String!] certifications: [String!]
securityPageUrl: String securityPageUrl: String
trustPageUrl: String trustPageUrl: String
businessOwnerId: ID
securityOwnerId: ID
} }
input DeleteVendorInput { input DeleteVendorInput {

View File

@@ -526,6 +526,7 @@ type ComplexityRoot struct {
} }
Vendor struct { Vendor struct {
BusinessOwner func(childComplexity int) int
Certifications func(childComplexity int) int Certifications func(childComplexity int) int
ComplianceReports func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorComplianceReportOrderBy) int ComplianceReports func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorComplianceReportOrderBy) int
CreatedAt func(childComplexity int) int CreatedAt func(childComplexity int) int
@@ -537,6 +538,7 @@ type ComplexityRoot struct {
Name func(childComplexity int) int Name func(childComplexity int) int
PrivacyPolicyURL func(childComplexity int) int PrivacyPolicyURL func(childComplexity int) int
RiskTier func(childComplexity int) int RiskTier func(childComplexity int) int
SecurityOwner func(childComplexity int) int
SecurityPageURL func(childComplexity int) int SecurityPageURL func(childComplexity int) int
ServiceCriticality func(childComplexity int) int ServiceCriticality func(childComplexity int) int
ServiceLevelAgreementURL func(childComplexity int) int ServiceLevelAgreementURL func(childComplexity int) int
@@ -679,6 +681,8 @@ type TaskResolver interface {
} }
type VendorResolver interface { type VendorResolver interface {
ComplianceReports(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorComplianceReportOrderBy) (*types.VendorComplianceReportConnection, error) ComplianceReports(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorComplianceReportOrderBy) (*types.VendorComplianceReportConnection, error)
BusinessOwner(ctx context.Context, obj *types.Vendor) (*types.People, error)
SecurityOwner(ctx context.Context, obj *types.Vendor) (*types.People, error)
} }
type VendorComplianceReportResolver interface { type VendorComplianceReportResolver interface {
Vendor(ctx context.Context, obj *types.VendorComplianceReport) (*types.Vendor, error) Vendor(ctx context.Context, obj *types.VendorComplianceReport) (*types.Vendor, error)
@@ -2633,6 +2637,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.UserEdge.Node(childComplexity), true return e.complexity.UserEdge.Node(childComplexity), true
case "Vendor.businessOwner":
if e.complexity.Vendor.BusinessOwner == nil {
break
}
return e.complexity.Vendor.BusinessOwner(childComplexity), true
case "Vendor.certifications": case "Vendor.certifications":
if e.complexity.Vendor.Certifications == nil { if e.complexity.Vendor.Certifications == nil {
break break
@@ -2715,6 +2726,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Vendor.RiskTier(childComplexity), true return e.complexity.Vendor.RiskTier(childComplexity), true
case "Vendor.securityOwner":
if e.complexity.Vendor.SecurityOwner == nil {
break
}
return e.complexity.Vendor.SecurityOwner(childComplexity), true
case "Vendor.securityPageUrl": case "Vendor.securityPageUrl":
if e.complexity.Vendor.SecurityPageURL == nil { if e.complexity.Vendor.SecurityPageURL == nil {
break break
@@ -3550,6 +3568,9 @@ type Vendor implements Node {
orderBy: VendorComplianceReportOrder orderBy: VendorComplianceReportOrder
): VendorComplianceReportConnection! @goField(forceResolver: true) ): VendorComplianceReportConnection! @goField(forceResolver: true)
businessOwner: People @goField(forceResolver: true)
securityOwner: People @goField(forceResolver: true)
serviceStartAt: Datetime! serviceStartAt: Datetime!
serviceTerminationAt: Datetime serviceTerminationAt: Datetime
serviceCriticality: ServiceCriticality! serviceCriticality: ServiceCriticality!
@@ -4036,6 +4057,8 @@ input CreateVendorInput {
serviceTerminationAt: Datetime serviceTerminationAt: Datetime
serviceCriticality: ServiceCriticality! serviceCriticality: ServiceCriticality!
riskTier: RiskTier! riskTier: RiskTier!
businessOwnerId: ID
securityOwnerId: ID
} }
input UpdateVendorInput { input UpdateVendorInput {
@@ -4058,6 +4081,8 @@ input UpdateVendorInput {
certifications: [String!] certifications: [String!]
securityPageUrl: String securityPageUrl: String
trustPageUrl: String trustPageUrl: String
businessOwnerId: ID
securityOwnerId: ID
} }
input DeleteVendorInput { input DeleteVendorInput {
@@ -18974,6 +18999,10 @@ func (ec *executionContext) fieldContext_UpdateVendorPayload_vendor(_ context.Co
return ec.fieldContext_Vendor_description(ctx, field) return ec.fieldContext_Vendor_description(ctx, field)
case "complianceReports": case "complianceReports":
return ec.fieldContext_Vendor_complianceReports(ctx, field) return ec.fieldContext_Vendor_complianceReports(ctx, field)
case "businessOwner":
return ec.fieldContext_Vendor_businessOwner(ctx, field)
case "securityOwner":
return ec.fieldContext_Vendor_securityOwner(ctx, field)
case "serviceStartAt": case "serviceStartAt":
return ec.fieldContext_Vendor_serviceStartAt(ctx, field) return ec.fieldContext_Vendor_serviceStartAt(ctx, field)
case "serviceTerminationAt": case "serviceTerminationAt":
@@ -19679,6 +19708,120 @@ func (ec *executionContext) fieldContext_Vendor_complianceReports(ctx context.Co
return fc, nil return fc, nil
} }
func (ec *executionContext) _Vendor_businessOwner(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Vendor_businessOwner(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Vendor().BusinessOwner(rctx, obj)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*types.People)
fc.Result = res
return ec.marshalOPeople2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐPeople(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Vendor_businessOwner(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Vendor",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "id":
return ec.fieldContext_People_id(ctx, field)
case "fullName":
return ec.fieldContext_People_fullName(ctx, field)
case "primaryEmailAddress":
return ec.fieldContext_People_primaryEmailAddress(ctx, field)
case "additionalEmailAddresses":
return ec.fieldContext_People_additionalEmailAddresses(ctx, field)
case "kind":
return ec.fieldContext_People_kind(ctx, field)
case "createdAt":
return ec.fieldContext_People_createdAt(ctx, field)
case "updatedAt":
return ec.fieldContext_People_updatedAt(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type People", field.Name)
},
}
return fc, nil
}
func (ec *executionContext) _Vendor_securityOwner(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Vendor_securityOwner(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Vendor().SecurityOwner(rctx, obj)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*types.People)
fc.Result = res
return ec.marshalOPeople2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐPeople(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Vendor_securityOwner(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Vendor",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "id":
return ec.fieldContext_People_id(ctx, field)
case "fullName":
return ec.fieldContext_People_fullName(ctx, field)
case "primaryEmailAddress":
return ec.fieldContext_People_primaryEmailAddress(ctx, field)
case "additionalEmailAddresses":
return ec.fieldContext_People_additionalEmailAddresses(ctx, field)
case "kind":
return ec.fieldContext_People_kind(ctx, field)
case "createdAt":
return ec.fieldContext_People_createdAt(ctx, field)
case "updatedAt":
return ec.fieldContext_People_updatedAt(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type People", field.Name)
},
}
return fc, nil
}
func (ec *executionContext) _Vendor_serviceStartAt(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) { func (ec *executionContext) _Vendor_serviceStartAt(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Vendor_serviceStartAt(ctx, field) fc, err := ec.fieldContext_Vendor_serviceStartAt(ctx, field)
if err != nil { if err != nil {
@@ -20485,6 +20628,10 @@ func (ec *executionContext) fieldContext_VendorComplianceReport_vendor(_ context
return ec.fieldContext_Vendor_description(ctx, field) return ec.fieldContext_Vendor_description(ctx, field)
case "complianceReports": case "complianceReports":
return ec.fieldContext_Vendor_complianceReports(ctx, field) return ec.fieldContext_Vendor_complianceReports(ctx, field)
case "businessOwner":
return ec.fieldContext_Vendor_businessOwner(ctx, field)
case "securityOwner":
return ec.fieldContext_Vendor_securityOwner(ctx, field)
case "serviceStartAt": case "serviceStartAt":
return ec.fieldContext_Vendor_serviceStartAt(ctx, field) return ec.fieldContext_Vendor_serviceStartAt(ctx, field)
case "serviceTerminationAt": case "serviceTerminationAt":
@@ -21238,6 +21385,10 @@ func (ec *executionContext) fieldContext_VendorEdge_node(_ context.Context, fiel
return ec.fieldContext_Vendor_description(ctx, field) return ec.fieldContext_Vendor_description(ctx, field)
case "complianceReports": case "complianceReports":
return ec.fieldContext_Vendor_complianceReports(ctx, field) return ec.fieldContext_Vendor_complianceReports(ctx, field)
case "businessOwner":
return ec.fieldContext_Vendor_businessOwner(ctx, field)
case "securityOwner":
return ec.fieldContext_Vendor_securityOwner(ctx, field)
case "serviceStartAt": case "serviceStartAt":
return ec.fieldContext_Vendor_serviceStartAt(ctx, field) return ec.fieldContext_Vendor_serviceStartAt(ctx, field)
case "serviceTerminationAt": case "serviceTerminationAt":
@@ -24069,7 +24220,7 @@ func (ec *executionContext) unmarshalInputCreateVendorInput(ctx context.Context,
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"organizationId", "name", "description", "headquarterAddress", "legalName", "websiteUrl", "privacyPolicyUrl", "category", "serviceLevelAgreementUrl", "dataProcessingAgreementUrl", "certifications", "securityPageUrl", "trustPageUrl", "statusPageUrl", "termsOfServiceUrl", "serviceStartAt", "serviceTerminationAt", "serviceCriticality", "riskTier"} fieldsInOrder := [...]string{"organizationId", "name", "description", "headquarterAddress", "legalName", "websiteUrl", "privacyPolicyUrl", "category", "serviceLevelAgreementUrl", "dataProcessingAgreementUrl", "certifications", "securityPageUrl", "trustPageUrl", "statusPageUrl", "termsOfServiceUrl", "serviceStartAt", "serviceTerminationAt", "serviceCriticality", "riskTier", "businessOwnerId", "securityOwnerId"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -24209,6 +24360,20 @@ func (ec *executionContext) unmarshalInputCreateVendorInput(ctx context.Context,
return it, err return it, err
} }
it.RiskTier = data it.RiskTier = data
case "businessOwnerId":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("businessOwnerId"))
data, err := ec.unmarshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v)
if err != nil {
return it, err
}
it.BusinessOwnerID = data
case "securityOwnerId":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("securityOwnerId"))
data, err := ec.unmarshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v)
if err != nil {
return it, err
}
it.SecurityOwnerID = data
} }
} }
@@ -25538,7 +25703,7 @@ func (ec *executionContext) unmarshalInputUpdateVendorInput(ctx context.Context,
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"id", "name", "description", "serviceStartAt", "serviceTerminationAt", "serviceCriticality", "riskTier", "statusPageUrl", "termsOfServiceUrl", "privacyPolicyUrl", "serviceLevelAgreementUrl", "dataProcessingAgreementUrl", "websiteUrl", "legalName", "headquarterAddress", "category", "certifications", "securityPageUrl", "trustPageUrl"} fieldsInOrder := [...]string{"id", "name", "description", "serviceStartAt", "serviceTerminationAt", "serviceCriticality", "riskTier", "statusPageUrl", "termsOfServiceUrl", "privacyPolicyUrl", "serviceLevelAgreementUrl", "dataProcessingAgreementUrl", "websiteUrl", "legalName", "headquarterAddress", "category", "certifications", "securityPageUrl", "trustPageUrl", "businessOwnerId", "securityOwnerId"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -25678,6 +25843,20 @@ func (ec *executionContext) unmarshalInputUpdateVendorInput(ctx context.Context,
return it, err return it, err
} }
it.TrustPageURL = data it.TrustPageURL = data
case "businessOwnerId":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("businessOwnerId"))
data, err := ec.unmarshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v)
if err != nil {
return it, err
}
it.BusinessOwnerID = data
case "securityOwnerId":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("securityOwnerId"))
data, err := ec.unmarshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v)
if err != nil {
return it, err
}
it.SecurityOwnerID = data
} }
} }
@@ -30634,6 +30813,72 @@ func (ec *executionContext) _Vendor(ctx context.Context, sel ast.SelectionSet, o
continue continue
} }
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
case "businessOwner":
field := field
innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Vendor_businessOwner(ctx, field, obj)
return res
}
if field.Deferrable != nil {
dfs, ok := deferred[field.Deferrable.Label]
di := 0
if ok {
dfs.AddField(field)
di = len(dfs.Values) - 1
} else {
dfs = graphql.NewFieldSet([]graphql.CollectedField{field})
deferred[field.Deferrable.Label] = dfs
}
dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler {
return innerFunc(ctx, dfs)
})
// don't run the out.Concurrently() call below
out.Values[i] = graphql.Null
continue
}
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
case "securityOwner":
field := field
innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._Vendor_securityOwner(ctx, field, obj)
return res
}
if field.Deferrable != nil {
dfs, ok := deferred[field.Deferrable.Label]
di := 0
if ok {
dfs.AddField(field)
di = len(dfs.Values) - 1
} else {
dfs = graphql.NewFieldSet([]graphql.CollectedField{field})
deferred[field.Deferrable.Label] = dfs
}
dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler {
return innerFunc(ctx, dfs)
})
// don't run the out.Concurrently() call below
out.Values[i] = graphql.Null
continue
}
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
case "serviceStartAt": case "serviceStartAt":
out.Values[i] = ec._Vendor_serviceStartAt(ctx, field, obj) out.Values[i] = ec._Vendor_serviceStartAt(ctx, field, obj)

View File

@@ -212,6 +212,8 @@ type CreateVendorInput struct {
ServiceTerminationAt *time.Time `json:"serviceTerminationAt,omitempty"` ServiceTerminationAt *time.Time `json:"serviceTerminationAt,omitempty"`
ServiceCriticality coredata.ServiceCriticality `json:"serviceCriticality"` ServiceCriticality coredata.ServiceCriticality `json:"serviceCriticality"`
RiskTier coredata.RiskTier `json:"riskTier"` RiskTier coredata.RiskTier `json:"riskTier"`
BusinessOwnerID *gid.GID `json:"businessOwnerId,omitempty"`
SecurityOwnerID *gid.GID `json:"securityOwnerId,omitempty"`
} }
type CreateVendorPayload struct { type CreateVendorPayload struct {
@@ -731,6 +733,8 @@ type UpdateVendorInput struct {
Certifications []string `json:"certifications,omitempty"` Certifications []string `json:"certifications,omitempty"`
SecurityPageURL *string `json:"securityPageUrl,omitempty"` SecurityPageURL *string `json:"securityPageUrl,omitempty"`
TrustPageURL *string `json:"trustPageUrl,omitempty"` TrustPageURL *string `json:"trustPageUrl,omitempty"`
BusinessOwnerID *gid.GID `json:"businessOwnerId,omitempty"`
SecurityOwnerID *gid.GID `json:"securityOwnerId,omitempty"`
} }
type UpdateVendorPayload struct { type UpdateVendorPayload struct {
@@ -775,6 +779,8 @@ type Vendor struct {
Name string `json:"name"` Name string `json:"name"`
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
ComplianceReports *VendorComplianceReportConnection `json:"complianceReports"` ComplianceReports *VendorComplianceReportConnection `json:"complianceReports"`
BusinessOwner *People `json:"businessOwner,omitempty"`
SecurityOwner *People `json:"securityOwner,omitempty"`
ServiceStartAt time.Time `json:"serviceStartAt"` ServiceStartAt time.Time `json:"serviceStartAt"`
ServiceTerminationAt *time.Time `json:"serviceTerminationAt,omitempty"` ServiceTerminationAt *time.Time `json:"serviceTerminationAt,omitempty"`
ServiceCriticality coredata.ServiceCriticality `json:"serviceCriticality"` ServiceCriticality coredata.ServiceCriticality `json:"serviceCriticality"`

View File

@@ -377,6 +377,8 @@ func (r *mutationResolver) CreateVendor(ctx context.Context, input types.CreateV
Certifications: input.Certifications, Certifications: input.Certifications,
SecurityPageURL: input.SecurityPageURL, SecurityPageURL: input.SecurityPageURL,
TrustPageURL: input.TrustPageURL, TrustPageURL: input.TrustPageURL,
BusinessOwnerID: input.BusinessOwnerID,
SecurityOwnerID: input.SecurityOwnerID,
}, },
) )
if err != nil { if err != nil {
@@ -411,6 +413,8 @@ func (r *mutationResolver) UpdateVendor(ctx context.Context, input types.UpdateV
WebsiteURL: input.WebsiteURL, WebsiteURL: input.WebsiteURL,
Category: input.Category, Category: input.Category,
Certifications: input.Certifications, Certifications: input.Certifications,
BusinessOwnerID: input.BusinessOwnerID,
SecurityOwnerID: input.SecurityOwnerID,
}) })
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot update vendor: %w", err) return nil, fmt.Errorf("cannot update vendor: %w", err)
@@ -1513,6 +1517,48 @@ func (r *vendorResolver) ComplianceReports(ctx context.Context, obj *types.Vendo
return types.NewVendorComplianceReportConnection(page), nil return types.NewVendorComplianceReportConnection(page), nil
} }
// BusinessOwner is the resolver for the businessOwner field.
func (r *vendorResolver) BusinessOwner(ctx context.Context, obj *types.Vendor) (*types.People, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, obj.ID.TenantID())
vendor, err := svc.Vendors.Get(ctx, obj.ID)
if err != nil {
panic(fmt.Errorf("failed to get vendor: %w", err))
}
if vendor.BusinessOwnerID == nil {
return nil, nil
}
people, err := svc.Peoples.Get(ctx, *vendor.BusinessOwnerID)
if err != nil {
panic(fmt.Errorf("failed to get business owner: %w", err))
}
return types.NewPeople(people), nil
}
// SecurityOwner is the resolver for the securityOwner field.
func (r *vendorResolver) SecurityOwner(ctx context.Context, obj *types.Vendor) (*types.People, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, obj.ID.TenantID())
vendor, err := svc.Vendors.Get(ctx, obj.ID)
if err != nil {
panic(fmt.Errorf("failed to get vendor: %w", err))
}
if vendor.SecurityOwnerID == nil {
return nil, nil
}
people, err := svc.Peoples.Get(ctx, *vendor.SecurityOwnerID)
if err != nil {
panic(fmt.Errorf("failed to get security owner: %w", err))
}
return types.NewPeople(people), nil
}
// Vendor is the resolver for the vendor field. // Vendor is the resolver for the vendor field.
func (r *vendorComplianceReportResolver) Vendor(ctx context.Context, obj *types.VendorComplianceReport) (*types.Vendor, error) { func (r *vendorComplianceReportResolver) Vendor(ctx context.Context, obj *types.VendorComplianceReport) (*types.Vendor, error) {
svc := r.GetTenantServiceIfAuthorized(ctx, obj.ID.TenantID()) svc := r.GetTenantServiceIfAuthorized(ctx, obj.ID.TenantID())