From 54c14a181609c813b8ba4b4345ab28543ccd6986 Mon Sep 17 00:00:00 2001 From: Sacha Al Himdani Date: Mon, 18 Aug 2025 18:26:17 +0200 Subject: [PATCH] Add vendor services Signed-off-by: Sacha Al Himdani --- apps/console/src/hooks/graph/VendorGraph.ts | 1 + .../VendorGraphNodeQuery.graphql.ts | 188 +- .../vendors/VendorDetailPage.tsx | 5 + .../vendors/dialogs/CreateServiceDialog.tsx | 123 + .../vendors/dialogs/EditServiceDialog.tsx | 120 + .../CreateServiceDialogMutation.graphql.ts | 216 ++ ...EditServiceDialogUpdateMutation.graphql.ts | 166 ++ .../vendors/tabs/VendorContactsTab.tsx | 3 - .../vendors/tabs/VendorServicesTab.tsx | 214 ++ .../VendorServicesListQuery.graphql.ts | 344 +++ ...ervicesTabDeleteServiceMutation.graphql.ts | 132 ++ .../VendorServicesTabFragment.graphql.ts | 225 ++ ...ndorServicesTabFragment_service.graphql.ts | 74 + apps/console/src/routes/vendorRoutes.ts | 8 + pkg/coredata/entity_type_reg.go | 1 + pkg/coredata/migrations/20250818T152559Z.sql | 15 + pkg/coredata/vendor_service.go | 259 +++ pkg/coredata/vendor_service_order_field.go | 51 + pkg/probo/service.go | 2 + pkg/probo/vendor_service_service.go | 185 ++ pkg/server/api/console/v1/schema.graphql | 86 + pkg/server/api/console/v1/schema/schema.go | 2072 +++++++++++++++++ pkg/server/api/console/v1/types/types.go | 55 + .../api/console/v1/types/vendor_service.go | 54 + pkg/server/api/console/v1/v1_resolver.go | 107 + 25 files changed, 4638 insertions(+), 68 deletions(-) create mode 100644 apps/console/src/pages/organizations/vendors/dialogs/CreateServiceDialog.tsx create mode 100644 apps/console/src/pages/organizations/vendors/dialogs/EditServiceDialog.tsx create mode 100644 apps/console/src/pages/organizations/vendors/dialogs/__generated__/CreateServiceDialogMutation.graphql.ts create mode 100644 apps/console/src/pages/organizations/vendors/dialogs/__generated__/EditServiceDialogUpdateMutation.graphql.ts create mode 100644 apps/console/src/pages/organizations/vendors/tabs/VendorServicesTab.tsx create mode 100644 apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesListQuery.graphql.ts create mode 100644 apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesTabDeleteServiceMutation.graphql.ts create mode 100644 apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesTabFragment.graphql.ts create mode 100644 apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesTabFragment_service.graphql.ts create mode 100644 pkg/coredata/migrations/20250818T152559Z.sql create mode 100644 pkg/coredata/vendor_service.go create mode 100644 pkg/coredata/vendor_service_order_field.go create mode 100644 pkg/probo/vendor_service_service.go create mode 100644 pkg/server/api/console/v1/types/vendor_service.go diff --git a/apps/console/src/hooks/graph/VendorGraph.ts b/apps/console/src/hooks/graph/VendorGraph.ts index e42611062..b9fde4876 100644 --- a/apps/console/src/hooks/graph/VendorGraph.ts +++ b/apps/console/src/hooks/graph/VendorGraph.ts @@ -153,6 +153,7 @@ export const vendorNodeQuery = graphql` ...useVendorFormFragment ...VendorComplianceTabFragment ...VendorContactsTabFragment + ...VendorServicesTabFragment ...VendorRiskAssessmentTabFragment ...VendorOverviewTabBusinessAssociateAgreementFragment ...VendorOverviewTabDataPrivacyAgreementFragment diff --git a/apps/console/src/hooks/graph/__generated__/VendorGraphNodeQuery.graphql.ts b/apps/console/src/hooks/graph/__generated__/VendorGraphNodeQuery.graphql.ts index d38447519..c9848c258 100644 --- a/apps/console/src/hooks/graph/__generated__/VendorGraphNodeQuery.graphql.ts +++ b/apps/console/src/hooks/graph/__generated__/VendorGraphNodeQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<46bd8a339fe6fd05256df0b1f806e0bd>> * @lightSyntaxTransform * @nogrep */ @@ -19,7 +19,7 @@ export type VendorGraphNodeQuery$data = { readonly id?: string; readonly name?: string; readonly websiteUrl?: string | null | undefined; - readonly " $fragmentSpreads": FragmentRefs<"VendorComplianceTabFragment" | "VendorContactsTabFragment" | "VendorOverviewTabBusinessAssociateAgreementFragment" | "VendorOverviewTabDataPrivacyAgreementFragment" | "VendorRiskAssessmentTabFragment" | "useVendorFormFragment">; + readonly " $fragmentSpreads": FragmentRefs<"VendorComplianceTabFragment" | "VendorContactsTabFragment" | "VendorOverviewTabBusinessAssociateAgreementFragment" | "VendorOverviewTabDataPrivacyAgreementFragment" | "VendorRiskAssessmentTabFragment" | "VendorServicesTabFragment" | "useVendorFormFragment">; }; readonly viewer: { readonly user: { @@ -99,63 +99,70 @@ v8 = { "name": "__typename", "storageKey": null }, -v9 = [ +v9 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "description", + "storageKey": null +}, +v10 = [ { "kind": "Literal", "name": "first", "value": 50 } ], -v10 = { +v11 = { "alias": null, "args": null, "kind": "ScalarField", "name": "validUntil", "storageKey": null }, -v11 = { +v12 = { "alias": null, "args": null, "kind": "ScalarField", "name": "fileUrl", "storageKey": null }, -v12 = { +v13 = { "alias": null, "args": null, "kind": "ScalarField", "name": "cursor", "storageKey": null }, -v13 = { +v14 = { "alias": null, "args": null, "kind": "ScalarField", "name": "endCursor", "storageKey": null }, -v14 = { +v15 = { "alias": null, "args": null, "kind": "ScalarField", "name": "hasNextPage", "storageKey": null }, -v15 = { +v16 = { "alias": null, "args": null, "kind": "ScalarField", "name": "hasPreviousPage", "storageKey": null }, -v16 = { +v17 = { "alias": null, "args": null, "kind": "ScalarField", "name": "startCursor", "storageKey": null }, -v17 = { +v18 = { "alias": null, "args": null, "concreteType": "PageInfo", @@ -163,14 +170,14 @@ v17 = { "name": "pageInfo", "plural": false, "selections": [ - (v13/*: any*/), (v14/*: any*/), (v15/*: any*/), - (v16/*: any*/) + (v16/*: any*/), + (v17/*: any*/) ], "storageKey": null }, -v18 = { +v19 = { "kind": "ClientExtension", "selections": [ { @@ -182,24 +189,31 @@ v18 = { } ] }, -v19 = [ +v20 = [ "orderBy" ], -v20 = { +v21 = { "alias": null, "args": null, "kind": "ScalarField", "name": "fullName", "storageKey": null }, -v21 = { +v22 = { "alias": null, "args": null, "kind": "ScalarField", "name": "createdAt", "storageKey": null }, -v22 = [ +v23 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "updatedAt", + "storageKey": null +}, +v24 = [ (v3/*: any*/), { "alias": null, @@ -208,7 +222,7 @@ v22 = [ "name": "fileName", "storageKey": null }, - (v11/*: any*/), + (v12/*: any*/), { "alias": null, "args": null, @@ -216,8 +230,8 @@ v22 = [ "name": "validFrom", "storageKey": null }, - (v10/*: any*/), - (v21/*: any*/) + (v11/*: any*/), + (v22/*: any*/) ]; return { "fragment": { @@ -258,6 +272,11 @@ return { "kind": "FragmentSpread", "name": "VendorContactsTabFragment" }, + { + "args": null, + "kind": "FragmentSpread", + "name": "VendorServicesTabFragment" + }, { "args": null, "kind": "FragmentSpread", @@ -331,13 +350,7 @@ return { "selections": [ (v4/*: any*/), (v5/*: any*/), - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "description", - "storageKey": null - }, + (v9/*: any*/), { "alias": null, "args": null, @@ -430,7 +443,7 @@ return { }, { "alias": null, - "args": (v9/*: any*/), + "args": (v10/*: any*/), "concreteType": "VendorComplianceReportConnection", "kind": "LinkedField", "name": "complianceReports", @@ -460,7 +473,7 @@ return { "name": "reportDate", "storageKey": null }, - (v10/*: any*/), + (v11/*: any*/), { "alias": null, "args": null, @@ -468,7 +481,7 @@ return { "name": "reportName", "storageKey": null }, - (v11/*: any*/), + (v12/*: any*/), { "alias": null, "args": null, @@ -480,19 +493,19 @@ return { ], "storageKey": null }, - (v12/*: any*/) + (v13/*: any*/) ], "storageKey": null }, - (v17/*: any*/), - (v18/*: any*/) + (v18/*: any*/), + (v19/*: any*/) ], "storageKey": "complianceReports(first:50)" }, { "alias": null, - "args": (v9/*: any*/), - "filters": (v19/*: any*/), + "args": (v10/*: any*/), + "filters": (v20/*: any*/), "handle": "connection", "key": "VendorComplianceTabFragment_complianceReports", "kind": "LinkedHandle", @@ -500,7 +513,7 @@ return { }, { "alias": null, - "args": (v9/*: any*/), + "args": (v10/*: any*/), "concreteType": "VendorContactConnection", "kind": "LinkedField", "name": "contacts", @@ -523,7 +536,7 @@ return { "plural": false, "selections": [ (v3/*: any*/), - (v20/*: any*/), + (v21/*: any*/), { "alias": null, "args": null, @@ -545,31 +558,25 @@ return { "name": "role", "storageKey": null }, - (v21/*: any*/), - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "updatedAt", - "storageKey": null - }, + (v22/*: any*/), + (v23/*: any*/), (v8/*: any*/) ], "storageKey": null }, - (v12/*: any*/) + (v13/*: any*/) ], "storageKey": null }, - (v17/*: any*/), - (v18/*: any*/) + (v18/*: any*/), + (v19/*: any*/) ], "storageKey": "contacts(first:50)" }, { "alias": null, - "args": (v9/*: any*/), - "filters": (v19/*: any*/), + "args": (v10/*: any*/), + "filters": (v20/*: any*/), "handle": "connection", "key": "VendorContactsTabFragment_contacts", "kind": "LinkedHandle", @@ -577,7 +584,58 @@ return { }, { "alias": null, - "args": (v9/*: any*/), + "args": (v10/*: any*/), + "concreteType": "VendorServiceConnection", + "kind": "LinkedField", + "name": "services", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "VendorServiceEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "VendorService", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v3/*: any*/), + (v4/*: any*/), + (v9/*: any*/), + (v22/*: any*/), + (v23/*: any*/), + (v8/*: any*/) + ], + "storageKey": null + }, + (v13/*: any*/) + ], + "storageKey": null + }, + (v18/*: any*/), + (v19/*: any*/) + ], + "storageKey": "services(first:50)" + }, + { + "alias": null, + "args": (v10/*: any*/), + "filters": (v20/*: any*/), + "handle": "connection", + "key": "VendorServicesTabFragment_services", + "kind": "LinkedHandle", + "name": "services" + }, + { + "alias": null, + "args": (v10/*: any*/), "concreteType": "VendorRiskAssessmentConnection", "kind": "LinkedField", "name": "riskAssessments", @@ -616,7 +674,7 @@ return { "plural": false, "selections": [ (v3/*: any*/), - (v20/*: any*/) + (v21/*: any*/) ], "storageKey": null }, @@ -652,7 +710,7 @@ return { ], "storageKey": null }, - (v12/*: any*/) + (v13/*: any*/) ], "storageKey": null }, @@ -664,21 +722,21 @@ return { "name": "pageInfo", "plural": false, "selections": [ - (v14/*: any*/), - (v13/*: any*/), (v15/*: any*/), - (v16/*: any*/) + (v14/*: any*/), + (v16/*: any*/), + (v17/*: any*/) ], "storageKey": null }, - (v18/*: any*/) + (v19/*: any*/) ], "storageKey": "riskAssessments(first:50)" }, { "alias": null, - "args": (v9/*: any*/), - "filters": (v19/*: any*/), + "args": (v10/*: any*/), + "filters": (v20/*: any*/), "handle": "connection", "key": "VendorRiskAssessmentTabFragment_riskAssessments", "kind": "LinkedHandle", @@ -691,7 +749,7 @@ return { "kind": "LinkedField", "name": "businessAssociateAgreement", "plural": false, - "selections": (v22/*: any*/), + "selections": (v24/*: any*/), "storageKey": null }, { @@ -701,7 +759,7 @@ return { "kind": "LinkedField", "name": "dataPrivacyAgreement", "plural": false, - "selections": (v22/*: any*/), + "selections": (v24/*: any*/), "storageKey": null } ], @@ -739,16 +797,16 @@ return { ] }, "params": { - "cacheID": "5e87c78ed85f28f7390e2aada6c241e8", + "cacheID": "7e1a7455861aea37eee2d799d8385586", "id": null, "metadata": {}, "name": "VendorGraphNodeQuery", "operationKind": "query", - "text": "query VendorGraphNodeQuery(\n $vendorId: ID!\n $organizationId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n name\n websiteUrl\n ...useVendorFormFragment\n ...VendorComplianceTabFragment\n ...VendorContactsTabFragment\n ...VendorRiskAssessmentTabFragment\n ...VendorOverviewTabBusinessAssociateAgreementFragment\n ...VendorOverviewTabDataPrivacyAgreementFragment\n }\n id\n }\n viewer {\n user {\n people(organizationId: $organizationId) {\n id\n }\n id\n }\n id\n }\n}\n\nfragment VendorComplianceTabFragment on Vendor {\n complianceReports(first: 50) {\n edges {\n node {\n id\n ...VendorComplianceTabFragment_report\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorComplianceTabFragment_report on VendorComplianceReport {\n id\n reportDate\n validUntil\n reportName\n fileUrl\n fileSize\n}\n\nfragment VendorContactsTabFragment on Vendor {\n contacts(first: 50) {\n edges {\n node {\n id\n ...VendorContactsTabFragment_contact\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorContactsTabFragment_contact on VendorContact {\n id\n fullName\n email\n phone\n role\n createdAt\n updatedAt\n}\n\nfragment VendorOverviewTabBusinessAssociateAgreementFragment on Vendor {\n businessAssociateAgreement {\n id\n fileName\n fileUrl\n validFrom\n validUntil\n createdAt\n }\n}\n\nfragment VendorOverviewTabDataPrivacyAgreementFragment on Vendor {\n dataPrivacyAgreement {\n id\n fileName\n fileUrl\n validFrom\n validUntil\n createdAt\n }\n}\n\nfragment VendorRiskAssessmentTabFragment on Vendor {\n id\n riskAssessments(first: 50) {\n edges {\n node {\n id\n ...VendorRiskAssessmentTabFragment_assessment\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment VendorRiskAssessmentTabFragment_assessment on VendorRiskAssessment {\n id\n assessedAt\n assessedBy {\n id\n fullName\n }\n expiresAt\n dataSensitivity\n businessImpact\n notes\n}\n\nfragment useVendorFormFragment on Vendor {\n id\n name\n description\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n websiteUrl\n legalName\n headquarterAddress\n certifications\n securityPageUrl\n trustPageUrl\n businessOwner {\n id\n }\n securityOwner {\n id\n }\n}\n" + "text": "query VendorGraphNodeQuery(\n $vendorId: ID!\n $organizationId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n name\n websiteUrl\n ...useVendorFormFragment\n ...VendorComplianceTabFragment\n ...VendorContactsTabFragment\n ...VendorServicesTabFragment\n ...VendorRiskAssessmentTabFragment\n ...VendorOverviewTabBusinessAssociateAgreementFragment\n ...VendorOverviewTabDataPrivacyAgreementFragment\n }\n id\n }\n viewer {\n user {\n people(organizationId: $organizationId) {\n id\n }\n id\n }\n id\n }\n}\n\nfragment VendorComplianceTabFragment on Vendor {\n complianceReports(first: 50) {\n edges {\n node {\n id\n ...VendorComplianceTabFragment_report\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorComplianceTabFragment_report on VendorComplianceReport {\n id\n reportDate\n validUntil\n reportName\n fileUrl\n fileSize\n}\n\nfragment VendorContactsTabFragment on Vendor {\n contacts(first: 50) {\n edges {\n node {\n id\n ...VendorContactsTabFragment_contact\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorContactsTabFragment_contact on VendorContact {\n id\n fullName\n email\n phone\n role\n createdAt\n updatedAt\n}\n\nfragment VendorOverviewTabBusinessAssociateAgreementFragment on Vendor {\n businessAssociateAgreement {\n id\n fileName\n fileUrl\n validFrom\n validUntil\n createdAt\n }\n}\n\nfragment VendorOverviewTabDataPrivacyAgreementFragment on Vendor {\n dataPrivacyAgreement {\n id\n fileName\n fileUrl\n validFrom\n validUntil\n createdAt\n }\n}\n\nfragment VendorRiskAssessmentTabFragment on Vendor {\n id\n riskAssessments(first: 50) {\n edges {\n node {\n id\n ...VendorRiskAssessmentTabFragment_assessment\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment VendorRiskAssessmentTabFragment_assessment on VendorRiskAssessment {\n id\n assessedAt\n assessedBy {\n id\n fullName\n }\n expiresAt\n dataSensitivity\n businessImpact\n notes\n}\n\nfragment VendorServicesTabFragment on Vendor {\n services(first: 50) {\n edges {\n node {\n id\n ...VendorServicesTabFragment_service\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorServicesTabFragment_service on VendorService {\n id\n name\n description\n createdAt\n updatedAt\n}\n\nfragment useVendorFormFragment on Vendor {\n id\n name\n description\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n websiteUrl\n legalName\n headquarterAddress\n certifications\n securityPageUrl\n trustPageUrl\n businessOwner {\n id\n }\n securityOwner {\n id\n }\n}\n" } }; })(); -(node as any).hash = "82f82a56df0ea5b755937ebcc55c1382"; +(node as any).hash = "1eac0bd4bc5eccf51ea024d27f348e14"; export default node; diff --git a/apps/console/src/pages/organizations/vendors/VendorDetailPage.tsx b/apps/console/src/pages/organizations/vendors/VendorDetailPage.tsx index d69ea1821..230beb9f1 100644 --- a/apps/console/src/pages/organizations/vendors/VendorDetailPage.tsx +++ b/apps/console/src/pages/organizations/vendors/VendorDetailPage.tsx @@ -117,6 +117,11 @@ export default function VendorDetailPage(props: Props) { > {__("Contacts")} + + {__("Services")} + diff --git a/apps/console/src/pages/organizations/vendors/dialogs/CreateServiceDialog.tsx b/apps/console/src/pages/organizations/vendors/dialogs/CreateServiceDialog.tsx new file mode 100644 index 000000000..3510b6f8a --- /dev/null +++ b/apps/console/src/pages/organizations/vendors/dialogs/CreateServiceDialog.tsx @@ -0,0 +1,123 @@ +import { useTranslate } from "@probo/i18n"; +import { + Breadcrumb, + Button, + Dialog, + DialogContent, + DialogFooter, + Field, + useDialogRef, +} from "@probo/ui"; +import { cleanFormData } from "@probo/helpers"; +import { type ReactNode } from "react"; +import { graphql } from "relay-runtime"; +import { useMutationWithToasts } from "/hooks/useMutationWithToasts"; +import { z } from "zod"; +import { useFormWithSchema } from "/hooks/useFormWithSchema"; + +type Props = { + children: ReactNode; + connectionId: string; + vendorId: string; +}; + +const createServiceMutation = graphql` + mutation CreateServiceDialogMutation( + $input: CreateVendorServiceInput! + $connections: [ID!]! + ) { + createVendorService(input: $input) { + vendorServiceEdge @prependEdge(connections: $connections) { + node { + ...VendorServicesTabFragment_service + } + } + } + } +`; + +export function CreateServiceDialog({ + children, + connectionId, + vendorId, +}: Props) { + const { __ } = useTranslate(); + + const schema = z.object({ + name: z.string().min(1, __("Service name is required")), + description: z.string().optional(), + }); + + const { register, handleSubmit, formState, reset } = useFormWithSchema( + schema, + { + defaultValues: { + name: "", + description: "", + }, + } + ); + const [createService, isLoading] = useMutationWithToasts( + createServiceMutation, + { + successMessage: __("Service created successfully."), + errorMessage: __("Failed to create service. Please try again."), + } + ); + + const onSubmit = handleSubmit((data) => { + const cleanData = cleanFormData(data); + + createService({ + variables: { + input: { + vendorId, + ...cleanData, + }, + connections: [connectionId], + }, + onSuccess: () => { + dialogRef.current?.close(); + reset(); + }, + }); + }); + + const dialogRef = useDialogRef(); + + return ( + + } + > +
+ + + + + + + +
+
+ ); +} diff --git a/apps/console/src/pages/organizations/vendors/dialogs/EditServiceDialog.tsx b/apps/console/src/pages/organizations/vendors/dialogs/EditServiceDialog.tsx new file mode 100644 index 000000000..8ce3a13bb --- /dev/null +++ b/apps/console/src/pages/organizations/vendors/dialogs/EditServiceDialog.tsx @@ -0,0 +1,120 @@ +import { useTranslate } from "@probo/i18n"; +import { + Breadcrumb, + Button, + Dialog, + DialogContent, + DialogFooter, + Field, + useDialogRef, +} from "@probo/ui"; +import { cleanFormData } from "@probo/helpers"; +import { useEffect } from "react"; +import { graphql } from "relay-runtime"; +import { useMutationWithToasts } from "/hooks/useMutationWithToasts"; +import { z } from "zod"; +import { useFormWithSchema } from "/hooks/useFormWithSchema"; + +type Props = { + serviceId: string; + service: { + name: string; + description?: string | null; + }; + onClose: () => void; +}; + +const updateServiceMutation = graphql` + mutation EditServiceDialogUpdateMutation($input: UpdateVendorServiceInput!) { + updateVendorService(input: $input) { + vendorService { + ...VendorServicesTabFragment_service + } + } + } +`; + +export function EditServiceDialog({ serviceId, service, onClose }: Props) { + const { __ } = useTranslate(); + + const schema = z.object({ + name: z.string().min(1, __("Service name is required")), + description: z.string().optional(), + }); + + const { register, handleSubmit, formState } = useFormWithSchema( + schema, + { + defaultValues: { + name: service.name || "", + description: service.description || "", + }, + } + ); + + const [updateService, isLoading] = useMutationWithToasts( + updateServiceMutation, + { + successMessage: __("Service updated successfully."), + errorMessage: __("Failed to update service. Please try again."), + } + ); + + const onSubmit = handleSubmit((data) => { + const cleanData = cleanFormData(data); + + updateService({ + variables: { + input: { + id: serviceId, + ...cleanData, + }, + }, + onSuccess: () => { + onClose(); + }, + }); + }); + + const dialogRef = useDialogRef(); + + useEffect(() => { + dialogRef.current?.open(); + }, []); + + return ( + + } + > +
+ + + + + + + +
+
+ ); +} diff --git a/apps/console/src/pages/organizations/vendors/dialogs/__generated__/CreateServiceDialogMutation.graphql.ts b/apps/console/src/pages/organizations/vendors/dialogs/__generated__/CreateServiceDialogMutation.graphql.ts new file mode 100644 index 000000000..c07be296e --- /dev/null +++ b/apps/console/src/pages/organizations/vendors/dialogs/__generated__/CreateServiceDialogMutation.graphql.ts @@ -0,0 +1,216 @@ +/** + * @generated SignedSource<<57cf7bb390b9d8d00ce0368cf782205c>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type CreateVendorServiceInput = { + description?: string | null | undefined; + name: string; + type?: string | null | undefined; + url?: string | null | undefined; + vendorId: string; +}; +export type CreateServiceDialogMutation$variables = { + connections: ReadonlyArray; + input: CreateVendorServiceInput; +}; +export type CreateServiceDialogMutation$data = { + readonly createVendorService: { + readonly vendorServiceEdge: { + readonly node: { + readonly " $fragmentSpreads": FragmentRefs<"VendorServicesTabFragment_service">; + }; + }; + }; +}; +export type CreateServiceDialogMutation = { + response: CreateServiceDialogMutation$data; + variables: CreateServiceDialogMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "connections" +}, +v1 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" +}, +v2 = [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } +]; +return { + "fragment": { + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/) + ], + "kind": "Fragment", + "metadata": null, + "name": "CreateServiceDialogMutation", + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": "CreateVendorServicePayload", + "kind": "LinkedField", + "name": "createVendorService", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "VendorServiceEdge", + "kind": "LinkedField", + "name": "vendorServiceEdge", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "VendorService", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "VendorServicesTabFragment_service" + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [ + (v1/*: any*/), + (v0/*: any*/) + ], + "kind": "Operation", + "name": "CreateServiceDialogMutation", + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": "CreateVendorServicePayload", + "kind": "LinkedField", + "name": "createVendorService", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "VendorServiceEdge", + "kind": "LinkedField", + "name": "vendorServiceEdge", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "VendorService", + "kind": "LinkedField", + "name": "node", + "plural": false, + "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": "description", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "updatedAt", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "filters": null, + "handle": "prependEdge", + "key": "", + "kind": "LinkedHandle", + "name": "vendorServiceEdge", + "handleArgs": [ + { + "kind": "Variable", + "name": "connections", + "variableName": "connections" + } + ] + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "c4c687377eb1a18eb15abbfa1bf86bfa", + "id": null, + "metadata": {}, + "name": "CreateServiceDialogMutation", + "operationKind": "mutation", + "text": "mutation CreateServiceDialogMutation(\n $input: CreateVendorServiceInput!\n) {\n createVendorService(input: $input) {\n vendorServiceEdge {\n node {\n ...VendorServicesTabFragment_service\n id\n }\n }\n }\n}\n\nfragment VendorServicesTabFragment_service on VendorService {\n id\n name\n description\n createdAt\n updatedAt\n}\n" + } +}; +})(); + +(node as any).hash = "8dd0e535bfa15e8ac78b630139b57177"; + +export default node; diff --git a/apps/console/src/pages/organizations/vendors/dialogs/__generated__/EditServiceDialogUpdateMutation.graphql.ts b/apps/console/src/pages/organizations/vendors/dialogs/__generated__/EditServiceDialogUpdateMutation.graphql.ts new file mode 100644 index 000000000..e0b61d447 --- /dev/null +++ b/apps/console/src/pages/organizations/vendors/dialogs/__generated__/EditServiceDialogUpdateMutation.graphql.ts @@ -0,0 +1,166 @@ +/** + * @generated SignedSource<<97f0c6ed319e3fba440079ef085a55eb>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type UpdateVendorServiceInput = { + description?: string | null | undefined; + id: string; + name?: string | null | undefined; + type?: string | null | undefined; + url?: string | null | undefined; +}; +export type EditServiceDialogUpdateMutation$variables = { + input: UpdateVendorServiceInput; +}; +export type EditServiceDialogUpdateMutation$data = { + readonly updateVendorService: { + readonly vendorService: { + readonly " $fragmentSpreads": FragmentRefs<"VendorServicesTabFragment_service">; + }; + }; +}; +export type EditServiceDialogUpdateMutation = { + response: EditServiceDialogUpdateMutation$data; + variables: EditServiceDialogUpdateMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" + } +], +v1 = [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "EditServiceDialogUpdateMutation", + "selections": [ + { + "alias": null, + "args": (v1/*: any*/), + "concreteType": "UpdateVendorServicePayload", + "kind": "LinkedField", + "name": "updateVendorService", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "VendorService", + "kind": "LinkedField", + "name": "vendorService", + "plural": false, + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "VendorServicesTabFragment_service" + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "EditServiceDialogUpdateMutation", + "selections": [ + { + "alias": null, + "args": (v1/*: any*/), + "concreteType": "UpdateVendorServicePayload", + "kind": "LinkedField", + "name": "updateVendorService", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "VendorService", + "kind": "LinkedField", + "name": "vendorService", + "plural": false, + "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": "description", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "updatedAt", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "f2c37fa9a0b7f0ed043a4529d1f50c65", + "id": null, + "metadata": {}, + "name": "EditServiceDialogUpdateMutation", + "operationKind": "mutation", + "text": "mutation EditServiceDialogUpdateMutation(\n $input: UpdateVendorServiceInput!\n) {\n updateVendorService(input: $input) {\n vendorService {\n ...VendorServicesTabFragment_service\n id\n }\n }\n}\n\nfragment VendorServicesTabFragment_service on VendorService {\n id\n name\n description\n createdAt\n updatedAt\n}\n" + } +}; +})(); + +(node as any).hash = "8a34720f5ae7e1f5c619518d4e0db460"; + +export default node; diff --git a/apps/console/src/pages/organizations/vendors/tabs/VendorContactsTab.tsx b/apps/console/src/pages/organizations/vendors/tabs/VendorContactsTab.tsx index 6850a3d05..604026f9d 100644 --- a/apps/console/src/pages/organizations/vendors/tabs/VendorContactsTab.tsx +++ b/apps/console/src/pages/organizations/vendors/tabs/VendorContactsTab.tsx @@ -120,7 +120,6 @@ export default function VendorContactsTab() { {__("Email")} {__("Phone")} {__("Role")} - {__("Created")} {__("Actions")} @@ -165,7 +164,6 @@ function ContactRow(props: ContactRowProps) { contactFragment, props.contactKey ); - const { dateFormat } = useTranslate(); const confirm = useConfirm(); const [deleteContact] = useMutationWithToasts(deleteContactMutation, { successMessage: __("Contact deleted successfully"), @@ -222,7 +220,6 @@ function ContactRow(props: ContactRowProps) { )} {contact.role || __("—")} - {dateFormat(contact.createdAt)} (); + const [data, refetch] = useRefetchableFragment( + vendorServicesFragment, + vendor + ); + const connectionId = data.services.__id; + const services = data.services.edges.map((edge) => edge.node); + const { __ } = useTranslate(); + const [editingService, setEditingService] = useState<{ + id: string; + name: string; + description?: string | null; + } | null>(null); + + usePageTitle(vendor.name + " - " + __("Services")); + + return ( +
+ + + + + + + + + + {__("Name")} + {__("Description")} + {__("Actions")} + + + + {services.map((service) => ( + + ))} + + + + {editingService && ( + setEditingService(null)} + /> + )} +
+ ); +} + +type ServiceRowProps = { + serviceKey: VendorServicesTabFragment_service$key; + connectionId: string; + onEdit: (service: { + id: string; + name: string; + description?: string | null; + }) => void; +}; + +function ServiceRow(props: ServiceRowProps) { + const { __ } = useTranslate(); + const service = useFragment( + serviceFragment, + props.serviceKey + ); + const confirm = useConfirm(); + const [deleteService] = useMutationWithToasts(deleteServiceMutation, { + successMessage: __("Service deleted successfully"), + errorMessage: __("Failed to delete service"), + }); + + const handleDelete = () => { + confirm( + () => + deleteService({ + variables: { + connections: [props.connectionId], + input: { + vendorServiceId: service.id, + }, + }, + }), + { + message: sprintf( + __( + 'This will permanently delete the service "%s". This action cannot be undone.' + ), + service.name + ), + } + ); + }; + + return ( + + {service.name} + {service.description || __("—")} + + + props.onEdit({ + id: service.id, + name: service.name, + description: service.description, + })} + > + {__("Edit")} + + + {__("Delete")} + + + + + ); +} diff --git a/apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesListQuery.graphql.ts b/apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesListQuery.graphql.ts new file mode 100644 index 000000000..5eead22d4 --- /dev/null +++ b/apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesListQuery.graphql.ts @@ -0,0 +1,344 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type OrderDirection = "ASC" | "DESC"; +export type VendorServiceOrderField = "CREATED_AT" | "NAME"; +export type VendorServiceOrder = { + direction: OrderDirection; + field: VendorServiceOrderField; +}; +export type VendorServicesListQuery$variables = { + after?: any | null | undefined; + before?: any | null | undefined; + first?: number | null | undefined; + id: string; + last?: number | null | undefined; + order?: VendorServiceOrder | null | undefined; +}; +export type VendorServicesListQuery$data = { + readonly node: { + readonly " $fragmentSpreads": FragmentRefs<"VendorServicesTabFragment">; + }; +}; +export type VendorServicesListQuery = { + response: VendorServicesListQuery$data; + variables: VendorServicesListQuery$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "after" +}, +v1 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "before" +}, +v2 = { + "defaultValue": 50, + "kind": "LocalArgument", + "name": "first" +}, +v3 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "id" +}, +v4 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "last" +}, +v5 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "order" +}, +v6 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "id" + } +], +v7 = { + "kind": "Variable", + "name": "after", + "variableName": "after" +}, +v8 = { + "kind": "Variable", + "name": "before", + "variableName": "before" +}, +v9 = { + "kind": "Variable", + "name": "first", + "variableName": "first" +}, +v10 = { + "kind": "Variable", + "name": "last", + "variableName": "last" +}, +v11 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null +}, +v12 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v13 = [ + (v7/*: any*/), + (v8/*: any*/), + (v9/*: any*/), + (v10/*: any*/), + { + "kind": "Variable", + "name": "orderBy", + "variableName": "order" + } +]; +return { + "fragment": { + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/), + (v2/*: any*/), + (v3/*: any*/), + (v4/*: any*/), + (v5/*: any*/) + ], + "kind": "Fragment", + "metadata": null, + "name": "VendorServicesListQuery", + "selections": [ + { + "alias": null, + "args": (v6/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "args": [ + (v7/*: any*/), + (v8/*: any*/), + (v9/*: any*/), + (v10/*: any*/), + { + "kind": "Variable", + "name": "order", + "variableName": "order" + } + ], + "kind": "FragmentSpread", + "name": "VendorServicesTabFragment" + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/), + (v2/*: any*/), + (v4/*: any*/), + (v5/*: any*/), + (v3/*: any*/) + ], + "kind": "Operation", + "name": "VendorServicesListQuery", + "selections": [ + { + "alias": null, + "args": (v6/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v11/*: any*/), + (v12/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": (v13/*: any*/), + "concreteType": "VendorServiceConnection", + "kind": "LinkedField", + "name": "services", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "VendorServiceEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "VendorService", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v12/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "description", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "updatedAt", + "storageKey": null + }, + (v11/*: any*/) + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "cursor", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "PageInfo", + "kind": "LinkedField", + "name": "pageInfo", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "endCursor", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hasNextPage", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hasPreviousPage", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "startCursor", + "storageKey": null + } + ], + "storageKey": null + }, + { + "kind": "ClientExtension", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__id", + "storageKey": null + } + ] + } + ], + "storageKey": null + }, + { + "alias": null, + "args": (v13/*: any*/), + "filters": [ + "orderBy" + ], + "handle": "connection", + "key": "VendorServicesTabFragment_services", + "kind": "LinkedHandle", + "name": "services" + } + ], + "type": "Vendor", + "abstractKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "102f3aac3e2c7ef5115d73246f1bb241", + "id": null, + "metadata": {}, + "name": "VendorServicesListQuery", + "operationKind": "query", + "text": "query VendorServicesListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 50\n $last: Int = null\n $order: VendorServiceOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...VendorServicesTabFragment_16fISc\n id\n }\n}\n\nfragment VendorServicesTabFragment_16fISc on Vendor {\n services(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n edges {\n node {\n id\n ...VendorServicesTabFragment_service\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorServicesTabFragment_service on VendorService {\n id\n name\n description\n createdAt\n updatedAt\n}\n" + } +}; +})(); + +(node as any).hash = "fd0c58f2929f925fb47e5df22f6a84f7"; + +export default node; diff --git a/apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesTabDeleteServiceMutation.graphql.ts b/apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesTabDeleteServiceMutation.graphql.ts new file mode 100644 index 000000000..baa90fc88 --- /dev/null +++ b/apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesTabDeleteServiceMutation.graphql.ts @@ -0,0 +1,132 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type DeleteVendorServiceInput = { + vendorServiceId: string; +}; +export type VendorServicesTabDeleteServiceMutation$variables = { + connections: ReadonlyArray; + input: DeleteVendorServiceInput; +}; +export type VendorServicesTabDeleteServiceMutation$data = { + readonly deleteVendorService: { + readonly deletedVendorServiceId: string; + }; +}; +export type VendorServicesTabDeleteServiceMutation = { + response: VendorServicesTabDeleteServiceMutation$data; + variables: VendorServicesTabDeleteServiceMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "connections" +}, +v1 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" +}, +v2 = [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } +], +v3 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "deletedVendorServiceId", + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/) + ], + "kind": "Fragment", + "metadata": null, + "name": "VendorServicesTabDeleteServiceMutation", + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": "DeleteVendorServicePayload", + "kind": "LinkedField", + "name": "deleteVendorService", + "plural": false, + "selections": [ + (v3/*: any*/) + ], + "storageKey": null + } + ], + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [ + (v1/*: any*/), + (v0/*: any*/) + ], + "kind": "Operation", + "name": "VendorServicesTabDeleteServiceMutation", + "selections": [ + { + "alias": null, + "args": (v2/*: any*/), + "concreteType": "DeleteVendorServicePayload", + "kind": "LinkedField", + "name": "deleteVendorService", + "plural": false, + "selections": [ + (v3/*: any*/), + { + "alias": null, + "args": null, + "filters": null, + "handle": "deleteEdge", + "key": "", + "kind": "ScalarHandle", + "name": "deletedVendorServiceId", + "handleArgs": [ + { + "kind": "Variable", + "name": "connections", + "variableName": "connections" + } + ] + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "fef00196f74b15a5528a0974541f1ec4", + "id": null, + "metadata": {}, + "name": "VendorServicesTabDeleteServiceMutation", + "operationKind": "mutation", + "text": "mutation VendorServicesTabDeleteServiceMutation(\n $input: DeleteVendorServiceInput!\n) {\n deleteVendorService(input: $input) {\n deletedVendorServiceId\n }\n}\n" + } +}; +})(); + +(node as any).hash = "73d14c22b95d031b2c07b18dbbeb64d4"; + +export default node; diff --git a/apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesTabFragment.graphql.ts b/apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesTabFragment.graphql.ts new file mode 100644 index 000000000..0300210b3 --- /dev/null +++ b/apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesTabFragment.graphql.ts @@ -0,0 +1,225 @@ +/** + * @generated SignedSource<<4dfc017ac50d12a09ddac0cf37061c06>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ReaderFragment } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type VendorServicesTabFragment$data = { + readonly id: string; + readonly services: { + readonly __id: string; + readonly edges: ReadonlyArray<{ + readonly node: { + readonly id: string; + readonly " $fragmentSpreads": FragmentRefs<"VendorServicesTabFragment_service">; + }; + }>; + }; + readonly " $fragmentType": "VendorServicesTabFragment"; +}; +export type VendorServicesTabFragment$key = { + readonly " $data"?: VendorServicesTabFragment$data; + readonly " $fragmentSpreads": FragmentRefs<"VendorServicesTabFragment">; +}; + +import VendorServicesListQuery_graphql from './VendorServicesListQuery.graphql'; + +const node: ReaderFragment = (function(){ +var v0 = [ + "services" +], +v1 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}; +return { + "argumentDefinitions": [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "after" + }, + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "before" + }, + { + "defaultValue": 50, + "kind": "LocalArgument", + "name": "first" + }, + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "last" + }, + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "order" + } + ], + "kind": "Fragment", + "metadata": { + "connection": [ + { + "count": null, + "cursor": null, + "direction": "bidirectional", + "path": (v0/*: any*/) + } + ], + "refetch": { + "connection": { + "forward": { + "count": "first", + "cursor": "after" + }, + "backward": { + "count": "last", + "cursor": "before" + }, + "path": (v0/*: any*/) + }, + "fragmentPathInResult": [ + "node" + ], + "operation": VendorServicesListQuery_graphql, + "identifierInfo": { + "identifierField": "id", + "identifierQueryVariableName": "id" + } + } + }, + "name": "VendorServicesTabFragment", + "selections": [ + { + "alias": "services", + "args": [ + { + "kind": "Variable", + "name": "orderBy", + "variableName": "order" + } + ], + "concreteType": "VendorServiceConnection", + "kind": "LinkedField", + "name": "__VendorServicesTabFragment_services_connection", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "VendorServiceEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "VendorService", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "args": null, + "kind": "FragmentSpread", + "name": "VendorServicesTabFragment_service" + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "cursor", + "storageKey": null + } + ], + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "PageInfo", + "kind": "LinkedField", + "name": "pageInfo", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "endCursor", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hasNextPage", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "hasPreviousPage", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "startCursor", + "storageKey": null + } + ], + "storageKey": null + }, + { + "kind": "ClientExtension", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__id", + "storageKey": null + } + ] + } + ], + "storageKey": null + }, + (v1/*: any*/) + ], + "type": "Vendor", + "abstractKey": null +}; +})(); + +(node as any).hash = "fd0c58f2929f925fb47e5df22f6a84f7"; + +export default node; diff --git a/apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesTabFragment_service.graphql.ts b/apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesTabFragment_service.graphql.ts new file mode 100644 index 000000000..415b1e3f3 --- /dev/null +++ b/apps/console/src/pages/organizations/vendors/tabs/__generated__/VendorServicesTabFragment_service.graphql.ts @@ -0,0 +1,74 @@ +/** + * @generated SignedSource<<2f6dc5bf85b9ad81fe6c9af7955e4217>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ReaderFragment } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type VendorServicesTabFragment_service$data = { + readonly createdAt: any; + readonly description: string | null | undefined; + readonly id: string; + readonly name: string; + readonly updatedAt: any; + readonly " $fragmentType": "VendorServicesTabFragment_service"; +}; +export type VendorServicesTabFragment_service$key = { + readonly " $data"?: VendorServicesTabFragment_service$data; + readonly " $fragmentSpreads": FragmentRefs<"VendorServicesTabFragment_service">; +}; + +const node: ReaderFragment = { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "VendorServicesTabFragment_service", + "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": "description", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "createdAt", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "updatedAt", + "storageKey": null + } + ], + "type": "VendorService", + "abstractKey": null +}; + +(node as any).hash = "276b5545b9e5eb7f9d9f56c4ea2ed352"; + +export default node; diff --git a/apps/console/src/routes/vendorRoutes.ts b/apps/console/src/routes/vendorRoutes.ts index 88dea4ef2..e1515de2a 100644 --- a/apps/console/src/routes/vendorRoutes.ts +++ b/apps/console/src/routes/vendorRoutes.ts @@ -69,6 +69,14 @@ export const vendorRoutes = [ import("../pages/organizations/vendors/tabs/VendorContactsTab") ), }, + { + path: "services", + fallback: LinkCardSkeleton, + Component: lazy( + () => + import("../pages/organizations/vendors/tabs/VendorServicesTab") + ), + }, ], }, ] satisfies AppRoute[]; diff --git a/pkg/coredata/entity_type_reg.go b/pkg/coredata/entity_type_reg.go index 3380eec2e..509c33170 100644 --- a/pkg/coredata/entity_type_reg.go +++ b/pkg/coredata/entity_type_reg.go @@ -45,4 +45,5 @@ const ( VendorDataPrivacyAgreementEntityType NonconformityRegistryEntityType ComplianceRegistryEntityType + VendorServiceEntityType ) diff --git a/pkg/coredata/migrations/20250818T152559Z.sql b/pkg/coredata/migrations/20250818T152559Z.sql new file mode 100644 index 000000000..fc23d4486 --- /dev/null +++ b/pkg/coredata/migrations/20250818T152559Z.sql @@ -0,0 +1,15 @@ +CREATE TABLE vendor_services ( + id TEXT PRIMARY KEY, + tenant_id TEXT NOT NULL, + vendor_id TEXT NOT NULL, + name TEXT NOT NULL, + description TEXT, + created_at TIMESTAMP WITH TIME ZONE NOT NULL, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL, + + CONSTRAINT vendor_services_vendor_id_fkey + FOREIGN KEY (vendor_id) + REFERENCES vendors(id) + ON UPDATE CASCADE + ON DELETE CASCADE +); diff --git a/pkg/coredata/vendor_service.go b/pkg/coredata/vendor_service.go new file mode 100644 index 000000000..b95646cf7 --- /dev/null +++ b/pkg/coredata/vendor_service.go @@ -0,0 +1,259 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package coredata + +import ( + "context" + "errors" + "fmt" + "maps" + "time" + + "github.com/getprobo/probo/pkg/gid" + "github.com/getprobo/probo/pkg/page" + "github.com/jackc/pgx/v5" + "go.gearno.de/kit/pg" +) + +type ( + VendorService struct { + ID gid.GID `db:"id"` + VendorID gid.GID `db:"vendor_id"` + Name string `db:"name"` + Description *string `db:"description"` + CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` + } + + VendorServices []*VendorService + + ErrVendorServiceNotFound struct { + Identifier string + } +) + +func (e ErrVendorServiceNotFound) Error() string { + return fmt.Sprintf("vendor service not found: %s", e.Identifier) +} + +func (vs VendorService) CursorKey(orderBy VendorServiceOrderField) page.CursorKey { + switch orderBy { + case VendorServiceOrderFieldCreatedAt: + return page.CursorKey{ID: vs.ID, Value: vs.CreatedAt} + case VendorServiceOrderFieldName: + return page.CursorKey{ID: vs.ID, Value: vs.Name} + } + + panic(fmt.Sprintf("unsupported order by: %s", orderBy)) +} + +func (vs *VendorService) LoadByID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + vendorServiceID gid.GID, +) error { + q := ` +SELECT + id, + vendor_id, + name, + description, + created_at, + updated_at +FROM + vendor_services +WHERE + %s + AND id = @vendor_service_id +LIMIT 1; +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{"vendor_service_id": vendorServiceID} + maps.Copy(args, scope.SQLArguments()) + + rows, err := conn.Query(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot query vendor service: %w", err) + } + defer rows.Close() + + vendorService, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[VendorService]) + if err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return &ErrVendorServiceNotFound{Identifier: vendorServiceID.String()} + } + + return fmt.Errorf("cannot collect vendor service: %w", err) + } + + *vs = vendorService + + return nil +} + +func (vs *VendorServices) LoadByVendorID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + vendorID gid.GID, + cursor *page.Cursor[VendorServiceOrderField], +) error { + q := ` +SELECT + id, + vendor_id, + name, + description, + created_at, + updated_at +FROM + vendor_services +WHERE + %s + AND vendor_id = @vendor_id + AND %s +` + q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment()) + + args := pgx.StrictNamedArgs{ + "vendor_id": vendorID, + } + maps.Copy(args, scope.SQLArguments()) + maps.Copy(args, cursor.SQLArguments()) + + rows, err := conn.Query(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot query vendor services: %w", err) + } + defer rows.Close() + + vendorServices, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[VendorService]) + if err != nil { + return fmt.Errorf("cannot collect vendor services: %w", err) + } + + *vs = vendorServices + + return nil +} + +func (vs VendorService) Insert( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +INSERT INTO + vendor_services ( + tenant_id, + id, + vendor_id, + name, + description, + created_at, + updated_at + ) +VALUES ( + @tenant_id, + @vendor_service_id, + @vendor_id, + @name, + @description, + @created_at, + @updated_at +) +` + + args := pgx.StrictNamedArgs{ + "tenant_id": scope.GetTenantID(), + "vendor_service_id": vs.ID, + "vendor_id": vs.VendorID, + "name": vs.Name, + "description": vs.Description, + "created_at": vs.CreatedAt, + "updated_at": vs.UpdatedAt, + } + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot insert vendor service: %w", err) + } + + return nil +} + +func (vs VendorService) Update( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +UPDATE + vendor_services +SET + name = @name, + description = @description, + updated_at = @updated_at +WHERE + %s + AND id = @vendor_service_id +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{ + "vendor_service_id": vs.ID, + "name": vs.Name, + "description": vs.Description, + "updated_at": vs.UpdatedAt, + } + maps.Copy(args, scope.SQLArguments()) + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot update vendor service: %w", err) + } + + return nil +} + +func (vs VendorService) Delete( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +DELETE FROM + vendor_services +WHERE + %s + AND id = @vendor_service_id +` + + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{"vendor_service_id": vs.ID} + maps.Copy(args, scope.SQLArguments()) + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot delete vendor service: %w", err) + } + + return nil +} diff --git a/pkg/coredata/vendor_service_order_field.go b/pkg/coredata/vendor_service_order_field.go new file mode 100644 index 000000000..819d1b2da --- /dev/null +++ b/pkg/coredata/vendor_service_order_field.go @@ -0,0 +1,51 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package coredata + +import ( + "fmt" +) + +type ( + VendorServiceOrderField string +) + +const ( + VendorServiceOrderFieldCreatedAt VendorServiceOrderField = "CREATED_AT" + VendorServiceOrderFieldName VendorServiceOrderField = "NAME" +) + +func (p VendorServiceOrderField) Column() string { + return string(p) +} + +func (p VendorServiceOrderField) String() string { + return string(p) +} + +func (p VendorServiceOrderField) MarshalText() ([]byte, error) { + return []byte(p.String()), nil +} + +func (p *VendorServiceOrderField) UnmarshalText(text []byte) error { + val := string(text) + switch val { + case string(VendorServiceOrderFieldCreatedAt), + string(VendorServiceOrderFieldName): + *p = VendorServiceOrderField(val) + return nil + } + return fmt.Errorf("invalid VendorServiceOrderField value: %q", val) +} diff --git a/pkg/probo/service.go b/pkg/probo/service.go index f448a3ba9..d1e69e856 100644 --- a/pkg/probo/service.go +++ b/pkg/probo/service.go @@ -74,6 +74,7 @@ type ( VendorBusinessAssociateAgreements *VendorBusinessAssociateAgreementService VendorContacts *VendorContactService VendorDataPrivacyAgreements *VendorDataPrivacyAgreementService + VendorServices *VendorServiceService Connectors *ConnectorService Assets *AssetService Data *DatumService @@ -165,6 +166,7 @@ func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService { tenantService.VendorBusinessAssociateAgreements = &VendorBusinessAssociateAgreementService{svc: tenantService} tenantService.VendorContacts = &VendorContactService{svc: tenantService} tenantService.VendorDataPrivacyAgreements = &VendorDataPrivacyAgreementService{svc: tenantService} + tenantService.VendorServices = &VendorServiceService{svc: tenantService} tenantService.Connectors = &ConnectorService{svc: tenantService} tenantService.Assets = &AssetService{svc: tenantService} tenantService.Data = &DatumService{svc: tenantService} diff --git a/pkg/probo/vendor_service_service.go b/pkg/probo/vendor_service_service.go new file mode 100644 index 000000000..ac9bda094 --- /dev/null +++ b/pkg/probo/vendor_service_service.go @@ -0,0 +1,185 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package probo + +import ( + "context" + "fmt" + "time" + + "github.com/getprobo/probo/pkg/coredata" + "github.com/getprobo/probo/pkg/gid" + "github.com/getprobo/probo/pkg/page" + "go.gearno.de/kit/pg" +) + +type ( + VendorServiceService struct { + svc *TenantService + } + + CreateVendorServiceRequest struct { + VendorID gid.GID + Name string + Description *string + } + + UpdateVendorServiceRequest struct { + ID gid.GID + Name *string + Description **string + } +) + +func (s VendorServiceService) Get( + ctx context.Context, + vendorServiceID gid.GID, +) (*coredata.VendorService, error) { + vendorService := &coredata.VendorService{} + + err := s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + err := vendorService.LoadByID(ctx, conn, s.svc.scope, vendorServiceID) + if err != nil { + return fmt.Errorf("cannot load vendor service: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return vendorService, nil +} + +func (s VendorServiceService) List( + ctx context.Context, + vendorID gid.GID, + cursor *page.Cursor[coredata.VendorServiceOrderField], +) (*page.Page[*coredata.VendorService, coredata.VendorServiceOrderField], error) { + var vendorServices coredata.VendorServices + + err := s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + err := vendorServices.LoadByVendorID(ctx, conn, s.svc.scope, vendorID, cursor) + if err != nil { + return fmt.Errorf("cannot load vendor services: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return page.NewPage(vendorServices, cursor), nil +} + +func (s VendorServiceService) Create( + ctx context.Context, + req CreateVendorServiceRequest, +) (*coredata.VendorService, error) { + now := time.Now() + vendorService := &coredata.VendorService{ + ID: gid.New(s.svc.scope.GetTenantID(), coredata.VendorServiceEntityType), + VendorID: req.VendorID, + Name: req.Name, + Description: req.Description, + CreatedAt: now, + UpdatedAt: now, + } + + err := s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + if err := vendorService.Insert(ctx, conn, s.svc.scope); err != nil { + return fmt.Errorf("cannot insert vendor service: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return vendorService, nil +} + +func (s VendorServiceService) Update( + ctx context.Context, + req UpdateVendorServiceRequest, +) (*coredata.VendorService, error) { + vendorService := &coredata.VendorService{} + + err := s.svc.pg.WithTx( + ctx, + func(conn pg.Conn) error { + err := vendorService.LoadByID(ctx, conn, s.svc.scope, req.ID) + if err != nil { + return fmt.Errorf("cannot load vendor service: %w", err) + } + + if req.Name != nil { + vendorService.Name = *req.Name + } + if req.Description != nil { + vendorService.Description = *req.Description + } + vendorService.UpdatedAt = time.Now() + + if err := vendorService.Update(ctx, conn, s.svc.scope); err != nil { + return fmt.Errorf("cannot update vendor service: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return vendorService, nil +} + +func (s VendorServiceService) Delete( + ctx context.Context, + vendorServiceID gid.GID, +) error { + vendorService := coredata.VendorService{ID: vendorServiceID} + return s.svc.pg.WithTx( + ctx, + func(conn pg.Conn) error { + if err := vendorService.LoadByID(ctx, conn, s.svc.scope, vendorServiceID); err != nil { + return fmt.Errorf("cannot load vendor service: %w", err) + } + + if err := vendorService.Delete(ctx, conn, s.svc.scope); err != nil { + return fmt.Errorf("cannot delete vendor service: %w", err) + } + + return nil + }, + ) +} diff --git a/pkg/server/api/console/v1/schema.graphql b/pkg/server/api/console/v1/schema.graphql index 2926d4f29..2893d6733 100644 --- a/pkg/server/api/console/v1/schema.graphql +++ b/pkg/server/api/console/v1/schema.graphql @@ -342,6 +342,20 @@ enum VendorContactOrderField ) } +enum VendorServiceOrderField + @goModel( + model: "github.com/getprobo/probo/pkg/coredata.VendorServiceOrderField" + ) { + CREATED_AT + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.VendorServiceOrderFieldCreatedAt" + ) + NAME + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.VendorServiceOrderFieldName" + ) +} + enum OrganizationOrderField @goModel( model: "github.com/getprobo/probo/pkg/coredata.OrganizationOrderField" @@ -801,6 +815,14 @@ input VendorContactOrder field: VendorContactOrderField! } +input VendorServiceOrder + @goModel( + model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.VendorServiceOrderBy" + ) { + direction: OrderDirection! + field: VendorServiceOrderField! +} + input OrganizationOrder { direction: OrderDirection! field: OrganizationOrderField! @@ -1064,6 +1086,14 @@ type Vendor implements Node { orderBy: VendorContactOrder ): VendorContactConnection! @goField(forceResolver: true) + services( + first: Int + after: CursorKey + last: Int + before: CursorKey + orderBy: VendorServiceOrder + ): VendorServiceConnection! @goField(forceResolver: true) + riskAssessments( first: Int after: CursorKey @@ -1128,6 +1158,15 @@ type VendorContact implements Node { updatedAt: Datetime! } +type VendorService implements Node { + id: ID! + vendor: Vendor! @goField(forceResolver: true) + name: String! + description: String + createdAt: Datetime! + updatedAt: Datetime! +} + type VendorDataPrivacyAgreement implements Node { id: ID! vendor: Vendor! @goField(forceResolver: true) @@ -1652,6 +1691,16 @@ type VendorContactEdge { node: VendorContact! } +type VendorServiceConnection { + edges: [VendorServiceEdge!]! + pageInfo: PageInfo! +} + +type VendorServiceEdge { + cursor: CursorKey! + node: VendorService! +} + type ConnectorConnection { edges: [ConnectorEdge!]! pageInfo: PageInfo! @@ -1796,6 +1845,11 @@ type Mutation { updateVendorContact(input: UpdateVendorContactInput!): UpdateVendorContactPayload! deleteVendorContact(input: DeleteVendorContactInput!): DeleteVendorContactPayload! + # Vendor Service mutations + createVendorService(input: CreateVendorServiceInput!): CreateVendorServicePayload! + updateVendorService(input: UpdateVendorServiceInput!): UpdateVendorServicePayload! + deleteVendorService(input: DeleteVendorServiceInput!): DeleteVendorServicePayload! + # Framework mutations createFramework(input: CreateFrameworkInput!): CreateFrameworkPayload! updateFramework(input: UpdateFrameworkInput!): UpdateFrameworkPayload! @@ -2089,6 +2143,26 @@ input DeleteVendorContactInput { vendorContactId: ID! } +input CreateVendorServiceInput { + vendorId: ID! + name: String! + description: String + url: String + type: String +} + +input UpdateVendorServiceInput { + id: ID! + name: String + description: String + url: String + type: String +} + +input DeleteVendorServiceInput { + vendorServiceId: ID! +} + input CreatePeopleInput { organizationId: ID! fullName: String! @@ -2570,6 +2644,18 @@ type DeleteVendorContactPayload { deletedVendorContactId: ID! } +type CreateVendorServicePayload { + vendorServiceEdge: VendorServiceEdge! +} + +type UpdateVendorServicePayload { + vendorService: VendorService! +} + +type DeleteVendorServicePayload { + deletedVendorServiceId: ID! +} + type CreatePeoplePayload { peopleEdge: PeopleEdge! } diff --git a/pkg/server/api/console/v1/schema/schema.go b/pkg/server/api/console/v1/schema/schema.go index bda55dad3..2010fc33d 100644 --- a/pkg/server/api/console/v1/schema/schema.go +++ b/pkg/server/api/console/v1/schema/schema.go @@ -84,6 +84,7 @@ type ResolverRoot interface { VendorContact() VendorContactResolver VendorDataPrivacyAgreement() VendorDataPrivacyAgreementResolver VendorRiskAssessment() VendorRiskAssessmentResolver + VendorService() VendorServiceResolver Viewer() ViewerResolver } @@ -343,6 +344,10 @@ type ComplexityRoot struct { VendorRiskAssessmentEdge func(childComplexity int) int } + CreateVendorServicePayload struct { + VendorServiceEdge func(childComplexity int) int + } + Datum struct { CreatedAt func(childComplexity int) int DataClassification func(childComplexity int) int @@ -478,6 +483,10 @@ type ComplexityRoot struct { DeletedVendorID func(childComplexity int) int } + DeleteVendorServicePayload struct { + DeletedVendorServiceID func(childComplexity int) int + } + Document struct { Controls func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ControlOrderBy, filter *types.ControlFilter) int CreatedAt func(childComplexity int) int @@ -683,6 +692,7 @@ type ComplexityRoot struct { CreateVendor func(childComplexity int, input types.CreateVendorInput) int CreateVendorContact func(childComplexity int, input types.CreateVendorContactInput) int CreateVendorRiskAssessment func(childComplexity int, input types.CreateVendorRiskAssessmentInput) int + CreateVendorService func(childComplexity int, input types.CreateVendorServiceInput) int DeleteAsset func(childComplexity int, input types.DeleteAssetInput) int DeleteAudit func(childComplexity int, input types.DeleteAuditInput) int DeleteAuditReport func(childComplexity int, input types.DeleteAuditReportInput) int @@ -710,6 +720,7 @@ type ComplexityRoot struct { DeleteVendorComplianceReport func(childComplexity int, input types.DeleteVendorComplianceReportInput) int DeleteVendorContact func(childComplexity int, input types.DeleteVendorContactInput) int DeleteVendorDataPrivacyAgreement func(childComplexity int, input types.DeleteVendorDataPrivacyAgreementInput) int + DeleteVendorService func(childComplexity int, input types.DeleteVendorServiceInput) int ExportDocumentVersionPDF func(childComplexity int, input types.ExportDocumentVersionPDFInput) int FulfillEvidence func(childComplexity int, input types.FulfillEvidenceInput) int GenerateDocumentChangelog func(childComplexity int, input types.GenerateDocumentChangelogInput) int @@ -742,6 +753,7 @@ type ComplexityRoot struct { UpdateVendorBusinessAssociateAgreement func(childComplexity int, input types.UpdateVendorBusinessAssociateAgreementInput) int UpdateVendorContact func(childComplexity int, input types.UpdateVendorContactInput) int UpdateVendorDataPrivacyAgreement func(childComplexity int, input types.UpdateVendorDataPrivacyAgreementInput) int + UpdateVendorService func(childComplexity int, input types.UpdateVendorServiceInput) int UploadAuditReport func(childComplexity int, input types.UploadAuditReportInput) int UploadMeasureEvidence func(childComplexity int, input types.UploadMeasureEvidenceInput) int UploadTaskEvidence func(childComplexity int, input types.UploadTaskEvidenceInput) int @@ -1063,6 +1075,10 @@ type ComplexityRoot struct { Vendor func(childComplexity int) int } + UpdateVendorServicePayload struct { + VendorService func(childComplexity int) int + } + UploadAuditReportPayload struct { Audit func(childComplexity int) int } @@ -1128,6 +1144,7 @@ type ComplexityRoot struct { SecurityOwner func(childComplexity int) int SecurityPageURL func(childComplexity int) int ServiceLevelAgreementURL func(childComplexity int) int + Services func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorServiceOrderBy) int ShowOnTrustCenter func(childComplexity int) int StatusPageURL func(childComplexity int) int SubprocessorsListURL func(childComplexity int) int @@ -1238,6 +1255,25 @@ type ComplexityRoot struct { Node func(childComplexity int) int } + VendorService struct { + CreatedAt func(childComplexity int) int + Description func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + UpdatedAt func(childComplexity int) int + Vendor func(childComplexity int) int + } + + VendorServiceConnection struct { + Edges func(childComplexity int) int + PageInfo func(childComplexity int) int + } + + VendorServiceEdge struct { + Cursor func(childComplexity int) int + Node func(childComplexity int) int + } + Viewer struct { ID func(childComplexity int) int Organizations func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrganizationOrder, filter *types.OrganizationFilter) int @@ -1362,6 +1398,9 @@ type MutationResolver interface { CreateVendorContact(ctx context.Context, input types.CreateVendorContactInput) (*types.CreateVendorContactPayload, error) UpdateVendorContact(ctx context.Context, input types.UpdateVendorContactInput) (*types.UpdateVendorContactPayload, error) DeleteVendorContact(ctx context.Context, input types.DeleteVendorContactInput) (*types.DeleteVendorContactPayload, error) + CreateVendorService(ctx context.Context, input types.CreateVendorServiceInput) (*types.CreateVendorServicePayload, error) + UpdateVendorService(ctx context.Context, input types.UpdateVendorServiceInput) (*types.UpdateVendorServicePayload, error) + DeleteVendorService(ctx context.Context, input types.DeleteVendorServiceInput) (*types.DeleteVendorServicePayload, error) CreateFramework(ctx context.Context, input types.CreateFrameworkInput) (*types.CreateFrameworkPayload, error) UpdateFramework(ctx context.Context, input types.UpdateFrameworkInput) (*types.UpdateFrameworkPayload, error) ImportFramework(ctx context.Context, input types.ImportFrameworkInput) (*types.ImportFrameworkPayload, error) @@ -1511,6 +1550,7 @@ type VendorResolver interface { BusinessAssociateAgreement(ctx context.Context, obj *types.Vendor) (*types.VendorBusinessAssociateAgreement, error) DataPrivacyAgreement(ctx context.Context, obj *types.Vendor) (*types.VendorDataPrivacyAgreement, error) Contacts(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorContactOrderBy) (*types.VendorContactConnection, error) + Services(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorServiceOrderBy) (*types.VendorServiceConnection, error) RiskAssessments(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorRiskAssessmentOrder) (*types.VendorRiskAssessmentConnection, error) BusinessOwner(ctx context.Context, obj *types.Vendor) (*types.People, error) SecurityOwner(ctx context.Context, obj *types.Vendor) (*types.People, error) @@ -1541,6 +1581,9 @@ type VendorRiskAssessmentResolver interface { AssessedBy(ctx context.Context, obj *types.VendorRiskAssessment) (*types.People, error) } +type VendorServiceResolver interface { + Vendor(ctx context.Context, obj *types.VendorService) (*types.Vendor, error) +} type ViewerResolver interface { Organizations(ctx context.Context, obj *types.Viewer, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrganizationOrder, filter *types.OrganizationFilter) (*types.OrganizationConnection, error) } @@ -2408,6 +2451,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.CreateVendorRiskAssessmentPayload.VendorRiskAssessmentEdge(childComplexity), true + case "CreateVendorServicePayload.vendorServiceEdge": + if e.complexity.CreateVendorServicePayload.VendorServiceEdge == nil { + break + } + + return e.complexity.CreateVendorServicePayload.VendorServiceEdge(childComplexity), true + case "Datum.createdAt": if e.complexity.Datum.CreatedAt == nil { break @@ -2728,6 +2778,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.DeleteVendorPayload.DeletedVendorID(childComplexity), true + case "DeleteVendorServicePayload.deletedVendorServiceId": + if e.complexity.DeleteVendorServicePayload.DeletedVendorServiceID == nil { + break + } + + return e.complexity.DeleteVendorServicePayload.DeletedVendorServiceID(childComplexity), true + case "Document.controls": if e.complexity.Document.Controls == nil { break @@ -3816,6 +3873,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.Mutation.CreateVendorRiskAssessment(childComplexity, args["input"].(types.CreateVendorRiskAssessmentInput)), true + case "Mutation.createVendorService": + if e.complexity.Mutation.CreateVendorService == nil { + break + } + + args, err := ec.field_Mutation_createVendorService_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.CreateVendorService(childComplexity, args["input"].(types.CreateVendorServiceInput)), true + case "Mutation.deleteAsset": if e.complexity.Mutation.DeleteAsset == nil { break @@ -4140,6 +4209,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.Mutation.DeleteVendorDataPrivacyAgreement(childComplexity, args["input"].(types.DeleteVendorDataPrivacyAgreementInput)), true + case "Mutation.deleteVendorService": + if e.complexity.Mutation.DeleteVendorService == nil { + break + } + + args, err := ec.field_Mutation_deleteVendorService_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.DeleteVendorService(childComplexity, args["input"].(types.DeleteVendorServiceInput)), true + case "Mutation.exportDocumentVersionPDF": if e.complexity.Mutation.ExportDocumentVersionPDF == nil { break @@ -4524,6 +4605,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.Mutation.UpdateVendorDataPrivacyAgreement(childComplexity, args["input"].(types.UpdateVendorDataPrivacyAgreementInput)), true + case "Mutation.updateVendorService": + if e.complexity.Mutation.UpdateVendorService == nil { + break + } + + args, err := ec.field_Mutation_updateVendorService_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.UpdateVendorService(childComplexity, args["input"].(types.UpdateVendorServiceInput)), true + case "Mutation.uploadAuditReport": if e.complexity.Mutation.UploadAuditReport == nil { break @@ -5847,6 +5940,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.UpdateVendorPayload.Vendor(childComplexity), true + case "UpdateVendorServicePayload.vendorService": + if e.complexity.UpdateVendorServicePayload.VendorService == nil { + break + } + + return e.complexity.UpdateVendorServicePayload.VendorService(childComplexity), true + case "UploadAuditReportPayload.audit": if e.complexity.UploadAuditReportPayload.Audit == nil { break @@ -6126,6 +6226,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.Vendor.ServiceLevelAgreementURL(childComplexity), true + case "Vendor.services": + if e.complexity.Vendor.Services == nil { + break + } + + args, err := ec.field_Vendor_services_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Vendor.Services(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey), args["orderBy"].(*types.VendorServiceOrderBy)), true + case "Vendor.showOnTrustCenter": if e.complexity.Vendor.ShowOnTrustCenter == nil { break @@ -6609,6 +6721,76 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.complexity.VendorRiskAssessmentEdge.Node(childComplexity), true + case "VendorService.createdAt": + if e.complexity.VendorService.CreatedAt == nil { + break + } + + return e.complexity.VendorService.CreatedAt(childComplexity), true + + case "VendorService.description": + if e.complexity.VendorService.Description == nil { + break + } + + return e.complexity.VendorService.Description(childComplexity), true + + case "VendorService.id": + if e.complexity.VendorService.ID == nil { + break + } + + return e.complexity.VendorService.ID(childComplexity), true + + case "VendorService.name": + if e.complexity.VendorService.Name == nil { + break + } + + return e.complexity.VendorService.Name(childComplexity), true + + case "VendorService.updatedAt": + if e.complexity.VendorService.UpdatedAt == nil { + break + } + + return e.complexity.VendorService.UpdatedAt(childComplexity), true + + case "VendorService.vendor": + if e.complexity.VendorService.Vendor == nil { + break + } + + return e.complexity.VendorService.Vendor(childComplexity), true + + case "VendorServiceConnection.edges": + if e.complexity.VendorServiceConnection.Edges == nil { + break + } + + return e.complexity.VendorServiceConnection.Edges(childComplexity), true + + case "VendorServiceConnection.pageInfo": + if e.complexity.VendorServiceConnection.PageInfo == nil { + break + } + + return e.complexity.VendorServiceConnection.PageInfo(childComplexity), true + + case "VendorServiceEdge.cursor": + if e.complexity.VendorServiceEdge.Cursor == nil { + break + } + + return e.complexity.VendorServiceEdge.Cursor(childComplexity), true + + case "VendorServiceEdge.node": + if e.complexity.VendorServiceEdge.Node == nil { + break + } + + return e.complexity.VendorServiceEdge.Node(childComplexity), true + case "Viewer.id": if e.complexity.Viewer.ID == nil { break @@ -6679,6 +6861,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputCreateVendorContactInput, ec.unmarshalInputCreateVendorInput, ec.unmarshalInputCreateVendorRiskAssessmentInput, + ec.unmarshalInputCreateVendorServiceInput, ec.unmarshalInputDatumOrder, ec.unmarshalInputDeleteAssetInput, ec.unmarshalInputDeleteAuditInput, @@ -6707,6 +6890,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputDeleteVendorContactInput, ec.unmarshalInputDeleteVendorDataPrivacyAgreementInput, ec.unmarshalInputDeleteVendorInput, + ec.unmarshalInputDeleteVendorServiceInput, ec.unmarshalInputDocumentFilter, ec.unmarshalInputDocumentOrder, ec.unmarshalInputDocumentVersionFilter, @@ -6758,6 +6942,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputUpdateVendorContactInput, ec.unmarshalInputUpdateVendorDataPrivacyAgreementInput, ec.unmarshalInputUpdateVendorInput, + ec.unmarshalInputUpdateVendorServiceInput, ec.unmarshalInputUploadAuditReportInput, ec.unmarshalInputUploadMeasureEvidenceInput, ec.unmarshalInputUploadTaskEvidenceInput, @@ -6769,6 +6954,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputVendorContactOrder, ec.unmarshalInputVendorOrder, ec.unmarshalInputVendorRiskAssessmentOrder, + ec.unmarshalInputVendorServiceOrder, ) first := true @@ -7210,6 +7396,20 @@ enum VendorContactOrderField ) } +enum VendorServiceOrderField + @goModel( + model: "github.com/getprobo/probo/pkg/coredata.VendorServiceOrderField" + ) { + CREATED_AT + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.VendorServiceOrderFieldCreatedAt" + ) + NAME + @goEnum( + value: "github.com/getprobo/probo/pkg/coredata.VendorServiceOrderFieldName" + ) +} + enum OrganizationOrderField @goModel( model: "github.com/getprobo/probo/pkg/coredata.OrganizationOrderField" @@ -7669,6 +7869,14 @@ input VendorContactOrder field: VendorContactOrderField! } +input VendorServiceOrder + @goModel( + model: "github.com/getprobo/probo/pkg/server/api/console/v1/types.VendorServiceOrderBy" + ) { + direction: OrderDirection! + field: VendorServiceOrderField! +} + input OrganizationOrder { direction: OrderDirection! field: OrganizationOrderField! @@ -7932,6 +8140,14 @@ type Vendor implements Node { orderBy: VendorContactOrder ): VendorContactConnection! @goField(forceResolver: true) + services( + first: Int + after: CursorKey + last: Int + before: CursorKey + orderBy: VendorServiceOrder + ): VendorServiceConnection! @goField(forceResolver: true) + riskAssessments( first: Int after: CursorKey @@ -7996,6 +8212,15 @@ type VendorContact implements Node { updatedAt: Datetime! } +type VendorService implements Node { + id: ID! + vendor: Vendor! @goField(forceResolver: true) + name: String! + description: String + createdAt: Datetime! + updatedAt: Datetime! +} + type VendorDataPrivacyAgreement implements Node { id: ID! vendor: Vendor! @goField(forceResolver: true) @@ -8520,6 +8745,16 @@ type VendorContactEdge { node: VendorContact! } +type VendorServiceConnection { + edges: [VendorServiceEdge!]! + pageInfo: PageInfo! +} + +type VendorServiceEdge { + cursor: CursorKey! + node: VendorService! +} + type ConnectorConnection { edges: [ConnectorEdge!]! pageInfo: PageInfo! @@ -8664,6 +8899,11 @@ type Mutation { updateVendorContact(input: UpdateVendorContactInput!): UpdateVendorContactPayload! deleteVendorContact(input: DeleteVendorContactInput!): DeleteVendorContactPayload! + # Vendor Service mutations + createVendorService(input: CreateVendorServiceInput!): CreateVendorServicePayload! + updateVendorService(input: UpdateVendorServiceInput!): UpdateVendorServicePayload! + deleteVendorService(input: DeleteVendorServiceInput!): DeleteVendorServicePayload! + # Framework mutations createFramework(input: CreateFrameworkInput!): CreateFrameworkPayload! updateFramework(input: UpdateFrameworkInput!): UpdateFrameworkPayload! @@ -8957,6 +9197,26 @@ input DeleteVendorContactInput { vendorContactId: ID! } +input CreateVendorServiceInput { + vendorId: ID! + name: String! + description: String + url: String + type: String +} + +input UpdateVendorServiceInput { + id: ID! + name: String + description: String + url: String + type: String +} + +input DeleteVendorServiceInput { + vendorServiceId: ID! +} + input CreatePeopleInput { organizationId: ID! fullName: String! @@ -9438,6 +9698,18 @@ type DeleteVendorContactPayload { deletedVendorContactId: ID! } +type CreateVendorServicePayload { + vendorServiceEdge: VendorServiceEdge! +} + +type UpdateVendorServicePayload { + vendorService: VendorService! +} + +type DeleteVendorServicePayload { + deletedVendorServiceId: ID! +} + type CreatePeoplePayload { peopleEdge: PeopleEdge! } @@ -12194,6 +12466,29 @@ func (ec *executionContext) field_Mutation_createVendorRiskAssessment_argsInput( return zeroVal, nil } +func (ec *executionContext) field_Mutation_createVendorService_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_createVendorService_argsInput(ctx, rawArgs) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_createVendorService_argsInput( + ctx context.Context, + rawArgs map[string]any, +) (types.CreateVendorServiceInput, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + if tmp, ok := rawArgs["input"]; ok { + return ec.unmarshalNCreateVendorServiceInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateVendorServiceInput(ctx, tmp) + } + + var zeroVal types.CreateVendorServiceInput + return zeroVal, nil +} + func (ec *executionContext) field_Mutation_createVendor_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -12815,6 +13110,29 @@ func (ec *executionContext) field_Mutation_deleteVendorDataPrivacyAgreement_args return zeroVal, nil } +func (ec *executionContext) field_Mutation_deleteVendorService_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_deleteVendorService_argsInput(ctx, rawArgs) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_deleteVendorService_argsInput( + ctx context.Context, + rawArgs map[string]any, +) (types.DeleteVendorServiceInput, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + if tmp, ok := rawArgs["input"]; ok { + return ec.unmarshalNDeleteVendorServiceInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorServiceInput(ctx, tmp) + } + + var zeroVal types.DeleteVendorServiceInput + return zeroVal, nil +} + func (ec *executionContext) field_Mutation_deleteVendor_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -13551,6 +13869,29 @@ func (ec *executionContext) field_Mutation_updateVendorDataPrivacyAgreement_args return zeroVal, nil } +func (ec *executionContext) field_Mutation_updateVendorService_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Mutation_updateVendorService_argsInput(ctx, rawArgs) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} +func (ec *executionContext) field_Mutation_updateVendorService_argsInput( + ctx context.Context, + rawArgs map[string]any, +) (types.UpdateVendorServiceInput, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + if tmp, ok := rawArgs["input"]; ok { + return ec.unmarshalNUpdateVendorServiceInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateVendorServiceInput(ctx, tmp) + } + + var zeroVal types.UpdateVendorServiceInput + return zeroVal, nil +} + func (ec *executionContext) field_Mutation_updateVendor_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -16205,6 +16546,101 @@ func (ec *executionContext) field_Vendor_riskAssessments_argsOrderBy( return zeroVal, nil } +func (ec *executionContext) field_Vendor_services_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := ec.field_Vendor_services_argsFirst(ctx, rawArgs) + if err != nil { + return nil, err + } + args["first"] = arg0 + arg1, err := ec.field_Vendor_services_argsAfter(ctx, rawArgs) + if err != nil { + return nil, err + } + args["after"] = arg1 + arg2, err := ec.field_Vendor_services_argsLast(ctx, rawArgs) + if err != nil { + return nil, err + } + args["last"] = arg2 + arg3, err := ec.field_Vendor_services_argsBefore(ctx, rawArgs) + if err != nil { + return nil, err + } + args["before"] = arg3 + arg4, err := ec.field_Vendor_services_argsOrderBy(ctx, rawArgs) + if err != nil { + return nil, err + } + args["orderBy"] = arg4 + return args, nil +} +func (ec *executionContext) field_Vendor_services_argsFirst( + ctx context.Context, + rawArgs map[string]any, +) (*int, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("first")) + if tmp, ok := rawArgs["first"]; ok { + return ec.unmarshalOInt2ᚖint(ctx, tmp) + } + + var zeroVal *int + return zeroVal, nil +} + +func (ec *executionContext) field_Vendor_services_argsAfter( + ctx context.Context, + rawArgs map[string]any, +) (*page.CursorKey, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("after")) + if tmp, ok := rawArgs["after"]; ok { + return ec.unmarshalOCursorKey2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋpageᚐCursorKey(ctx, tmp) + } + + var zeroVal *page.CursorKey + return zeroVal, nil +} + +func (ec *executionContext) field_Vendor_services_argsLast( + ctx context.Context, + rawArgs map[string]any, +) (*int, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("last")) + if tmp, ok := rawArgs["last"]; ok { + return ec.unmarshalOInt2ᚖint(ctx, tmp) + } + + var zeroVal *int + return zeroVal, nil +} + +func (ec *executionContext) field_Vendor_services_argsBefore( + ctx context.Context, + rawArgs map[string]any, +) (*page.CursorKey, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("before")) + if tmp, ok := rawArgs["before"]; ok { + return ec.unmarshalOCursorKey2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋpageᚐCursorKey(ctx, tmp) + } + + var zeroVal *page.CursorKey + return zeroVal, nil +} + +func (ec *executionContext) field_Vendor_services_argsOrderBy( + ctx context.Context, + rawArgs map[string]any, +) (*types.VendorServiceOrderBy, error) { + ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("orderBy")) + if tmp, ok := rawArgs["orderBy"]; ok { + return ec.unmarshalOVendorServiceOrder2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorServiceOrderBy(ctx, tmp) + } + + var zeroVal *types.VendorServiceOrderBy + return zeroVal, nil +} + func (ec *executionContext) field_Viewer_organizations_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -16475,6 +16911,8 @@ func (ec *executionContext) fieldContext_AssessVendorPayload_vendor(_ context.Co return ec.fieldContext_Vendor_dataPrivacyAgreement(ctx, field) case "contacts": return ec.fieldContext_Vendor_contacts(ctx, field) + case "services": + return ec.fieldContext_Vendor_services(ctx, field) case "riskAssessments": return ec.fieldContext_Vendor_riskAssessments(ctx, field) case "businessOwner": @@ -22360,6 +22798,56 @@ func (ec *executionContext) fieldContext_CreateVendorRiskAssessmentPayload_vendo return fc, nil } +func (ec *executionContext) _CreateVendorServicePayload_vendorServiceEdge(ctx context.Context, field graphql.CollectedField, obj *types.CreateVendorServicePayload) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CreateVendorServicePayload_vendorServiceEdge(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 obj.VendorServiceEdge, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.VendorServiceEdge) + fc.Result = res + return ec.marshalNVendorServiceEdge2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorServiceEdge(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CreateVendorServicePayload_vendorServiceEdge(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CreateVendorServicePayload", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "cursor": + return ec.fieldContext_VendorServiceEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_VendorServiceEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type VendorServiceEdge", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _Datum_id(ctx context.Context, field graphql.CollectedField, obj *types.Datum) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Datum_id(ctx, field) if err != nil { @@ -24487,6 +24975,50 @@ func (ec *executionContext) fieldContext_DeleteVendorPayload_deletedVendorId(_ c return fc, nil } +func (ec *executionContext) _DeleteVendorServicePayload_deletedVendorServiceId(ctx context.Context, field graphql.CollectedField, obj *types.DeleteVendorServicePayload) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_DeleteVendorServicePayload_deletedVendorServiceId(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 obj.DeletedVendorServiceID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(gid.GID) + fc.Result = res + return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_DeleteVendorServicePayload_deletedVendorServiceId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "DeleteVendorServicePayload", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _Document_id(ctx context.Context, field graphql.CollectedField, obj *types.Document) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Document_id(ctx, field) if err != nil { @@ -30634,6 +31166,183 @@ func (ec *executionContext) fieldContext_Mutation_deleteVendorContact(ctx contex return fc, nil } +func (ec *executionContext) _Mutation_createVendorService(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_createVendorService(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.Mutation().CreateVendorService(rctx, fc.Args["input"].(types.CreateVendorServiceInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.CreateVendorServicePayload) + fc.Result = res + return ec.marshalNCreateVendorServicePayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateVendorServicePayload(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_createVendorService(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "vendorServiceEdge": + return ec.fieldContext_CreateVendorServicePayload_vendorServiceEdge(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type CreateVendorServicePayload", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Mutation_createVendorService_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_updateVendorService(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_updateVendorService(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.Mutation().UpdateVendorService(rctx, fc.Args["input"].(types.UpdateVendorServiceInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.UpdateVendorServicePayload) + fc.Result = res + return ec.marshalNUpdateVendorServicePayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateVendorServicePayload(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_updateVendorService(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "vendorService": + return ec.fieldContext_UpdateVendorServicePayload_vendorService(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type UpdateVendorServicePayload", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Mutation_updateVendorService_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_deleteVendorService(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Mutation_deleteVendorService(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.Mutation().DeleteVendorService(rctx, fc.Args["input"].(types.DeleteVendorServiceInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.DeleteVendorServicePayload) + fc.Result = res + return ec.marshalNDeleteVendorServicePayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorServicePayload(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Mutation_deleteVendorService(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "deletedVendorServiceId": + return ec.fieldContext_DeleteVendorServicePayload_deletedVendorServiceId(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type DeleteVendorServicePayload", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Mutation_deleteVendorService_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Mutation_createFramework(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Mutation_createFramework(ctx, field) if err != nil { @@ -43978,6 +44687,8 @@ func (ec *executionContext) fieldContext_UpdateVendorPayload_vendor(_ context.Co return ec.fieldContext_Vendor_dataPrivacyAgreement(ctx, field) case "contacts": return ec.fieldContext_Vendor_contacts(ctx, field) + case "services": + return ec.fieldContext_Vendor_services(ctx, field) case "riskAssessments": return ec.fieldContext_Vendor_riskAssessments(ctx, field) case "businessOwner": @@ -44023,6 +44734,64 @@ func (ec *executionContext) fieldContext_UpdateVendorPayload_vendor(_ context.Co return fc, nil } +func (ec *executionContext) _UpdateVendorServicePayload_vendorService(ctx context.Context, field graphql.CollectedField, obj *types.UpdateVendorServicePayload) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_UpdateVendorServicePayload_vendorService(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 obj.VendorService, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.VendorService) + fc.Result = res + return ec.marshalNVendorService2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorService(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_UpdateVendorServicePayload_vendorService(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "UpdateVendorServicePayload", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_VendorService_id(ctx, field) + case "vendor": + return ec.fieldContext_VendorService_vendor(ctx, field) + case "name": + return ec.fieldContext_VendorService_name(ctx, field) + case "description": + return ec.fieldContext_VendorService_description(ctx, field) + case "createdAt": + return ec.fieldContext_VendorService_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_VendorService_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type VendorService", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _UploadAuditReportPayload_audit(ctx context.Context, field graphql.CollectedField, obj *types.UploadAuditReportPayload) (ret graphql.Marshaler) { fc, err := ec.fieldContext_UploadAuditReportPayload_audit(ctx, field) if err != nil { @@ -45378,6 +46147,67 @@ func (ec *executionContext) fieldContext_Vendor_contacts(ctx context.Context, fi return fc, nil } +func (ec *executionContext) _Vendor_services(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Vendor_services(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().Services(rctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey), fc.Args["orderBy"].(*types.VendorServiceOrderBy)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.VendorServiceConnection) + fc.Result = res + return ec.marshalNVendorServiceConnection2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorServiceConnection(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Vendor_services(ctx 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 "edges": + return ec.fieldContext_VendorServiceConnection_edges(ctx, field) + case "pageInfo": + return ec.fieldContext_VendorServiceConnection_pageInfo(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type VendorServiceConnection", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Vendor_services_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Vendor_riskAssessments(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Vendor_riskAssessments(ctx, field) if err != nil { @@ -46334,6 +47164,8 @@ func (ec *executionContext) fieldContext_VendorBusinessAssociateAgreement_vendor return ec.fieldContext_Vendor_dataPrivacyAgreement(ctx, field) case "contacts": return ec.fieldContext_Vendor_contacts(ctx, field) + case "services": + return ec.fieldContext_Vendor_services(ctx, field) case "riskAssessments": return ec.fieldContext_Vendor_riskAssessments(ctx, field) case "businessOwner": @@ -46782,6 +47614,8 @@ func (ec *executionContext) fieldContext_VendorComplianceReport_vendor(_ context return ec.fieldContext_Vendor_dataPrivacyAgreement(ctx, field) case "contacts": return ec.fieldContext_Vendor_contacts(ctx, field) + case "services": + return ec.fieldContext_Vendor_services(ctx, field) case "riskAssessments": return ec.fieldContext_Vendor_riskAssessments(ctx, field) case "businessOwner": @@ -47593,6 +48427,8 @@ func (ec *executionContext) fieldContext_VendorContact_vendor(_ context.Context, return ec.fieldContext_Vendor_dataPrivacyAgreement(ctx, field) case "contacts": return ec.fieldContext_Vendor_contacts(ctx, field) + case "services": + return ec.fieldContext_Vendor_services(ctx, field) case "riskAssessments": return ec.fieldContext_Vendor_riskAssessments(ctx, field) case "businessOwner": @@ -48201,6 +49037,8 @@ func (ec *executionContext) fieldContext_VendorDataPrivacyAgreement_vendor(_ con return ec.fieldContext_Vendor_dataPrivacyAgreement(ctx, field) case "contacts": return ec.fieldContext_Vendor_contacts(ctx, field) + case "services": + return ec.fieldContext_Vendor_services(ctx, field) case "riskAssessments": return ec.fieldContext_Vendor_riskAssessments(ctx, field) case "businessOwner": @@ -48649,6 +49487,8 @@ func (ec *executionContext) fieldContext_VendorEdge_node(_ context.Context, fiel return ec.fieldContext_Vendor_dataPrivacyAgreement(ctx, field) case "contacts": return ec.fieldContext_Vendor_contacts(ctx, field) + case "services": + return ec.fieldContext_Vendor_services(ctx, field) case "riskAssessments": return ec.fieldContext_Vendor_riskAssessments(ctx, field) case "businessOwner": @@ -48795,6 +49635,8 @@ func (ec *executionContext) fieldContext_VendorRiskAssessment_vendor(_ context.C return ec.fieldContext_Vendor_dataPrivacyAgreement(ctx, field) case "contacts": return ec.fieldContext_Vendor_contacts(ctx, field) + case "services": + return ec.fieldContext_Vendor_services(ctx, field) case "riskAssessments": return ec.fieldContext_Vendor_riskAssessments(ctx, field) case "businessOwner": @@ -49425,6 +50267,533 @@ func (ec *executionContext) fieldContext_VendorRiskAssessmentEdge_node(_ context return fc, nil } +func (ec *executionContext) _VendorService_id(ctx context.Context, field graphql.CollectedField, obj *types.VendorService) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorService_id(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 obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(gid.GID) + fc.Result = res + return ec.marshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorService_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorService", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorService_vendor(ctx context.Context, field graphql.CollectedField, obj *types.VendorService) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorService_vendor(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.VendorService().Vendor(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.Vendor) + fc.Result = res + return ec.marshalNVendor2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendor(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorService_vendor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorService", + 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_Vendor_id(ctx, field) + case "name": + return ec.fieldContext_Vendor_name(ctx, field) + case "category": + return ec.fieldContext_Vendor_category(ctx, field) + case "description": + return ec.fieldContext_Vendor_description(ctx, field) + case "organization": + return ec.fieldContext_Vendor_organization(ctx, field) + case "complianceReports": + return ec.fieldContext_Vendor_complianceReports(ctx, field) + case "businessAssociateAgreement": + return ec.fieldContext_Vendor_businessAssociateAgreement(ctx, field) + case "dataPrivacyAgreement": + return ec.fieldContext_Vendor_dataPrivacyAgreement(ctx, field) + case "contacts": + return ec.fieldContext_Vendor_contacts(ctx, field) + case "services": + return ec.fieldContext_Vendor_services(ctx, field) + case "riskAssessments": + return ec.fieldContext_Vendor_riskAssessments(ctx, field) + case "businessOwner": + return ec.fieldContext_Vendor_businessOwner(ctx, field) + case "securityOwner": + return ec.fieldContext_Vendor_securityOwner(ctx, field) + case "statusPageUrl": + return ec.fieldContext_Vendor_statusPageUrl(ctx, field) + case "termsOfServiceUrl": + return ec.fieldContext_Vendor_termsOfServiceUrl(ctx, field) + case "privacyPolicyUrl": + return ec.fieldContext_Vendor_privacyPolicyUrl(ctx, field) + case "serviceLevelAgreementUrl": + return ec.fieldContext_Vendor_serviceLevelAgreementUrl(ctx, field) + case "dataProcessingAgreementUrl": + return ec.fieldContext_Vendor_dataProcessingAgreementUrl(ctx, field) + case "businessAssociateAgreementUrl": + return ec.fieldContext_Vendor_businessAssociateAgreementUrl(ctx, field) + case "subprocessorsListUrl": + return ec.fieldContext_Vendor_subprocessorsListUrl(ctx, field) + case "certifications": + return ec.fieldContext_Vendor_certifications(ctx, field) + case "securityPageUrl": + return ec.fieldContext_Vendor_securityPageUrl(ctx, field) + case "trustPageUrl": + return ec.fieldContext_Vendor_trustPageUrl(ctx, field) + case "headquarterAddress": + return ec.fieldContext_Vendor_headquarterAddress(ctx, field) + case "legalName": + return ec.fieldContext_Vendor_legalName(ctx, field) + case "websiteUrl": + return ec.fieldContext_Vendor_websiteUrl(ctx, field) + case "showOnTrustCenter": + return ec.fieldContext_Vendor_showOnTrustCenter(ctx, field) + case "createdAt": + return ec.fieldContext_Vendor_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_Vendor_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Vendor", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorService_name(ctx context.Context, field graphql.CollectedField, obj *types.VendorService) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorService_name(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 obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorService_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorService", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorService_description(ctx context.Context, field graphql.CollectedField, obj *types.VendorService) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorService_description(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 obj.Description, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorService_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorService", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorService_createdAt(ctx context.Context, field graphql.CollectedField, obj *types.VendorService) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorService_createdAt(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 obj.CreatedAt, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + fc.Result = res + return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorService_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorService", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Datetime does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorService_updatedAt(ctx context.Context, field graphql.CollectedField, obj *types.VendorService) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorService_updatedAt(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 obj.UpdatedAt, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + fc.Result = res + return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorService_updatedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorService", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Datetime does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorServiceConnection_edges(ctx context.Context, field graphql.CollectedField, obj *types.VendorServiceConnection) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorServiceConnection_edges(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 obj.Edges, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*types.VendorServiceEdge) + fc.Result = res + return ec.marshalNVendorServiceEdge2ᚕᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorServiceEdgeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorServiceConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorServiceConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "cursor": + return ec.fieldContext_VendorServiceEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_VendorServiceEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type VendorServiceEdge", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorServiceConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *types.VendorServiceConnection) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorServiceConnection_pageInfo(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 obj.PageInfo, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.PageInfo) + fc.Result = res + return ec.marshalNPageInfo2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐPageInfo(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorServiceConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorServiceConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "hasNextPage": + return ec.fieldContext_PageInfo_hasNextPage(ctx, field) + case "hasPreviousPage": + return ec.fieldContext_PageInfo_hasPreviousPage(ctx, field) + case "startCursor": + return ec.fieldContext_PageInfo_startCursor(ctx, field) + case "endCursor": + return ec.fieldContext_PageInfo_endCursor(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type PageInfo", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorServiceEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *types.VendorServiceEdge) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorServiceEdge_cursor(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 obj.Cursor, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(page.CursorKey) + fc.Result = res + return ec.marshalNCursorKey2githubᚗcomᚋgetproboᚋproboᚋpkgᚋpageᚐCursorKey(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorServiceEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorServiceEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type CursorKey does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _VendorServiceEdge_node(ctx context.Context, field graphql.CollectedField, obj *types.VendorServiceEdge) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_VendorServiceEdge_node(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 obj.Node, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*types.VendorService) + fc.Result = res + return ec.marshalNVendorService2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorService(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_VendorServiceEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VendorServiceEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_VendorService_id(ctx, field) + case "vendor": + return ec.fieldContext_VendorService_vendor(ctx, field) + case "name": + return ec.fieldContext_VendorService_name(ctx, field) + case "description": + return ec.fieldContext_VendorService_description(ctx, field) + case "createdAt": + return ec.fieldContext_VendorService_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_VendorService_updatedAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type VendorService", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _Viewer_id(ctx context.Context, field graphql.CollectedField, obj *types.Viewer) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Viewer_id(ctx, field) if err != nil { @@ -53369,6 +54738,61 @@ func (ec *executionContext) unmarshalInputCreateVendorRiskAssessmentInput(ctx co return it, nil } +func (ec *executionContext) unmarshalInputCreateVendorServiceInput(ctx context.Context, obj any) (types.CreateVendorServiceInput, error) { + var it types.CreateVendorServiceInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"vendorId", "name", "description", "url", "type"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "vendorId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vendorId")) + data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.VendorID = data + case "name": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Name = data + case "description": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("description")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Description = data + case "url": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("url")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.URL = data + case "type": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("type")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Type = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputDatumOrder(ctx context.Context, obj any) (types.DatumOrderBy, error) { var it types.DatumOrderBy asMap := map[string]any{} @@ -54167,6 +55591,33 @@ func (ec *executionContext) unmarshalInputDeleteVendorInput(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputDeleteVendorServiceInput(ctx context.Context, obj any) (types.DeleteVendorServiceInput, error) { + var it types.DeleteVendorServiceInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"vendorServiceId"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "vendorServiceId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("vendorServiceId")) + data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.VendorServiceID = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputDocumentFilter(ctx context.Context, obj any) (types.DocumentFilter, error) { var it types.DocumentFilter asMap := map[string]any{} @@ -56475,6 +57926,61 @@ func (ec *executionContext) unmarshalInputUpdateVendorInput(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputUpdateVendorServiceInput(ctx context.Context, obj any) (types.UpdateVendorServiceInput, error) { + var it types.UpdateVendorServiceInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"id", "name", "description", "url", "type"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "id": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.ID = data + case "name": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Name = data + case "description": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("description")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Description = data + case "url": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("url")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.URL = data + case "type": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("type")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Type = data + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputUploadAuditReportInput(ctx context.Context, obj any) (types.UploadAuditReportInput, error) { var it types.UploadAuditReportInput asMap := map[string]any{} @@ -56912,6 +58418,40 @@ func (ec *executionContext) unmarshalInputVendorRiskAssessmentOrder(ctx context. return it, nil } +func (ec *executionContext) unmarshalInputVendorServiceOrder(ctx context.Context, obj any) (types.VendorServiceOrderBy, error) { + var it types.VendorServiceOrderBy + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"direction", "field"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "direction": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("direction")) + data, err := ec.unmarshalNOrderDirection2githubᚗcomᚋgetproboᚋproboᚋpkgᚋpageᚐOrderDirection(ctx, v) + if err != nil { + return it, err + } + it.Direction = data + case "field": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("field")) + data, err := ec.unmarshalNVendorServiceOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorServiceOrderField(ctx, v) + if err != nil { + return it, err + } + it.Field = data + } + } + + return it, nil +} + // endregion **************************** input.gotpl ***************************** // region ************************** interface.gotpl *************************** @@ -56920,6 +58460,13 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj switch obj := (obj).(type) { case nil: return graphql.Null + case types.VendorService: + return ec._VendorService(ctx, sel, &obj) + case *types.VendorService: + if obj == nil { + return graphql.Null + } + return ec._VendorService(ctx, sel, obj) case types.VendorRiskAssessment: return ec._VendorRiskAssessment(ctx, sel, &obj) case *types.VendorRiskAssessment: @@ -59814,6 +61361,45 @@ func (ec *executionContext) _CreateVendorRiskAssessmentPayload(ctx context.Conte return out } +var createVendorServicePayloadImplementors = []string{"CreateVendorServicePayload"} + +func (ec *executionContext) _CreateVendorServicePayload(ctx context.Context, sel ast.SelectionSet, obj *types.CreateVendorServicePayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, createVendorServicePayloadImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("CreateVendorServicePayload") + case "vendorServiceEdge": + out.Values[i] = ec._CreateVendorServicePayload_vendorServiceEdge(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var datumImplementors = []string{"Datum", "Node"} func (ec *executionContext) _Datum(ctx context.Context, sel ast.SelectionSet, obj *types.Datum) graphql.Marshaler { @@ -61183,6 +62769,45 @@ func (ec *executionContext) _DeleteVendorPayload(ctx context.Context, sel ast.Se return out } +var deleteVendorServicePayloadImplementors = []string{"DeleteVendorServicePayload"} + +func (ec *executionContext) _DeleteVendorServicePayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteVendorServicePayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, deleteVendorServicePayloadImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("DeleteVendorServicePayload") + case "deletedVendorServiceId": + out.Values[i] = ec._DeleteVendorServicePayload_deletedVendorServiceId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var documentImplementors = []string{"Document", "Node"} func (ec *executionContext) _Document(ctx context.Context, sel ast.SelectionSet, obj *types.Document) graphql.Marshaler { @@ -63401,6 +65026,27 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } + case "createVendorService": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_createVendorService(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "updateVendorService": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_updateVendorService(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deleteVendorService": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_deleteVendorService(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "createFramework": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_createFramework(ctx, field) @@ -67600,6 +69246,45 @@ func (ec *executionContext) _UpdateVendorPayload(ctx context.Context, sel ast.Se return out } +var updateVendorServicePayloadImplementors = []string{"UpdateVendorServicePayload"} + +func (ec *executionContext) _UpdateVendorServicePayload(ctx context.Context, sel ast.SelectionSet, obj *types.UpdateVendorServicePayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, updateVendorServicePayloadImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("UpdateVendorServicePayload") + case "vendorService": + out.Values[i] = ec._UpdateVendorServicePayload_vendorService(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var uploadAuditReportPayloadImplementors = []string{"UploadAuditReportPayload"} func (ec *executionContext) _UploadAuditReportPayload(ctx context.Context, sel ast.SelectionSet, obj *types.UploadAuditReportPayload) graphql.Marshaler { @@ -68215,6 +69900,42 @@ func (ec *executionContext) _Vendor(ctx context.Context, sel ast.SelectionSet, o continue } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "services": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Vendor_services(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + 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 "riskAssessments": field := field @@ -69417,6 +71138,186 @@ func (ec *executionContext) _VendorRiskAssessmentEdge(ctx context.Context, sel a return out } +var vendorServiceImplementors = []string{"VendorService", "Node"} + +func (ec *executionContext) _VendorService(ctx context.Context, sel ast.SelectionSet, obj *types.VendorService) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, vendorServiceImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("VendorService") + case "id": + out.Values[i] = ec._VendorService_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "vendor": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._VendorService_vendor(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + 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 "name": + out.Values[i] = ec._VendorService_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "description": + out.Values[i] = ec._VendorService_description(ctx, field, obj) + case "createdAt": + out.Values[i] = ec._VendorService_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "updatedAt": + out.Values[i] = ec._VendorService_updatedAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var vendorServiceConnectionImplementors = []string{"VendorServiceConnection"} + +func (ec *executionContext) _VendorServiceConnection(ctx context.Context, sel ast.SelectionSet, obj *types.VendorServiceConnection) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, vendorServiceConnectionImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("VendorServiceConnection") + case "edges": + out.Values[i] = ec._VendorServiceConnection_edges(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "pageInfo": + out.Values[i] = ec._VendorServiceConnection_pageInfo(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var vendorServiceEdgeImplementors = []string{"VendorServiceEdge"} + +func (ec *executionContext) _VendorServiceEdge(ctx context.Context, sel ast.SelectionSet, obj *types.VendorServiceEdge) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, vendorServiceEdgeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("VendorServiceEdge") + case "cursor": + out.Values[i] = ec._VendorServiceEdge_cursor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "node": + out.Values[i] = ec._VendorServiceEdge_node(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var viewerImplementors = []string{"Viewer"} func (ec *executionContext) _Viewer(ctx context.Context, sel ast.SelectionSet, obj *types.Viewer) graphql.Marshaler { @@ -71097,6 +72998,25 @@ func (ec *executionContext) marshalNCreateVendorRiskAssessmentPayload2ᚖgithub return ec._CreateVendorRiskAssessmentPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNCreateVendorServiceInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateVendorServiceInput(ctx context.Context, v any) (types.CreateVendorServiceInput, error) { + res, err := ec.unmarshalInputCreateVendorServiceInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNCreateVendorServicePayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateVendorServicePayload(ctx context.Context, sel ast.SelectionSet, v types.CreateVendorServicePayload) graphql.Marshaler { + return ec._CreateVendorServicePayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNCreateVendorServicePayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateVendorServicePayload(ctx context.Context, sel ast.SelectionSet, v *types.CreateVendorServicePayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._CreateVendorServicePayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNCriticityLevel2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐCriticityLevel(ctx context.Context, v any) (coredata.CriticityLevel, error) { tmp, err := graphql.UnmarshalString(v) res := unmarshalNCriticityLevel2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐCriticityLevel[tmp] @@ -71846,6 +73766,25 @@ func (ec *executionContext) marshalNDeleteVendorPayload2ᚖgithubᚗcomᚋgetpro return ec._DeleteVendorPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNDeleteVendorServiceInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorServiceInput(ctx context.Context, v any) (types.DeleteVendorServiceInput, error) { + res, err := ec.unmarshalInputDeleteVendorServiceInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNDeleteVendorServicePayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorServicePayload(ctx context.Context, sel ast.SelectionSet, v types.DeleteVendorServicePayload) graphql.Marshaler { + return ec._DeleteVendorServicePayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNDeleteVendorServicePayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteVendorServicePayload(ctx context.Context, sel ast.SelectionSet, v *types.DeleteVendorServicePayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._DeleteVendorServicePayload(ctx, sel, v) +} + func (ec *executionContext) marshalNDocument2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDocument(ctx context.Context, sel ast.SelectionSet, v types.Document) graphql.Marshaler { return ec._Document(ctx, sel, &v) } @@ -74276,6 +76215,25 @@ func (ec *executionContext) marshalNUpdateVendorPayload2ᚖgithubᚗcomᚋgetpro return ec._UpdateVendorPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNUpdateVendorServiceInput2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateVendorServiceInput(ctx context.Context, v any) (types.UpdateVendorServiceInput, error) { + res, err := ec.unmarshalInputUpdateVendorServiceInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNUpdateVendorServicePayload2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateVendorServicePayload(ctx context.Context, sel ast.SelectionSet, v types.UpdateVendorServicePayload) graphql.Marshaler { + return ec._UpdateVendorServicePayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNUpdateVendorServicePayload2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateVendorServicePayload(ctx context.Context, sel ast.SelectionSet, v *types.UpdateVendorServicePayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._UpdateVendorServicePayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNUpload2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚐUpload(ctx context.Context, v any) (graphql.Upload, error) { res, err := graphql.UnmarshalUpload(v) return res, graphql.ErrorOnPath(ctx, err) @@ -75032,6 +76990,112 @@ var ( } ) +func (ec *executionContext) marshalNVendorService2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorService(ctx context.Context, sel ast.SelectionSet, v *types.VendorService) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._VendorService(ctx, sel, v) +} + +func (ec *executionContext) marshalNVendorServiceConnection2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorServiceConnection(ctx context.Context, sel ast.SelectionSet, v types.VendorServiceConnection) graphql.Marshaler { + return ec._VendorServiceConnection(ctx, sel, &v) +} + +func (ec *executionContext) marshalNVendorServiceConnection2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorServiceConnection(ctx context.Context, sel ast.SelectionSet, v *types.VendorServiceConnection) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._VendorServiceConnection(ctx, sel, v) +} + +func (ec *executionContext) marshalNVendorServiceEdge2ᚕᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorServiceEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []*types.VendorServiceEdge) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNVendorServiceEdge2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorServiceEdge(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNVendorServiceEdge2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorServiceEdge(ctx context.Context, sel ast.SelectionSet, v *types.VendorServiceEdge) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._VendorServiceEdge(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNVendorServiceOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorServiceOrderField(ctx context.Context, v any) (coredata.VendorServiceOrderField, error) { + tmp, err := graphql.UnmarshalString(v) + res := unmarshalNVendorServiceOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorServiceOrderField[tmp] + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNVendorServiceOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorServiceOrderField(ctx context.Context, sel ast.SelectionSet, v coredata.VendorServiceOrderField) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(marshalNVendorServiceOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorServiceOrderField[v]) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +var ( + unmarshalNVendorServiceOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorServiceOrderField = map[string]coredata.VendorServiceOrderField{ + "CREATED_AT": coredata.VendorServiceOrderFieldCreatedAt, + "NAME": coredata.VendorServiceOrderFieldName, + } + marshalNVendorServiceOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorServiceOrderField = map[coredata.VendorServiceOrderField]string{ + coredata.VendorServiceOrderFieldCreatedAt: "CREATED_AT", + coredata.VendorServiceOrderFieldName: "NAME", + } +) + func (ec *executionContext) marshalNViewer2githubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐViewer(ctx context.Context, sel ast.SelectionSet, v types.Viewer) graphql.Marshaler { return ec._Viewer(ctx, sel, &v) } @@ -76312,6 +78376,14 @@ func (ec *executionContext) unmarshalOVendorRiskAssessmentOrder2ᚖgithubᚗcom return &res, graphql.ErrorOnPath(ctx, err) } +func (ec *executionContext) unmarshalOVendorServiceOrder2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐVendorServiceOrderBy(ctx context.Context, v any) (*types.VendorServiceOrderBy, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputVendorServiceOrder(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/pkg/server/api/console/v1/types/types.go b/pkg/server/api/console/v1/types/types.go index 57cf03340..7e4f3e53e 100644 --- a/pkg/server/api/console/v1/types/types.go +++ b/pkg/server/api/console/v1/types/types.go @@ -505,6 +505,18 @@ type CreateVendorRiskAssessmentPayload struct { VendorRiskAssessmentEdge *VendorRiskAssessmentEdge `json:"vendorRiskAssessmentEdge"` } +type CreateVendorServiceInput struct { + VendorID gid.GID `json:"vendorId"` + Name string `json:"name"` + Description *string `json:"description,omitempty"` + URL *string `json:"url,omitempty"` + Type *string `json:"type,omitempty"` +} + +type CreateVendorServicePayload struct { + VendorServiceEdge *VendorServiceEdge `json:"vendorServiceEdge"` +} + type Datum struct { ID gid.GID `json:"id"` Name string `json:"name"` @@ -750,6 +762,14 @@ type DeleteVendorPayload struct { DeletedVendorID gid.GID `json:"deletedVendorId"` } +type DeleteVendorServiceInput struct { + VendorServiceID gid.GID `json:"vendorServiceId"` +} + +type DeleteVendorServicePayload struct { + DeletedVendorServiceID gid.GID `json:"deletedVendorServiceId"` +} + type Document struct { ID gid.GID `json:"id"` Title string `json:"title"` @@ -1519,6 +1539,18 @@ type UpdateVendorPayload struct { Vendor *Vendor `json:"vendor"` } +type UpdateVendorServiceInput struct { + ID gid.GID `json:"id"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + URL *string `json:"url,omitempty"` + Type *string `json:"type,omitempty"` +} + +type UpdateVendorServicePayload struct { + VendorService *VendorService `json:"vendorService"` +} + type UploadAuditReportInput struct { AuditID gid.GID `json:"auditId"` File graphql.Upload `json:"file"` @@ -1614,6 +1646,7 @@ type Vendor struct { BusinessAssociateAgreement *VendorBusinessAssociateAgreement `json:"businessAssociateAgreement,omitempty"` DataPrivacyAgreement *VendorDataPrivacyAgreement `json:"dataPrivacyAgreement,omitempty"` Contacts *VendorContactConnection `json:"contacts"` + Services *VendorServiceConnection `json:"services"` RiskAssessments *VendorRiskAssessmentConnection `json:"riskAssessments"` BusinessOwner *People `json:"businessOwner,omitempty"` SecurityOwner *People `json:"securityOwner,omitempty"` @@ -1753,6 +1786,28 @@ type VendorRiskAssessmentOrder struct { Direction page.OrderDirection `json:"direction"` } +type VendorService struct { + ID gid.GID `json:"id"` + Vendor *Vendor `json:"vendor"` + Name string `json:"name"` + Description *string `json:"description,omitempty"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` +} + +func (VendorService) IsNode() {} +func (this VendorService) GetID() gid.GID { return this.ID } + +type VendorServiceConnection struct { + Edges []*VendorServiceEdge `json:"edges"` + PageInfo *PageInfo `json:"pageInfo"` +} + +type VendorServiceEdge struct { + Cursor page.CursorKey `json:"cursor"` + Node *VendorService `json:"node"` +} + type Viewer struct { ID gid.GID `json:"id"` User *User `json:"user"` diff --git a/pkg/server/api/console/v1/types/vendor_service.go b/pkg/server/api/console/v1/types/vendor_service.go new file mode 100644 index 000000000..9ed7cfdda --- /dev/null +++ b/pkg/server/api/console/v1/types/vendor_service.go @@ -0,0 +1,54 @@ +// Copyright (c) 2025 Probo Inc . +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +package types + +import ( + "github.com/getprobo/probo/pkg/coredata" + "github.com/getprobo/probo/pkg/page" +) + +type ( + VendorServiceOrderBy OrderBy[coredata.VendorServiceOrderField] +) + +func NewVendorServiceConnection(p *page.Page[*coredata.VendorService, coredata.VendorServiceOrderField]) *VendorServiceConnection { + var edges = make([]*VendorServiceEdge, len(p.Data)) + + for i := range edges { + edges[i] = NewVendorServiceEdge(p.Data[i], p.Cursor.OrderBy.Field) + } + + return &VendorServiceConnection{ + Edges: edges, + PageInfo: NewPageInfo(p), + } +} + +func NewVendorServiceEdge(s *coredata.VendorService, orderBy coredata.VendorServiceOrderField) *VendorServiceEdge { + return &VendorServiceEdge{ + Cursor: s.CursorKey(orderBy), + Node: NewVendorService(s), + } +} + +func NewVendorService(s *coredata.VendorService) *VendorService { + return &VendorService{ + ID: s.ID, + Name: s.Name, + Description: s.Description, + CreatedAt: s.CreatedAt, + UpdatedAt: s.UpdatedAt, + } +} diff --git a/pkg/server/api/console/v1/v1_resolver.go b/pkg/server/api/console/v1/v1_resolver.go index 03a3ef218..26067bcb5 100644 --- a/pkg/server/api/console/v1/v1_resolver.go +++ b/pkg/server/api/console/v1/v1_resolver.go @@ -1430,6 +1430,60 @@ func (r *mutationResolver) DeleteVendorContact(ctx context.Context, input types. }, nil } +// CreateVendorService is the resolver for the createVendorService field. +func (r *mutationResolver) CreateVendorService(ctx context.Context, input types.CreateVendorServiceInput) (*types.CreateVendorServicePayload, error) { + prb := r.ProboService(ctx, input.VendorID.TenantID()) + + req := probo.CreateVendorServiceRequest{ + VendorID: input.VendorID, + Name: input.Name, + Description: input.Description, + } + + vendorService, err := prb.VendorServices.Create(ctx, req) + if err != nil { + return nil, fmt.Errorf("failed to create vendor service: %w", err) + } + + return &types.CreateVendorServicePayload{ + VendorServiceEdge: types.NewVendorServiceEdge(vendorService, coredata.VendorServiceOrderFieldCreatedAt), + }, nil +} + +// UpdateVendorService is the resolver for the updateVendorService field. +func (r *mutationResolver) UpdateVendorService(ctx context.Context, input types.UpdateVendorServiceInput) (*types.UpdateVendorServicePayload, error) { + prb := r.ProboService(ctx, input.ID.TenantID()) + + req := probo.UpdateVendorServiceRequest{ + ID: input.ID, + Name: input.Name, + Description: &input.Description, + } + + vendorService, err := prb.VendorServices.Update(ctx, req) + if err != nil { + return nil, fmt.Errorf("failed to update vendor service: %w", err) + } + + return &types.UpdateVendorServicePayload{ + VendorService: types.NewVendorService(vendorService), + }, nil +} + +// DeleteVendorService is the resolver for the deleteVendorService field. +func (r *mutationResolver) DeleteVendorService(ctx context.Context, input types.DeleteVendorServiceInput) (*types.DeleteVendorServicePayload, error) { + prb := r.ProboService(ctx, input.VendorServiceID.TenantID()) + + err := prb.VendorServices.Delete(ctx, input.VendorServiceID) + if err != nil { + return nil, fmt.Errorf("failed to delete vendor service: %w", err) + } + + return &types.DeleteVendorServicePayload{ + DeletedVendorServiceID: input.VendorServiceID, + }, nil +} + // CreateFramework is the resolver for the createFramework field. func (r *mutationResolver) CreateFramework(ctx context.Context, input types.CreateFrameworkInput) (*types.CreateFrameworkPayload, error) { prb := r.ProboService(ctx, input.OrganizationID.TenantID()) @@ -3507,6 +3561,12 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error panic(fmt.Errorf("cannot get vendor contact: %w", err)) } return types.NewVendorContact(vendorContact), nil + case coredata.VendorServiceEntityType: + vendorService, err := prb.VendorServices.Get(ctx, id) + if err != nil { + panic(fmt.Errorf("cannot get vendor service: %w", err)) + } + return types.NewVendorService(vendorService), nil case coredata.DocumentVersionEntityType: documentVersion, err := prb.Documents.GetVersion(ctx, id) if err != nil { @@ -3993,6 +4053,31 @@ func (r *vendorResolver) Contacts(ctx context.Context, obj *types.Vendor, first return types.NewVendorContactConnection(page), nil } +// Services is the resolver for the services field. +func (r *vendorResolver) Services(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorServiceOrderBy) (*types.VendorServiceConnection, error) { + prb := r.ProboService(ctx, obj.ID.TenantID()) + + pageOrderBy := page.OrderBy[coredata.VendorServiceOrderField]{ + Field: coredata.VendorServiceOrderFieldCreatedAt, + Direction: page.OrderDirectionDesc, + } + if orderBy != nil { + pageOrderBy = page.OrderBy[coredata.VendorServiceOrderField]{ + Field: orderBy.Field, + Direction: orderBy.Direction, + } + } + + cursor := types.NewCursor(first, after, last, before, pageOrderBy) + + page, err := prb.VendorServices.List(ctx, obj.ID, cursor) + if err != nil { + panic(fmt.Errorf("failed to list vendor services: %w", err)) + } + + return types.NewVendorServiceConnection(page), nil +} + // RiskAssessments is the resolver for the riskAssessments field. func (r *vendorResolver) RiskAssessments(ctx context.Context, obj *types.Vendor, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorRiskAssessmentOrder) (*types.VendorRiskAssessmentConnection, error) { prb := r.ProboService(ctx, obj.ID.TenantID()) @@ -4206,6 +4291,24 @@ func (r *vendorRiskAssessmentResolver) AssessedBy(ctx context.Context, obj *type return types.NewPeople(people), nil } +// Vendor is the resolver for the vendor field. +func (r *vendorServiceResolver) Vendor(ctx context.Context, obj *types.VendorService) (*types.Vendor, error) { + prb := r.ProboService(ctx, obj.ID.TenantID()) + + // Get the vendor service to access the VendorID + vendorService, err := prb.VendorServices.Get(ctx, obj.ID) + if err != nil { + panic(fmt.Errorf("failed to get vendor service: %w", err)) + } + + vendor, err := prb.Vendors.Get(ctx, vendorService.VendorID) + if err != nil { + panic(fmt.Errorf("failed to get vendor: %w", err)) + } + + return types.NewVendor(vendor), nil +} + // Organizations is the resolver for the organizations field. func (r *viewerResolver) Organizations(ctx context.Context, obj *types.Viewer, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrganizationOrder, filter *types.OrganizationFilter) (*types.OrganizationConnection, error) { user := UserFromContext(ctx) @@ -4391,6 +4494,9 @@ func (r *Resolver) VendorRiskAssessment() schema.VendorRiskAssessmentResolver { return &vendorRiskAssessmentResolver{r} } +// VendorService returns schema.VendorServiceResolver implementation. +func (r *Resolver) VendorService() schema.VendorServiceResolver { return &vendorServiceResolver{r} } + // Viewer returns schema.ViewerResolver implementation. func (r *Resolver) Viewer() schema.ViewerResolver { return &viewerResolver{r} } @@ -4434,4 +4540,5 @@ type vendorConnectionResolver struct{ *Resolver } type vendorContactResolver struct{ *Resolver } type vendorDataPrivacyAgreementResolver struct{ *Resolver } type vendorRiskAssessmentResolver struct{ *Resolver } +type vendorServiceResolver struct{ *Resolver } type viewerResolver struct{ *Resolver }