From fe241fc1368ccb926cee2601b06e497178e84cdc Mon Sep 17 00:00:00 2001 From: Sacha Al Himdani Date: Mon, 9 Mar 2026 09:28:12 +0100 Subject: [PATCH] Add social links Signed-off-by: Sacha Al Himdani --- .../CompliancePageBrandPageQuery.graphql.ts | 294 ++- ...ernalUrlsSection_createMutation.graphql.ts | 144 ++ ...ernalUrlsSection_deleteMutation.graphql.ts | 92 + ...UrlsSection_trustCenterFragment.graphql.ts | 233 +++ ...Section_trustCenterRefetchQuery.graphql.ts | 309 +++ ...ernalUrlsSection_updateMutation.graphql.ts | 132 ++ ...CompliancePageOverviewPageQuery.graphql.ts | 214 +-- .../brand/CompliancePageBrandPage.tsx | 233 +-- .../overview/CompliancePageOverviewPage.tsx | 17 - .../CompliancePageExternalUrlsSection.tsx | 453 +++++ .../src/components/OrganizationSidebar.tsx | 23 +- apps/trust/src/queries/TrustGraph.ts | 9 + .../TrustGraphCurrentQuery.graphql.ts | 107 +- packages/helpers/src/dom.ts | 19 + packages/helpers/src/index.ts | 2 + packages/helpers/src/socialUrl.ts | 12 + .../ui/src/Atoms/Icons/IconBrandFacebook.tsx | 14 + .../ui/src/Atoms/Icons/IconBrandLinkedin.tsx | 14 + packages/ui/src/Atoms/Icons/IconBrandX.tsx | 14 + packages/ui/src/Atoms/Icons/IconGlobe.tsx | 12 + packages/ui/src/Atoms/Icons/SocialIcon.tsx | 16 + packages/ui/src/Atoms/Icons/index.tsx | 6 + pkg/coredata/compliance_external_url.go | 303 +++ .../compliance_external_url_order_field.go | 34 + pkg/coredata/entity_type_reg.go | 3 + pkg/coredata/migrations/20260306T200000Z.sql | 16 + pkg/probo/actions.go | 6 + pkg/probo/compliance_external_url_service.go | 195 ++ pkg/probo/service.go | 2 + pkg/probo/trust_center_service.go | 1 - pkg/server/api/console/v1/schema.graphql | 92 + pkg/server/api/console/v1/schema/schema.go | 1678 +++++++++++++++++ .../v1/types/compliance_external_url.go | 44 + pkg/server/api/console/v1/types/types.go | 74 +- pkg/server/api/console/v1/v1_resolver.go | 109 ++ pkg/server/api/trust/v1/schema.graphql | 24 + pkg/server/api/trust/v1/schema/schema.go | 673 +++++++ .../trust/v1/types/compliance_external_url.go | 51 + pkg/server/api/trust/v1/types/types.go | 47 +- pkg/server/api/trust/v1/v1_resolver.go | 19 + pkg/trust/compliance_external_url_service.go | 55 + pkg/trust/service.go | 48 +- 42 files changed, 5428 insertions(+), 415 deletions(-) create mode 100644 apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_createMutation.graphql.ts create mode 100644 apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_deleteMutation.graphql.ts create mode 100644 apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_trustCenterFragment.graphql.ts create mode 100644 apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_trustCenterRefetchQuery.graphql.ts create mode 100644 apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_updateMutation.graphql.ts create mode 100644 apps/console/src/pages/organizations/compliance-page/overview/_components/CompliancePageExternalUrlsSection.tsx create mode 100644 packages/helpers/src/socialUrl.ts create mode 100644 packages/ui/src/Atoms/Icons/IconBrandFacebook.tsx create mode 100644 packages/ui/src/Atoms/Icons/IconBrandLinkedin.tsx create mode 100644 packages/ui/src/Atoms/Icons/IconBrandX.tsx create mode 100644 packages/ui/src/Atoms/Icons/IconGlobe.tsx create mode 100644 packages/ui/src/Atoms/Icons/SocialIcon.tsx create mode 100644 pkg/coredata/compliance_external_url.go create mode 100644 pkg/coredata/compliance_external_url_order_field.go create mode 100644 pkg/coredata/migrations/20260306T200000Z.sql create mode 100644 pkg/probo/compliance_external_url_service.go create mode 100644 pkg/server/api/console/v1/types/compliance_external_url.go create mode 100644 pkg/server/api/trust/v1/types/compliance_external_url.go create mode 100644 pkg/trust/compliance_external_url_service.go diff --git a/apps/console/src/__generated__/core/CompliancePageBrandPageQuery.graphql.ts b/apps/console/src/__generated__/core/CompliancePageBrandPageQuery.graphql.ts index 947f441ff..6f145d628 100644 --- a/apps/console/src/__generated__/core/CompliancePageBrandPageQuery.graphql.ts +++ b/apps/console/src/__generated__/core/CompliancePageBrandPageQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<6ae7a5c203ff61690408ec2753fe2f11>> + * @generated SignedSource<> * @lightSyntaxTransform * @nogrep */ @@ -9,6 +9,7 @@ // @ts-nocheck import { ConcreteRequest } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; export type CompliancePageBrandPageQuery$variables = { organizationId: string; }; @@ -20,6 +21,7 @@ export type CompliancePageBrandPageQuery$data = { readonly darkLogoFileUrl: string | null | undefined; readonly id: string; readonly logoFileUrl: string | null | undefined; + readonly " $fragmentSpreads": FragmentRefs<"CompliancePageExternalUrlsSection_trustCenterFragment" | "CompliancePageFrameworkList_compliancePageFragment">; }; } | { // This will never be '%other', but we need some @@ -62,44 +64,108 @@ v3 = { "storageKey": null }, v4 = { - "alias": "compliancePage", + "alias": null, "args": null, - "concreteType": "TrustCenter", + "kind": "ScalarField", + "name": "logoFileUrl", + "storageKey": null +}, +v5 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "darkLogoFileUrl", + "storageKey": null +}, +v6 = { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center:update\")" +}, +v7 = [ + { + "kind": "Literal", + "name": "first", + "value": 100 + }, + { + "kind": "Literal", + "name": "orderBy", + "value": { + "direction": "ASC", + "field": "RANK" + } + } +], +v8 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "rank", + "storageKey": null +}, +v9 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null +}, +v10 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "cursor", + "storageKey": null +}, +v11 = { + "alias": null, + "args": null, + "concreteType": "PageInfo", "kind": "LinkedField", - "name": "trustCenter", + "name": "pageInfo", "plural": false, "selections": [ - (v3/*: any*/), { "alias": null, "args": null, "kind": "ScalarField", - "name": "logoFileUrl", + "name": "endCursor", "storageKey": null }, { "alias": null, "args": null, "kind": "ScalarField", - "name": "darkLogoFileUrl", + "name": "hasNextPage", "storageKey": null - }, - { - "alias": "canUpdate", - "args": [ - { - "kind": "Literal", - "name": "action", - "value": "core:trust-center:update" - } - ], - "kind": "ScalarField", - "name": "permission", - "storageKey": "permission(action:\"core:trust-center:update\")" } ], "storageKey": null -}; +}, +v12 = { + "kind": "ClientExtension", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__id", + "storageKey": null + } + ] +}, +v13 = [ + "orderBy" +]; return { "fragment": { "argumentDefinitions": (v0/*: any*/), @@ -121,7 +187,31 @@ return { "selections": [ { "kind": "RequiredField", - "field": (v4/*: any*/), + "field": { + "alias": "compliancePage", + "args": null, + "concreteType": "TrustCenter", + "kind": "LinkedField", + "name": "trustCenter", + "plural": false, + "selections": [ + (v3/*: any*/), + (v4/*: any*/), + (v5/*: any*/), + (v6/*: any*/), + { + "args": null, + "kind": "FragmentSpread", + "name": "CompliancePageFrameworkList_compliancePageFragment" + }, + { + "args": null, + "kind": "FragmentSpread", + "name": "CompliancePageExternalUrlsSection_trustCenterFragment" + } + ], + "storageKey": null + }, "action": "THROW" } ], @@ -153,7 +243,159 @@ return { { "kind": "InlineFragment", "selections": [ - (v4/*: any*/) + { + "alias": "compliancePage", + "args": null, + "concreteType": "TrustCenter", + "kind": "LinkedField", + "name": "trustCenter", + "plural": false, + "selections": [ + (v3/*: any*/), + (v4/*: any*/), + (v5/*: any*/), + (v6/*: any*/), + { + "alias": null, + "args": (v7/*: any*/), + "concreteType": "ComplianceFrameworkConnection", + "kind": "LinkedField", + "name": "complianceFrameworks", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFrameworkEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceFramework", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v3/*: any*/), + (v8/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "visibility", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "Framework", + "kind": "LinkedField", + "name": "framework", + "plural": false, + "selections": [ + (v3/*: any*/), + (v9/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "lightLogoURL", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "darkLogoURL", + "storageKey": null + } + ], + "storageKey": null + }, + (v2/*: any*/) + ], + "storageKey": null + }, + (v10/*: any*/) + ], + "storageKey": null + }, + (v11/*: any*/), + (v12/*: any*/) + ], + "storageKey": "complianceFrameworks(first:100,orderBy:{\"direction\":\"ASC\",\"field\":\"RANK\"})" + }, + { + "alias": null, + "args": (v7/*: any*/), + "filters": (v13/*: any*/), + "handle": "connection", + "key": "CompliancePageFrameworkList_complianceFrameworks", + "kind": "LinkedHandle", + "name": "complianceFrameworks" + }, + { + "alias": null, + "args": (v7/*: any*/), + "concreteType": "ComplianceExternalURLConnection", + "kind": "LinkedField", + "name": "externalUrls", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceExternalURLEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceExternalURL", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v3/*: any*/), + (v9/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "url", + "storageKey": null + }, + (v8/*: any*/), + (v2/*: any*/) + ], + "storageKey": null + }, + (v10/*: any*/) + ], + "storageKey": null + }, + (v11/*: any*/), + (v12/*: any*/) + ], + "storageKey": "externalUrls(first:100,orderBy:{\"direction\":\"ASC\",\"field\":\"RANK\"})" + }, + { + "alias": null, + "args": (v7/*: any*/), + "filters": (v13/*: any*/), + "handle": "connection", + "key": "CompliancePageExternalUrlsSection_externalUrls", + "kind": "LinkedHandle", + "name": "externalUrls" + } + ], + "storageKey": null + } ], "type": "Organization", "abstractKey": null @@ -165,16 +407,16 @@ return { ] }, "params": { - "cacheID": "a0e24c6bb927ff34274492952df0346b", + "cacheID": "8a6a8094cbc0edebe011b284ac9638dc", "id": null, "metadata": {}, "name": "CompliancePageBrandPageQuery", "operationKind": "query", - "text": "query CompliancePageBrandPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n compliancePage: trustCenter {\n id\n logoFileUrl\n darkLogoFileUrl\n canUpdate: permission(action: \"core:trust-center:update\")\n }\n }\n id\n }\n}\n" + "text": "query CompliancePageBrandPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n compliancePage: trustCenter {\n id\n logoFileUrl\n darkLogoFileUrl\n canUpdate: permission(action: \"core:trust-center:update\")\n ...CompliancePageFrameworkList_compliancePageFragment\n ...CompliancePageExternalUrlsSection_trustCenterFragment\n }\n }\n id\n }\n}\n\nfragment CompliancePageExternalUrlsSection_trustCenterFragment on TrustCenter {\n id\n canUpdate: permission(action: \"core:trust-center:update\")\n externalUrls(first: 100, orderBy: {field: RANK, direction: ASC}) {\n edges {\n node {\n id\n name\n url\n rank\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment CompliancePageFrameworkList_compliancePageFragment on TrustCenter {\n id\n canUpdate: permission(action: \"core:trust-center:update\")\n complianceFrameworks(first: 100, orderBy: {field: RANK, direction: ASC}) {\n edges {\n node {\n id\n rank\n visibility\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n" } }; })(); -(node as any).hash = "3d2d6ef82bb9cf232aad738c906b8a54"; +(node as any).hash = "d0a4169ebdc6d099e49faa2839d6f33d"; export default node; diff --git a/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_createMutation.graphql.ts b/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_createMutation.graphql.ts new file mode 100644 index 000000000..194f7fdf6 --- /dev/null +++ b/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_createMutation.graphql.ts @@ -0,0 +1,144 @@ +/** + * @generated SignedSource<<23a875a3299a51bdebef4d121b0b84ff>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type CreateComplianceExternalURLInput = { + name: string; + trustCenterId: string; + url: string; +}; +export type CompliancePageExternalUrlsSection_createMutation$variables = { + input: CreateComplianceExternalURLInput; +}; +export type CompliancePageExternalUrlsSection_createMutation$data = { + readonly createComplianceExternalURL: { + readonly complianceExternalUrlEdge: { + readonly node: { + readonly id: string; + readonly name: string; + readonly rank: number; + readonly url: string; + }; + }; + }; +}; +export type CompliancePageExternalUrlsSection_createMutation = { + response: CompliancePageExternalUrlsSection_createMutation$data; + variables: CompliancePageExternalUrlsSection_createMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" + } +], +v1 = [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } + ], + "concreteType": "CreateComplianceExternalURLPayload", + "kind": "LinkedField", + "name": "createComplianceExternalURL", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceExternalURLEdge", + "kind": "LinkedField", + "name": "complianceExternalUrlEdge", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceExternalURL", + "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": "url", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "rank", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "CompliancePageExternalUrlsSection_createMutation", + "selections": (v1/*: any*/), + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "CompliancePageExternalUrlsSection_createMutation", + "selections": (v1/*: any*/) + }, + "params": { + "cacheID": "946285e4ff57ca46030c3c2ec5b8cc22", + "id": null, + "metadata": {}, + "name": "CompliancePageExternalUrlsSection_createMutation", + "operationKind": "mutation", + "text": "mutation CompliancePageExternalUrlsSection_createMutation(\n $input: CreateComplianceExternalURLInput!\n) {\n createComplianceExternalURL(input: $input) {\n complianceExternalUrlEdge {\n node {\n id\n name\n url\n rank\n }\n }\n }\n}\n" + } +}; +})(); + +(node as any).hash = "8441156775b5070a2dc3f0e316d5bb0b"; + +export default node; diff --git a/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_deleteMutation.graphql.ts b/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_deleteMutation.graphql.ts new file mode 100644 index 000000000..d2b23f2ed --- /dev/null +++ b/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_deleteMutation.graphql.ts @@ -0,0 +1,92 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type DeleteComplianceExternalURLInput = { + id: string; +}; +export type CompliancePageExternalUrlsSection_deleteMutation$variables = { + input: DeleteComplianceExternalURLInput; +}; +export type CompliancePageExternalUrlsSection_deleteMutation$data = { + readonly deleteComplianceExternalURL: { + readonly deletedComplianceExternalUrlId: string; + }; +}; +export type CompliancePageExternalUrlsSection_deleteMutation = { + response: CompliancePageExternalUrlsSection_deleteMutation$data; + variables: CompliancePageExternalUrlsSection_deleteMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" + } +], +v1 = [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } + ], + "concreteType": "DeleteComplianceExternalURLPayload", + "kind": "LinkedField", + "name": "deleteComplianceExternalURL", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "deletedComplianceExternalUrlId", + "storageKey": null + } + ], + "storageKey": null + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "CompliancePageExternalUrlsSection_deleteMutation", + "selections": (v1/*: any*/), + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "CompliancePageExternalUrlsSection_deleteMutation", + "selections": (v1/*: any*/) + }, + "params": { + "cacheID": "e0715ce1d37b8854b0eeea3e6214973c", + "id": null, + "metadata": {}, + "name": "CompliancePageExternalUrlsSection_deleteMutation", + "operationKind": "mutation", + "text": "mutation CompliancePageExternalUrlsSection_deleteMutation(\n $input: DeleteComplianceExternalURLInput!\n) {\n deleteComplianceExternalURL(input: $input) {\n deletedComplianceExternalUrlId\n }\n}\n" + } +}; +})(); + +(node as any).hash = "394380c11f7ee240360143f8f71f058c"; + +export default node; diff --git a/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_trustCenterFragment.graphql.ts b/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_trustCenterFragment.graphql.ts new file mode 100644 index 000000000..959a8750c --- /dev/null +++ b/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_trustCenterFragment.graphql.ts @@ -0,0 +1,233 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ReaderFragment } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type CompliancePageExternalUrlsSection_trustCenterFragment$data = { + readonly canUpdate: boolean; + readonly externalUrls: { + readonly __id: string; + readonly edges: ReadonlyArray<{ + readonly node: { + readonly id: string; + readonly name: string; + readonly rank: number; + readonly url: string; + }; + }>; + }; + readonly id: string; + readonly " $fragmentType": "CompliancePageExternalUrlsSection_trustCenterFragment"; +}; +export type CompliancePageExternalUrlsSection_trustCenterFragment$key = { + readonly " $data"?: CompliancePageExternalUrlsSection_trustCenterFragment$data; + readonly " $fragmentSpreads": FragmentRefs<"CompliancePageExternalUrlsSection_trustCenterFragment">; +}; + +import CompliancePageExternalUrlsSection_trustCenterRefetchQuery_graphql from './CompliancePageExternalUrlsSection_trustCenterRefetchQuery.graphql'; + +const node: ReaderFragment = (function(){ +var v0 = [ + "externalUrls" +], +v1 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}; +return { + "argumentDefinitions": [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "after" + }, + { + "defaultValue": 100, + "kind": "LocalArgument", + "name": "first" + }, + { + "defaultValue": { + "direction": "ASC", + "field": "RANK" + }, + "kind": "LocalArgument", + "name": "order" + } + ], + "kind": "Fragment", + "metadata": { + "connection": [ + { + "count": "first", + "cursor": "after", + "direction": "forward", + "path": (v0/*: any*/) + } + ], + "refetch": { + "connection": { + "forward": { + "count": "first", + "cursor": "after" + }, + "backward": null, + "path": (v0/*: any*/) + }, + "fragmentPathInResult": [ + "node" + ], + "operation": CompliancePageExternalUrlsSection_trustCenterRefetchQuery_graphql, + "identifierInfo": { + "identifierField": "id", + "identifierQueryVariableName": "id" + } + } + }, + "name": "CompliancePageExternalUrlsSection_trustCenterFragment", + "selections": [ + (v1/*: any*/), + { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center:update\")" + }, + { + "alias": "externalUrls", + "args": [ + { + "kind": "Variable", + "name": "orderBy", + "variableName": "order" + } + ], + "concreteType": "ComplianceExternalURLConnection", + "kind": "LinkedField", + "name": "__CompliancePageExternalUrlsSection_externalUrls_connection", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceExternalURLEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceExternalURL", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v1/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "url", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "rank", + "storageKey": null + }, + { + "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 + } + ], + "storageKey": null + }, + { + "kind": "ClientExtension", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__id", + "storageKey": null + } + ] + } + ], + "storageKey": null + } + ], + "type": "TrustCenter", + "abstractKey": null +}; +})(); + +(node as any).hash = "f2614c45eaf65a9d6c6f857abc7c66f6"; + +export default node; diff --git a/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_trustCenterRefetchQuery.graphql.ts b/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_trustCenterRefetchQuery.graphql.ts new file mode 100644 index 000000000..e88004bf3 --- /dev/null +++ b/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_trustCenterRefetchQuery.graphql.ts @@ -0,0 +1,309 @@ +/** + * @generated SignedSource<<1fdf3d464ce9b10a9dd2ea55a9dbfc26>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +import { FragmentRefs } from "relay-runtime"; +export type ComplianceExternalURLOrderField = "CREATED_AT" | "RANK"; +export type OrderDirection = "ASC" | "DESC"; +export type ComplianceExternalURLOrder = { + direction: OrderDirection; + field: ComplianceExternalURLOrderField; +}; +export type CompliancePageExternalUrlsSection_trustCenterRefetchQuery$variables = { + after?: string | null | undefined; + first?: number | null | undefined; + id: string; + order?: ComplianceExternalURLOrder | null | undefined; +}; +export type CompliancePageExternalUrlsSection_trustCenterRefetchQuery$data = { + readonly node: { + readonly " $fragmentSpreads": FragmentRefs<"CompliancePageExternalUrlsSection_trustCenterFragment">; + }; +}; +export type CompliancePageExternalUrlsSection_trustCenterRefetchQuery = { + response: CompliancePageExternalUrlsSection_trustCenterRefetchQuery$data; + variables: CompliancePageExternalUrlsSection_trustCenterRefetchQuery$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "after" +}, +v1 = { + "defaultValue": 100, + "kind": "LocalArgument", + "name": "first" +}, +v2 = { + "defaultValue": null, + "kind": "LocalArgument", + "name": "id" +}, +v3 = { + "defaultValue": { + "direction": "ASC", + "field": "RANK" + }, + "kind": "LocalArgument", + "name": "order" +}, +v4 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "id" + } +], +v5 = { + "kind": "Variable", + "name": "after", + "variableName": "after" +}, +v6 = { + "kind": "Variable", + "name": "first", + "variableName": "first" +}, +v7 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null +}, +v8 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v9 = [ + (v5/*: any*/), + (v6/*: any*/), + { + "kind": "Variable", + "name": "orderBy", + "variableName": "order" + } +]; +return { + "fragment": { + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/), + (v2/*: any*/), + (v3/*: any*/) + ], + "kind": "Fragment", + "metadata": null, + "name": "CompliancePageExternalUrlsSection_trustCenterRefetchQuery", + "selections": [ + { + "alias": null, + "args": (v4/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "args": [ + (v5/*: any*/), + (v6/*: any*/), + { + "kind": "Variable", + "name": "order", + "variableName": "order" + } + ], + "kind": "FragmentSpread", + "name": "CompliancePageExternalUrlsSection_trustCenterFragment" + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [ + (v0/*: any*/), + (v1/*: any*/), + (v3/*: any*/), + (v2/*: any*/) + ], + "kind": "Operation", + "name": "CompliancePageExternalUrlsSection_trustCenterRefetchQuery", + "selections": [ + { + "alias": null, + "args": (v4/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v7/*: any*/), + (v8/*: any*/), + { + "kind": "InlineFragment", + "selections": [ + { + "alias": "canUpdate", + "args": [ + { + "kind": "Literal", + "name": "action", + "value": "core:trust-center:update" + } + ], + "kind": "ScalarField", + "name": "permission", + "storageKey": "permission(action:\"core:trust-center:update\")" + }, + { + "alias": null, + "args": (v9/*: any*/), + "concreteType": "ComplianceExternalURLConnection", + "kind": "LinkedField", + "name": "externalUrls", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceExternalURLEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceExternalURL", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v8/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "url", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "rank", + "storageKey": null + }, + (v7/*: 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 + } + ], + "storageKey": null + }, + { + "kind": "ClientExtension", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__id", + "storageKey": null + } + ] + } + ], + "storageKey": null + }, + { + "alias": null, + "args": (v9/*: any*/), + "filters": [ + "orderBy" + ], + "handle": "connection", + "key": "CompliancePageExternalUrlsSection_externalUrls", + "kind": "LinkedHandle", + "name": "externalUrls" + } + ], + "type": "TrustCenter", + "abstractKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "0732bd06586ed31ed89b4dfad14d1fbd", + "id": null, + "metadata": {}, + "name": "CompliancePageExternalUrlsSection_trustCenterRefetchQuery", + "operationKind": "query", + "text": "query CompliancePageExternalUrlsSection_trustCenterRefetchQuery(\n $after: CursorKey = null\n $first: Int = 100\n $order: ComplianceExternalURLOrder = {field: RANK, direction: ASC}\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...CompliancePageExternalUrlsSection_trustCenterFragment_gOVF5\n id\n }\n}\n\nfragment CompliancePageExternalUrlsSection_trustCenterFragment_gOVF5 on TrustCenter {\n id\n canUpdate: permission(action: \"core:trust-center:update\")\n externalUrls(first: $first, after: $after, orderBy: $order) {\n edges {\n node {\n id\n name\n url\n rank\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n" + } +}; +})(); + +(node as any).hash = "f2614c45eaf65a9d6c6f857abc7c66f6"; + +export default node; diff --git a/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_updateMutation.graphql.ts b/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_updateMutation.graphql.ts new file mode 100644 index 000000000..461f29725 --- /dev/null +++ b/apps/console/src/__generated__/core/CompliancePageExternalUrlsSection_updateMutation.graphql.ts @@ -0,0 +1,132 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type UpdateComplianceExternalURLInput = { + id: string; + name: string; + rank?: number | null | undefined; + url: string; +}; +export type CompliancePageExternalUrlsSection_updateMutation$variables = { + input: UpdateComplianceExternalURLInput; +}; +export type CompliancePageExternalUrlsSection_updateMutation$data = { + readonly updateComplianceExternalURL: { + readonly complianceExternalUrl: { + readonly id: string; + readonly name: string; + readonly rank: number; + readonly url: string; + }; + }; +}; +export type CompliancePageExternalUrlsSection_updateMutation = { + response: CompliancePageExternalUrlsSection_updateMutation$data; + variables: CompliancePageExternalUrlsSection_updateMutation$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "input" + } +], +v1 = [ + { + "alias": null, + "args": [ + { + "kind": "Variable", + "name": "input", + "variableName": "input" + } + ], + "concreteType": "UpdateComplianceExternalURLPayload", + "kind": "LinkedField", + "name": "updateComplianceExternalURL", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceExternalURL", + "kind": "LinkedField", + "name": "complianceExternalUrl", + "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": "url", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "rank", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } +]; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "CompliancePageExternalUrlsSection_updateMutation", + "selections": (v1/*: any*/), + "type": "Mutation", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "CompliancePageExternalUrlsSection_updateMutation", + "selections": (v1/*: any*/) + }, + "params": { + "cacheID": "f771e54a9a15080525576308c8277815", + "id": null, + "metadata": {}, + "name": "CompliancePageExternalUrlsSection_updateMutation", + "operationKind": "mutation", + "text": "mutation CompliancePageExternalUrlsSection_updateMutation(\n $input: UpdateComplianceExternalURLInput!\n) {\n updateComplianceExternalURL(input: $input) {\n complianceExternalUrl {\n id\n name\n url\n rank\n }\n }\n}\n" + } +}; +})(); + +(node as any).hash = "b6162bd7b54e784dff62db83e0ff32be"; + +export default node; diff --git a/apps/console/src/__generated__/core/CompliancePageOverviewPageQuery.graphql.ts b/apps/console/src/__generated__/core/CompliancePageOverviewPageQuery.graphql.ts index 361719aca..0e3948146 100644 --- a/apps/console/src/__generated__/core/CompliancePageOverviewPageQuery.graphql.ts +++ b/apps/console/src/__generated__/core/CompliancePageOverviewPageQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<> + * @generated SignedSource<<18bb7ea1b507c374c33d9f4f7a56db2d>> * @lightSyntaxTransform * @nogrep */ @@ -17,7 +17,6 @@ export type CompliancePageOverviewPageQuery$data = { readonly organization: { readonly compliancePage?: { readonly canGetNDA: boolean; - readonly " $fragmentSpreads": FragmentRefs<"CompliancePageFrameworkList_compliancePageFragment">; } | null | undefined; readonly " $fragmentSpreads": FragmentRefs<"CompliancePageNDASectionFragment" | "CompliancePageSlackSectionFragment" | "CompliancePageStatusSectionFragment">; }; @@ -56,35 +55,12 @@ v2 = { "storageKey": "permission(action:\"core:trust-center:get-nda\")" }, v3 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "__typename", - "storageKey": null -}, -v4 = { "alias": null, "args": null, "kind": "ScalarField", "name": "id", "storageKey": null -}, -v5 = { - "kind": "Literal", - "name": "first", - "value": 100 -}, -v6 = [ - (v5/*: any*/), - { - "kind": "Literal", - "name": "orderBy", - "value": { - "direction": "ASC", - "field": "RANK" - } - } -]; +}; return { "fragment": { "argumentDefinitions": (v0/*: any*/), @@ -111,12 +87,7 @@ return { "name": "trustCenter", "plural": false, "selections": [ - (v2/*: any*/), - { - "args": null, - "kind": "FragmentSpread", - "name": "CompliancePageFrameworkList_compliancePageFragment" - } + (v2/*: any*/) ], "storageKey": null } @@ -160,7 +131,13 @@ return { "name": "node", "plural": false, "selections": [ - (v3/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null + }, { "kind": "InlineFragment", "selections": [ @@ -173,7 +150,14 @@ return { "plural": false, "selections": [ (v2/*: any*/), - (v4/*: any*/), + (v3/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "active", + "storageKey": null + }, { "alias": "canUpdate", "args": [ @@ -187,150 +171,6 @@ return { "name": "permission", "storageKey": "permission(action:\"core:trust-center:update\")" }, - { - "alias": null, - "args": (v6/*: any*/), - "concreteType": "ComplianceFrameworkConnection", - "kind": "LinkedField", - "name": "complianceFrameworks", - "plural": false, - "selections": [ - { - "alias": null, - "args": null, - "concreteType": "ComplianceFrameworkEdge", - "kind": "LinkedField", - "name": "edges", - "plural": true, - "selections": [ - { - "alias": null, - "args": null, - "concreteType": "ComplianceFramework", - "kind": "LinkedField", - "name": "node", - "plural": false, - "selections": [ - (v4/*: any*/), - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "rank", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "visibility", - "storageKey": null - }, - { - "alias": null, - "args": null, - "concreteType": "Framework", - "kind": "LinkedField", - "name": "framework", - "plural": false, - "selections": [ - (v4/*: any*/), - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "name", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "lightLogoURL", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "darkLogoURL", - "storageKey": null - } - ], - "storageKey": null - }, - (v3/*: 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 - } - ], - "storageKey": null - }, - { - "kind": "ClientExtension", - "selections": [ - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "__id", - "storageKey": null - } - ] - } - ], - "storageKey": "complianceFrameworks(first:100,orderBy:{\"direction\":\"ASC\",\"field\":\"RANK\"})" - }, - { - "alias": null, - "args": (v6/*: any*/), - "filters": [ - "orderBy" - ], - "handle": "connection", - "key": "CompliancePageFrameworkList_complianceFrameworks", - "kind": "LinkedHandle", - "name": "complianceFrameworks" - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "active", - "storageKey": null - }, { "alias": null, "args": null, @@ -389,14 +229,18 @@ return { "name": "domain", "storageKey": null }, - (v4/*: any*/) + (v3/*: any*/) ], "storageKey": null }, { "alias": null, "args": [ - (v5/*: any*/) + { + "kind": "Literal", + "name": "first", + "value": 100 + } ], "concreteType": "SlackConnectionConnection", "kind": "LinkedField", @@ -419,7 +263,7 @@ return { "name": "node", "plural": false, "selections": [ - (v4/*: any*/), + (v3/*: any*/), { "alias": null, "args": null, @@ -447,23 +291,23 @@ return { "type": "Organization", "abstractKey": null }, - (v4/*: any*/) + (v3/*: any*/) ], "storageKey": null } ] }, "params": { - "cacheID": "e6cc68fe4df4a8dffc558f6db82ead9c", + "cacheID": "0041132d3ac46a3193d9acbd6f27bdf5", "id": null, "metadata": {}, "name": "CompliancePageOverviewPageQuery", "operationKind": "query", - "text": "query CompliancePageOverviewPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n compliancePage: trustCenter {\n canGetNDA: permission(action: \"core:trust-center:get-nda\")\n ...CompliancePageFrameworkList_compliancePageFragment\n id\n }\n }\n ...CompliancePageStatusSectionFragment\n ...CompliancePageNDASectionFragment\n ...CompliancePageSlackSectionFragment\n id\n }\n}\n\nfragment CompliancePageFrameworkList_compliancePageFragment on TrustCenter {\n id\n canUpdate: permission(action: \"core:trust-center:update\")\n complianceFrameworks(first: 100, orderBy: {field: RANK, direction: ASC}) {\n edges {\n node {\n id\n rank\n visibility\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment CompliancePageNDASectionFragment on Organization {\n compliancePage: trustCenter {\n id\n ndaFileName\n ndaFileUrl\n canUpdate: permission(action: \"core:trust-center:update\")\n canUploadNDA: permission(action: \"core:trust-center:upload-nda\")\n canDeleteNDA: permission(action: \"core:trust-center:delete-nda\")\n }\n}\n\nfragment CompliancePageSlackSectionFragment on Organization {\n compliancePage: trustCenter {\n canUpdate: permission(action: \"core:trust-center:update\")\n id\n }\n slackConnections(first: 100) {\n edges {\n node {\n id\n channel\n createdAt\n }\n }\n }\n}\n\nfragment CompliancePageStatusSectionFragment on Organization {\n customDomain {\n domain\n id\n }\n compliancePage: trustCenter {\n id\n active\n canUpdate: permission(action: \"core:trust-center:update\")\n }\n}\n" + "text": "query CompliancePageOverviewPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n compliancePage: trustCenter {\n canGetNDA: permission(action: \"core:trust-center:get-nda\")\n id\n }\n }\n ...CompliancePageStatusSectionFragment\n ...CompliancePageNDASectionFragment\n ...CompliancePageSlackSectionFragment\n id\n }\n}\n\nfragment CompliancePageNDASectionFragment on Organization {\n compliancePage: trustCenter {\n id\n ndaFileName\n ndaFileUrl\n canUpdate: permission(action: \"core:trust-center:update\")\n canUploadNDA: permission(action: \"core:trust-center:upload-nda\")\n canDeleteNDA: permission(action: \"core:trust-center:delete-nda\")\n }\n}\n\nfragment CompliancePageSlackSectionFragment on Organization {\n compliancePage: trustCenter {\n canUpdate: permission(action: \"core:trust-center:update\")\n id\n }\n slackConnections(first: 100) {\n edges {\n node {\n id\n channel\n createdAt\n }\n }\n }\n}\n\nfragment CompliancePageStatusSectionFragment on Organization {\n customDomain {\n domain\n id\n }\n compliancePage: trustCenter {\n id\n active\n canUpdate: permission(action: \"core:trust-center:update\")\n }\n}\n" } }; })(); -(node as any).hash = "be0dff83941c21755ea2ff77a865805b"; +(node as any).hash = "689133b7f1c380266e6f15a60c527c91"; export default node; diff --git a/apps/console/src/pages/organizations/compliance-page/brand/CompliancePageBrandPage.tsx b/apps/console/src/pages/organizations/compliance-page/brand/CompliancePageBrandPage.tsx index 499e00470..75fe44d95 100644 --- a/apps/console/src/pages/organizations/compliance-page/brand/CompliancePageBrandPage.tsx +++ b/apps/console/src/pages/organizations/compliance-page/brand/CompliancePageBrandPage.tsx @@ -17,6 +17,9 @@ import type { CompliancePageBrandPage_updateMutation } from "#/__generated__/cor import type { CompliancePageBrandPageQuery } from "#/__generated__/core/CompliancePageBrandPageQuery.graphql"; import { useMutationWithToasts } from "#/hooks/useMutationWithToasts"; +import { CompliancePageExternalUrlsSection } from "../overview/_components/CompliancePageExternalUrlsSection"; +import { CompliancePageFrameworkList } from "../overview/_components/CompliancePageFrameworkList"; + export const compliancePageBrandPageQuery = graphql` query CompliancePageBrandPageQuery($organizationId: ID!) { organization: node(id: $organizationId) { @@ -27,6 +30,8 @@ export const compliancePageBrandPageQuery = graphql` logoFileUrl darkLogoFileUrl canUpdate: permission(action: "core:trust-center:update") + ...CompliancePageFrameworkList_compliancePageFragment + ...CompliancePageExternalUrlsSection_trustCenterFragment } } } @@ -218,116 +223,130 @@ export function CompliancePageBrandPage(props: { queryRef: PreloadedQuery -
-

{__("Branding")}

- {isUpdating && } +
+
+
+

{__("Branding")}

+ {isUpdating && } +
+ + +
+
+ +

+ {__("This logo will be displayed on your public compliance page.")} +

+ + {currentLogoUrl + ? ( +
+
+ {__("Compliance +
+ + {isUpdating ? __("Uploading...") : __("Change logo")} + +
+ ) + : ( + + )} +
+
+ +

+ {__("This logo will be used when dark mode is enabled.")} +

+ + {currentDarkLogoUrl + ? ( +
+
+ {__("Compliance +
+ + {isUpdating ? __("Uploading...") : __("Change dark logo")} + +
+ ) + : ( + + )} +
+
+
- -
-
- -

- {__("This logo will be displayed on your public compliance page.")} -

- - {currentLogoUrl - ? ( -
-
- {__("Compliance -
- - {isUpdating ? __("Uploading...") : __("Change logo")} - -
- ) - : ( - - )} -
-
- -

- {__("This logo will be used when dark mode is enabled.")} -

- - {currentDarkLogoUrl - ? ( -
-
- {__("Compliance -
- - {isUpdating ? __("Uploading...") : __("Change dark logo")} - -
- ) - : ( - - )} -
+
+
+

{__("Frameworks")}

+

+ {__("Select which frameworks to display as badges on your compliance page")} +

- + +
+ +
); } diff --git a/apps/console/src/pages/organizations/compliance-page/overview/CompliancePageOverviewPage.tsx b/apps/console/src/pages/organizations/compliance-page/overview/CompliancePageOverviewPage.tsx index d63a55074..ffb449191 100644 --- a/apps/console/src/pages/organizations/compliance-page/overview/CompliancePageOverviewPage.tsx +++ b/apps/console/src/pages/organizations/compliance-page/overview/CompliancePageOverviewPage.tsx @@ -1,10 +1,8 @@ -import { useTranslate } from "@probo/i18n"; import { type PreloadedQuery, usePreloadedQuery } from "react-relay"; import { graphql } from "relay-runtime"; import type { CompliancePageOverviewPageQuery } from "#/__generated__/core/CompliancePageOverviewPageQuery.graphql"; -import { CompliancePageFrameworkList } from "./_components/CompliancePageFrameworkList"; import { CompliancePageNDASection } from "./_components/CompliancePageNDASection"; import { CompliancePageSlackSection } from "./_components/CompliancePageSlackSection"; import { CompliancePageStatusSection } from "./_components/CompliancePageStatusSection"; @@ -15,7 +13,6 @@ export const compliancePageOverviewPageQuery = graphql` ... on Organization { compliancePage: trustCenter { canGetNDA: permission(action: "core:trust-center:get-nda") - ...CompliancePageFrameworkList_compliancePageFragment } } ...CompliancePageStatusSectionFragment @@ -28,8 +25,6 @@ export const compliancePageOverviewPageQuery = graphql` export function CompliancePageOverviewPage(props: { queryRef: PreloadedQuery }) { const { queryRef } = props; - const { __ } = useTranslate(); - const { organization } = usePreloadedQuery( compliancePageOverviewPageQuery, queryRef, @@ -44,18 +39,6 @@ export function CompliancePageOverviewPage(props: { queryRef: PreloadedQuery - - {organization.compliancePage && ( -
-
-

{__("Frameworks")}

-

- {__("Select which frameworks to display as badges on your compliance page")} -

-
- -
- )}
); } diff --git a/apps/console/src/pages/organizations/compliance-page/overview/_components/CompliancePageExternalUrlsSection.tsx b/apps/console/src/pages/organizations/compliance-page/overview/_components/CompliancePageExternalUrlsSection.tsx new file mode 100644 index 000000000..865a85309 --- /dev/null +++ b/apps/console/src/pages/organizations/compliance-page/overview/_components/CompliancePageExternalUrlsSection.tsx @@ -0,0 +1,453 @@ +import { detectSocialName, safeOpenUrl } from "@probo/helpers"; +import { useTranslate } from "@probo/i18n"; +import { + Button, + Dialog, + DialogContent, + DialogFooter, + Field, + IconArrowLink, + IconPencil, + IconPlusLarge, + IconTrashCan, + SocialIcon, + Spinner, + Table, + Tbody, + Td, + Th, + Thead, + Tr, + useDialogRef, +} from "@probo/ui"; +import { forwardRef, useCallback, useImperativeHandle, useRef, useState, useTransition } from "react"; +import { useRefetchableFragment } from "react-relay"; +import { ConnectionHandler, graphql } from "relay-runtime"; +import { z } from "zod"; + +import type { CompliancePageExternalUrlsSection_createMutation } from "#/__generated__/core/CompliancePageExternalUrlsSection_createMutation.graphql"; +import type { CompliancePageExternalUrlsSection_deleteMutation } from "#/__generated__/core/CompliancePageExternalUrlsSection_deleteMutation.graphql"; +import type { CompliancePageExternalUrlsSection_trustCenterFragment$key } from "#/__generated__/core/CompliancePageExternalUrlsSection_trustCenterFragment.graphql"; +import type { CompliancePageExternalUrlsSection_trustCenterRefetchQuery } from "#/__generated__/core/CompliancePageExternalUrlsSection_trustCenterRefetchQuery.graphql"; +import type { CompliancePageExternalUrlsSection_updateMutation } from "#/__generated__/core/CompliancePageExternalUrlsSection_updateMutation.graphql"; +import { useFormWithSchema } from "#/hooks/useFormWithSchema"; +import { useMutationWithToasts } from "#/hooks/useMutationWithToasts"; + +const trustCenterFragment = graphql` + fragment CompliancePageExternalUrlsSection_trustCenterFragment on TrustCenter + @refetchable(queryName: "CompliancePageExternalUrlsSection_trustCenterRefetchQuery") + @argumentDefinitions( + first: { type: Int, defaultValue: 100 } + after: { type: CursorKey, defaultValue: null } + order: { type: ComplianceExternalURLOrder, defaultValue: { field: RANK, direction: ASC } } + ) { + id + canUpdate: permission(action: "core:trust-center:update") + externalUrls(first: $first, after: $after, orderBy: $order) + @connection(key: "CompliancePageExternalUrlsSection_externalUrls", filters: ["orderBy"]) { + __id + edges { + node { + id + name + url + rank + } + } + } + } +`; + +const createMutation = graphql` + mutation CompliancePageExternalUrlsSection_createMutation($input: CreateComplianceExternalURLInput!) { + createComplianceExternalURL(input: $input) { + complianceExternalUrlEdge { + node { + id + name + url + rank + } + } + } + } +`; + +const updateMutation = graphql` + mutation CompliancePageExternalUrlsSection_updateMutation($input: UpdateComplianceExternalURLInput!) { + updateComplianceExternalURL(input: $input) { + complianceExternalUrl { + id + name + url + rank + } + } + } +`; + +const deleteMutation = graphql` + mutation CompliancePageExternalUrlsSection_deleteMutation($input: DeleteComplianceExternalURLInput!) { + deleteComplianceExternalURL(input: $input) { + deletedComplianceExternalUrlId + } + } +`; + +const urlSchema = z.object({ + name: z.string().min(1, "Name is required"), + url: z.string().url("Please enter a valid URL"), +}); + +type UrlFormData = z.infer; + +type UrlNode = { id: string; name: string; url: string; rank: number }; + +type ExternalUrlDialogRef = { + openCreate: (trustCenterId: string, connectionId: string) => void; + openEdit: (node: UrlNode) => void; +}; + +const ExternalUrlDialog = forwardRef( + function ExternalUrlDialog(_, ref) { + const { __ } = useTranslate(); + const dialogRef = useDialogRef(); + const [mode, setMode] = useState<"create" | "edit">("create"); + const [trustCenterId, setTrustCenterId] = useState(""); + const [connectionId, setConnectionId] = useState(""); + const [editNode, setEditNode] = useState(null); + + const [create, isCreating] = useMutationWithToasts( + createMutation, + { successMessage: __("Link added successfully."), errorMessage: __("Failed to add link.") }, + ); + + const [update, isUpdating] = useMutationWithToasts( + updateMutation, + { successMessage: __("Link updated successfully."), errorMessage: __("Failed to update link.") }, + ); + + const { register, handleSubmit, formState: { errors }, reset, setValue, watch } = useFormWithSchema(urlSchema, { + defaultValues: { name: "", url: "" }, + }); + + const [nameAutoDetected, setNameAutoDetected] = useState(false); + + const handleUrlChange = (e: React.ChangeEvent) => { + const url = e.target.value; + const detected = detectSocialName(url); + if (detected && (nameAutoDetected || watch("name") === "")) { + setValue("name", detected, { shouldValidate: true }); + setNameAutoDetected(true); + } else if (!detected && nameAutoDetected) { + setValue("name", "", { shouldValidate: false }); + setNameAutoDetected(false); + } + }; + + useImperativeHandle(ref, () => ({ + openCreate: (tId, cId) => { + setMode("create"); + setTrustCenterId(tId); + setConnectionId(cId); + setEditNode(null); + setNameAutoDetected(false); + reset({ name: "", url: "" }); + dialogRef.current?.open(); + }, + openEdit: (node) => { + setMode("edit"); + setEditNode(node); + setNameAutoDetected(false); + reset({ name: node.name, url: node.url }); + dialogRef.current?.open(); + }, + })); + + const onSubmit = async (data: UrlFormData) => { + if (mode === "create") { + await create({ + variables: { + input: { trustCenterId, name: data.name, url: data.url }, + }, + updater: (store) => { + const payload = store.getRootField("createComplianceExternalURL"); + const edge = payload?.getLinkedRecord("complianceExternalUrlEdge"); + if (!edge) return; + const connection = store.get(connectionId); + if (!connection) return; + ConnectionHandler.insertEdgeAfter(connection, edge); + }, + onCompleted: (_, errs) => { + if (!errs?.length) { + reset(); + dialogRef.current?.close(); + } + }, + }); + } else if (editNode) { + await update({ + variables: { input: { id: editNode.id, name: data.name, url: data.url } }, + onCompleted: (_, errs) => { + if (!errs?.length) { + reset(); + dialogRef.current?.close(); + } + }, + }); + } + }; + + const isSubmitting = isCreating || isUpdating; + const title = mode === "create" ? __("Add link") : __("Edit link"); + + return ( + reset()}> +
void handleSubmit(onSubmit)(e)}> + + + + + + + +
+
+ ); + }, +); + +function ExternalUrlRow(props: { + node: UrlNode; + canEdit: boolean; + connectionId: string; + isDragging: boolean; + isDropTarget: boolean; + onDragStart: () => void; + onDragOver: (e: React.DragEvent) => void; + onDrop: () => void; + onDragEnd: () => void; + onEdit: (node: UrlNode) => void; +}) { + const { node, canEdit, connectionId, isDragging, isDropTarget, onDragStart, onDragOver, onDrop, onDragEnd, onEdit } = props; + const { __ } = useTranslate(); + const [isMouseDown, setIsMouseDown] = useState(false); + + const [deleteUrl] = useMutationWithToasts( + deleteMutation, + { successMessage: __("Link removed."), errorMessage: __("Failed to remove link.") }, + ); + + const handleDelete = () => { + void deleteUrl({ + variables: { input: { id: node.id } }, + updater: (store) => { + const connection = store.get(connectionId); + if (!connection) return; + ConnectionHandler.deleteNode(connection, node.id); + }, + }); + }; + + const className = [ + isDragging && "opacity-50 cursor-grabbing", + !isDragging && !isMouseDown && "cursor-grab", + !isDragging && isMouseDown && "cursor-grabbing", + isDropTarget && "!bg-primary-50 border-y-2 border-primary-500", + ] + .filter(Boolean) + .join(" "); + + return ( + setIsMouseDown(true) : undefined} + onMouseUp={canEdit ? () => setIsMouseDown(false) : undefined} + onMouseLeave={canEdit ? () => setIsMouseDown(false) : undefined} + className={className} + > + +
+ + {node.name} +
+ + + {node.url} + + +
+
+ + + ); +} + +export function CompliancePageExternalUrlsSection(props: { + trustCenterRef: CompliancePageExternalUrlsSection_trustCenterFragment$key; +}) { + const { __ } = useTranslate(); + const [, startTransition] = useTransition(); + const dialogRef = useRef(null); + + const [trustCenter, refetch] = useRefetchableFragment< + CompliancePageExternalUrlsSection_trustCenterRefetchQuery, + CompliancePageExternalUrlsSection_trustCenterFragment$key + >(trustCenterFragment, props.trustCenterRef); + + const [draggedIndex, setDraggedIndex] = useState(null); + const [dragOverIndex, setDragOverIndex] = useState(null); + + const [updateRank] = useMutationWithToasts( + updateMutation, + { successMessage: __("Order updated."), errorMessage: __("Failed to update order.") }, + ); + + const edges = trustCenter.externalUrls.edges; + const canEdit = trustCenter.canUpdate; + + const connectionId = trustCenter.externalUrls.__id; + + const handleCreate = () => { + dialogRef.current?.openCreate(trustCenter.id, connectionId); + }; + + const handleEdit = (node: UrlNode) => { + dialogRef.current?.openEdit(node); + }; + + const handleDragOver = (e: React.DragEvent, index: number) => { + e.preventDefault(); + if (draggedIndex !== index) setDragOverIndex(index); + }; + + const handleDrop = useCallback( + async (targetIndex: number) => { + if (draggedIndex === null || draggedIndex === targetIndex) { + setDraggedIndex(null); + setDragOverIndex(null); + return; + } + + const draggedEdge = edges[draggedIndex]; + const targetRank = edges[targetIndex].node.rank; + const draggedId = draggedEdge.node.id; + + await updateRank({ + variables: { input: { id: draggedId, name: draggedEdge.node.name, url: draggedEdge.node.url, rank: targetRank } }, + updater: (store) => { + const connection = store.get(connectionId); + if (!connection) return; + const storeEdges = connection.getLinkedRecords("edges"); + if (!storeEdges) return; + const fromIdx = storeEdges.findIndex(e => e.getLinkedRecord("node")?.getDataID() === draggedId); + const toIdx = storeEdges.findIndex(e => e.getLinkedRecord("node")?.getDataID() === edges[targetIndex].node.id); + if (fromIdx === -1 || toIdx === -1) return; + const reordered = [...storeEdges]; + const [moved] = reordered.splice(fromIdx, 1); + reordered.splice(toIdx, 0, moved); + connection.setLinkedRecords(reordered, "edges"); + }, + onCompleted: (_, errors) => { + startTransition(() => { + refetch({}, { fetchPolicy: errors?.length ? "network-only" : "store-and-network" }); + }); + }, + }); + + setDraggedIndex(null); + setDragOverIndex(null); + }, + [draggedIndex, edges, connectionId, updateRank, refetch, startTransition], + ); + + return ( +
+
+
+

{__("Custom links")}

+

+ {__("Add external URLs to display on your compliance page")} +

+
+ {canEdit && ( + + )} +
+ + + + + + + + + + {edges.length === 0 && ( + + + + )} + {edges.map(({ node }, index) => ( + setDraggedIndex(index)} + onDragOver={e => handleDragOver(e, index)} + onDrop={() => void handleDrop(index)} + onDragEnd={() => { + setDraggedIndex(null); + setDragOverIndex(null); + }} + onEdit={handleEdit} + /> + ))} + +
{__("Name")}{__("URL")} +
+ {__("No custom links yet")} +
+ + {edges.length > 1 && canEdit && ( +

+ {__("Drag and drop to change the displayed order")} +

+ )} + + +
+ ); +} diff --git a/apps/trust/src/components/OrganizationSidebar.tsx b/apps/trust/src/components/OrganizationSidebar.tsx index 47cf917ab..36f1491f1 100644 --- a/apps/trust/src/components/OrganizationSidebar.tsx +++ b/apps/trust/src/components/OrganizationSidebar.tsx @@ -1,4 +1,4 @@ -import { formatError } from "@probo/helpers"; +import { detectSocialName, externalLinkProps, formatError } from "@probo/helpers"; import { useSystemTheme } from "@probo/hooks"; import { useTranslate } from "@probo/i18n"; import { UnAuthenticatedError } from "@probo/relay"; @@ -8,6 +8,7 @@ import { IconBlock, IconLock, IconMedal, + SocialIcon, useToast, } from "@probo/ui"; import { type PropsWithChildren } from "react"; @@ -125,11 +126,7 @@ export function OrganizationSidebar({ {trustCenter.organization.websiteUrl && ( - + {new URL(trustCenter.organization.websiteUrl).host} @@ -150,6 +147,20 @@ export function OrganizationSidebar({ {trustCenter.organization.headquarterAddress} )} + {trustCenter.externalUrls.edges.length > 0 && ( + + )}
diff --git a/apps/trust/src/queries/TrustGraph.ts b/apps/trust/src/queries/TrustGraph.ts index eb6426dfb..376f1acc1 100644 --- a/apps/trust/src/queries/TrustGraph.ts +++ b/apps/trust/src/queries/TrustGraph.ts @@ -22,6 +22,15 @@ export const currentTrustGraphQuery = graphql` email headquarterAddress } + externalUrls(first: 20) { + edges { + node { + id + name + url + } + } + } ...OverviewPageFragment vendorInfo: vendors(first: 0) { totalCount diff --git a/apps/trust/src/queries/__generated__/TrustGraphCurrentQuery.graphql.ts b/apps/trust/src/queries/__generated__/TrustGraphCurrentQuery.graphql.ts index cd852af52..1f584cb58 100644 --- a/apps/trust/src/queries/__generated__/TrustGraphCurrentQuery.graphql.ts +++ b/apps/trust/src/queries/__generated__/TrustGraphCurrentQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<4eef287e3e3152affa1b16189a504c36>> + * @generated SignedSource<<74757bf9a32552f6353eb888c9f663cd>> * @lightSyntaxTransform * @nogrep */ @@ -33,6 +33,15 @@ export type TrustGraphCurrentQuery$data = { }>; }; readonly darkLogoFileUrl: string | null | undefined; + readonly externalUrls: { + readonly edges: ReadonlyArray<{ + readonly node: { + readonly id: string; + readonly name: string; + readonly url: string; + }; + }>; + }; readonly id: string; readonly logoFileUrl: string | null | undefined; readonly nonDisclosureAgreement: { @@ -147,6 +156,54 @@ v11 = { "storageKey": null }, v12 = { + "alias": null, + "args": [ + { + "kind": "Literal", + "name": "first", + "value": 20 + } + ], + "concreteType": "ComplianceExternalURLConnection", + "kind": "LinkedField", + "name": "externalUrls", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceExternalURLEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "ComplianceExternalURL", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v0/*: any*/), + (v7/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "url", + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": "externalUrls(first:20)" +}, +v13 = { "alias": "vendorInfo", "args": [ { @@ -170,28 +227,28 @@ v12 = { ], "storageKey": "vendors(first:0)" }, -v13 = [ +v14 = [ { "kind": "Literal", "name": "first", "value": 50 } ], -v14 = [ +v15 = [ { "kind": "Literal", "name": "first", "value": 5 } ], -v15 = { +v16 = { "alias": null, "args": null, "kind": "ScalarField", "name": "isUserAuthorized", "storageKey": null }, -v16 = { +v17 = { "alias": null, "args": null, "concreteType": "DocumentAccess", @@ -204,7 +261,7 @@ v16 = { ], "storageKey": null }, -v17 = { +v18 = { "alias": null, "args": null, "concreteType": "Framework", @@ -293,15 +350,16 @@ return { ], "storageKey": null }, + (v12/*: any*/), { "args": null, "kind": "FragmentSpread", "name": "OverviewPageFragment" }, - (v12/*: any*/), + (v13/*: any*/), { "alias": null, - "args": (v13/*: any*/), + "args": (v14/*: any*/), "concreteType": "AuditConnection", "kind": "LinkedField", "name": "audits", @@ -340,7 +398,7 @@ return { }, { "alias": null, - "args": (v13/*: any*/), + "args": (v14/*: any*/), "concreteType": "ComplianceFrameworkConnection", "kind": "LinkedField", "name": "complianceFrameworks", @@ -458,6 +516,7 @@ return { ], "storageKey": null }, + (v12/*: any*/), { "alias": null, "args": [ @@ -559,7 +618,7 @@ return { }, { "alias": null, - "args": (v14/*: any*/), + "args": (v15/*: any*/), "concreteType": "DocumentConnection", "kind": "LinkedField", "name": "documents", @@ -589,8 +648,8 @@ return { "name": "title", "storageKey": null }, - (v15/*: any*/), (v16/*: any*/), + (v17/*: any*/), { "alias": null, "args": null, @@ -609,7 +668,7 @@ return { }, { "alias": null, - "args": (v14/*: any*/), + "args": (v15/*: any*/), "concreteType": "TrustCenterFileConnection", "kind": "LinkedField", "name": "trustCenterFiles", @@ -640,8 +699,8 @@ return { "storageKey": null }, (v7/*: any*/), - (v15/*: any*/), - (v16/*: any*/) + (v16/*: any*/), + (v17/*: any*/) ], "storageKey": null } @@ -651,10 +710,10 @@ return { ], "storageKey": "trustCenterFiles(first:5)" }, - (v12/*: any*/), + (v13/*: any*/), { "alias": null, - "args": (v13/*: any*/), + "args": (v14/*: any*/), "concreteType": "AuditConnection", "kind": "LinkedField", "name": "audits", @@ -694,12 +753,12 @@ return { "name": "filename", "storageKey": null }, - (v15/*: any*/), - (v16/*: any*/) + (v16/*: any*/), + (v17/*: any*/) ], "storageKey": null }, - (v17/*: any*/) + (v18/*: any*/) ], "storageKey": null } @@ -711,7 +770,7 @@ return { }, { "alias": null, - "args": (v13/*: any*/), + "args": (v14/*: any*/), "concreteType": "ComplianceFrameworkConnection", "kind": "LinkedField", "name": "complianceFrameworks", @@ -734,7 +793,7 @@ return { "plural": false, "selections": [ (v0/*: any*/), - (v17/*: any*/) + (v18/*: any*/) ], "storageKey": null } @@ -750,16 +809,16 @@ return { ] }, "params": { - "cacheID": "e64b984bdcf5a5fb2f19e69c6205ba9a", + "cacheID": "96e75937f385e17b760440e001cefc47", "id": null, "metadata": {}, "name": "TrustGraphCurrentQuery", "operationKind": "query", - "text": "query TrustGraphCurrentQuery {\n currentTrustCenter {\n id\n slug\n logoFileUrl\n darkLogoFileUrl\n nonDisclosureAgreement {\n fileName\n fileUrl\n viewerSignature {\n status\n id\n }\n }\n organization {\n name\n description\n websiteUrl\n email\n headquarterAddress\n id\n }\n ...OverviewPageFragment\n vendorInfo: vendors(first: 0) {\n totalCount\n }\n audits(first: 50) {\n edges {\n node {\n id\n ...AuditRowFragment\n }\n }\n }\n complianceFrameworks(first: 50) {\n edges {\n node {\n id\n framework {\n ...FrameworkBadgeFragment\n id\n }\n }\n }\n }\n }\n}\n\nfragment AuditRowFragment on Audit {\n name\n report {\n id\n filename\n isUserAuthorized\n access {\n id\n status\n }\n }\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n}\n\nfragment DocumentRowFragment on Document {\n id\n title\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment FrameworkBadgeFragment on Framework {\n id\n name\n lightLogoURL\n darkLogoURL\n}\n\nfragment OverviewPageFragment on TrustCenter {\n references(first: 14) {\n edges {\n node {\n id\n name\n logoUrl\n websiteUrl\n }\n }\n }\n vendors(first: 3) {\n edges {\n node {\n id\n countries\n ...VendorRowFragment\n }\n }\n }\n documents(first: 5) {\n edges {\n node {\n id\n ...DocumentRowFragment\n documentType\n }\n }\n }\n trustCenterFiles(first: 5) {\n edges {\n node {\n id\n category\n ...TrustCenterFileRowFragment\n }\n }\n }\n}\n\nfragment TrustCenterFileRowFragment on TrustCenterFile {\n id\n name\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment VendorRowFragment on Vendor {\n name\n description\n websiteUrl\n countries\n}\n" + "text": "query TrustGraphCurrentQuery {\n currentTrustCenter {\n id\n slug\n logoFileUrl\n darkLogoFileUrl\n nonDisclosureAgreement {\n fileName\n fileUrl\n viewerSignature {\n status\n id\n }\n }\n organization {\n name\n description\n websiteUrl\n email\n headquarterAddress\n id\n }\n externalUrls(first: 20) {\n edges {\n node {\n id\n name\n url\n }\n }\n }\n ...OverviewPageFragment\n vendorInfo: vendors(first: 0) {\n totalCount\n }\n audits(first: 50) {\n edges {\n node {\n id\n ...AuditRowFragment\n }\n }\n }\n complianceFrameworks(first: 50) {\n edges {\n node {\n id\n framework {\n ...FrameworkBadgeFragment\n id\n }\n }\n }\n }\n }\n}\n\nfragment AuditRowFragment on Audit {\n name\n report {\n id\n filename\n isUserAuthorized\n access {\n id\n status\n }\n }\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n}\n\nfragment DocumentRowFragment on Document {\n id\n title\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment FrameworkBadgeFragment on Framework {\n id\n name\n lightLogoURL\n darkLogoURL\n}\n\nfragment OverviewPageFragment on TrustCenter {\n references(first: 14) {\n edges {\n node {\n id\n name\n logoUrl\n websiteUrl\n }\n }\n }\n vendors(first: 3) {\n edges {\n node {\n id\n countries\n ...VendorRowFragment\n }\n }\n }\n documents(first: 5) {\n edges {\n node {\n id\n ...DocumentRowFragment\n documentType\n }\n }\n }\n trustCenterFiles(first: 5) {\n edges {\n node {\n id\n category\n ...TrustCenterFileRowFragment\n }\n }\n }\n}\n\nfragment TrustCenterFileRowFragment on TrustCenterFile {\n id\n name\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment VendorRowFragment on Vendor {\n name\n description\n websiteUrl\n countries\n}\n" } }; })(); -(node as any).hash = "d1ce7e38b42fad48e9f38bf00bb34d56"; +(node as any).hash = "ca6f04fecf9bce92407f33e8c0e4bd03"; export default node; diff --git a/packages/helpers/src/dom.ts b/packages/helpers/src/dom.ts index 263e82c6e..7f52733a7 100644 --- a/packages/helpers/src/dom.ts +++ b/packages/helpers/src/dom.ts @@ -21,6 +21,25 @@ export function downloadFile(url: string | undefined | null, filename: string) { document.body.removeChild(link); } +export function externalLinkProps(url: string): { + href: string | undefined; + target: "_blank"; + rel: "noopener noreferrer"; +} { + let safeHref: string | undefined; + try { + const parsed = new URL(url); + if (parsed.protocol === "http:" || parsed.protocol === "https:") { + safeHref = url; + } else { + console.error("Invalid URL protocol. Only HTTP and HTTPS URLs are allowed:", url); + } + } catch (error) { + console.error("Invalid URL format:", url, error); + } + return { href: safeHref, target: "_blank", rel: "noopener noreferrer" }; +} + export function safeOpenUrl(url: string) { try { const parsedUrl = new URL(url); diff --git a/packages/helpers/src/index.ts b/packages/helpers/src/index.ts index fdd34355c..f8001420e 100644 --- a/packages/helpers/src/index.ts +++ b/packages/helpers/src/index.ts @@ -13,6 +13,7 @@ export { export { withViewTransition, downloadFile, + externalLinkProps, safeOpenUrl, focusSiblingElement, } from "./dom"; @@ -78,6 +79,7 @@ export { parseDate, } from "./date"; export { getTrustCenterUrl } from "./trustCenter"; +export { detectSocialName } from "./socialUrl"; export { formatError, type GraphQLError } from "./error"; export { Role, roles, getAssignableRoles } from "./roles"; export { diff --git a/packages/helpers/src/socialUrl.ts b/packages/helpers/src/socialUrl.ts new file mode 100644 index 000000000..82a529f3d --- /dev/null +++ b/packages/helpers/src/socialUrl.ts @@ -0,0 +1,12 @@ +const SOCIAL_PATTERNS: Array<[RegExp, string]> = [ + [/linkedin\.com/i, "LinkedIn"], + [/(?:twitter|x)\.com/i, "X"], + [/facebook\.com/i, "Facebook"], +]; + +export function detectSocialName(url: string): string | null { + for (const [pattern, name] of SOCIAL_PATTERNS) { + if (pattern.test(url)) return name; + } + return null; +} diff --git a/packages/ui/src/Atoms/Icons/IconBrandFacebook.tsx b/packages/ui/src/Atoms/Icons/IconBrandFacebook.tsx new file mode 100644 index 000000000..810b3e4c6 --- /dev/null +++ b/packages/ui/src/Atoms/Icons/IconBrandFacebook.tsx @@ -0,0 +1,14 @@ +// Facebook logo — trademark of Meta Platforms, Inc. +// Used here solely for brand identification (nominative fair use). +// SVG path from Simple Icons (https://simpleicons.org), CC0 license. +import type { IconProps } from "./type"; + +type Props = IconProps & { colored?: boolean }; + +export function IconBrandFacebook({ size = 24, className, colored = false }: Props) { + return ( + + + + ); +} diff --git a/packages/ui/src/Atoms/Icons/IconBrandLinkedin.tsx b/packages/ui/src/Atoms/Icons/IconBrandLinkedin.tsx new file mode 100644 index 000000000..9bbd56f77 --- /dev/null +++ b/packages/ui/src/Atoms/Icons/IconBrandLinkedin.tsx @@ -0,0 +1,14 @@ +// LinkedIn logo — trademark of LinkedIn Corporation. +// Used here solely for brand identification (nominative fair use). +// SVG path from Simple Icons (https://simpleicons.org), CC0 license. +import type { IconProps } from "./type"; + +type Props = IconProps & { colored?: boolean }; + +export function IconBrandLinkedin({ size = 24, className, colored = false }: Props) { + return ( + + + + ); +} diff --git a/packages/ui/src/Atoms/Icons/IconBrandX.tsx b/packages/ui/src/Atoms/Icons/IconBrandX.tsx new file mode 100644 index 000000000..d27ceb9df --- /dev/null +++ b/packages/ui/src/Atoms/Icons/IconBrandX.tsx @@ -0,0 +1,14 @@ +// X (formerly Twitter) logo — trademark of X Corp. +// Used here solely for brand identification (nominative fair use). +// SVG path from Simple Icons (https://simpleicons.org), CC0 license. +import type { IconProps } from "./type"; + +type Props = IconProps & { colored?: boolean }; + +export function IconBrandX({ size = 24, className, colored = false }: Props) { + return ( + + + + ); +} diff --git a/packages/ui/src/Atoms/Icons/IconGlobe.tsx b/packages/ui/src/Atoms/Icons/IconGlobe.tsx new file mode 100644 index 000000000..367028c6a --- /dev/null +++ b/packages/ui/src/Atoms/Icons/IconGlobe.tsx @@ -0,0 +1,12 @@ +// Globe icon from Lucide (https://lucide.dev), ISC license. +import type { IconProps } from "./type"; + +export function IconGlobe({ size = 24, className }: IconProps) { + return ( + + + + + + ); +} diff --git a/packages/ui/src/Atoms/Icons/SocialIcon.tsx b/packages/ui/src/Atoms/Icons/SocialIcon.tsx new file mode 100644 index 000000000..df6f968bd --- /dev/null +++ b/packages/ui/src/Atoms/Icons/SocialIcon.tsx @@ -0,0 +1,16 @@ +import { IconBrandFacebook } from "./IconBrandFacebook"; +import { IconBrandLinkedin } from "./IconBrandLinkedin"; +import { IconBrandX } from "./IconBrandX"; +import { IconGlobe } from "./IconGlobe"; +import type { IconProps } from "./type"; + +export type SocialIconProps = IconProps & { colored?: boolean }; + +export function SocialIcon({ socialName, ...props }: { socialName: string | null } & SocialIconProps) { + switch (socialName) { + case "LinkedIn": return ; + case "X": return ; + case "Facebook": return ; + default: return ; + } +} diff --git a/packages/ui/src/Atoms/Icons/index.tsx b/packages/ui/src/Atoms/Icons/index.tsx index 74789c649..9e65786c2 100644 --- a/packages/ui/src/Atoms/Icons/index.tsx +++ b/packages/ui/src/Atoms/Icons/index.tsx @@ -85,3 +85,9 @@ export { IconPageCross } from "./IconPageCross"; export { IconRotateCw } from "./IconRotateCw"; export { IconPin } from "./IconPin"; export { IconMinusLarge } from "./IconMinusLarge"; +export { IconBrandFacebook } from "./IconBrandFacebook"; +export { IconBrandLinkedin } from "./IconBrandLinkedin"; +export { IconBrandX } from "./IconBrandX"; +export { IconGlobe } from "./IconGlobe"; +export { SocialIcon } from "./SocialIcon"; +export type { SocialIconProps } from "./SocialIcon"; diff --git a/pkg/coredata/compliance_external_url.go b/pkg/coredata/compliance_external_url.go new file mode 100644 index 000000000..8efa3d4bf --- /dev/null +++ b/pkg/coredata/compliance_external_url.go @@ -0,0 +1,303 @@ +package coredata + +import ( + "context" + "errors" + "fmt" + "maps" + "time" + + "github.com/jackc/pgx/v5" + "go.gearno.de/kit/pg" + "go.probo.inc/probo/pkg/gid" + "go.probo.inc/probo/pkg/page" +) + +type ( + ComplianceExternalURL struct { + ID gid.GID `db:"id"` + OrganizationID gid.GID `db:"organization_id"` + TrustCenterID gid.GID `db:"trust_center_id"` + Name string `db:"name"` + URL string `db:"url"` + Rank int `db:"rank"` + CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` + } + + ComplianceExternalURLs []*ComplianceExternalURL +) + +func (c ComplianceExternalURL) CursorKey(orderBy ComplianceExternalURLOrderField) page.CursorKey { + switch orderBy { + case ComplianceExternalURLOrderFieldCreatedAt: + return page.NewCursorKey(c.ID, c.CreatedAt) + case ComplianceExternalURLOrderFieldRank: + return page.NewCursorKey(c.ID, c.Rank) + } + panic(fmt.Sprintf("unsupported order by: %s", orderBy)) +} + +func (c *ComplianceExternalURL) AuthorizationAttributes(ctx context.Context, conn pg.Conn) (map[string]string, error) { + q := `SELECT organization_id FROM compliance_external_urls WHERE id = $1 LIMIT 1;` + + var organizationID gid.GID + if err := conn.QueryRow(ctx, q, c.ID).Scan(&organizationID); err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return nil, ErrResourceNotFound + } + return nil, fmt.Errorf("cannot query compliance external URL authorization attributes: %w", err) + } + + return map[string]string{"organization_id": organizationID.String()}, nil +} + +func (c *ComplianceExternalURL) LoadByID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + id gid.GID, +) error { + q := ` +SELECT + id, + organization_id, + trust_center_id, + name, + url, + rank, + created_at, + updated_at +FROM + compliance_external_urls +WHERE + %s + AND id = @id +LIMIT 1; +` + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{"id": id} + maps.Copy(args, scope.SQLArguments()) + + rows, err := conn.Query(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot query compliance_external_urls: %w", err) + } + + result, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[ComplianceExternalURL]) + if err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return ErrResourceNotFound + } + return fmt.Errorf("cannot collect compliance external URL: %w", err) + } + + *c = result + + return nil +} + +func (c *ComplianceExternalURL) Insert( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +INSERT INTO + compliance_external_urls ( + id, + tenant_id, + organization_id, + trust_center_id, + name, + url, + rank, + created_at, + updated_at + ) +VALUES ( + @id, + @tenant_id, + @organization_id, + @trust_center_id, + @name, + @url, + (SELECT COALESCE(MAX(rank), 0) + 1 FROM compliance_external_urls WHERE trust_center_id = @trust_center_id), + @created_at, + @updated_at +) +RETURNING rank; +` + + args := pgx.StrictNamedArgs{ + "id": c.ID, + "tenant_id": scope.GetTenantID(), + "organization_id": c.OrganizationID, + "trust_center_id": c.TrustCenterID, + "name": c.Name, + "url": c.URL, + "created_at": c.CreatedAt, + "updated_at": c.UpdatedAt, + } + + if err := conn.QueryRow(ctx, q, args).Scan(&c.Rank); err != nil { + return fmt.Errorf("cannot insert compliance external URL: %w", err) + } + + return nil +} + +func (c *ComplianceExternalURL) Update( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +UPDATE compliance_external_urls +SET + name = @name, + url = @url, + updated_at = @updated_at +WHERE + %s + AND id = @id; +` + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{ + "id": c.ID, + "name": c.Name, + "url": c.URL, + "updated_at": c.UpdatedAt, + } + maps.Copy(args, scope.SQLArguments()) + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot update compliance external URL: %w", err) + } + + return nil +} + +func (c *ComplianceExternalURL) UpdateRank( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +WITH old AS ( + SELECT + rank AS old_rank + FROM compliance_external_urls + WHERE %s AND id = @id AND trust_center_id = @trust_center_id +) + +UPDATE compliance_external_urls +SET + rank = CASE + WHEN id = @id THEN @new_rank + ELSE rank + CASE + WHEN @new_rank < old.old_rank THEN 1 + WHEN @new_rank > old.old_rank THEN -1 + END + END, + updated_at = @updated_at +FROM old +WHERE %s + AND trust_center_id = @trust_center_id + AND ( + id = @id + OR (rank BETWEEN LEAST(old.old_rank, @new_rank) AND GREATEST(old.old_rank, @new_rank)) + ); +` + + scopeFragment := scope.SQLFragment() + q = fmt.Sprintf(q, scopeFragment, scopeFragment) + + args := pgx.StrictNamedArgs{ + "id": c.ID, + "new_rank": c.Rank, + "trust_center_id": c.TrustCenterID, + "updated_at": c.UpdatedAt, + } + maps.Copy(args, scope.SQLArguments()) + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot update compliance external URL rank: %w", err) + } + + return nil +} + +func (c *ComplianceExternalURL) Delete( + ctx context.Context, + conn pg.Conn, + scope Scoper, +) error { + q := ` +DELETE FROM + compliance_external_urls +WHERE + %s + AND id = @id; +` + q = fmt.Sprintf(q, scope.SQLFragment()) + + args := pgx.StrictNamedArgs{"id": c.ID} + maps.Copy(args, scope.SQLArguments()) + + _, err := conn.Exec(ctx, q, args) + if err != nil { + return fmt.Errorf("cannot delete compliance external URL: %w", err) + } + + return nil +} + +func (c *ComplianceExternalURLs) LoadByTrustCenterID( + ctx context.Context, + conn pg.Conn, + scope Scoper, + trustCenterID gid.GID, + cursor *page.Cursor[ComplianceExternalURLOrderField], +) error { + q := ` +SELECT + id, + organization_id, + trust_center_id, + name, + url, + rank, + created_at, + updated_at +FROM + compliance_external_urls +WHERE + %s + AND trust_center_id = @trust_center_id + AND %s +` + q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment()) + + args := pgx.NamedArgs{"trust_center_id": trustCenterID} + 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 compliance_external_urls: %w", err) + } + + results, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[ComplianceExternalURL]) + if err != nil { + return fmt.Errorf("cannot collect compliance external URLs: %w", err) + } + + *c = results + + return nil +} diff --git a/pkg/coredata/compliance_external_url_order_field.go b/pkg/coredata/compliance_external_url_order_field.go new file mode 100644 index 000000000..f996449b2 --- /dev/null +++ b/pkg/coredata/compliance_external_url_order_field.go @@ -0,0 +1,34 @@ +package coredata + +type ( + ComplianceExternalURLOrderField string +) + +const ( + ComplianceExternalURLOrderFieldCreatedAt ComplianceExternalURLOrderField = "CREATED_AT" + ComplianceExternalURLOrderFieldRank ComplianceExternalURLOrderField = "RANK" +) + +func (p ComplianceExternalURLOrderField) Column() string { + switch p { + case ComplianceExternalURLOrderFieldCreatedAt: + return "created_at" + case ComplianceExternalURLOrderFieldRank: + return "rank" + default: + return string(p) + } +} + +func (p ComplianceExternalURLOrderField) String() string { + return string(p) +} + +func (p ComplianceExternalURLOrderField) MarshalText() ([]byte, error) { + return []byte(p.String()), nil +} + +func (p *ComplianceExternalURLOrderField) UnmarshalText(text []byte) error { + *p = ComplianceExternalURLOrderField(text) + return nil +} diff --git a/pkg/coredata/entity_type_reg.go b/pkg/coredata/entity_type_reg.go index f163f6f7b..4a5819b5c 100644 --- a/pkg/coredata/entity_type_reg.go +++ b/pkg/coredata/entity_type_reg.go @@ -86,6 +86,7 @@ const ( ElectronicSignatureEventEntityType uint16 = 60 EmailAttachmentEntityType uint16 = 61 ComplianceFrameworkEntityType uint16 = 62 + ComplianceExternalURLEntityType uint16 = 63 ) func NewEntityFromID(id gid.GID) (any, bool) { @@ -212,6 +213,8 @@ func NewEntityFromID(id gid.GID) (any, bool) { return &EmailAttachment{ID: id}, true case ComplianceFrameworkEntityType: return &ComplianceFramework{ID: id}, true + case ComplianceExternalURLEntityType: + return &ComplianceExternalURL{ID: id}, true default: return nil, false } diff --git a/pkg/coredata/migrations/20260306T200000Z.sql b/pkg/coredata/migrations/20260306T200000Z.sql new file mode 100644 index 000000000..5442119f4 --- /dev/null +++ b/pkg/coredata/migrations/20260306T200000Z.sql @@ -0,0 +1,16 @@ +CREATE TABLE compliance_external_urls ( + id TEXT NOT NULL PRIMARY KEY, + tenant_id TEXT NOT NULL, + organization_id TEXT NOT NULL REFERENCES organizations(id) ON UPDATE CASCADE ON DELETE CASCADE, + trust_center_id TEXT NOT NULL REFERENCES trust_centers(id) ON UPDATE CASCADE ON DELETE CASCADE, + name TEXT NOT NULL, + url TEXT NOT NULL, + rank INTEGER NOT NULL, + created_at TIMESTAMP WITH TIME ZONE NOT NULL, + updated_at TIMESTAMP WITH TIME ZONE NOT NULL +); + +ALTER TABLE compliance_external_urls +ADD CONSTRAINT compliance_external_urls_trust_center_id_rank_key + UNIQUE (trust_center_id, rank) + DEFERRABLE INITIALLY DEFERRED; diff --git a/pkg/probo/actions.go b/pkg/probo/actions.go index bf119ea60..3d6c2a198 100644 --- a/pkg/probo/actions.go +++ b/pkg/probo/actions.go @@ -53,6 +53,12 @@ const ( ActionComplianceFrameworkDelete = "core:compliance-framework:delete" ActionComplianceFrameworkUpdateRank = "core:compliance-framework:update-rank" + // ComplianceExternalURL actions + ActionComplianceExternalURLList = "core:compliance-external-url:list" + ActionComplianceExternalURLCreate = "core:compliance-external-url:create" + ActionComplianceExternalURLUpdate = "core:compliance-external-url:update" + ActionComplianceExternalURLDelete = "core:compliance-external-url:delete" + // TrustCenterFile actions ActionTrustCenterFileGet = "core:trust-center-file:get" ActionTrustCenterFileList = "core:trust-center-file:list" diff --git a/pkg/probo/compliance_external_url_service.go b/pkg/probo/compliance_external_url_service.go new file mode 100644 index 000000000..5525aa777 --- /dev/null +++ b/pkg/probo/compliance_external_url_service.go @@ -0,0 +1,195 @@ +package probo + +import ( + "context" + "fmt" + "time" + + "go.gearno.de/kit/pg" + "go.probo.inc/probo/pkg/coredata" + "go.probo.inc/probo/pkg/gid" + "go.probo.inc/probo/pkg/page" + "go.probo.inc/probo/pkg/validator" +) + +type ( + ComplianceExternalURLService struct { + svc *TenantService + } + + CreateComplianceExternalURLRequest struct { + TrustCenterID gid.GID + Name string + URL string + } + + UpdateComplianceExternalURLRequest struct { + ID gid.GID + Name string + URL string + Rank *int + } + + DeleteComplianceExternalURLRequest struct { + ID gid.GID + } +) + +func (r *CreateComplianceExternalURLRequest) Validate() error { + v := validator.New() + v.Check(r.TrustCenterID, "trust_center_id", validator.Required(), validator.GID(coredata.TrustCenterEntityType)) + v.Check(r.URL, "url", validator.Required(), validator.URL()) + return v.Error() +} + +func (r *UpdateComplianceExternalURLRequest) Validate() error { + v := validator.New() + v.Check(r.ID, "id", validator.Required(), validator.GID(coredata.ComplianceExternalURLEntityType)) + v.Check(r.URL, "url", validator.Required(), validator.URL()) + v.Check(r.Rank, "rank", validator.Min(1)) + return v.Error() +} + +func (r *DeleteComplianceExternalURLRequest) Validate() error { + v := validator.New() + v.Check(r.ID, "id", validator.Required(), validator.GID(coredata.ComplianceExternalURLEntityType)) + return v.Error() +} + +func (s ComplianceExternalURLService) List( + ctx context.Context, + trustCenterID gid.GID, + cursor *page.Cursor[coredata.ComplianceExternalURLOrderField], +) (*page.Page[*coredata.ComplianceExternalURL, coredata.ComplianceExternalURLOrderField], error) { + var items coredata.ComplianceExternalURLs + + err := s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + if err := items.LoadByTrustCenterID(ctx, conn, s.svc.scope, trustCenterID, cursor); err != nil { + return fmt.Errorf("cannot load compliance external URLs: %w", err) + } + return nil + }, + ) + if err != nil { + return nil, err + } + + return page.NewPage(items, cursor), nil +} + +func (s ComplianceExternalURLService) Create( + ctx context.Context, + req *CreateComplianceExternalURLRequest, +) (*coredata.ComplianceExternalURL, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + now := time.Now() + id := gid.New(s.svc.scope.GetTenantID(), coredata.ComplianceExternalURLEntityType) + + var item *coredata.ComplianceExternalURL + + err := s.svc.pg.WithTx( + ctx, + func(tx pg.Conn) error { + trustCenter := &coredata.TrustCenter{} + if err := trustCenter.LoadByID(ctx, tx, s.svc.scope, req.TrustCenterID); err != nil { + return fmt.Errorf("cannot load trust center: %w", err) + } + + item = &coredata.ComplianceExternalURL{ + ID: id, + OrganizationID: trustCenter.OrganizationID, + TrustCenterID: req.TrustCenterID, + Name: req.Name, + URL: req.URL, + CreatedAt: now, + UpdatedAt: now, + } + + if err := item.Insert(ctx, tx, s.svc.scope); err != nil { + return fmt.Errorf("cannot insert compliance external URL: %w", err) + } + + return nil + }, + ) + if err != nil { + return nil, err + } + + return item, nil +} + +func (s ComplianceExternalURLService) Update( + ctx context.Context, + req *UpdateComplianceExternalURLRequest, +) (*coredata.ComplianceExternalURL, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + var item *coredata.ComplianceExternalURL + + err := s.svc.pg.WithTx( + ctx, + func(tx pg.Conn) error { + item = &coredata.ComplianceExternalURL{} + + if err := item.LoadByID(ctx, tx, s.svc.scope, req.ID); err != nil { + return fmt.Errorf("cannot load compliance external URL: %w", err) + } + + item.Name = req.Name + item.URL = req.URL + item.UpdatedAt = time.Now() + + if req.Rank != nil { + item.Rank = *req.Rank + if err := item.UpdateRank(ctx, tx, s.svc.scope); err != nil { + return fmt.Errorf("cannot update compliance external URL rank: %w", err) + } + } + + if err := item.Update(ctx, tx, s.svc.scope); err != nil { + return fmt.Errorf("cannot update compliance external URL: %w", err) + } + + return nil + }, + ) + if err != nil { + return nil, err + } + + return item, nil +} + +func (s ComplianceExternalURLService) Delete( + ctx context.Context, + req *DeleteComplianceExternalURLRequest, +) error { + if err := req.Validate(); err != nil { + return err + } + + return s.svc.pg.WithTx( + ctx, + func(tx pg.Conn) error { + item := &coredata.ComplianceExternalURL{} + + if err := item.LoadByID(ctx, tx, s.svc.scope, req.ID); err != nil { + return fmt.Errorf("cannot load compliance external URL: %w", err) + } + + if err := item.Delete(ctx, tx, s.svc.scope); err != nil { + return fmt.Errorf("cannot delete compliance external URL: %w", err) + } + + return nil + }, + ) +} diff --git a/pkg/probo/service.go b/pkg/probo/service.go index 516cdcca1..4e0303e91 100644 --- a/pkg/probo/service.go +++ b/pkg/probo/service.go @@ -101,6 +101,7 @@ type ( TrustCenterReferences *TrustCenterReferenceService TrustCenterFiles *TrustCenterFileService ComplianceFrameworks *ComplianceFrameworkService + ComplianceExternalURLs *ComplianceExternalURLService Nonconformities *NonconformityService Obligations *ObligationService Snapshots *SnapshotService @@ -226,6 +227,7 @@ func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService { tenantService.TrustCenterAccesses = &TrustCenterAccessService{svc: tenantService} tenantService.TrustCenterReferences = &TrustCenterReferenceService{svc: tenantService} tenantService.ComplianceFrameworks = &ComplianceFrameworkService{svc: tenantService} + tenantService.ComplianceExternalURLs = &ComplianceExternalURLService{svc: tenantService} tenantService.TrustCenterFiles = &TrustCenterFileService{ svc: tenantService, fileValidator: filevalidation.NewValidator( diff --git a/pkg/probo/trust_center_service.go b/pkg/probo/trust_center_service.go index cec98b182..29deaa367 100644 --- a/pkg/probo/trust_center_service.go +++ b/pkg/probo/trust_center_service.go @@ -178,7 +178,6 @@ func (s TrustCenterService) Update( if req.Slug != nil { trustCenter.Slug = *req.Slug } - trustCenter.UpdatedAt = time.Now() if err := trustCenter.Update(ctx, conn, s.svc.scope); err != nil { diff --git a/pkg/server/api/console/v1/schema.graphql b/pkg/server/api/console/v1/schema.graphql index 43e6ef8fe..be4959042 100644 --- a/pkg/server/api/console/v1/schema.graphql +++ b/pkg/server/api/console/v1/schema.graphql @@ -1227,6 +1227,20 @@ enum TrustCenterReferenceOrderField ) } +enum ComplianceExternalURLOrderField + @goModel( + model: "go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderField" + ) { + CREATED_AT + @goEnum( + value: "go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderFieldCreatedAt" + ) + RANK + @goEnum( + value: "go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderFieldRank" + ) +} + enum ComplianceFrameworkOrderField @goModel( model: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkOrderField" @@ -1491,6 +1505,14 @@ input TrustCenterFileOrder field: TrustCenterFileOrderField! } +input ComplianceExternalURLOrder + @goModel( + model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceExternalURLOrderBy" + ) { + direction: OrderDirection! + field: ComplianceExternalURLOrderField! +} + input ComplianceFrameworkOrder @goModel( model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFrameworkOrderBy" @@ -1658,6 +1680,14 @@ type TrustCenter implements Node { orderBy: ComplianceFrameworkOrder ): ComplianceFrameworkConnection! @goField(forceResolver: true) + externalUrls( + first: Int + after: CursorKey + last: Int + before: CursorKey + orderBy: ComplianceExternalURLOrder + ): ComplianceExternalURLConnection! @goField(forceResolver: true) + permission(action: String!): Boolean! @goField(forceResolver: true) } @@ -2882,6 +2912,30 @@ type ComplianceFrameworkEdge { node: ComplianceFramework! } +type ComplianceExternalURL implements Node { + id: ID! + name: String! + url: String! + rank: Int! + createdAt: Datetime! + updatedAt: Datetime! + + permission(action: String!): Boolean! @goField(forceResolver: true) +} + +type ComplianceExternalURLConnection + @goModel( + model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceExternalURLConnection" + ) { + edges: [ComplianceExternalURLEdge!]! + pageInfo: PageInfo! +} + +type ComplianceExternalURLEdge { + cursor: CursorKey! + node: ComplianceExternalURL! +} + type TrustCenterFile implements Node { id: ID! name: String! @@ -3330,6 +3384,15 @@ type Mutation { deleteComplianceFramework( input: DeleteComplianceFrameworkInput! ): DeleteComplianceFrameworkPayload! + createComplianceExternalURL( + input: CreateComplianceExternalURLInput! + ): CreateComplianceExternalURLPayload! + updateComplianceExternalURL( + input: UpdateComplianceExternalURLInput! + ): UpdateComplianceExternalURLPayload! + deleteComplianceExternalURL( + input: DeleteComplianceExternalURLInput! + ): DeleteComplianceExternalURLPayload! # Trust Center File mutations createTrustCenterFile( input: CreateTrustCenterFileInput! @@ -3738,6 +3801,23 @@ input DeleteComplianceFrameworkInput { id: ID! } +input CreateComplianceExternalURLInput { + trustCenterId: ID! + name: String! + url: String! +} + +input UpdateComplianceExternalURLInput { + id: ID! + name: String! + url: String! + rank: Int +} + +input DeleteComplianceExternalURLInput { + id: ID! +} + input CreateTrustCenterFileInput { organizationId: ID! name: String! @@ -4561,6 +4641,18 @@ type DeleteComplianceFrameworkPayload { deletedComplianceFrameworkId: ID! } +type CreateComplianceExternalURLPayload { + complianceExternalUrlEdge: ComplianceExternalURLEdge! +} + +type UpdateComplianceExternalURLPayload { + complianceExternalUrl: ComplianceExternalURL! +} + +type DeleteComplianceExternalURLPayload { + deletedComplianceExternalUrlId: ID! +} + type CreateTrustCenterFilePayload { trustCenterFileEdge: TrustCenterFileEdge! } diff --git a/pkg/server/api/console/v1/schema/schema.go b/pkg/server/api/console/v1/schema/schema.go index 120fc3b4d..84f07b052 100644 --- a/pkg/server/api/console/v1/schema/schema.go +++ b/pkg/server/api/console/v1/schema/schema.go @@ -42,6 +42,7 @@ type ResolverRoot interface { AssetConnection() AssetConnectionResolver Audit() AuditResolver AuditConnection() AuditConnectionResolver + ComplianceExternalURL() ComplianceExternalURLResolver ComplianceFramework() ComplianceFrameworkResolver ContinualImprovement() ContinualImprovementResolver ContinualImprovementConnection() ContinualImprovementConnectionResolver @@ -220,6 +221,26 @@ type ComplexityRoot struct { DeletedDocumentVersionSignatureID func(childComplexity int) int } + ComplianceExternalURL struct { + CreatedAt func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + Permission func(childComplexity int, action string) int + Rank func(childComplexity int) int + URL func(childComplexity int) int + UpdatedAt func(childComplexity int) int + } + + ComplianceExternalURLConnection struct { + Edges func(childComplexity int) int + PageInfo func(childComplexity int) int + } + + ComplianceExternalURLEdge struct { + Cursor func(childComplexity int) int + Node func(childComplexity int) int + } + ComplianceFramework struct { CreatedAt func(childComplexity int) int Framework func(childComplexity int) int @@ -311,6 +332,10 @@ type ComplexityRoot struct { AuditEdge func(childComplexity int) int } + CreateComplianceExternalURLPayload struct { + ComplianceExternalURLEdge func(childComplexity int) int + } + CreateComplianceFrameworkPayload struct { ComplianceFrameworkEdge func(childComplexity int) int } @@ -545,6 +570,10 @@ type ComplexityRoot struct { Audit func(childComplexity int) int } + DeleteComplianceExternalURLPayload struct { + DeletedComplianceExternalURLID func(childComplexity int) int + } + DeleteComplianceFrameworkPayload struct { DeletedComplianceFrameworkID func(childComplexity int) int } @@ -980,6 +1009,7 @@ type ComplexityRoot struct { CreateApplicabilityStatement func(childComplexity int, input types.CreateApplicabilityStatementInput) int CreateAsset func(childComplexity int, input types.CreateAssetInput) int CreateAudit func(childComplexity int, input types.CreateAuditInput) int + CreateComplianceExternalURL func(childComplexity int, input types.CreateComplianceExternalURLInput) int CreateComplianceFramework func(childComplexity int, input types.CreateComplianceFrameworkInput) int CreateContinualImprovement func(childComplexity int, input types.CreateContinualImprovementInput) int CreateControl func(childComplexity int, input types.CreateControlInput) int @@ -1019,6 +1049,7 @@ type ComplexityRoot struct { DeleteAsset func(childComplexity int, input types.DeleteAssetInput) int DeleteAudit func(childComplexity int, input types.DeleteAuditInput) int DeleteAuditReport func(childComplexity int, input types.DeleteAuditReportInput) int + DeleteComplianceExternalURL func(childComplexity int, input types.DeleteComplianceExternalURLInput) int DeleteComplianceFramework func(childComplexity int, input types.DeleteComplianceFrameworkInput) int DeleteContinualImprovement func(childComplexity int, input types.DeleteContinualImprovementInput) int DeleteControl func(childComplexity int, input types.DeleteControlInput) int @@ -1077,6 +1108,7 @@ type ComplexityRoot struct { UpdateApplicabilityStatement func(childComplexity int, input types.UpdateApplicabilityStatementInput) int UpdateAsset func(childComplexity int, input types.UpdateAssetInput) int UpdateAudit func(childComplexity int, input types.UpdateAuditInput) int + UpdateComplianceExternalURL func(childComplexity int, input types.UpdateComplianceExternalURLInput) int UpdateComplianceFramework func(childComplexity int, input types.UpdateComplianceFrameworkInput) int UpdateContinualImprovement func(childComplexity int, input types.UpdateContinualImprovementInput) int UpdateControl func(childComplexity int, input types.UpdateControlInput) int @@ -1539,6 +1571,7 @@ type ComplexityRoot struct { ComplianceFrameworks func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.ComplianceFrameworkOrderField]) int CreatedAt func(childComplexity int) int DarkLogoFileURL func(childComplexity int) int + ExternalUrls func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.ComplianceExternalURLOrderField]) int ID func(childComplexity int) int LogoFileURL func(childComplexity int) int NdaFileName func(childComplexity int) int @@ -1660,6 +1693,10 @@ type ComplexityRoot struct { Audit func(childComplexity int) int } + UpdateComplianceExternalURLPayload struct { + ComplianceExternalURL func(childComplexity int) int + } + UpdateComplianceFrameworkPayload struct { ComplianceFramework func(childComplexity int) int } @@ -2045,6 +2082,9 @@ type AuditResolver interface { type AuditConnectionResolver interface { TotalCount(ctx context.Context, obj *types.AuditConnection) (int, error) } +type ComplianceExternalURLResolver interface { + Permission(ctx context.Context, obj *types.ComplianceExternalURL, action string) (bool, error) +} type ComplianceFrameworkResolver interface { Framework(ctx context.Context, obj *types.ComplianceFramework) (*types.Framework, error) } @@ -2194,6 +2234,9 @@ type MutationResolver interface { CreateComplianceFramework(ctx context.Context, input types.CreateComplianceFrameworkInput) (*types.CreateComplianceFrameworkPayload, error) UpdateComplianceFramework(ctx context.Context, input types.UpdateComplianceFrameworkInput) (*types.UpdateComplianceFrameworkPayload, error) DeleteComplianceFramework(ctx context.Context, input types.DeleteComplianceFrameworkInput) (*types.DeleteComplianceFrameworkPayload, error) + CreateComplianceExternalURL(ctx context.Context, input types.CreateComplianceExternalURLInput) (*types.CreateComplianceExternalURLPayload, error) + UpdateComplianceExternalURL(ctx context.Context, input types.UpdateComplianceExternalURLInput) (*types.UpdateComplianceExternalURLPayload, error) + DeleteComplianceExternalURL(ctx context.Context, input types.DeleteComplianceExternalURLInput) (*types.DeleteComplianceExternalURLPayload, error) CreateTrustCenterFile(ctx context.Context, input types.CreateTrustCenterFileInput) (*types.CreateTrustCenterFilePayload, error) UpdateTrustCenterFile(ctx context.Context, input types.UpdateTrustCenterFileInput) (*types.UpdateTrustCenterFilePayload, error) GetTrustCenterFile(ctx context.Context, input types.GetTrustCenterFileInput) (*types.GetTrustCenterFilePayload, error) @@ -2484,6 +2527,7 @@ type TrustCenterResolver interface { Accesses(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterAccessOrderField]) (*types.TrustCenterAccessConnection, error) References(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.TrustCenterReferenceOrderField]) (*types.TrustCenterReferenceConnection, error) ComplianceFrameworks(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.ComplianceFrameworkOrderField]) (*types.ComplianceFrameworkConnection, error) + ExternalUrls(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.ComplianceExternalURLOrderField]) (*types.ComplianceExternalURLConnection, error) Permission(ctx context.Context, obj *types.TrustCenter, action string) (bool, error) } type TrustCenterAccessResolver interface { @@ -2982,6 +3026,80 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.CancelSignatureRequestPayload.DeletedDocumentVersionSignatureID(childComplexity), true + case "ComplianceExternalURL.createdAt": + if e.ComplexityRoot.ComplianceExternalURL.CreatedAt == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURL.CreatedAt(childComplexity), true + case "ComplianceExternalURL.id": + if e.ComplexityRoot.ComplianceExternalURL.ID == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURL.ID(childComplexity), true + case "ComplianceExternalURL.name": + if e.ComplexityRoot.ComplianceExternalURL.Name == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURL.Name(childComplexity), true + case "ComplianceExternalURL.permission": + if e.ComplexityRoot.ComplianceExternalURL.Permission == nil { + break + } + + args, err := ec.field_ComplianceExternalURL_permission_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.ComplianceExternalURL.Permission(childComplexity, args["action"].(string)), true + case "ComplianceExternalURL.rank": + if e.ComplexityRoot.ComplianceExternalURL.Rank == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURL.Rank(childComplexity), true + case "ComplianceExternalURL.url": + if e.ComplexityRoot.ComplianceExternalURL.URL == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURL.URL(childComplexity), true + case "ComplianceExternalURL.updatedAt": + if e.ComplexityRoot.ComplianceExternalURL.UpdatedAt == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURL.UpdatedAt(childComplexity), true + + case "ComplianceExternalURLConnection.edges": + if e.ComplexityRoot.ComplianceExternalURLConnection.Edges == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURLConnection.Edges(childComplexity), true + case "ComplianceExternalURLConnection.pageInfo": + if e.ComplexityRoot.ComplianceExternalURLConnection.PageInfo == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURLConnection.PageInfo(childComplexity), true + + case "ComplianceExternalURLEdge.cursor": + if e.ComplexityRoot.ComplianceExternalURLEdge.Cursor == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURLEdge.Cursor(childComplexity), true + case "ComplianceExternalURLEdge.node": + if e.ComplexityRoot.ComplianceExternalURLEdge.Node == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURLEdge.Node(childComplexity), true + case "ComplianceFramework.createdAt": if e.ComplexityRoot.ComplianceFramework.CreatedAt == nil { break @@ -3359,6 +3477,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.CreateAuditPayload.AuditEdge(childComplexity), true + case "CreateComplianceExternalURLPayload.complianceExternalUrlEdge": + if e.ComplexityRoot.CreateComplianceExternalURLPayload.ComplianceExternalURLEdge == nil { + break + } + + return e.ComplexityRoot.CreateComplianceExternalURLPayload.ComplianceExternalURLEdge(childComplexity), true + case "CreateComplianceFrameworkPayload.complianceFrameworkEdge": if e.ComplexityRoot.CreateComplianceFrameworkPayload.ComplianceFrameworkEdge == nil { break @@ -3984,6 +4109,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.DeleteAuditReportPayload.Audit(childComplexity), true + case "DeleteComplianceExternalURLPayload.deletedComplianceExternalUrlId": + if e.ComplexityRoot.DeleteComplianceExternalURLPayload.DeletedComplianceExternalURLID == nil { + break + } + + return e.ComplexityRoot.DeleteComplianceExternalURLPayload.DeletedComplianceExternalURLID(childComplexity), true + case "DeleteComplianceFrameworkPayload.deletedComplianceFrameworkId": if e.ComplexityRoot.DeleteComplianceFrameworkPayload.DeletedComplianceFrameworkID == nil { break @@ -5443,6 +5575,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.Mutation.CreateAudit(childComplexity, args["input"].(types.CreateAuditInput)), true + case "Mutation.createComplianceExternalURL": + if e.ComplexityRoot.Mutation.CreateComplianceExternalURL == nil { + break + } + + args, err := ec.field_Mutation_createComplianceExternalURL_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Mutation.CreateComplianceExternalURL(childComplexity, args["input"].(types.CreateComplianceExternalURLInput)), true case "Mutation.createComplianceFramework": if e.ComplexityRoot.Mutation.CreateComplianceFramework == nil { break @@ -5872,6 +6015,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.Mutation.DeleteAuditReport(childComplexity, args["input"].(types.DeleteAuditReportInput)), true + case "Mutation.deleteComplianceExternalURL": + if e.ComplexityRoot.Mutation.DeleteComplianceExternalURL == nil { + break + } + + args, err := ec.field_Mutation_deleteComplianceExternalURL_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Mutation.DeleteComplianceExternalURL(childComplexity, args["input"].(types.DeleteComplianceExternalURLInput)), true case "Mutation.deleteComplianceFramework": if e.ComplexityRoot.Mutation.DeleteComplianceFramework == nil { break @@ -6510,6 +6664,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.Mutation.UpdateAudit(childComplexity, args["input"].(types.UpdateAuditInput)), true + case "Mutation.updateComplianceExternalURL": + if e.ComplexityRoot.Mutation.UpdateComplianceExternalURL == nil { + break + } + + args, err := ec.field_Mutation_updateComplianceExternalURL_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Mutation.UpdateComplianceExternalURL(childComplexity, args["input"].(types.UpdateComplianceExternalURLInput)), true case "Mutation.updateComplianceFramework": if e.ComplexityRoot.Mutation.UpdateComplianceFramework == nil { break @@ -8920,6 +9085,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.TrustCenter.DarkLogoFileURL(childComplexity), true + case "TrustCenter.externalUrls": + if e.ComplexityRoot.TrustCenter.ExternalUrls == nil { + break + } + + args, err := ec.field_TrustCenter_externalUrls_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.TrustCenter.ExternalUrls(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey), args["orderBy"].(*types.OrderBy[coredata.ComplianceExternalURLOrderField])), true case "TrustCenter.id": if e.ComplexityRoot.TrustCenter.ID == nil { break @@ -9376,6 +9552,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.UpdateAuditPayload.Audit(childComplexity), true + case "UpdateComplianceExternalURLPayload.complianceExternalUrl": + if e.ComplexityRoot.UpdateComplianceExternalURLPayload.ComplianceExternalURL == nil { + break + } + + return e.ComplexityRoot.UpdateComplianceExternalURLPayload.ComplianceExternalURL(childComplexity), true + case "UpdateComplianceFrameworkPayload.complianceFramework": if e.ComplexityRoot.UpdateComplianceFrameworkPayload.ComplianceFramework == nil { break @@ -10550,6 +10733,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputBulkPublishDocumentVersionsInput, ec.unmarshalInputBulkRequestSignaturesInput, ec.unmarshalInputCancelSignatureRequestInput, + ec.unmarshalInputComplianceExternalURLOrder, ec.unmarshalInputComplianceFrameworkOrder, ec.unmarshalInputContinualImprovementFilter, ec.unmarshalInputContinualImprovementOrder, @@ -10558,6 +10742,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputCreateApplicabilityStatementInput, ec.unmarshalInputCreateAssetInput, ec.unmarshalInputCreateAuditInput, + ec.unmarshalInputCreateComplianceExternalURLInput, ec.unmarshalInputCreateComplianceFrameworkInput, ec.unmarshalInputCreateContinualImprovementInput, ec.unmarshalInputCreateControlAuditMappingInput, @@ -10601,6 +10786,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputDeleteAssetInput, ec.unmarshalInputDeleteAuditInput, ec.unmarshalInputDeleteAuditReportInput, + ec.unmarshalInputDeleteComplianceExternalURLInput, ec.unmarshalInputDeleteComplianceFrameworkInput, ec.unmarshalInputDeleteContinualImprovementInput, ec.unmarshalInputDeleteControlAuditMappingInput, @@ -10692,6 +10878,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputUpdateApplicabilityStatementInput, ec.unmarshalInputUpdateAssetInput, ec.unmarshalInputUpdateAuditInput, + ec.unmarshalInputUpdateComplianceExternalURLInput, ec.unmarshalInputUpdateComplianceFrameworkInput, ec.unmarshalInputUpdateContinualImprovementInput, ec.unmarshalInputUpdateControlInput, @@ -12040,6 +12227,20 @@ enum TrustCenterReferenceOrderField ) } +enum ComplianceExternalURLOrderField + @goModel( + model: "go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderField" + ) { + CREATED_AT + @goEnum( + value: "go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderFieldCreatedAt" + ) + RANK + @goEnum( + value: "go.probo.inc/probo/pkg/coredata.ComplianceExternalURLOrderFieldRank" + ) +} + enum ComplianceFrameworkOrderField @goModel( model: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkOrderField" @@ -12304,6 +12505,14 @@ input TrustCenterFileOrder field: TrustCenterFileOrderField! } +input ComplianceExternalURLOrder + @goModel( + model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceExternalURLOrderBy" + ) { + direction: OrderDirection! + field: ComplianceExternalURLOrderField! +} + input ComplianceFrameworkOrder @goModel( model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFrameworkOrderBy" @@ -12471,6 +12680,14 @@ type TrustCenter implements Node { orderBy: ComplianceFrameworkOrder ): ComplianceFrameworkConnection! @goField(forceResolver: true) + externalUrls( + first: Int + after: CursorKey + last: Int + before: CursorKey + orderBy: ComplianceExternalURLOrder + ): ComplianceExternalURLConnection! @goField(forceResolver: true) + permission(action: String!): Boolean! @goField(forceResolver: true) } @@ -13695,6 +13912,30 @@ type ComplianceFrameworkEdge { node: ComplianceFramework! } +type ComplianceExternalURL implements Node { + id: ID! + name: String! + url: String! + rank: Int! + createdAt: Datetime! + updatedAt: Datetime! + + permission(action: String!): Boolean! @goField(forceResolver: true) +} + +type ComplianceExternalURLConnection + @goModel( + model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceExternalURLConnection" + ) { + edges: [ComplianceExternalURLEdge!]! + pageInfo: PageInfo! +} + +type ComplianceExternalURLEdge { + cursor: CursorKey! + node: ComplianceExternalURL! +} + type TrustCenterFile implements Node { id: ID! name: String! @@ -14143,6 +14384,15 @@ type Mutation { deleteComplianceFramework( input: DeleteComplianceFrameworkInput! ): DeleteComplianceFrameworkPayload! + createComplianceExternalURL( + input: CreateComplianceExternalURLInput! + ): CreateComplianceExternalURLPayload! + updateComplianceExternalURL( + input: UpdateComplianceExternalURLInput! + ): UpdateComplianceExternalURLPayload! + deleteComplianceExternalURL( + input: DeleteComplianceExternalURLInput! + ): DeleteComplianceExternalURLPayload! # Trust Center File mutations createTrustCenterFile( input: CreateTrustCenterFileInput! @@ -14551,6 +14801,23 @@ input DeleteComplianceFrameworkInput { id: ID! } +input CreateComplianceExternalURLInput { + trustCenterId: ID! + name: String! + url: String! +} + +input UpdateComplianceExternalURLInput { + id: ID! + name: String! + url: String! + rank: Int +} + +input DeleteComplianceExternalURLInput { + id: ID! +} + input CreateTrustCenterFileInput { organizationId: ID! name: String! @@ -15374,6 +15641,18 @@ type DeleteComplianceFrameworkPayload { deletedComplianceFrameworkId: ID! } +type CreateComplianceExternalURLPayload { + complianceExternalUrlEdge: ComplianceExternalURLEdge! +} + +type UpdateComplianceExternalURLPayload { + complianceExternalUrl: ComplianceExternalURL! +} + +type DeleteComplianceExternalURLPayload { + deletedComplianceExternalUrlId: ID! +} + type CreateTrustCenterFilePayload { trustCenterFileEdge: TrustCenterFileEdge! } @@ -16566,6 +16845,17 @@ func (ec *executionContext) field_Audit_permission_args(ctx context.Context, raw return args, nil } +func (ec *executionContext) field_ComplianceExternalURL_permission_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "action", ec.unmarshalNString2string) + if err != nil { + return nil, err + } + args["action"] = arg0 + return args, nil +} + func (ec *executionContext) field_ContinualImprovement_permission_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -17338,6 +17628,17 @@ func (ec *executionContext) field_Mutation_createAudit_args(ctx context.Context, return args, nil } +func (ec *executionContext) field_Mutation_createComplianceExternalURL_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", ec.unmarshalNCreateComplianceExternalURLInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateComplianceExternalURLInput) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation_createComplianceFramework_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -17767,6 +18068,17 @@ func (ec *executionContext) field_Mutation_deleteAudit_args(ctx context.Context, return args, nil } +func (ec *executionContext) field_Mutation_deleteComplianceExternalURL_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", ec.unmarshalNDeleteComplianceExternalURLInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteComplianceExternalURLInput) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation_deleteComplianceFramework_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -18405,6 +18717,17 @@ func (ec *executionContext) field_Mutation_updateAudit_args(ctx context.Context, return args, nil } +func (ec *executionContext) field_Mutation_updateComplianceExternalURL_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", ec.unmarshalNUpdateComplianceExternalURLInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateComplianceExternalURLInput) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation_updateComplianceFramework_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -20204,6 +20527,37 @@ func (ec *executionContext) field_TrustCenter_complianceFrameworks_args(ctx cont return args, nil } +func (ec *executionContext) field_TrustCenter_externalUrls_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "first", ec.unmarshalOInt2ᚖint) + if err != nil { + return nil, err + } + args["first"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "after", ec.unmarshalOCursorKey2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋpageᚐCursorKey) + if err != nil { + return nil, err + } + args["after"] = arg1 + arg2, err := graphql.ProcessArgField(ctx, rawArgs, "last", ec.unmarshalOInt2ᚖint) + if err != nil { + return nil, err + } + args["last"] = arg2 + arg3, err := graphql.ProcessArgField(ctx, rawArgs, "before", ec.unmarshalOCursorKey2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋpageᚐCursorKey) + if err != nil { + return nil, err + } + args["before"] = arg3 + arg4, err := graphql.ProcessArgField(ctx, rawArgs, "orderBy", ec.unmarshalOComplianceExternalURLOrder2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐOrderBy) + if err != nil { + return nil, err + } + args["orderBy"] = arg4 + return args, nil +} + func (ec *executionContext) field_TrustCenter_permission_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -22780,6 +23134,369 @@ func (ec *executionContext) fieldContext_CancelSignatureRequestPayload_deletedDo return fc, nil } +func (ec *executionContext) _ComplianceExternalURL_id(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURL) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURL_id, + func(ctx context.Context) (any, error) { + return obj.ID, nil + }, + nil, + ec.marshalNID2goᚗproboᚗincᚋproboᚋpkgᚋgidᚐGID, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURL_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURL", + 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) _ComplianceExternalURL_name(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURL) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURL_name, + func(ctx context.Context) (any, error) { + return obj.Name, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURL_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURL", + 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) _ComplianceExternalURL_url(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURL) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURL_url, + func(ctx context.Context) (any, error) { + return obj.URL, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURL_url(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURL", + 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) _ComplianceExternalURL_rank(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURL) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURL_rank, + func(ctx context.Context) (any, error) { + return obj.Rank, nil + }, + nil, + ec.marshalNInt2int, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURL_rank(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURL", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceExternalURL_createdAt(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURL) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURL_createdAt, + func(ctx context.Context) (any, error) { + return obj.CreatedAt, nil + }, + nil, + ec.marshalNDatetime2timeᚐTime, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURL_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURL", + 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) _ComplianceExternalURL_updatedAt(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURL) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURL_updatedAt, + func(ctx context.Context) (any, error) { + return obj.UpdatedAt, nil + }, + nil, + ec.marshalNDatetime2timeᚐTime, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURL_updatedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURL", + 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) _ComplianceExternalURL_permission(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURL) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURL_permission, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.ComplianceExternalURL().Permission(ctx, obj, fc.Args["action"].(string)) + }, + nil, + ec.marshalNBoolean2bool, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURL_permission(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURL", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + 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_ComplianceExternalURL_permission_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _ComplianceExternalURLConnection_edges(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURLConnection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURLConnection_edges, + func(ctx context.Context) (any, error) { + return obj.Edges, nil + }, + nil, + ec.marshalNComplianceExternalURLEdge2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceExternalURLEdgeᚄ, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURLConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURLConnection", + 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_ComplianceExternalURLEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_ComplianceExternalURLEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceExternalURLEdge", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceExternalURLConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURLConnection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURLConnection_pageInfo, + func(ctx context.Context) (any, error) { + return obj.PageInfo, nil + }, + nil, + ec.marshalNPageInfo2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐPageInfo, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURLConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURLConnection", + 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) _ComplianceExternalURLEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURLEdge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURLEdge_cursor, + func(ctx context.Context) (any, error) { + return obj.Cursor, nil + }, + nil, + ec.marshalNCursorKey2goᚗproboᚗincᚋproboᚋpkgᚋpageᚐCursorKey, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURLEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURLEdge", + 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) _ComplianceExternalURLEdge_node(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURLEdge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURLEdge_node, + func(ctx context.Context) (any, error) { + return obj.Node, nil + }, + nil, + ec.marshalNComplianceExternalURL2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceExternalURL, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURLEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURLEdge", + 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_ComplianceExternalURL_id(ctx, field) + case "name": + return ec.fieldContext_ComplianceExternalURL_name(ctx, field) + case "url": + return ec.fieldContext_ComplianceExternalURL_url(ctx, field) + case "rank": + return ec.fieldContext_ComplianceExternalURL_rank(ctx, field) + case "createdAt": + return ec.fieldContext_ComplianceExternalURL_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_ComplianceExternalURL_updatedAt(ctx, field) + case "permission": + return ec.fieldContext_ComplianceExternalURL_permission(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceExternalURL", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _ComplianceFramework_id(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFramework) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -24873,6 +25590,41 @@ func (ec *executionContext) fieldContext_CreateAuditPayload_auditEdge(_ context. return fc, nil } +func (ec *executionContext) _CreateComplianceExternalURLPayload_complianceExternalUrlEdge(ctx context.Context, field graphql.CollectedField, obj *types.CreateComplianceExternalURLPayload) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CreateComplianceExternalURLPayload_complianceExternalUrlEdge, + func(ctx context.Context) (any, error) { + return obj.ComplianceExternalURLEdge, nil + }, + nil, + ec.marshalNComplianceExternalURLEdge2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceExternalURLEdge, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_CreateComplianceExternalURLPayload_complianceExternalUrlEdge(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CreateComplianceExternalURLPayload", + 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_ComplianceExternalURLEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_ComplianceExternalURLEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceExternalURLEdge", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _CreateComplianceFrameworkPayload_complianceFrameworkEdge(ctx context.Context, field graphql.CollectedField, obj *types.CreateComplianceFrameworkPayload) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -28380,6 +29132,35 @@ func (ec *executionContext) fieldContext_DeleteAuditReportPayload_audit(_ contex return fc, nil } +func (ec *executionContext) _DeleteComplianceExternalURLPayload_deletedComplianceExternalUrlId(ctx context.Context, field graphql.CollectedField, obj *types.DeleteComplianceExternalURLPayload) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_DeleteComplianceExternalURLPayload_deletedComplianceExternalUrlId, + func(ctx context.Context) (any, error) { + return obj.DeletedComplianceExternalURLID, nil + }, + nil, + ec.marshalNID2goᚗproboᚗincᚋproboᚋpkgᚋgidᚐGID, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_DeleteComplianceExternalURLPayload_deletedComplianceExternalUrlId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "DeleteComplianceExternalURLPayload", + 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) _DeleteComplianceFrameworkPayload_deletedComplianceFrameworkId(ctx context.Context, field graphql.CollectedField, obj *types.DeleteComplianceFrameworkPayload) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -29559,6 +30340,8 @@ func (ec *executionContext) fieldContext_DeleteTrustCenterNDAPayload_trustCenter return ec.fieldContext_TrustCenter_references(ctx, field) case "complianceFrameworks": return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) + case "externalUrls": + return ec.fieldContext_TrustCenter_externalUrls(ctx, field) case "permission": return ec.fieldContext_TrustCenter_permission(ctx, field) } @@ -35833,6 +36616,141 @@ func (ec *executionContext) fieldContext_Mutation_deleteComplianceFramework(ctx return fc, nil } +func (ec *executionContext) _Mutation_createComplianceExternalURL(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Mutation_createComplianceExternalURL, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Mutation().CreateComplianceExternalURL(ctx, fc.Args["input"].(types.CreateComplianceExternalURLInput)) + }, + nil, + ec.marshalNCreateComplianceExternalURLPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateComplianceExternalURLPayload, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Mutation_createComplianceExternalURL(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 "complianceExternalUrlEdge": + return ec.fieldContext_CreateComplianceExternalURLPayload_complianceExternalUrlEdge(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type CreateComplianceExternalURLPayload", 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_createComplianceExternalURL_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_updateComplianceExternalURL(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Mutation_updateComplianceExternalURL, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Mutation().UpdateComplianceExternalURL(ctx, fc.Args["input"].(types.UpdateComplianceExternalURLInput)) + }, + nil, + ec.marshalNUpdateComplianceExternalURLPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateComplianceExternalURLPayload, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Mutation_updateComplianceExternalURL(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 "complianceExternalUrl": + return ec.fieldContext_UpdateComplianceExternalURLPayload_complianceExternalUrl(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type UpdateComplianceExternalURLPayload", 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_updateComplianceExternalURL_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Mutation_deleteComplianceExternalURL(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Mutation_deleteComplianceExternalURL, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Mutation().DeleteComplianceExternalURL(ctx, fc.Args["input"].(types.DeleteComplianceExternalURLInput)) + }, + nil, + ec.marshalNDeleteComplianceExternalURLPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteComplianceExternalURLPayload, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Mutation_deleteComplianceExternalURL(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 "deletedComplianceExternalUrlId": + return ec.fieldContext_DeleteComplianceExternalURLPayload_deletedComplianceExternalUrlId(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type DeleteComplianceExternalURLPayload", 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_deleteComplianceExternalURL_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Mutation_createTrustCenterFile(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -44727,6 +45645,8 @@ func (ec *executionContext) fieldContext_Organization_trustCenter(_ context.Cont return ec.fieldContext_TrustCenter_references(ctx, field) case "complianceFrameworks": return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) + case "externalUrls": + return ec.fieldContext_TrustCenter_externalUrls(ctx, field) case "permission": return ec.fieldContext_TrustCenter_permission(ctx, field) } @@ -53033,6 +53953,53 @@ func (ec *executionContext) fieldContext_TrustCenter_complianceFrameworks(ctx co return fc, nil } +func (ec *executionContext) _TrustCenter_externalUrls(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_TrustCenter_externalUrls, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.TrustCenter().ExternalUrls(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey), fc.Args["orderBy"].(*types.OrderBy[coredata.ComplianceExternalURLOrderField])) + }, + nil, + ec.marshalNComplianceExternalURLConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceExternalURLConnection, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_TrustCenter_externalUrls(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TrustCenter", + 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_ComplianceExternalURLConnection_edges(ctx, field) + case "pageInfo": + return ec.fieldContext_ComplianceExternalURLConnection_pageInfo(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceExternalURLConnection", 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_TrustCenter_externalUrls_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _TrustCenter_permission(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -54170,6 +55137,8 @@ func (ec *executionContext) fieldContext_TrustCenterEdge_node(_ context.Context, return ec.fieldContext_TrustCenter_references(ctx, field) case "complianceFrameworks": return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) + case "externalUrls": + return ec.fieldContext_TrustCenter_externalUrls(ctx, field) case "permission": return ec.fieldContext_TrustCenter_permission(ctx, field) } @@ -55326,6 +56295,51 @@ func (ec *executionContext) fieldContext_UpdateAuditPayload_audit(_ context.Cont return fc, nil } +func (ec *executionContext) _UpdateComplianceExternalURLPayload_complianceExternalUrl(ctx context.Context, field graphql.CollectedField, obj *types.UpdateComplianceExternalURLPayload) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_UpdateComplianceExternalURLPayload_complianceExternalUrl, + func(ctx context.Context) (any, error) { + return obj.ComplianceExternalURL, nil + }, + nil, + ec.marshalNComplianceExternalURL2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceExternalURL, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_UpdateComplianceExternalURLPayload_complianceExternalUrl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "UpdateComplianceExternalURLPayload", + 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_ComplianceExternalURL_id(ctx, field) + case "name": + return ec.fieldContext_ComplianceExternalURL_name(ctx, field) + case "url": + return ec.fieldContext_ComplianceExternalURL_url(ctx, field) + case "rank": + return ec.fieldContext_ComplianceExternalURL_rank(ctx, field) + case "createdAt": + return ec.fieldContext_ComplianceExternalURL_createdAt(ctx, field) + case "updatedAt": + return ec.fieldContext_ComplianceExternalURL_updatedAt(ctx, field) + case "permission": + return ec.fieldContext_ComplianceExternalURL_permission(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceExternalURL", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _UpdateComplianceFrameworkPayload_complianceFramework(ctx context.Context, field graphql.CollectedField, obj *types.UpdateComplianceFrameworkPayload) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -56518,6 +57532,8 @@ func (ec *executionContext) fieldContext_UpdateTrustCenterBrandPayload_trustCent return ec.fieldContext_TrustCenter_references(ctx, field) case "complianceFrameworks": return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) + case "externalUrls": + return ec.fieldContext_TrustCenter_externalUrls(ctx, field) case "permission": return ec.fieldContext_TrustCenter_permission(ctx, field) } @@ -56624,6 +57640,8 @@ func (ec *executionContext) fieldContext_UpdateTrustCenterPayload_trustCenter(_ return ec.fieldContext_TrustCenter_references(ctx, field) case "complianceFrameworks": return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) + case "externalUrls": + return ec.fieldContext_TrustCenter_externalUrls(ctx, field) case "permission": return ec.fieldContext_TrustCenter_permission(ctx, field) } @@ -57164,6 +58182,8 @@ func (ec *executionContext) fieldContext_UploadTrustCenterNDAPayload_trustCenter return ec.fieldContext_TrustCenter_references(ctx, field) case "complianceFrameworks": return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) + case "externalUrls": + return ec.fieldContext_TrustCenter_externalUrls(ctx, field) case "permission": return ec.fieldContext_TrustCenter_permission(ctx, field) } @@ -64193,6 +65213,39 @@ func (ec *executionContext) unmarshalInputCancelSignatureRequestInput(ctx contex return it, nil } +func (ec *executionContext) unmarshalInputComplianceExternalURLOrder(ctx context.Context, obj any) (types.OrderBy[coredata.ComplianceExternalURLOrderField], error) { + var it types.OrderBy[coredata.ComplianceExternalURLOrderField] + 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.unmarshalNOrderDirection2goᚗproboᚗincᚋ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.unmarshalNComplianceExternalURLOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceExternalURLOrderField(ctx, v) + if err != nil { + return it, err + } + it.Field = data + } + } + return it, nil +} + func (ec *executionContext) unmarshalInputComplianceFrameworkOrder(ctx context.Context, obj any) (types.OrderBy[coredata.ComplianceFrameworkOrderField], error) { var it types.OrderBy[coredata.ComplianceFrameworkOrderField] asMap := map[string]any{} @@ -64527,6 +65580,46 @@ func (ec *executionContext) unmarshalInputCreateAuditInput(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputCreateComplianceExternalURLInput(ctx context.Context, obj any) (types.CreateComplianceExternalURLInput, error) { + var it types.CreateComplianceExternalURLInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"trustCenterId", "name", "url"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "trustCenterId": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("trustCenterId")) + data, err := ec.unmarshalNID2goᚗproboᚗincᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.TrustCenterID = 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 "url": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("url")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.URL = data + } + } + return it, nil +} + func (ec *executionContext) unmarshalInputCreateComplianceFrameworkInput(ctx context.Context, obj any) (types.CreateComplianceFrameworkInput, error) { var it types.CreateComplianceFrameworkInput asMap := map[string]any{} @@ -66772,6 +67865,32 @@ func (ec *executionContext) unmarshalInputDeleteAuditReportInput(ctx context.Con return it, nil } +func (ec *executionContext) unmarshalInputDeleteComplianceExternalURLInput(ctx context.Context, obj any) (types.DeleteComplianceExternalURLInput, error) { + var it types.DeleteComplianceExternalURLInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"id"} + 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.unmarshalNID2goᚗproboᚗincᚋproboᚋpkgᚋgidᚐGID(ctx, v) + if err != nil { + return it, err + } + it.ID = data + } + } + return it, nil +} + func (ec *executionContext) unmarshalInputDeleteComplianceFrameworkInput(ctx context.Context, obj any) (types.DeleteComplianceFrameworkInput, error) { var it types.DeleteComplianceFrameworkInput asMap := map[string]any{} @@ -69530,6 +70649,53 @@ func (ec *executionContext) unmarshalInputUpdateAuditInput(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputUpdateComplianceExternalURLInput(ctx context.Context, obj any) (types.UpdateComplianceExternalURLInput, error) { + var it types.UpdateComplianceExternalURLInput + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"id", "name", "url", "rank"} + 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.unmarshalNID2goᚗproboᚗincᚋ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.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Name = data + case "url": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("url")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.URL = data + case "rank": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("rank")) + data, err := ec.unmarshalOInt2ᚖint(ctx, v) + if err != nil { + return it, err + } + it.Rank = data + } + } + return it, nil +} + func (ec *executionContext) unmarshalInputUpdateComplianceFrameworkInput(ctx context.Context, obj any) (types.UpdateComplianceFrameworkInput, error) { var it types.UpdateComplianceFrameworkInput asMap := map[string]any{} @@ -72236,6 +73402,13 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._ComplianceFramework(ctx, sel, obj) + case types.ComplianceExternalURL: + return ec._ComplianceExternalURL(ctx, sel, &obj) + case *types.ComplianceExternalURL: + if obj == nil { + return graphql.Null + } + return ec._ComplianceExternalURL(ctx, sel, obj) case types.Audit: return ec._Audit(ctx, sel, &obj) case *types.Audit: @@ -73538,6 +74711,194 @@ func (ec *executionContext) _CancelSignatureRequestPayload(ctx context.Context, return out } +var complianceExternalURLImplementors = []string{"ComplianceExternalURL", "Node"} + +func (ec *executionContext) _ComplianceExternalURL(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceExternalURL) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, complianceExternalURLImplementors) + + 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("ComplianceExternalURL") + case "id": + out.Values[i] = ec._ComplianceExternalURL_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "name": + out.Values[i] = ec._ComplianceExternalURL_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "url": + out.Values[i] = ec._ComplianceExternalURL_url(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "rank": + out.Values[i] = ec._ComplianceExternalURL_rank(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "createdAt": + out.Values[i] = ec._ComplianceExternalURL_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "updatedAt": + out.Values[i] = ec._ComplianceExternalURL_updatedAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "permission": + 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._ComplianceExternalURL_permission(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) }) + 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 complianceExternalURLConnectionImplementors = []string{"ComplianceExternalURLConnection"} + +func (ec *executionContext) _ComplianceExternalURLConnection(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceExternalURLConnection) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, complianceExternalURLConnectionImplementors) + + 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("ComplianceExternalURLConnection") + case "edges": + out.Values[i] = ec._ComplianceExternalURLConnection_edges(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "pageInfo": + out.Values[i] = ec._ComplianceExternalURLConnection_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 complianceExternalURLEdgeImplementors = []string{"ComplianceExternalURLEdge"} + +func (ec *executionContext) _ComplianceExternalURLEdge(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceExternalURLEdge) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, complianceExternalURLEdgeImplementors) + + 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("ComplianceExternalURLEdge") + case "cursor": + out.Values[i] = ec._ComplianceExternalURLEdge_cursor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "node": + out.Values[i] = ec._ComplianceExternalURLEdge_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 complianceFrameworkImplementors = []string{"ComplianceFramework", "Node"} func (ec *executionContext) _ComplianceFramework(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceFramework) graphql.Marshaler { @@ -74727,6 +76088,45 @@ func (ec *executionContext) _CreateAuditPayload(ctx context.Context, sel ast.Sel return out } +var createComplianceExternalURLPayloadImplementors = []string{"CreateComplianceExternalURLPayload"} + +func (ec *executionContext) _CreateComplianceExternalURLPayload(ctx context.Context, sel ast.SelectionSet, obj *types.CreateComplianceExternalURLPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, createComplianceExternalURLPayloadImplementors) + + 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("CreateComplianceExternalURLPayload") + case "complianceExternalUrlEdge": + out.Values[i] = ec._CreateComplianceExternalURLPayload_complianceExternalUrlEdge(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 createComplianceFrameworkPayloadImplementors = []string{"CreateComplianceFrameworkPayload"} func (ec *executionContext) _CreateComplianceFrameworkPayload(ctx context.Context, sel ast.SelectionSet, obj *types.CreateComplianceFrameworkPayload) graphql.Marshaler { @@ -77079,6 +78479,45 @@ func (ec *executionContext) _DeleteAuditReportPayload(ctx context.Context, sel a return out } +var deleteComplianceExternalURLPayloadImplementors = []string{"DeleteComplianceExternalURLPayload"} + +func (ec *executionContext) _DeleteComplianceExternalURLPayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteComplianceExternalURLPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, deleteComplianceExternalURLPayloadImplementors) + + 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("DeleteComplianceExternalURLPayload") + case "deletedComplianceExternalUrlId": + out.Values[i] = ec._DeleteComplianceExternalURLPayload_deletedComplianceExternalUrlId(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 deleteComplianceFrameworkPayloadImplementors = []string{"DeleteComplianceFrameworkPayload"} func (ec *executionContext) _DeleteComplianceFrameworkPayload(ctx context.Context, sel ast.SelectionSet, obj *types.DeleteComplianceFrameworkPayload) graphql.Marshaler { @@ -81931,6 +83370,27 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } + case "createComplianceExternalURL": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_createComplianceExternalURL(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "updateComplianceExternalURL": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_updateComplianceExternalURL(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deleteComplianceExternalURL": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_deleteComplianceExternalURL(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "createTrustCenterFile": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_createTrustCenterFile(ctx, field) @@ -88475,6 +89935,42 @@ func (ec *executionContext) _TrustCenter(ctx context.Context, sel ast.SelectionS continue } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "externalUrls": + 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._TrustCenter_externalUrls(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 "permission": field := field @@ -89925,6 +91421,45 @@ func (ec *executionContext) _UpdateAuditPayload(ctx context.Context, sel ast.Sel return out } +var updateComplianceExternalURLPayloadImplementors = []string{"UpdateComplianceExternalURLPayload"} + +func (ec *executionContext) _UpdateComplianceExternalURLPayload(ctx context.Context, sel ast.SelectionSet, obj *types.UpdateComplianceExternalURLPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, updateComplianceExternalURLPayloadImplementors) + + 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("UpdateComplianceExternalURLPayload") + case "complianceExternalUrl": + out.Values[i] = ec._UpdateComplianceExternalURLPayload_complianceExternalUrl(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 updateComplianceFrameworkPayloadImplementors = []string{"UpdateComplianceFrameworkPayload"} func (ec *executionContext) _UpdateComplianceFrameworkPayload(ctx context.Context, sel ast.SelectionSet, obj *types.UpdateComplianceFrameworkPayload) graphql.Marshaler { @@ -94583,6 +96118,84 @@ func (ec *executionContext) marshalNCancelSignatureRequestPayload2ᚖgoᚗprobo return ec._CancelSignatureRequestPayload(ctx, sel, v) } +func (ec *executionContext) marshalNComplianceExternalURL2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceExternalURL(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceExternalURL) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._ComplianceExternalURL(ctx, sel, v) +} + +func (ec *executionContext) marshalNComplianceExternalURLConnection2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceExternalURLConnection(ctx context.Context, sel ast.SelectionSet, v types.ComplianceExternalURLConnection) graphql.Marshaler { + return ec._ComplianceExternalURLConnection(ctx, sel, &v) +} + +func (ec *executionContext) marshalNComplianceExternalURLConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceExternalURLConnection(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceExternalURLConnection) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._ComplianceExternalURLConnection(ctx, sel, v) +} + +func (ec *executionContext) marshalNComplianceExternalURLEdge2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceExternalURLEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []*types.ComplianceExternalURLEdge) graphql.Marshaler { + ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { + fc := graphql.GetFieldContext(ctx) + fc.Result = &v[i] + return ec.marshalNComplianceExternalURLEdge2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceExternalURLEdge(ctx, sel, v[i]) + }) + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNComplianceExternalURLEdge2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceExternalURLEdge(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceExternalURLEdge) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._ComplianceExternalURLEdge(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNComplianceExternalURLOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceExternalURLOrderField(ctx context.Context, v any) (coredata.ComplianceExternalURLOrderField, error) { + tmp, err := graphql.UnmarshalString(v) + res := unmarshalNComplianceExternalURLOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceExternalURLOrderField[tmp] + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNComplianceExternalURLOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceExternalURLOrderField(ctx context.Context, sel ast.SelectionSet, v coredata.ComplianceExternalURLOrderField) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(marshalNComplianceExternalURLOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceExternalURLOrderField[v]) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +var ( + unmarshalNComplianceExternalURLOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceExternalURLOrderField = map[string]coredata.ComplianceExternalURLOrderField{ + "CREATED_AT": coredata.ComplianceExternalURLOrderFieldCreatedAt, + "RANK": coredata.ComplianceExternalURLOrderFieldRank, + } + marshalNComplianceExternalURLOrderField2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐComplianceExternalURLOrderField = map[coredata.ComplianceExternalURLOrderField]string{ + coredata.ComplianceExternalURLOrderFieldCreatedAt: "CREATED_AT", + coredata.ComplianceExternalURLOrderFieldRank: "RANK", + } +) + func (ec *executionContext) marshalNComplianceFramework2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐComplianceFramework(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceFramework) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { @@ -95525,6 +97138,25 @@ func (ec *executionContext) marshalNCreateAuditPayload2ᚖgoᚗproboᚗincᚋpro return ec._CreateAuditPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNCreateComplianceExternalURLInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateComplianceExternalURLInput(ctx context.Context, v any) (types.CreateComplianceExternalURLInput, error) { + res, err := ec.unmarshalInputCreateComplianceExternalURLInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNCreateComplianceExternalURLPayload2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateComplianceExternalURLPayload(ctx context.Context, sel ast.SelectionSet, v types.CreateComplianceExternalURLPayload) graphql.Marshaler { + return ec._CreateComplianceExternalURLPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNCreateComplianceExternalURLPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateComplianceExternalURLPayload(ctx context.Context, sel ast.SelectionSet, v *types.CreateComplianceExternalURLPayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._CreateComplianceExternalURLPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNCreateComplianceFrameworkInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐCreateComplianceFrameworkInput(ctx context.Context, v any) (types.CreateComplianceFrameworkInput, error) { res, err := ec.unmarshalInputCreateComplianceFrameworkInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -96556,6 +98188,25 @@ func (ec *executionContext) marshalNDeleteAuditReportPayload2ᚖgoᚗproboᚗinc return ec._DeleteAuditReportPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNDeleteComplianceExternalURLInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteComplianceExternalURLInput(ctx context.Context, v any) (types.DeleteComplianceExternalURLInput, error) { + res, err := ec.unmarshalInputDeleteComplianceExternalURLInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNDeleteComplianceExternalURLPayload2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteComplianceExternalURLPayload(ctx context.Context, sel ast.SelectionSet, v types.DeleteComplianceExternalURLPayload) graphql.Marshaler { + return ec._DeleteComplianceExternalURLPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNDeleteComplianceExternalURLPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteComplianceExternalURLPayload(ctx context.Context, sel ast.SelectionSet, v *types.DeleteComplianceExternalURLPayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._DeleteComplianceExternalURLPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNDeleteComplianceFrameworkInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐDeleteComplianceFrameworkInput(ctx context.Context, v any) (types.DeleteComplianceFrameworkInput, error) { res, err := ec.unmarshalInputDeleteComplianceFrameworkInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -100623,6 +102274,25 @@ func (ec *executionContext) marshalNUpdateAuditPayload2ᚖgoᚗproboᚗincᚋpro return ec._UpdateAuditPayload(ctx, sel, v) } +func (ec *executionContext) unmarshalNUpdateComplianceExternalURLInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateComplianceExternalURLInput(ctx context.Context, v any) (types.UpdateComplianceExternalURLInput, error) { + res, err := ec.unmarshalInputUpdateComplianceExternalURLInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNUpdateComplianceExternalURLPayload2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateComplianceExternalURLPayload(ctx context.Context, sel ast.SelectionSet, v types.UpdateComplianceExternalURLPayload) graphql.Marshaler { + return ec._UpdateComplianceExternalURLPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNUpdateComplianceExternalURLPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateComplianceExternalURLPayload(ctx context.Context, sel ast.SelectionSet, v *types.UpdateComplianceExternalURLPayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._UpdateComplianceExternalURLPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNUpdateComplianceFrameworkInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐUpdateComplianceFrameworkInput(ctx context.Context, v any) (types.UpdateComplianceFrameworkInput, error) { res, err := ec.unmarshalInputUpdateComplianceFrameworkInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -102360,6 +104030,14 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast return res } +func (ec *executionContext) unmarshalOComplianceExternalURLOrder2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐOrderBy(ctx context.Context, v any) (*types.OrderBy[coredata.ComplianceExternalURLOrderField], error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputComplianceExternalURLOrder(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) unmarshalOComplianceFrameworkOrder2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐOrderBy(ctx context.Context, v any) (*types.OrderBy[coredata.ComplianceFrameworkOrderField], error) { if v == nil { return nil, nil diff --git a/pkg/server/api/console/v1/types/compliance_external_url.go b/pkg/server/api/console/v1/types/compliance_external_url.go new file mode 100644 index 000000000..df5eb9979 --- /dev/null +++ b/pkg/server/api/console/v1/types/compliance_external_url.go @@ -0,0 +1,44 @@ +package types + +import ( + "go.probo.inc/probo/pkg/coredata" + "go.probo.inc/probo/pkg/page" +) + +type ComplianceExternalURLOrderBy = OrderBy[coredata.ComplianceExternalURLOrderField] + +type ComplianceExternalURLConnection struct { + Edges []*ComplianceExternalURLEdge `json:"edges"` + PageInfo *PageInfo `json:"pageInfo"` +} + +func NewComplianceExternalURL(c *coredata.ComplianceExternalURL) *ComplianceExternalURL { + return &ComplianceExternalURL{ + ID: c.ID, + Name: c.Name, + URL: c.URL, + Rank: c.Rank, + CreatedAt: c.CreatedAt, + UpdatedAt: c.UpdatedAt, + } +} + +func NewComplianceExternalURLConnection( + p *page.Page[*coredata.ComplianceExternalURL, coredata.ComplianceExternalURLOrderField], +) *ComplianceExternalURLConnection { + edges := make([]*ComplianceExternalURLEdge, len(p.Data)) + for i := range edges { + edges[i] = NewComplianceExternalURLEdge(p.Data[i], p.Cursor.OrderBy.Field) + } + return &ComplianceExternalURLConnection{ + Edges: edges, + PageInfo: NewPageInfo(p), + } +} + +func NewComplianceExternalURLEdge(c *coredata.ComplianceExternalURL, orderBy coredata.ComplianceExternalURLOrderField) *ComplianceExternalURLEdge { + return &ComplianceExternalURLEdge{ + Cursor: c.CursorKey(orderBy), + Node: NewComplianceExternalURL(c), + } +} diff --git a/pkg/server/api/console/v1/types/types.go b/pkg/server/api/console/v1/types/types.go index 35a518c08..1057b6801 100644 --- a/pkg/server/api/console/v1/types/types.go +++ b/pkg/server/api/console/v1/types/types.go @@ -149,6 +149,24 @@ type CancelSignatureRequestPayload struct { DeletedDocumentVersionSignatureID gid.GID `json:"deletedDocumentVersionSignatureId"` } +type ComplianceExternalURL struct { + ID gid.GID `json:"id"` + Name string `json:"name"` + URL string `json:"url"` + Rank int `json:"rank"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + Permission bool `json:"permission"` +} + +func (ComplianceExternalURL) IsNode() {} +func (this ComplianceExternalURL) GetID() gid.GID { return this.ID } + +type ComplianceExternalURLEdge struct { + Cursor page.CursorKey `json:"cursor"` + Node *ComplianceExternalURL `json:"node"` +} + type ComplianceFrameworkEdge struct { Cursor page.CursorKey `json:"cursor"` Node *ComplianceFramework `json:"node"` @@ -255,6 +273,16 @@ type CreateAuditPayload struct { AuditEdge *AuditEdge `json:"auditEdge"` } +type CreateComplianceExternalURLInput struct { + TrustCenterID gid.GID `json:"trustCenterId"` + Name string `json:"name"` + URL string `json:"url"` +} + +type CreateComplianceExternalURLPayload struct { + ComplianceExternalURLEdge *ComplianceExternalURLEdge `json:"complianceExternalUrlEdge"` +} + type CreateComplianceFrameworkInput struct { TrustCenterID gid.GID `json:"trustCenterId"` FrameworkID gid.GID `json:"frameworkId"` @@ -793,6 +821,14 @@ type DeleteAuditReportPayload struct { Audit *Audit `json:"audit"` } +type DeleteComplianceExternalURLInput struct { + ID gid.GID `json:"id"` +} + +type DeleteComplianceExternalURLPayload struct { + DeletedComplianceExternalURLID gid.GID `json:"deletedComplianceExternalUrlId"` +} + type DeleteComplianceFrameworkInput struct { ID gid.GID `json:"id"` } @@ -1864,19 +1900,20 @@ type TransferImpactAssessmentFilter struct { } type TrustCenter struct { - ID gid.GID `json:"id"` - Active bool `json:"active"` - LogoFileURL *string `json:"logoFileUrl,omitempty"` - DarkLogoFileURL *string `json:"darkLogoFileUrl,omitempty"` - NdaFileName *string `json:"ndaFileName,omitempty"` - NdaFileURL *string `json:"ndaFileUrl,omitempty"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - Organization *Organization `json:"organization"` - Accesses *TrustCenterAccessConnection `json:"accesses"` - References *TrustCenterReferenceConnection `json:"references"` - ComplianceFrameworks *ComplianceFrameworkConnection `json:"complianceFrameworks"` - Permission bool `json:"permission"` + ID gid.GID `json:"id"` + Active bool `json:"active"` + LogoFileURL *string `json:"logoFileUrl,omitempty"` + DarkLogoFileURL *string `json:"darkLogoFileUrl,omitempty"` + NdaFileName *string `json:"ndaFileName,omitempty"` + NdaFileURL *string `json:"ndaFileUrl,omitempty"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + Organization *Organization `json:"organization"` + Accesses *TrustCenterAccessConnection `json:"accesses"` + References *TrustCenterReferenceConnection `json:"references"` + ComplianceFrameworks *ComplianceFrameworkConnection `json:"complianceFrameworks"` + ExternalUrls *ComplianceExternalURLConnection `json:"externalUrls"` + Permission bool `json:"permission"` } func (TrustCenter) IsNode() {} @@ -2006,6 +2043,17 @@ type UpdateAuditPayload struct { Audit *Audit `json:"audit"` } +type UpdateComplianceExternalURLInput struct { + ID gid.GID `json:"id"` + Name string `json:"name"` + URL string `json:"url"` + Rank *int `json:"rank,omitempty"` +} + +type UpdateComplianceExternalURLPayload struct { + ComplianceExternalURL *ComplianceExternalURL `json:"complianceExternalUrl"` +} + type UpdateComplianceFrameworkInput struct { ID gid.GID `json:"id"` Rank int `json:"rank"` diff --git a/pkg/server/api/console/v1/v1_resolver.go b/pkg/server/api/console/v1/v1_resolver.go index 68a92c12e..82f061912 100644 --- a/pkg/server/api/console/v1/v1_resolver.go +++ b/pkg/server/api/console/v1/v1_resolver.go @@ -324,6 +324,11 @@ func (r *auditConnectionResolver) TotalCount(ctx context.Context, obj *types.Aud return count, nil } +// Permission is the resolver for the permission field. +func (r *complianceExternalURLResolver) Permission(ctx context.Context, obj *types.ComplianceExternalURL, action string) (bool, error) { + return r.Resolver.Permission(ctx, obj, action) +} + // Framework is the resolver for the framework field. func (r *complianceFrameworkResolver) Framework(ctx context.Context, obj *types.ComplianceFramework) (*types.Framework, error) { if err := r.authorize(ctx, obj.FrameworkID, probo.ActionFrameworkGet); err != nil { @@ -2141,6 +2146,74 @@ func (r *mutationResolver) DeleteComplianceFramework(ctx context.Context, input }, nil } +// CreateComplianceExternalURL is the resolver for the createComplianceExternalURL field. +func (r *mutationResolver) CreateComplianceExternalURL(ctx context.Context, input types.CreateComplianceExternalURLInput) (*types.CreateComplianceExternalURLPayload, error) { + if err := r.authorize(ctx, input.TrustCenterID, probo.ActionComplianceExternalURLCreate); err != nil { + return nil, err + } + + prb := r.ProboService(ctx, input.TrustCenterID.TenantID()) + + item, err := prb.ComplianceExternalURLs.Create( + ctx, + &probo.CreateComplianceExternalURLRequest{ + TrustCenterID: input.TrustCenterID, + Name: input.Name, + URL: input.URL, + }, + ) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot create compliance external URL", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + return &types.CreateComplianceExternalURLPayload{ + ComplianceExternalURLEdge: types.NewComplianceExternalURLEdge(item, coredata.ComplianceExternalURLOrderFieldRank), + }, nil +} + +// UpdateComplianceExternalURL is the resolver for the updateComplianceExternalURL field. +func (r *mutationResolver) UpdateComplianceExternalURL(ctx context.Context, input types.UpdateComplianceExternalURLInput) (*types.UpdateComplianceExternalURLPayload, error) { + if err := r.authorize(ctx, input.ID, probo.ActionComplianceExternalURLUpdate); err != nil { + return nil, err + } + + prb := r.ProboService(ctx, input.ID.TenantID()) + + item, err := prb.ComplianceExternalURLs.Update(ctx, &probo.UpdateComplianceExternalURLRequest{ + ID: input.ID, + Name: input.Name, + URL: input.URL, + Rank: input.Rank, + }) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot update compliance external URL", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + return &types.UpdateComplianceExternalURLPayload{ + ComplianceExternalURL: types.NewComplianceExternalURL(item), + }, nil +} + +// DeleteComplianceExternalURL is the resolver for the deleteComplianceExternalURL field. +func (r *mutationResolver) DeleteComplianceExternalURL(ctx context.Context, input types.DeleteComplianceExternalURLInput) (*types.DeleteComplianceExternalURLPayload, error) { + if err := r.authorize(ctx, input.ID, probo.ActionComplianceExternalURLDelete); err != nil { + return nil, err + } + + prb := r.ProboService(ctx, input.ID.TenantID()) + + if err := prb.ComplianceExternalURLs.Delete(ctx, &probo.DeleteComplianceExternalURLRequest{ID: input.ID}); err != nil { + r.logger.ErrorCtx(ctx, "cannot delete compliance external URL", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + return &types.DeleteComplianceExternalURLPayload{ + DeletedComplianceExternalURLID: input.ID, + }, nil +} + // CreateTrustCenterFile is the resolver for the createTrustCenterFile field. func (r *mutationResolver) CreateTrustCenterFile(ctx context.Context, input types.CreateTrustCenterFileInput) (*types.CreateTrustCenterFilePayload, error) { if err := r.authorize(ctx, input.OrganizationID, probo.ActionTrustCenterFileCreate); err != nil { @@ -7887,6 +7960,36 @@ func (r *trustCenterResolver) ComplianceFrameworks(ctx context.Context, obj *typ return types.NewComplianceFrameworkConnection(result), nil } +// ExternalUrls is the resolver for the externalUrls field. +func (r *trustCenterResolver) ExternalUrls(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.OrderBy[coredata.ComplianceExternalURLOrderField]) (*types.ComplianceExternalURLConnection, error) { + if err := r.authorize(ctx, obj.ID, probo.ActionComplianceExternalURLList); err != nil { + return nil, err + } + + prb := r.ProboService(ctx, obj.ID.TenantID()) + + pageOrderBy := page.OrderBy[coredata.ComplianceExternalURLOrderField]{ + Field: coredata.ComplianceExternalURLOrderFieldRank, + Direction: page.OrderDirectionAsc, + } + if orderBy != nil { + pageOrderBy = page.OrderBy[coredata.ComplianceExternalURLOrderField]{ + Field: orderBy.Field, + Direction: orderBy.Direction, + } + } + + cursor := types.NewCursor(first, after, last, before, pageOrderBy) + + result, err := prb.ComplianceExternalURLs.List(ctx, obj.ID, cursor) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot list compliance external URLs", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + return types.NewComplianceExternalURLConnection(result), nil +} + // Permission is the resolver for the permission field. func (r *trustCenterResolver) Permission(ctx context.Context, obj *types.TrustCenter, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) @@ -8868,6 +8971,11 @@ func (r *Resolver) AuditConnection() schema.AuditConnectionResolver { return &auditConnectionResolver{r} } +// ComplianceExternalURL returns schema.ComplianceExternalURLResolver implementation. +func (r *Resolver) ComplianceExternalURL() schema.ComplianceExternalURLResolver { + return &complianceExternalURLResolver{r} +} + // ComplianceFramework returns schema.ComplianceFrameworkResolver implementation. func (r *Resolver) ComplianceFramework() schema.ComplianceFrameworkResolver { return &complianceFrameworkResolver{r} @@ -9175,6 +9283,7 @@ type assetResolver struct{ *Resolver } type assetConnectionResolver struct{ *Resolver } type auditResolver struct{ *Resolver } type auditConnectionResolver struct{ *Resolver } +type complianceExternalURLResolver struct{ *Resolver } type complianceFrameworkResolver struct{ *Resolver } type continualImprovementResolver struct{ *Resolver } type continualImprovementConnectionResolver struct{ *Resolver } diff --git a/pkg/server/api/trust/v1/schema.graphql b/pkg/server/api/trust/v1/schema.graphql index 64222612f..e2193bec9 100644 --- a/pkg/server/api/trust/v1/schema.graphql +++ b/pkg/server/api/trust/v1/schema.graphql @@ -573,6 +573,30 @@ type TrustCenter implements Node { last: Int before: CursorKey ): ComplianceFrameworkConnection! @goField(forceResolver: true) + + externalUrls( + first: Int + after: CursorKey + last: Int + before: CursorKey + ): ComplianceExternalURLConnection! @goField(forceResolver: true) +} + +type ComplianceExternalURL implements Node { + id: ID! + name: String! + url: String! + rank: Int! +} + +type ComplianceExternalURLConnection { + edges: [ComplianceExternalURLEdge!]! + pageInfo: PageInfo! +} + +type ComplianceExternalURLEdge { + cursor: CursorKey! + node: ComplianceExternalURL! } type TrustCenterAccess implements Node { diff --git a/pkg/server/api/trust/v1/schema/schema.go b/pkg/server/api/trust/v1/schema/schema.go index a44513d9b..529f766d9 100644 --- a/pkg/server/api/trust/v1/schema/schema.go +++ b/pkg/server/api/trust/v1/schema/schema.go @@ -78,6 +78,23 @@ type ComplexityRoot struct { Node func(childComplexity int) int } + ComplianceExternalURL struct { + ID func(childComplexity int) int + Name func(childComplexity int) int + Rank func(childComplexity int) int + URL func(childComplexity int) int + } + + ComplianceExternalURLConnection struct { + Edges func(childComplexity int) int + PageInfo func(childComplexity int) int + } + + ComplianceExternalURLEdge struct { + Cursor func(childComplexity int) int + Node func(childComplexity int) int + } + ComplianceFramework struct { Framework func(childComplexity int) int ID func(childComplexity int) int @@ -236,6 +253,7 @@ type ComplexityRoot struct { ComplianceFrameworks func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int DarkLogoFileURL func(childComplexity int) int Documents func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int + ExternalUrls func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int ID func(childComplexity int) int LogoFileURL func(childComplexity int) int NonDisclosureAgreement func(childComplexity int) int @@ -376,6 +394,7 @@ type TrustCenterResolver interface { References(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.TrustCenterReferenceConnection, error) TrustCenterFiles(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.TrustCenterFileConnection, error) ComplianceFrameworks(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.ComplianceFrameworkConnection, error) + ExternalUrls(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.ComplianceExternalURLConnection, error) } type TrustCenterFileResolver interface { IsUserAuthorized(ctx context.Context, obj *types.TrustCenterFile) (bool, error) @@ -460,6 +479,57 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.AuditEdge.Node(childComplexity), true + case "ComplianceExternalURL.id": + if e.ComplexityRoot.ComplianceExternalURL.ID == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURL.ID(childComplexity), true + case "ComplianceExternalURL.name": + if e.ComplexityRoot.ComplianceExternalURL.Name == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURL.Name(childComplexity), true + case "ComplianceExternalURL.rank": + if e.ComplexityRoot.ComplianceExternalURL.Rank == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURL.Rank(childComplexity), true + case "ComplianceExternalURL.url": + if e.ComplexityRoot.ComplianceExternalURL.URL == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURL.URL(childComplexity), true + + case "ComplianceExternalURLConnection.edges": + if e.ComplexityRoot.ComplianceExternalURLConnection.Edges == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURLConnection.Edges(childComplexity), true + case "ComplianceExternalURLConnection.pageInfo": + if e.ComplexityRoot.ComplianceExternalURLConnection.PageInfo == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURLConnection.PageInfo(childComplexity), true + + case "ComplianceExternalURLEdge.cursor": + if e.ComplexityRoot.ComplianceExternalURLEdge.Cursor == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURLEdge.Cursor(childComplexity), true + case "ComplianceExternalURLEdge.node": + if e.ComplexityRoot.ComplianceExternalURLEdge.Node == nil { + break + } + + return e.ComplexityRoot.ComplianceExternalURLEdge.Node(childComplexity), true + case "ComplianceFramework.framework": if e.ComplexityRoot.ComplianceFramework.Framework == nil { break @@ -1053,6 +1123,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin } return e.ComplexityRoot.TrustCenter.Documents(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey)), true + case "TrustCenter.externalUrls": + if e.ComplexityRoot.TrustCenter.ExternalUrls == nil { + break + } + + args, err := ec.field_TrustCenter_externalUrls_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.TrustCenter.ExternalUrls(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey)), true case "TrustCenter.id": if e.ComplexityRoot.TrustCenter.ID == nil { break @@ -2020,6 +2101,30 @@ type TrustCenter implements Node { last: Int before: CursorKey ): ComplianceFrameworkConnection! @goField(forceResolver: true) + + externalUrls( + first: Int + after: CursorKey + last: Int + before: CursorKey + ): ComplianceExternalURLConnection! @goField(forceResolver: true) +} + +type ComplianceExternalURL implements Node { + id: ID! + name: String! + url: String! + rank: Int! +} + +type ComplianceExternalURLConnection { + edges: [ComplianceExternalURLEdge!]! + pageInfo: PageInfo! +} + +type ComplianceExternalURLEdge { + cursor: CursorKey! + node: ComplianceExternalURL! } type TrustCenterAccess implements Node { @@ -2595,6 +2700,32 @@ func (ec *executionContext) field_TrustCenter_documents_args(ctx context.Context return args, nil } +func (ec *executionContext) field_TrustCenter_externalUrls_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "first", ec.unmarshalOInt2ᚖint) + if err != nil { + return nil, err + } + args["first"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "after", ec.unmarshalOCursorKey2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋpageᚐCursorKey) + if err != nil { + return nil, err + } + args["after"] = arg1 + arg2, err := graphql.ProcessArgField(ctx, rawArgs, "last", ec.unmarshalOInt2ᚖint) + if err != nil { + return nil, err + } + args["last"] = arg2 + arg3, err := graphql.ProcessArgField(ctx, rawArgs, "before", ec.unmarshalOCursorKey2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋpageᚐCursorKey) + if err != nil { + return nil, err + } + args["before"] = arg3 + return args, nil +} + func (ec *executionContext) field_TrustCenter_references_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -3102,6 +3233,264 @@ func (ec *executionContext) fieldContext_AuditEdge_node(_ context.Context, field return fc, nil } +func (ec *executionContext) _ComplianceExternalURL_id(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURL) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURL_id, + func(ctx context.Context) (any, error) { + return obj.ID, nil + }, + nil, + ec.marshalNID2goᚗproboᚗincᚋproboᚋpkgᚋgidᚐGID, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURL_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURL", + 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) _ComplianceExternalURL_name(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURL) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURL_name, + func(ctx context.Context) (any, error) { + return obj.Name, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURL_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURL", + 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) _ComplianceExternalURL_url(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURL) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURL_url, + func(ctx context.Context) (any, error) { + return obj.URL, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURL_url(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURL", + 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) _ComplianceExternalURL_rank(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURL) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURL_rank, + func(ctx context.Context) (any, error) { + return obj.Rank, nil + }, + nil, + ec.marshalNInt2int, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURL_rank(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURL", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceExternalURLConnection_edges(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURLConnection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURLConnection_edges, + func(ctx context.Context) (any, error) { + return obj.Edges, nil + }, + nil, + ec.marshalNComplianceExternalURLEdge2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceExternalURLEdgeᚄ, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURLConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURLConnection", + 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_ComplianceExternalURLEdge_cursor(ctx, field) + case "node": + return ec.fieldContext_ComplianceExternalURLEdge_node(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceExternalURLEdge", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ComplianceExternalURLConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURLConnection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURLConnection_pageInfo, + func(ctx context.Context) (any, error) { + return obj.PageInfo, nil + }, + nil, + ec.marshalNPageInfo2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐPageInfo, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURLConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURLConnection", + 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) _ComplianceExternalURLEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURLEdge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURLEdge_cursor, + func(ctx context.Context) (any, error) { + return obj.Cursor, nil + }, + nil, + ec.marshalNCursorKey2goᚗproboᚗincᚋproboᚋpkgᚋpageᚐCursorKey, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURLEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURLEdge", + 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) _ComplianceExternalURLEdge_node(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceExternalURLEdge) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_ComplianceExternalURLEdge_node, + func(ctx context.Context) (any, error) { + return obj.Node, nil + }, + nil, + ec.marshalNComplianceExternalURL2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceExternalURL, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_ComplianceExternalURLEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ComplianceExternalURLEdge", + 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_ComplianceExternalURL_id(ctx, field) + case "name": + return ec.fieldContext_ComplianceExternalURL_name(ctx, field) + case "url": + return ec.fieldContext_ComplianceExternalURL_url(ctx, field) + case "rank": + return ec.fieldContext_ComplianceExternalURL_rank(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceExternalURL", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _ComplianceFramework_id(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFramework) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -5660,6 +6049,8 @@ func (ec *executionContext) fieldContext_Query_currentTrustCenter(_ context.Cont return ec.fieldContext_TrustCenter_trustCenterFiles(ctx, field) case "complianceFrameworks": return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field) + case "externalUrls": + return ec.fieldContext_TrustCenter_externalUrls(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type TrustCenter", field.Name) }, @@ -6732,6 +7123,53 @@ func (ec *executionContext) fieldContext_TrustCenter_complianceFrameworks(ctx co return fc, nil } +func (ec *executionContext) _TrustCenter_externalUrls(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_TrustCenter_externalUrls, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.TrustCenter().ExternalUrls(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey)) + }, + nil, + ec.marshalNComplianceExternalURLConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceExternalURLConnection, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_TrustCenter_externalUrls(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TrustCenter", + 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_ComplianceExternalURLConnection_edges(ctx, field) + case "pageInfo": + return ec.fieldContext_ComplianceExternalURLConnection_pageInfo(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ComplianceExternalURLConnection", 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_TrustCenter_externalUrls_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _TrustCenterAccess_id(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenterAccess) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -9822,6 +10260,13 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._ComplianceFramework(ctx, sel, obj) + case types.ComplianceExternalURL: + return ec._ComplianceExternalURL(ctx, sel, &obj) + case *types.ComplianceExternalURL: + if obj == nil { + return graphql.Null + } + return ec._ComplianceExternalURL(ctx, sel, obj) case types.Audit: return ec._Audit(ctx, sel, &obj) case *types.Audit: @@ -10079,6 +10524,148 @@ func (ec *executionContext) _AuditEdge(ctx context.Context, sel ast.SelectionSet return out } +var complianceExternalURLImplementors = []string{"ComplianceExternalURL", "Node"} + +func (ec *executionContext) _ComplianceExternalURL(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceExternalURL) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, complianceExternalURLImplementors) + + 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("ComplianceExternalURL") + case "id": + out.Values[i] = ec._ComplianceExternalURL_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._ComplianceExternalURL_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "url": + out.Values[i] = ec._ComplianceExternalURL_url(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "rank": + out.Values[i] = ec._ComplianceExternalURL_rank(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 complianceExternalURLConnectionImplementors = []string{"ComplianceExternalURLConnection"} + +func (ec *executionContext) _ComplianceExternalURLConnection(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceExternalURLConnection) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, complianceExternalURLConnectionImplementors) + + 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("ComplianceExternalURLConnection") + case "edges": + out.Values[i] = ec._ComplianceExternalURLConnection_edges(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "pageInfo": + out.Values[i] = ec._ComplianceExternalURLConnection_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 complianceExternalURLEdgeImplementors = []string{"ComplianceExternalURLEdge"} + +func (ec *executionContext) _ComplianceExternalURLEdge(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceExternalURLEdge) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, complianceExternalURLEdgeImplementors) + + 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("ComplianceExternalURLEdge") + case "cursor": + out.Values[i] = ec._ComplianceExternalURLEdge_cursor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "node": + out.Values[i] = ec._ComplianceExternalURLEdge_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 complianceFrameworkImplementors = []string{"ComplianceFramework", "Node"} func (ec *executionContext) _ComplianceFramework(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceFramework) graphql.Marshaler { @@ -12027,6 +12614,42 @@ func (ec *executionContext) _TrustCenter(ctx context.Context, sel ast.SelectionS continue } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "externalUrls": + 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._TrustCenter_externalUrls(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) }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -13156,6 +13779,56 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se return res } +func (ec *executionContext) marshalNComplianceExternalURL2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceExternalURL(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceExternalURL) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._ComplianceExternalURL(ctx, sel, v) +} + +func (ec *executionContext) marshalNComplianceExternalURLConnection2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceExternalURLConnection(ctx context.Context, sel ast.SelectionSet, v types.ComplianceExternalURLConnection) graphql.Marshaler { + return ec._ComplianceExternalURLConnection(ctx, sel, &v) +} + +func (ec *executionContext) marshalNComplianceExternalURLConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceExternalURLConnection(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceExternalURLConnection) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._ComplianceExternalURLConnection(ctx, sel, v) +} + +func (ec *executionContext) marshalNComplianceExternalURLEdge2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceExternalURLEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []*types.ComplianceExternalURLEdge) graphql.Marshaler { + ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { + fc := graphql.GetFieldContext(ctx) + fc.Result = &v[i] + return ec.marshalNComplianceExternalURLEdge2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceExternalURLEdge(ctx, sel, v[i]) + }) + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNComplianceExternalURLEdge2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceExternalURLEdge(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceExternalURLEdge) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._ComplianceExternalURLEdge(ctx, sel, v) +} + func (ec *executionContext) marshalNComplianceFramework2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFramework(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceFramework) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { diff --git a/pkg/server/api/trust/v1/types/compliance_external_url.go b/pkg/server/api/trust/v1/types/compliance_external_url.go new file mode 100644 index 000000000..24bcb2d76 --- /dev/null +++ b/pkg/server/api/trust/v1/types/compliance_external_url.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 types + +import ( + "go.probo.inc/probo/pkg/coredata" + "go.probo.inc/probo/pkg/page" +) + +func NewComplianceExternalURL(c *coredata.ComplianceExternalURL) *ComplianceExternalURL { + return &ComplianceExternalURL{ + ID: c.ID, + Name: c.Name, + URL: c.URL, + Rank: c.Rank, + } +} + +func NewComplianceExternalURLConnection( + p *page.Page[*coredata.ComplianceExternalURL, coredata.ComplianceExternalURLOrderField], +) *ComplianceExternalURLConnection { + edges := make([]*ComplianceExternalURLEdge, len(p.Data)) + + for i, item := range p.Data { + edges[i] = NewComplianceExternalURLEdge(item, p.Cursor.OrderBy.Field) + } + + return &ComplianceExternalURLConnection{ + Edges: edges, + PageInfo: NewPageInfo(p), + } +} + +func NewComplianceExternalURLEdge(c *coredata.ComplianceExternalURL, orderBy coredata.ComplianceExternalURLOrderField) *ComplianceExternalURLEdge { + return &ComplianceExternalURLEdge{ + Cursor: c.CursorKey(orderBy), + Node: NewComplianceExternalURL(c), + } +} diff --git a/pkg/server/api/trust/v1/types/types.go b/pkg/server/api/trust/v1/types/types.go index beec30cef..6dec3dc0b 100644 --- a/pkg/server/api/trust/v1/types/types.go +++ b/pkg/server/api/trust/v1/types/types.go @@ -44,6 +44,26 @@ type AuditEdge struct { Node *Audit `json:"node"` } +type ComplianceExternalURL struct { + ID gid.GID `json:"id"` + Name string `json:"name"` + URL string `json:"url"` + Rank int `json:"rank"` +} + +func (ComplianceExternalURL) IsNode() {} +func (this ComplianceExternalURL) GetID() gid.GID { return this.ID } + +type ComplianceExternalURLConnection struct { + Edges []*ComplianceExternalURLEdge `json:"edges"` + PageInfo *PageInfo `json:"pageInfo"` +} + +type ComplianceExternalURLEdge struct { + Cursor page.CursorKey `json:"cursor"` + Node *ComplianceExternalURL `json:"node"` +} + type Document struct { ID gid.GID `json:"id"` Title string `json:"title"` @@ -222,19 +242,20 @@ type SendMagicLinkPayload struct { } type TrustCenter struct { - ID gid.GID `json:"id"` - Active bool `json:"active"` - Slug string `json:"slug"` - LogoFileURL *string `json:"logoFileUrl,omitempty"` - DarkLogoFileURL *string `json:"darkLogoFileUrl,omitempty"` - NonDisclosureAgreement *NonDisclosureAgreement `json:"nonDisclosureAgreement,omitempty"` - Organization *Organization `json:"organization"` - Documents *DocumentConnection `json:"documents"` - Audits *AuditConnection `json:"audits"` - Vendors *VendorConnection `json:"vendors"` - References *TrustCenterReferenceConnection `json:"references"` - TrustCenterFiles *TrustCenterFileConnection `json:"trustCenterFiles"` - ComplianceFrameworks *ComplianceFrameworkConnection `json:"complianceFrameworks"` + ID gid.GID `json:"id"` + Active bool `json:"active"` + Slug string `json:"slug"` + LogoFileURL *string `json:"logoFileUrl,omitempty"` + DarkLogoFileURL *string `json:"darkLogoFileUrl,omitempty"` + NonDisclosureAgreement *NonDisclosureAgreement `json:"nonDisclosureAgreement,omitempty"` + Organization *Organization `json:"organization"` + Documents *DocumentConnection `json:"documents"` + Audits *AuditConnection `json:"audits"` + Vendors *VendorConnection `json:"vendors"` + References *TrustCenterReferenceConnection `json:"references"` + TrustCenterFiles *TrustCenterFileConnection `json:"trustCenterFiles"` + ComplianceFrameworks *ComplianceFrameworkConnection `json:"complianceFrameworks"` + ExternalUrls *ComplianceExternalURLConnection `json:"externalUrls"` } func (TrustCenter) IsNode() {} diff --git a/pkg/server/api/trust/v1/v1_resolver.go b/pkg/server/api/trust/v1/v1_resolver.go index d75d58dba..ed2372839 100644 --- a/pkg/server/api/trust/v1/v1_resolver.go +++ b/pkg/server/api/trust/v1/v1_resolver.go @@ -1108,6 +1108,25 @@ func (r *trustCenterResolver) ComplianceFrameworks(ctx context.Context, obj *typ return types.NewComplianceFrameworkConnection(cfPage), nil } +// ExternalUrls is the resolver for the externalUrls field. +func (r *trustCenterResolver) ExternalUrls(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.ComplianceExternalURLConnection, error) { + trustService := r.TrustService(ctx, obj.ID.TenantID()) + + pageOrderBy := page.OrderBy[coredata.ComplianceExternalURLOrderField]{ + Field: coredata.ComplianceExternalURLOrderFieldRank, + Direction: page.OrderDirectionAsc, + } + cursor := types.NewCursor(first, after, last, before, pageOrderBy) + + result, err := trustService.ComplianceExternalURLs.ListForTrustCenterID(ctx, obj.ID, cursor) + if err != nil { + r.logger.ErrorCtx(ctx, "cannot list compliance external URLs", log.Error(err)) + return nil, gqlutils.Internal(ctx) + } + + return types.NewComplianceExternalURLConnection(result), nil +} + // IsUserAuthorized is the resolver for the isUserAuthorized field. func (r *trustCenterFileResolver) IsUserAuthorized(ctx context.Context, obj *types.TrustCenterFile) (bool, error) { trustService := r.TrustService(ctx, obj.ID.TenantID()) diff --git a/pkg/trust/compliance_external_url_service.go b/pkg/trust/compliance_external_url_service.go new file mode 100644 index 000000000..95d6372ff --- /dev/null +++ b/pkg/trust/compliance_external_url_service.go @@ -0,0 +1,55 @@ +// 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 trust + +import ( + "context" + "fmt" + + "go.gearno.de/kit/pg" + "go.probo.inc/probo/pkg/coredata" + "go.probo.inc/probo/pkg/gid" + "go.probo.inc/probo/pkg/page" +) + +type ComplianceExternalURLService struct { + svc *TenantService +} + +func (s ComplianceExternalURLService) ListForTrustCenterID( + ctx context.Context, + trustCenterID gid.GID, + cursor *page.Cursor[coredata.ComplianceExternalURLOrderField], +) (*page.Page[*coredata.ComplianceExternalURL, coredata.ComplianceExternalURLOrderField], error) { + var items coredata.ComplianceExternalURLs + + err := s.svc.pg.WithConn( + ctx, + func(conn pg.Conn) error { + err := items.LoadByTrustCenterID(ctx, conn, s.svc.scope, trustCenterID, cursor) + if err != nil { + return fmt.Errorf("cannot load compliance external URLs: %w", err) + } + + return nil + }, + ) + + if err != nil { + return nil, err + } + + return page.NewPage(items, cursor), nil +} diff --git a/pkg/trust/service.go b/pkg/trust/service.go index 6e5ac169a..6749dcbd8 100644 --- a/pkg/trust/service.go +++ b/pkg/trust/service.go @@ -50,29 +50,30 @@ type ( } TenantService struct { - pg *pg.Client - s3 *s3.Client - bucket string - scope coredata.Scoper - proboSvc *probo.Service - baseURL string - iam *iam.Service - esign *esign.Service - html2pdfConverter *html2pdf.Converter - fileManager *filemanager.Service - logger *log.Logger - TrustCenters *TrustCenterService - Documents *DocumentService - Audits *AuditService - Vendors *VendorService - Frameworks *FrameworkService - ComplianceFrameworks *ComplianceFrameworkService - TrustCenterAccesses *TrustCenterAccessService - TrustCenterReferences *TrustCenterReferenceService - TrustCenterFiles *TrustCenterFileService - Reports *ReportService - Organizations *OrganizationService - SlackMessages *slack.SlackMessageService + pg *pg.Client + s3 *s3.Client + bucket string + scope coredata.Scoper + proboSvc *probo.Service + baseURL string + iam *iam.Service + esign *esign.Service + html2pdfConverter *html2pdf.Converter + fileManager *filemanager.Service + logger *log.Logger + TrustCenters *TrustCenterService + Documents *DocumentService + Audits *AuditService + Vendors *VendorService + Frameworks *FrameworkService + ComplianceFrameworks *ComplianceFrameworkService + TrustCenterAccesses *TrustCenterAccessService + TrustCenterReferences *TrustCenterReferenceService + TrustCenterFiles *TrustCenterFileService + Reports *ReportService + Organizations *OrganizationService + ComplianceExternalURLs *ComplianceExternalURLService + SlackMessages *slack.SlackMessageService } ) @@ -130,6 +131,7 @@ func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService { tenantService.TrustCenterFiles = &TrustCenterFileService{svc: tenantService} tenantService.Reports = &ReportService{svc: tenantService} tenantService.Organizations = &OrganizationService{svc: tenantService} + tenantService.ComplianceExternalURLs = &ComplianceExternalURLService{svc: tenantService} tenantService.SlackMessages = s.slack.WithTenant(tenantID).SlackMessages return tenantService