Add compliance frameworks
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
265
apps/console/src/__generated__/core/CompliancePageFrameworkList_compliancePageFragment.graphql.ts
generated
Normal file
265
apps/console/src/__generated__/core/CompliancePageFrameworkList_compliancePageFragment.graphql.ts
generated
Normal file
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* @generated SignedSource<<8626547ee7655aabebf153f2429023d7>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
export type ComplianceFrameworkVisibility = "NONE" | "PUBLIC";
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type CompliancePageFrameworkList_compliancePageFragment$data = {
|
||||
readonly canUpdate: boolean;
|
||||
readonly complianceFrameworks: {
|
||||
readonly __id: string;
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly framework: {
|
||||
readonly darkLogoURL: string | null | undefined;
|
||||
readonly id: string;
|
||||
readonly lightLogoURL: string | null | undefined;
|
||||
readonly name: string;
|
||||
};
|
||||
readonly id: string;
|
||||
readonly rank: number;
|
||||
readonly visibility: ComplianceFrameworkVisibility;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly id: string;
|
||||
readonly " $fragmentType": "CompliancePageFrameworkList_compliancePageFragment";
|
||||
};
|
||||
export type CompliancePageFrameworkList_compliancePageFragment$key = {
|
||||
readonly " $data"?: CompliancePageFrameworkList_compliancePageFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"CompliancePageFrameworkList_compliancePageFragment">;
|
||||
};
|
||||
|
||||
import CompliancePageFrameworkList_compliancePageRefetchQuery_graphql from './CompliancePageFrameworkList_compliancePageRefetchQuery.graphql';
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = [
|
||||
"complianceFrameworks"
|
||||
],
|
||||
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": CompliancePageFrameworkList_compliancePageRefetchQuery_graphql,
|
||||
"identifierInfo": {
|
||||
"identifierField": "id",
|
||||
"identifierQueryVariableName": "id"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "CompliancePageFrameworkList_compliancePageFragment",
|
||||
"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": "complianceFrameworks",
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "orderBy",
|
||||
"variableName": "order"
|
||||
}
|
||||
],
|
||||
"concreteType": "ComplianceFrameworkConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__CompliancePageFrameworkList_complianceFrameworks_connection",
|
||||
"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": [
|
||||
(v1/*: 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": [
|
||||
(v1/*: 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
|
||||
},
|
||||
{
|
||||
"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 = "981aff9d27dc71027541f7c3ed6984a9";
|
||||
|
||||
export default node;
|
||||
335
apps/console/src/__generated__/core/CompliancePageFrameworkList_compliancePageRefetchQuery.graphql.ts
generated
Normal file
335
apps/console/src/__generated__/core/CompliancePageFrameworkList_compliancePageRefetchQuery.graphql.ts
generated
Normal file
@@ -0,0 +1,335 @@
|
||||
/**
|
||||
* @generated SignedSource<<baca8afb1ea09de1d4e9cc721fa3318e>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type ComplianceFrameworkOrderField = "CREATED_AT" | "RANK";
|
||||
export type OrderDirection = "ASC" | "DESC";
|
||||
export type ComplianceFrameworkOrder = {
|
||||
direction: OrderDirection;
|
||||
field: ComplianceFrameworkOrderField;
|
||||
};
|
||||
export type CompliancePageFrameworkList_compliancePageRefetchQuery$variables = {
|
||||
after?: string | null | undefined;
|
||||
first?: number | null | undefined;
|
||||
id: string;
|
||||
order?: ComplianceFrameworkOrder | null | undefined;
|
||||
};
|
||||
export type CompliancePageFrameworkList_compliancePageRefetchQuery$data = {
|
||||
readonly node: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"CompliancePageFrameworkList_compliancePageFragment">;
|
||||
};
|
||||
};
|
||||
export type CompliancePageFrameworkList_compliancePageRefetchQuery = {
|
||||
response: CompliancePageFrameworkList_compliancePageRefetchQuery$data;
|
||||
variables: CompliancePageFrameworkList_compliancePageRefetchQuery$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": "CompliancePageFrameworkList_compliancePageRefetchQuery",
|
||||
"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": "CompliancePageFrameworkList_compliancePageFragment"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Query",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/),
|
||||
(v3/*: any*/),
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"kind": "Operation",
|
||||
"name": "CompliancePageFrameworkList_compliancePageRefetchQuery",
|
||||
"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": "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": [
|
||||
(v8/*: 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": [
|
||||
(v8/*: 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
|
||||
},
|
||||
(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": "CompliancePageFrameworkList_complianceFrameworks",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "complianceFrameworks"
|
||||
}
|
||||
],
|
||||
"type": "TrustCenter",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "c3c1d708940371ebc18c2c5272f0b26d",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "CompliancePageFrameworkList_compliancePageRefetchQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query CompliancePageFrameworkList_compliancePageRefetchQuery(\n $after: CursorKey = null\n $first: Int = 100\n $order: ComplianceFrameworkOrder = {field: RANK, direction: ASC}\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...CompliancePageFrameworkList_compliancePageFragment_gOVF5\n id\n }\n}\n\nfragment CompliancePageFrameworkList_compliancePageFragment_gOVF5 on TrustCenter {\n id\n canUpdate: permission(action: \"core:trust-center:update\")\n complianceFrameworks(first: $first, after: $after, orderBy: $order) {\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 = "981aff9d27dc71027541f7c3ed6984a9";
|
||||
|
||||
export default node;
|
||||
119
apps/console/src/__generated__/core/CompliancePageFrameworkList_createMutation.graphql.ts
generated
Normal file
119
apps/console/src/__generated__/core/CompliancePageFrameworkList_createMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* @generated SignedSource<<2980fa2d2a72851686e88a7b5402d720>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type CreateComplianceFrameworkInput = {
|
||||
frameworkId: string;
|
||||
trustCenterId: string;
|
||||
};
|
||||
export type CompliancePageFrameworkList_createMutation$variables = {
|
||||
input: CreateComplianceFrameworkInput;
|
||||
};
|
||||
export type CompliancePageFrameworkList_createMutation$data = {
|
||||
readonly createComplianceFramework: {
|
||||
readonly complianceFrameworkEdge: {
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
export type CompliancePageFrameworkList_createMutation = {
|
||||
response: CompliancePageFrameworkList_createMutation$data;
|
||||
variables: CompliancePageFrameworkList_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": "CreateComplianceFrameworkPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "createComplianceFramework",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ComplianceFrameworkEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "complianceFrameworkEdge",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ComplianceFramework",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "CompliancePageFrameworkList_createMutation",
|
||||
"selections": (v1/*: any*/),
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "CompliancePageFrameworkList_createMutation",
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "9caebfdeda321fb743a8d789c7e25e82",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "CompliancePageFrameworkList_createMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation CompliancePageFrameworkList_createMutation(\n $input: CreateComplianceFrameworkInput!\n) {\n createComplianceFramework(input: $input) {\n complianceFrameworkEdge {\n node {\n id\n }\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "41815aaef15ed1754b4d81c1d982a2c6";
|
||||
|
||||
export default node;
|
||||
92
apps/console/src/__generated__/core/CompliancePageFrameworkList_deleteMutation.graphql.ts
generated
Normal file
92
apps/console/src/__generated__/core/CompliancePageFrameworkList_deleteMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* @generated SignedSource<<0f29d441e95842685f0311839d3b45ef>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type DeleteComplianceFrameworkInput = {
|
||||
id: string;
|
||||
};
|
||||
export type CompliancePageFrameworkList_deleteMutation$variables = {
|
||||
input: DeleteComplianceFrameworkInput;
|
||||
};
|
||||
export type CompliancePageFrameworkList_deleteMutation$data = {
|
||||
readonly deleteComplianceFramework: {
|
||||
readonly deletedComplianceFrameworkId: string;
|
||||
};
|
||||
};
|
||||
export type CompliancePageFrameworkList_deleteMutation = {
|
||||
response: CompliancePageFrameworkList_deleteMutation$data;
|
||||
variables: CompliancePageFrameworkList_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": "DeleteComplianceFrameworkPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "deleteComplianceFramework",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deletedComplianceFrameworkId",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "CompliancePageFrameworkList_deleteMutation",
|
||||
"selections": (v1/*: any*/),
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "CompliancePageFrameworkList_deleteMutation",
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "5792168e44352169568a1378b621df16",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "CompliancePageFrameworkList_deleteMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation CompliancePageFrameworkList_deleteMutation(\n $input: DeleteComplianceFrameworkInput!\n) {\n deleteComplianceFramework(input: $input) {\n deletedComplianceFrameworkId\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "fed45c59adf7d88aec4bbb7eb61840c3";
|
||||
|
||||
export default node;
|
||||
114
apps/console/src/__generated__/core/CompliancePageFrameworkList_updateRankMutation.graphql.ts
generated
Normal file
114
apps/console/src/__generated__/core/CompliancePageFrameworkList_updateRankMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @generated SignedSource<<3c6052dff7f71548026fb23353e215b2>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest } from 'relay-runtime';
|
||||
export type UpdateComplianceFrameworkInput = {
|
||||
id: string;
|
||||
rank: number;
|
||||
};
|
||||
export type CompliancePageFrameworkList_updateRankMutation$variables = {
|
||||
input: UpdateComplianceFrameworkInput;
|
||||
};
|
||||
export type CompliancePageFrameworkList_updateRankMutation$data = {
|
||||
readonly updateComplianceFramework: {
|
||||
readonly complianceFramework: {
|
||||
readonly id: string;
|
||||
readonly rank: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
export type CompliancePageFrameworkList_updateRankMutation = {
|
||||
response: CompliancePageFrameworkList_updateRankMutation$data;
|
||||
variables: CompliancePageFrameworkList_updateRankMutation$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "input"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "input",
|
||||
"variableName": "input"
|
||||
}
|
||||
],
|
||||
"concreteType": "UpdateComplianceFrameworkPayload",
|
||||
"kind": "LinkedField",
|
||||
"name": "updateComplianceFramework",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ComplianceFramework",
|
||||
"kind": "LinkedField",
|
||||
"name": "complianceFramework",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"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": "CompliancePageFrameworkList_updateRankMutation",
|
||||
"selections": (v1/*: any*/),
|
||||
"type": "Mutation",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "CompliancePageFrameworkList_updateRankMutation",
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "429989dd7550f3c5466a8098f5167592",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "CompliancePageFrameworkList_updateRankMutation",
|
||||
"operationKind": "mutation",
|
||||
"text": "mutation CompliancePageFrameworkList_updateRankMutation(\n $input: UpdateComplianceFrameworkInput!\n) {\n updateComplianceFramework(input: $input) {\n complianceFramework {\n id\n rank\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "a60d166f55bbe09a53349b400355ffc0";
|
||||
|
||||
export default node;
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<18bb7ea1b507c374c33d9f4f7a56db2d>>
|
||||
* @generated SignedSource<<cf316aa4cda5fc4c9aebae8f0f10c365>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -17,6 +17,7 @@ export type CompliancePageOverviewPageQuery$data = {
|
||||
readonly organization: {
|
||||
readonly compliancePage?: {
|
||||
readonly canGetNDA: boolean;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"CompliancePageFrameworkList_compliancePageFragment">;
|
||||
} | null | undefined;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"CompliancePageNDASectionFragment" | "CompliancePageSlackSectionFragment" | "CompliancePageStatusSectionFragment">;
|
||||
};
|
||||
@@ -55,12 +56,35 @@ 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*/),
|
||||
@@ -87,7 +111,12 @@ return {
|
||||
"name": "trustCenter",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/)
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "CompliancePageFrameworkList_compliancePageFragment"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
@@ -131,13 +160,7 @@ return {
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
@@ -150,14 +173,7 @@ return {
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "active",
|
||||
"storageKey": null
|
||||
},
|
||||
(v4/*: any*/),
|
||||
{
|
||||
"alias": "canUpdate",
|
||||
"args": [
|
||||
@@ -171,6 +187,150 @@ 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,
|
||||
@@ -229,18 +389,14 @@ return {
|
||||
"name": "domain",
|
||||
"storageKey": null
|
||||
},
|
||||
(v3/*: any*/)
|
||||
(v4/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "first",
|
||||
"value": 100
|
||||
}
|
||||
(v5/*: any*/)
|
||||
],
|
||||
"concreteType": "SlackConnectionConnection",
|
||||
"kind": "LinkedField",
|
||||
@@ -263,7 +419,7 @@ return {
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v4/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
@@ -291,23 +447,23 @@ return {
|
||||
"type": "Organization",
|
||||
"abstractKey": null
|
||||
},
|
||||
(v3/*: any*/)
|
||||
(v4/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "0041132d3ac46a3193d9acbd6f27bdf5",
|
||||
"cacheID": "e6cc68fe4df4a8dffc558f6db82ead9c",
|
||||
"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 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"
|
||||
"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"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "689133b7f1c380266e6f15a60c527c91";
|
||||
(node as any).hash = "be0dff83941c21755ea2ff77a865805b";
|
||||
|
||||
export default node;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
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";
|
||||
@@ -13,6 +15,7 @@ export const compliancePageOverviewPageQuery = graphql`
|
||||
... on Organization {
|
||||
compliancePage: trustCenter {
|
||||
canGetNDA: permission(action: "core:trust-center:get-nda")
|
||||
...CompliancePageFrameworkList_compliancePageFragment
|
||||
}
|
||||
}
|
||||
...CompliancePageStatusSectionFragment
|
||||
@@ -25,6 +28,8 @@ export const compliancePageOverviewPageQuery = graphql`
|
||||
export function CompliancePageOverviewPage(props: { queryRef: PreloadedQuery<CompliancePageOverviewPageQuery> }) {
|
||||
const { queryRef } = props;
|
||||
|
||||
const { __ } = useTranslate();
|
||||
|
||||
const { organization } = usePreloadedQuery<CompliancePageOverviewPageQuery>(
|
||||
compliancePageOverviewPageQuery,
|
||||
queryRef,
|
||||
@@ -39,6 +44,18 @@ export function CompliancePageOverviewPage(props: { queryRef: PreloadedQuery<Com
|
||||
)}
|
||||
|
||||
<CompliancePageSlackSection fragmentRef={organization} />
|
||||
|
||||
{organization.compliancePage && (
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<h3 className="text-base font-medium">{__("Frameworks")}</h3>
|
||||
<p className="text-sm text-txt-tertiary">
|
||||
{__("Select which frameworks to display as badges on your compliance page")}
|
||||
</p>
|
||||
</div>
|
||||
<CompliancePageFrameworkList compliancePageRef={organization.compliancePage} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { Badge, Field, FrameworkLogo, Option, Table, Tbody, Td, Th, Thead, Tr } from "@probo/ui";
|
||||
import { useCallback, useState, useTransition } from "react";
|
||||
import { useRefetchableFragment } from "react-relay";
|
||||
import { ConnectionHandler, graphql } from "relay-runtime";
|
||||
|
||||
import type { CompliancePageFrameworkList_compliancePageFragment$key } from "#/__generated__/core/CompliancePageFrameworkList_compliancePageFragment.graphql";
|
||||
import type { CompliancePageFrameworkList_compliancePageFragment$data } from "#/__generated__/core/CompliancePageFrameworkList_compliancePageFragment.graphql";
|
||||
import type { CompliancePageFrameworkList_compliancePageRefetchQuery } from "#/__generated__/core/CompliancePageFrameworkList_compliancePageRefetchQuery.graphql";
|
||||
import type { CompliancePageFrameworkList_createMutation } from "#/__generated__/core/CompliancePageFrameworkList_createMutation.graphql";
|
||||
import type { CompliancePageFrameworkList_deleteMutation } from "#/__generated__/core/CompliancePageFrameworkList_deleteMutation.graphql";
|
||||
import type { CompliancePageFrameworkList_updateRankMutation } from "#/__generated__/core/CompliancePageFrameworkList_updateRankMutation.graphql";
|
||||
import { useMutationWithToasts } from "#/hooks/useMutationWithToasts";
|
||||
|
||||
const compliancePageFragment = graphql`
|
||||
fragment CompliancePageFrameworkList_compliancePageFragment on TrustCenter
|
||||
@refetchable(queryName: "CompliancePageFrameworkList_compliancePageRefetchQuery")
|
||||
@argumentDefinitions(
|
||||
first: { type: Int, defaultValue: 100 }
|
||||
after: { type: CursorKey, defaultValue: null }
|
||||
order: { type: ComplianceFrameworkOrder, defaultValue: { field: RANK, direction: ASC } }
|
||||
) {
|
||||
id
|
||||
canUpdate: permission(action: "core:trust-center:update")
|
||||
complianceFrameworks(first: $first, after: $after, orderBy: $order)
|
||||
@connection(key: "CompliancePageFrameworkList_complianceFrameworks", filters: ["orderBy"]) {
|
||||
__id
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
rank
|
||||
visibility
|
||||
framework {
|
||||
id
|
||||
name
|
||||
lightLogoURL
|
||||
darkLogoURL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const createMutation = graphql`
|
||||
mutation CompliancePageFrameworkList_createMutation($input: CreateComplianceFrameworkInput!) {
|
||||
createComplianceFramework(input: $input) {
|
||||
complianceFrameworkEdge {
|
||||
node {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const updateRankMutation = graphql`
|
||||
mutation CompliancePageFrameworkList_updateRankMutation($input: UpdateComplianceFrameworkInput!) {
|
||||
updateComplianceFramework(input: $input) {
|
||||
complianceFramework {
|
||||
id
|
||||
rank
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const deleteMutation = graphql`
|
||||
mutation CompliancePageFrameworkList_deleteMutation($input: DeleteComplianceFrameworkInput!) {
|
||||
deleteComplianceFramework(input: $input) {
|
||||
deletedComplianceFrameworkId
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
type Edge = CompliancePageFrameworkList_compliancePageFragment$data["complianceFrameworks"]["edges"][number];
|
||||
|
||||
function CompliancePageFrameworkListItem(props: {
|
||||
edge: Edge;
|
||||
compliancePage: CompliancePageFrameworkList_compliancePageFragment$data;
|
||||
draggedCfId: string | null;
|
||||
dragOverCfId: string | null;
|
||||
onDragStart: (cfId: string) => void;
|
||||
onDragEnd: () => void;
|
||||
onDragOver: (e: React.DragEvent, cfId: string) => void;
|
||||
onDrop: (cfId: string) => void;
|
||||
onRefetch: () => void;
|
||||
}) {
|
||||
const { edge, draggedCfId, dragOverCfId, onDragStart, onDragEnd, onDragOver, onDrop, onRefetch } = props;
|
||||
const { __ } = useTranslate();
|
||||
const [isMouseDown, setIsMouseDown] = useState(false);
|
||||
|
||||
const compliancePage = props.compliancePage;
|
||||
const { id, visibility, framework } = edge.node;
|
||||
|
||||
const isPublic = visibility === "PUBLIC";
|
||||
const canDrag = isPublic && compliancePage.canUpdate;
|
||||
|
||||
const isDragging = draggedCfId === id;
|
||||
const isDropTarget = dragOverCfId === id && draggedCfId !== id;
|
||||
|
||||
const [createComplianceFramework, isCreating] = useMutationWithToasts<CompliancePageFrameworkList_createMutation>(
|
||||
createMutation,
|
||||
{
|
||||
successMessage: __("Framework visibility updated successfully."),
|
||||
errorMessage: __("Failed to update framework visibility"),
|
||||
},
|
||||
);
|
||||
|
||||
const [deleteComplianceFramework, isDeleting] = useMutationWithToasts<CompliancePageFrameworkList_deleteMutation>(
|
||||
deleteMutation,
|
||||
{
|
||||
successMessage: __("Framework visibility updated successfully."),
|
||||
errorMessage: __("Failed to update framework visibility"),
|
||||
},
|
||||
);
|
||||
|
||||
const isLoading = isCreating || isDeleting;
|
||||
|
||||
const handleVisibilityChange = useCallback(
|
||||
async (value: string) => {
|
||||
if (value === "PUBLIC" && !isPublic) {
|
||||
await createComplianceFramework({
|
||||
variables: {
|
||||
input: {
|
||||
trustCenterId: compliancePage.id,
|
||||
frameworkId: framework.id,
|
||||
},
|
||||
},
|
||||
onCompleted: (_, errors) => {
|
||||
if (!errors?.length) {
|
||||
onRefetch();
|
||||
}
|
||||
},
|
||||
});
|
||||
} else if (value === "NONE" && isPublic) {
|
||||
await deleteComplianceFramework({
|
||||
variables: {
|
||||
input: { id },
|
||||
},
|
||||
onCompleted: (_, errors) => {
|
||||
if (!errors?.length) {
|
||||
onRefetch();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
[compliancePage.id, framework.id, id, isPublic, onRefetch, createComplianceFramework, deleteComplianceFramework],
|
||||
);
|
||||
|
||||
const visibilityOptions = [
|
||||
{ value: "PUBLIC", label: __("Public"), variant: "success" as const },
|
||||
{ value: "NONE", label: __("None"), variant: "neutral" as const },
|
||||
];
|
||||
|
||||
const rowClassName = [
|
||||
canDrag && isDragging && "opacity-50 cursor-grabbing",
|
||||
canDrag && !isDragging && !isMouseDown && "cursor-grab",
|
||||
canDrag && !isDragging && isMouseDown && "cursor-grabbing",
|
||||
isDropTarget && "!bg-primary-50 border-y-2 border-primary-500",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
|
||||
return (
|
||||
<Tr
|
||||
draggable={canDrag}
|
||||
onDragStart={canDrag ? () => onDragStart(id) : undefined}
|
||||
onDragEnd={canDrag ? onDragEnd : undefined}
|
||||
onDragOver={canDrag ? e => onDragOver(e, id) : undefined}
|
||||
onDrop={
|
||||
canDrag
|
||||
? (e) => {
|
||||
e.preventDefault();
|
||||
onDrop(id);
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
onMouseDown={canDrag ? () => setIsMouseDown(true) : undefined}
|
||||
onMouseUp={canDrag ? () => setIsMouseDown(false) : undefined}
|
||||
onMouseLeave={canDrag ? () => setIsMouseDown(false) : undefined}
|
||||
className={rowClassName}
|
||||
>
|
||||
<Td>
|
||||
<div className="flex items-center gap-3">
|
||||
<FrameworkLogo
|
||||
className="size-8"
|
||||
lightLogoURL={framework.lightLogoURL}
|
||||
darkLogoURL={framework.darkLogoURL}
|
||||
name={framework.name}
|
||||
/>
|
||||
{framework.name}
|
||||
</div>
|
||||
</Td>
|
||||
<Td noLink width={130} className="pr-0">
|
||||
<Field
|
||||
type="select"
|
||||
value={visibility}
|
||||
onValueChange={value => void handleVisibilityChange(value)}
|
||||
disabled={isLoading || !compliancePage.canUpdate}
|
||||
className="w-[105px]"
|
||||
>
|
||||
{visibilityOptions.map(option => (
|
||||
<Option key={option.value} value={option.value}>
|
||||
<div className="flex items-center justify-between w-full">
|
||||
<Badge variant={option.variant}>{option.label}</Badge>
|
||||
</div>
|
||||
</Option>
|
||||
))}
|
||||
</Field>
|
||||
</Td>
|
||||
</Tr>
|
||||
);
|
||||
}
|
||||
|
||||
export function CompliancePageFrameworkList(props: {
|
||||
compliancePageRef: CompliancePageFrameworkList_compliancePageFragment$key;
|
||||
}) {
|
||||
const { __ } = useTranslate();
|
||||
const [, startTransition] = useTransition();
|
||||
|
||||
const [compliancePage, refetch] = useRefetchableFragment<
|
||||
CompliancePageFrameworkList_compliancePageRefetchQuery,
|
||||
CompliancePageFrameworkList_compliancePageFragment$key
|
||||
>(compliancePageFragment, props.compliancePageRef);
|
||||
|
||||
const [updateRank] = useMutationWithToasts<CompliancePageFrameworkList_updateRankMutation>(
|
||||
updateRankMutation,
|
||||
{
|
||||
successMessage: __("Order updated successfully"),
|
||||
errorMessage: __("Failed to update order"),
|
||||
},
|
||||
);
|
||||
|
||||
const [draggedCfId, setDraggedCfId] = useState<string | null>(null);
|
||||
const [dragOverCfId, setDragOverCfId] = useState<string | null>(null);
|
||||
|
||||
const allEdges = compliancePage.complianceFrameworks.edges;
|
||||
const publicEdges = allEdges.filter(e => e.node.visibility === "PUBLIC");
|
||||
|
||||
const handleDragStart = (cfId: string) => {
|
||||
setDraggedCfId(cfId);
|
||||
};
|
||||
|
||||
const handleDragEnd = () => {
|
||||
setDraggedCfId(null);
|
||||
setDragOverCfId(null);
|
||||
};
|
||||
|
||||
const handleDragOver = (e: React.DragEvent, cfId: string) => {
|
||||
e.preventDefault();
|
||||
if (draggedCfId !== cfId) {
|
||||
setDragOverCfId(cfId);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDrop = async (targetCfId: string) => {
|
||||
if (!draggedCfId || draggedCfId === targetCfId) {
|
||||
setDraggedCfId(null);
|
||||
setDragOverCfId(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const targetEdge = publicEdges.find(e => e.node.id === targetCfId);
|
||||
if (!targetEdge) {
|
||||
setDraggedCfId(null);
|
||||
setDragOverCfId(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const draggedId = draggedCfId;
|
||||
|
||||
await updateRank({
|
||||
variables: {
|
||||
input: {
|
||||
id: draggedId,
|
||||
rank: targetEdge.node.rank,
|
||||
},
|
||||
},
|
||||
updater: (store) => {
|
||||
const trustCenterRecord = store.get(compliancePage.id);
|
||||
if (!trustCenterRecord) return;
|
||||
|
||||
const connection = ConnectionHandler.getConnection(
|
||||
trustCenterRecord,
|
||||
"CompliancePageFrameworkList_complianceFrameworks",
|
||||
{ orderBy: { field: "RANK", direction: "ASC" } },
|
||||
);
|
||||
if (!connection) return;
|
||||
|
||||
const edges = connection.getLinkedRecords("edges");
|
||||
if (!edges) return;
|
||||
|
||||
const fromIdx = edges.findIndex(e => e.getLinkedRecord("node")?.getDataID() === draggedId);
|
||||
const toIdx = edges.findIndex(e => e.getLinkedRecord("node")?.getDataID() === targetCfId);
|
||||
if (fromIdx === -1 || toIdx === -1) return;
|
||||
|
||||
const reordered = [...edges];
|
||||
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" });
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
setDraggedCfId(null);
|
||||
setDragOverCfId(null);
|
||||
};
|
||||
|
||||
const hasMultiplePublic = publicEdges.length > 1;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Table>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>{__("Framework")}</Th>
|
||||
<Th>{__("Visibility")}</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{allEdges.length === 0 && (
|
||||
<Tr>
|
||||
<Td colSpan={2} className="text-center text-txt-secondary">
|
||||
{__("No frameworks available")}
|
||||
</Td>
|
||||
</Tr>
|
||||
)}
|
||||
{allEdges.map(edge => (
|
||||
<CompliancePageFrameworkListItem
|
||||
key={edge.node.id}
|
||||
edge={edge}
|
||||
compliancePage={compliancePage}
|
||||
draggedCfId={draggedCfId}
|
||||
dragOverCfId={dragOverCfId}
|
||||
onDragStart={handleDragStart}
|
||||
onDragEnd={handleDragEnd}
|
||||
onDragOver={handleDragOver}
|
||||
onDrop={cfId => void handleDrop(cfId)}
|
||||
onRefetch={() => startTransition(() => { refetch({}, { fetchPolicy: "store-and-network" }); })}
|
||||
/>
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
|
||||
{hasMultiplePublic && compliancePage.canUpdate && (
|
||||
<p className="text-sm text-txt-tertiary">
|
||||
{__("Drag and drop public frameworks to change their displayed order")}
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -126,7 +126,7 @@ export function CompliancePageReferenceList(props: {
|
||||
</Tbody>
|
||||
</Table>
|
||||
|
||||
<p className="text-xs text-txt-tertiary">
|
||||
<p className="text-sm text-txt-tertiary">
|
||||
{__("Drag and drop references to change their displayed order")}
|
||||
</p>
|
||||
</>
|
||||
|
||||
32
apps/trust/src/components/FrameworkBadge.tsx
Normal file
32
apps/trust/src/components/FrameworkBadge.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import { FrameworkLogo } from "@probo/ui";
|
||||
import { useFragment } from "react-relay";
|
||||
import { graphql } from "relay-runtime";
|
||||
|
||||
import type { FrameworkBadgeFragment$key } from "./__generated__/FrameworkBadgeFragment.graphql";
|
||||
|
||||
const frameworkFragment = graphql`
|
||||
fragment FrameworkBadgeFragment on Framework {
|
||||
id
|
||||
name
|
||||
lightLogoURL
|
||||
darkLogoURL
|
||||
}
|
||||
`;
|
||||
|
||||
export function FrameworkBadge(props: { framework: FrameworkBadgeFragment$key }) {
|
||||
const framework = useFragment(frameworkFragment, props.framework);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2 items-center w-19">
|
||||
<FrameworkLogo
|
||||
className="size-19"
|
||||
lightLogoURL={framework.lightLogoURL}
|
||||
darkLogoURL={framework.darkLogoURL}
|
||||
name={framework.name}
|
||||
/>
|
||||
<div className="txt-primary text-sm max-w-19 overflow-hidden min-w-0 whitespace-nowrap text-ellipsis">
|
||||
{framework.name}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -19,7 +19,7 @@ import type { TrustGraphCurrentQuery$data } from "#/queries/__generated__/TrustG
|
||||
import { getPathPrefix } from "#/utils/pathPrefix";
|
||||
|
||||
import type { OrganizationSidebar_requestAllAccessesMutation } from "./__generated__/OrganizationSidebar_requestAllAccessesMutation.graphql";
|
||||
import { AuditRowAvatar } from "./AuditRow";
|
||||
import { FrameworkBadge } from "./FrameworkBadge";
|
||||
|
||||
const requestAllAccessesMutation = graphql`
|
||||
mutation OrganizationSidebar_requestAllAccessesMutation {
|
||||
@@ -154,7 +154,7 @@ export function OrganizationSidebar({
|
||||
<hr className="my-6 -mx-6 h-px bg-border-low border-none" />
|
||||
|
||||
{/* Certifications */}
|
||||
{trustCenter.audits.edges.length > 0 && (
|
||||
{trustCenter.complianceFrameworks.edges.length > 0 && (
|
||||
<>
|
||||
<div className="space-y-4">
|
||||
<h2 className="text-xs text-txt-secondary flex gap-1 items-center">
|
||||
@@ -167,8 +167,8 @@ export function OrganizationSidebar({
|
||||
gridTemplateColumns: "repeat(auto-fit, 75px",
|
||||
}}
|
||||
>
|
||||
{trustCenter.audits.edges.map(audit => (
|
||||
<AuditRowAvatar key={audit.node.id} audit={audit.node} />
|
||||
{trustCenter.complianceFrameworks.edges.map(edge => (
|
||||
<FrameworkBadge key={edge.node.id} framework={edge.node.framework} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
66
apps/trust/src/components/__generated__/FrameworkBadgeFragment.graphql.ts
generated
Normal file
66
apps/trust/src/components/__generated__/FrameworkBadgeFragment.graphql.ts
generated
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @generated SignedSource<<f13ba91513aa9a472ab62c4c6a93b6bb>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type FrameworkBadgeFragment$data = {
|
||||
readonly darkLogoURL: string | null | undefined;
|
||||
readonly id: string;
|
||||
readonly lightLogoURL: string | null | undefined;
|
||||
readonly name: string;
|
||||
readonly " $fragmentType": "FrameworkBadgeFragment";
|
||||
};
|
||||
export type FrameworkBadgeFragment$key = {
|
||||
readonly " $data"?: FrameworkBadgeFragment$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"FrameworkBadgeFragment">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "FrameworkBadgeFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "name",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "lightLogoURL",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "darkLogoURL",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Framework",
|
||||
"abstractKey": null
|
||||
};
|
||||
|
||||
(node as any).hash = "cdfaf9a4a0e2cb667a5ef8d3e7db1f99";
|
||||
|
||||
export default node;
|
||||
@@ -34,6 +34,16 @@ export const currentTrustGraphQuery = graphql`
|
||||
}
|
||||
}
|
||||
}
|
||||
complianceFrameworks(first: 50) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
framework {
|
||||
...FrameworkBadgeFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @generated SignedSource<<47a6e80d3532b4c93d18495c2be7676d>>
|
||||
* @generated SignedSource<<4eef287e3e3152affa1b16189a504c36>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
@@ -22,6 +22,16 @@ export type TrustGraphCurrentQuery$data = {
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly complianceFrameworks: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly framework: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"FrameworkBadgeFragment">;
|
||||
};
|
||||
readonly id: string;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly darkLogoFileUrl: string | null | undefined;
|
||||
readonly id: string;
|
||||
readonly logoFileUrl: string | null | undefined;
|
||||
@@ -193,6 +203,33 @@ v16 = {
|
||||
(v6/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
v17 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Framework",
|
||||
"kind": "LinkedField",
|
||||
"name": "framework",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
(v7/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "lightLogoURL",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "darkLogoURL",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
@@ -300,6 +337,56 @@ return {
|
||||
}
|
||||
],
|
||||
"storageKey": "audits(first:50)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v13/*: any*/),
|
||||
"concreteType": "ComplianceFrameworkConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "complianceFrameworks",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ComplianceFrameworkEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ComplianceFramework",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Framework",
|
||||
"kind": "LinkedField",
|
||||
"name": "framework",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "FrameworkBadgeFragment"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "complianceFrameworks(first:50)"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
@@ -612,33 +699,7 @@ return {
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Framework",
|
||||
"kind": "LinkedField",
|
||||
"name": "framework",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
(v7/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "lightLogoURL",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "darkLogoURL",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
(v17/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
@@ -647,6 +708,41 @@ return {
|
||||
}
|
||||
],
|
||||
"storageKey": "audits(first:50)"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v13/*: any*/),
|
||||
"concreteType": "ComplianceFrameworkConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "complianceFrameworks",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ComplianceFrameworkEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "ComplianceFramework",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
(v17/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "complianceFrameworks(first:50)"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
@@ -654,16 +750,16 @@ return {
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "42b477429f092f97b0f444433a78c6d1",
|
||||
"cacheID": "e64b984bdcf5a5fb2f19e69c6205ba9a",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "TrustGraphCurrentQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query TrustGraphCurrentQuery {\n currentTrustCenter {\n id\n slug\n logoFileUrl\n darkLogoFileUrl\n nonDisclosureAgreement {\n fileName\n fileUrl\n viewerSignature {\n status\n id\n }\n }\n organization {\n name\n description\n websiteUrl\n email\n headquarterAddress\n id\n }\n ...OverviewPageFragment\n vendorInfo: vendors(first: 0) {\n totalCount\n }\n audits(first: 50) {\n edges {\n node {\n id\n ...AuditRowFragment\n }\n }\n }\n }\n}\n\nfragment AuditRowFragment on Audit {\n name\n report {\n id\n filename\n isUserAuthorized\n access {\n id\n status\n }\n }\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n}\n\nfragment DocumentRowFragment on Document {\n id\n title\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment OverviewPageFragment on TrustCenter {\n references(first: 14) {\n edges {\n node {\n id\n name\n logoUrl\n websiteUrl\n }\n }\n }\n vendors(first: 3) {\n edges {\n node {\n id\n countries\n ...VendorRowFragment\n }\n }\n }\n documents(first: 5) {\n edges {\n node {\n id\n ...DocumentRowFragment\n documentType\n }\n }\n }\n trustCenterFiles(first: 5) {\n edges {\n node {\n id\n category\n ...TrustCenterFileRowFragment\n }\n }\n }\n}\n\nfragment TrustCenterFileRowFragment on TrustCenterFile {\n id\n name\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment VendorRowFragment on Vendor {\n name\n description\n websiteUrl\n countries\n}\n"
|
||||
"text": "query TrustGraphCurrentQuery {\n currentTrustCenter {\n id\n slug\n logoFileUrl\n darkLogoFileUrl\n nonDisclosureAgreement {\n fileName\n fileUrl\n viewerSignature {\n status\n id\n }\n }\n organization {\n name\n description\n websiteUrl\n email\n headquarterAddress\n id\n }\n ...OverviewPageFragment\n vendorInfo: vendors(first: 0) {\n totalCount\n }\n audits(first: 50) {\n edges {\n node {\n id\n ...AuditRowFragment\n }\n }\n }\n complianceFrameworks(first: 50) {\n edges {\n node {\n id\n framework {\n ...FrameworkBadgeFragment\n id\n }\n }\n }\n }\n }\n}\n\nfragment AuditRowFragment on Audit {\n name\n report {\n id\n filename\n isUserAuthorized\n access {\n id\n status\n }\n }\n framework {\n id\n name\n lightLogoURL\n darkLogoURL\n }\n}\n\nfragment DocumentRowFragment on Document {\n id\n title\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment FrameworkBadgeFragment on Framework {\n id\n name\n lightLogoURL\n darkLogoURL\n}\n\nfragment OverviewPageFragment on TrustCenter {\n references(first: 14) {\n edges {\n node {\n id\n name\n logoUrl\n websiteUrl\n }\n }\n }\n vendors(first: 3) {\n edges {\n node {\n id\n countries\n ...VendorRowFragment\n }\n }\n }\n documents(first: 5) {\n edges {\n node {\n id\n ...DocumentRowFragment\n documentType\n }\n }\n }\n trustCenterFiles(first: 5) {\n edges {\n node {\n id\n category\n ...TrustCenterFileRowFragment\n }\n }\n }\n}\n\nfragment TrustCenterFileRowFragment on TrustCenterFile {\n id\n name\n isUserAuthorized\n access {\n id\n status\n }\n}\n\nfragment VendorRowFragment on Vendor {\n name\n description\n websiteUrl\n countries\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "41cf8e5383cefdd5b3b7b85263eccb1f";
|
||||
(node as any).hash = "d1ce7e38b42fad48e9f38bf00bb34d56";
|
||||
|
||||
export default node;
|
||||
|
||||
428
pkg/coredata/compliance_framework.go
Normal file
428
pkg/coredata/compliance_framework.go
Normal file
@@ -0,0 +1,428 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package coredata
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"go.gearno.de/kit/pg"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
type (
|
||||
ComplianceFramework struct {
|
||||
ID gid.GID `db:"id"`
|
||||
OrganizationID gid.GID `db:"organization_id"`
|
||||
TrustCenterID gid.GID `db:"trust_center_id"`
|
||||
FrameworkID gid.GID `db:"framework_id"`
|
||||
Rank int `db:"rank"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
|
||||
// Visibility is a non-db field used to return all frameworks for a trust center, including hidden ones.
|
||||
Visibility ComplianceFrameworkVisibility `db:"visibility"`
|
||||
}
|
||||
|
||||
ComplianceFrameworks []*ComplianceFramework
|
||||
)
|
||||
|
||||
func (c ComplianceFramework) CursorKey(orderBy ComplianceFrameworkOrderField) page.CursorKey {
|
||||
switch orderBy {
|
||||
case ComplianceFrameworkOrderFieldCreatedAt:
|
||||
return page.NewCursorKey(c.ID, c.CreatedAt)
|
||||
case ComplianceFrameworkOrderFieldRank:
|
||||
return page.NewCursorKey(c.ID, c.Rank)
|
||||
}
|
||||
panic(fmt.Sprintf("unsupported order by: %s", orderBy))
|
||||
}
|
||||
|
||||
func (c *ComplianceFramework) AuthorizationAttributes(ctx context.Context, conn pg.Conn) (map[string]string, error) {
|
||||
q := `SELECT organization_id FROM compliance_frameworks 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 framework authorization attributes: %w", err)
|
||||
}
|
||||
|
||||
return map[string]string{"organization_id": organizationID.String()}, nil
|
||||
}
|
||||
|
||||
func (c *ComplianceFramework) LoadByID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
complianceFrameworkID gid.GID,
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
organization_id,
|
||||
trust_center_id,
|
||||
framework_id,
|
||||
rank,
|
||||
'PUBLIC' AS visibility,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
compliance_frameworks
|
||||
WHERE
|
||||
%s
|
||||
AND id = @compliance_framework_id
|
||||
LIMIT 1;
|
||||
`
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"compliance_framework_id": complianceFrameworkID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query compliance_frameworks: %w", err)
|
||||
}
|
||||
|
||||
cf, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[ComplianceFramework])
|
||||
if err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return ErrResourceNotFound
|
||||
}
|
||||
return fmt.Errorf("cannot collect compliance framework: %w", err)
|
||||
}
|
||||
|
||||
*c = cf
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ComplianceFramework) LoadByTrustCenterIDAndFrameworkID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
trustCenterID gid.GID,
|
||||
frameworkID gid.GID,
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
organization_id,
|
||||
trust_center_id,
|
||||
framework_id,
|
||||
rank,
|
||||
'PUBLIC' AS visibility,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
compliance_frameworks
|
||||
WHERE
|
||||
%s
|
||||
AND trust_center_id = @trust_center_id
|
||||
AND framework_id = @framework_id
|
||||
LIMIT 1;
|
||||
`
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{
|
||||
"trust_center_id": trustCenterID,
|
||||
"framework_id": frameworkID,
|
||||
}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
rows, err := conn.Query(ctx, q, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot query compliance_frameworks: %w", err)
|
||||
}
|
||||
|
||||
cf, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[ComplianceFramework])
|
||||
if err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return ErrResourceNotFound
|
||||
}
|
||||
return fmt.Errorf("cannot collect compliance framework: %w", err)
|
||||
}
|
||||
|
||||
*c = cf
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ComplianceFramework) Insert(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
INSERT INTO
|
||||
compliance_frameworks (
|
||||
id,
|
||||
tenant_id,
|
||||
organization_id,
|
||||
trust_center_id,
|
||||
framework_id,
|
||||
rank,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
@id,
|
||||
@tenant_id,
|
||||
@organization_id,
|
||||
@trust_center_id,
|
||||
@framework_id,
|
||||
(SELECT COALESCE(MAX(rank), 0) + 1 FROM compliance_frameworks 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,
|
||||
"framework_id": c.FrameworkID,
|
||||
"created_at": c.CreatedAt,
|
||||
"updated_at": c.UpdatedAt,
|
||||
}
|
||||
|
||||
err := conn.QueryRow(ctx, q, args).Scan(&c.Rank)
|
||||
if err != nil {
|
||||
var pgErr *pgconn.PgError
|
||||
if errors.As(err, &pgErr) {
|
||||
if pgErr.Code == "23505" {
|
||||
return ErrResourceAlreadyExists
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("cannot insert compliance framework: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ComplianceFramework) UpdateRank(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
WITH old AS (
|
||||
SELECT
|
||||
rank AS old_rank
|
||||
FROM compliance_frameworks
|
||||
WHERE %s AND id = @id AND trust_center_id = @trust_center_id
|
||||
)
|
||||
|
||||
UPDATE compliance_frameworks
|
||||
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 (
|
||||
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 framework rank: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ComplianceFramework) Delete(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
) error {
|
||||
q := `
|
||||
DELETE FROM
|
||||
compliance_frameworks
|
||||
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 framework: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ComplianceFrameworks) LoadByTrustCenterID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
trustCenterID gid.GID,
|
||||
cursor *page.Cursor[ComplianceFrameworkOrderField],
|
||||
) error {
|
||||
q := `
|
||||
SELECT
|
||||
id,
|
||||
organization_id,
|
||||
trust_center_id,
|
||||
framework_id,
|
||||
rank,
|
||||
'PUBLIC' AS visibility,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM
|
||||
compliance_frameworks
|
||||
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_frameworks: %w", err)
|
||||
}
|
||||
|
||||
results, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[ComplianceFramework])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect compliance frameworks: %w", err)
|
||||
}
|
||||
|
||||
*c = results
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ComplianceFrameworks) LoadWithHiddenByTrustCenterID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
trustCenterID gid.GID,
|
||||
cursor *page.Cursor[ComplianceFrameworkOrderField],
|
||||
) error {
|
||||
q := `
|
||||
WITH combined AS (
|
||||
SELECT
|
||||
COALESCE(cf.id, f.id) AS id,
|
||||
COALESCE(cf.organization_id, tc.organization_id) AS organization_id,
|
||||
COALESCE(cf.trust_center_id, tc.id) AS trust_center_id,
|
||||
f.id AS framework_id,
|
||||
CASE
|
||||
WHEN cf.id IS NOT NULL THEN cf.rank
|
||||
ELSE COALESCE(MAX(cf.rank) OVER (), 0) + ROW_NUMBER() OVER (PARTITION BY (cf.id IS NULL) ORDER BY f.created_at)
|
||||
END AS rank,
|
||||
CASE WHEN cf.id IS NULL THEN 'NONE' ELSE 'PUBLIC' END AS visibility,
|
||||
COALESCE(cf.created_at, f.created_at) AS created_at,
|
||||
COALESCE(cf.updated_at, f.updated_at) AS updated_at
|
||||
FROM trust_centers tc
|
||||
JOIN frameworks f
|
||||
ON f.organization_id = tc.organization_id
|
||||
AND f.tenant_id = @tenant_id
|
||||
LEFT JOIN compliance_frameworks cf
|
||||
ON cf.framework_id = f.id
|
||||
AND cf.trust_center_id = tc.id
|
||||
AND cf.tenant_id = @tenant_id
|
||||
WHERE tc.id = @trust_center_id
|
||||
AND tc.tenant_id = @tenant_id
|
||||
)
|
||||
SELECT id, organization_id, trust_center_id, framework_id, rank, visibility, created_at, updated_at
|
||||
FROM combined
|
||||
WHERE %s
|
||||
`
|
||||
q = fmt.Sprintf(q, 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 frameworks with hidden: %w", err)
|
||||
}
|
||||
|
||||
results, err := pgx.CollectRows(rows, pgx.RowToAddrOfStructByName[ComplianceFramework])
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot collect compliance frameworks with hidden: %w", err)
|
||||
}
|
||||
|
||||
*c = results
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ComplianceFrameworks) CountByTrustCenterID(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
scope Scoper,
|
||||
trustCenterID gid.GID,
|
||||
) (int, error) {
|
||||
q := `
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
compliance_frameworks
|
||||
WHERE
|
||||
%s
|
||||
AND trust_center_id = @trust_center_id
|
||||
`
|
||||
|
||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||
|
||||
args := pgx.StrictNamedArgs{"trust_center_id": trustCenterID}
|
||||
maps.Copy(args, scope.SQLArguments())
|
||||
|
||||
var count int
|
||||
err := conn.QueryRow(ctx, q, args).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("cannot count compliance frameworks: %w", err)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
48
pkg/coredata/compliance_framework_order_field.go
Normal file
48
pkg/coredata/compliance_framework_order_field.go
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package coredata
|
||||
|
||||
type (
|
||||
ComplianceFrameworkOrderField string
|
||||
)
|
||||
|
||||
const (
|
||||
ComplianceFrameworkOrderFieldCreatedAt ComplianceFrameworkOrderField = "CREATED_AT"
|
||||
ComplianceFrameworkOrderFieldRank ComplianceFrameworkOrderField = "RANK"
|
||||
)
|
||||
|
||||
func (p ComplianceFrameworkOrderField) Column() string {
|
||||
switch p {
|
||||
case ComplianceFrameworkOrderFieldCreatedAt:
|
||||
return "created_at"
|
||||
case ComplianceFrameworkOrderFieldRank:
|
||||
return "rank"
|
||||
default:
|
||||
return string(p)
|
||||
}
|
||||
}
|
||||
|
||||
func (p ComplianceFrameworkOrderField) String() string {
|
||||
return string(p)
|
||||
}
|
||||
|
||||
func (p ComplianceFrameworkOrderField) MarshalText() ([]byte, error) {
|
||||
return []byte(p.String()), nil
|
||||
}
|
||||
|
||||
func (p *ComplianceFrameworkOrderField) UnmarshalText(text []byte) error {
|
||||
*p = ComplianceFrameworkOrderField(text)
|
||||
return nil
|
||||
}
|
||||
26
pkg/coredata/compliance_framework_visibility.go
Normal file
26
pkg/coredata/compliance_framework_visibility.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package coredata
|
||||
|
||||
type ComplianceFrameworkVisibility string
|
||||
|
||||
const (
|
||||
ComplianceFrameworkVisibilityNone ComplianceFrameworkVisibility = "NONE"
|
||||
ComplianceFrameworkVisibilityPublic ComplianceFrameworkVisibility = "PUBLIC"
|
||||
)
|
||||
|
||||
func (v ComplianceFrameworkVisibility) String() string {
|
||||
return string(v)
|
||||
}
|
||||
@@ -85,6 +85,7 @@ const (
|
||||
ElectronicSignatureEntityType uint16 = 59
|
||||
ElectronicSignatureEventEntityType uint16 = 60
|
||||
EmailAttachmentEntityType uint16 = 61
|
||||
ComplianceFrameworkEntityType uint16 = 62
|
||||
)
|
||||
|
||||
func NewEntityFromID(id gid.GID) (any, bool) {
|
||||
@@ -209,6 +210,8 @@ func NewEntityFromID(id gid.GID) (any, bool) {
|
||||
return &ElectronicSignatureEvent{ID: id}, true
|
||||
case EmailAttachmentEntityType:
|
||||
return &EmailAttachment{ID: id}, true
|
||||
case ComplianceFrameworkEntityType:
|
||||
return &ComplianceFramework{ID: id}, true
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ type (
|
||||
func (f *Framework) CursorKey(orderBy FrameworkOrderField) page.CursorKey {
|
||||
switch orderBy {
|
||||
case FrameworkOrderFieldCreatedAt:
|
||||
return page.CursorKey{ID: f.ID, Value: f.CreatedAt}
|
||||
return page.NewCursorKey(f.ID, f.CreatedAt)
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unsupported order by: %s", orderBy))
|
||||
|
||||
54
pkg/coredata/migrations/20260302T120000Z.sql
Normal file
54
pkg/coredata/migrations/20260302T120000Z.sql
Normal file
@@ -0,0 +1,54 @@
|
||||
CREATE TABLE compliance_frameworks (
|
||||
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,
|
||||
framework_id TEXT NOT NULL REFERENCES frameworks(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
rank INTEGER NOT NULL,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
UNIQUE (trust_center_id, framework_id)
|
||||
);
|
||||
|
||||
ALTER TABLE compliance_frameworks
|
||||
ADD CONSTRAINT compliance_frameworks_trust_center_id_rank_key
|
||||
UNIQUE (trust_center_id, rank)
|
||||
DEFERRABLE INITIALLY DEFERRED;
|
||||
|
||||
INSERT INTO compliance_frameworks (
|
||||
id,
|
||||
tenant_id,
|
||||
organization_id,
|
||||
trust_center_id,
|
||||
framework_id,
|
||||
rank,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
WITH distinct_frameworks AS (
|
||||
SELECT DISTINCT
|
||||
a.tenant_id,
|
||||
a.organization_id,
|
||||
a.framework_id
|
||||
FROM audits a
|
||||
WHERE a.trust_center_visibility IN ('PRIVATE', 'PUBLIC')
|
||||
AND EXISTS (
|
||||
SELECT 1 FROM trust_centers tc
|
||||
WHERE tc.organization_id = a.organization_id
|
||||
)
|
||||
)
|
||||
SELECT
|
||||
generate_gid(decode_base64_unpadded(df.tenant_id), 62),
|
||||
df.tenant_id,
|
||||
df.organization_id,
|
||||
tc.id AS trust_center_id,
|
||||
df.framework_id,
|
||||
ROW_NUMBER() OVER (
|
||||
PARTITION BY df.organization_id
|
||||
ORDER BY f.created_at ASC, df.framework_id ASC
|
||||
) AS rank,
|
||||
NOW(),
|
||||
NOW()
|
||||
FROM distinct_frameworks df
|
||||
JOIN trust_centers tc ON tc.organization_id = df.organization_id
|
||||
JOIN frameworks f ON f.id = df.framework_id;
|
||||
@@ -47,6 +47,12 @@ const (
|
||||
ActionTrustCenterReferenceUpdate = "core:trust-center-reference:update"
|
||||
ActionTrustCenterReferenceDelete = "core:trust-center-reference:delete"
|
||||
|
||||
// ComplianceFramework actions
|
||||
ActionComplianceFrameworkList = "core:compliance-framework:list"
|
||||
ActionComplianceFrameworkCreate = "core:compliance-framework:create"
|
||||
ActionComplianceFrameworkDelete = "core:compliance-framework:delete"
|
||||
ActionComplianceFrameworkUpdateRank = "core:compliance-framework:update-rank"
|
||||
|
||||
// TrustCenterFile actions
|
||||
ActionTrustCenterFileGet = "core:trust-center-file:get"
|
||||
ActionTrustCenterFileList = "core:trust-center-file:list"
|
||||
|
||||
204
pkg/probo/compliance_framework_service.go
Normal file
204
pkg/probo/compliance_framework_service.go
Normal file
@@ -0,0 +1,204 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package probo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"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 (
|
||||
ComplianceFrameworkService struct {
|
||||
svc *TenantService
|
||||
}
|
||||
|
||||
CreateComplianceFrameworkRequest struct {
|
||||
TrustCenterID gid.GID
|
||||
FrameworkID gid.GID
|
||||
}
|
||||
|
||||
UpdateComplianceFrameworkRequest struct {
|
||||
ID gid.GID
|
||||
Rank int
|
||||
}
|
||||
|
||||
DeleteComplianceFrameworkRequest struct {
|
||||
ID gid.GID
|
||||
}
|
||||
)
|
||||
|
||||
func (r *CreateComplianceFrameworkRequest) Validate() error {
|
||||
v := validator.New()
|
||||
|
||||
v.Check(r.TrustCenterID, "trust_center_id", validator.Required(), validator.GID(coredata.TrustCenterEntityType))
|
||||
v.Check(r.FrameworkID, "framework_id", validator.Required(), validator.GID(coredata.FrameworkEntityType))
|
||||
|
||||
return v.Error()
|
||||
}
|
||||
|
||||
func (r *UpdateComplianceFrameworkRequest) Validate() error {
|
||||
v := validator.New()
|
||||
|
||||
v.Check(r.ID, "id", validator.Required(), validator.GID(coredata.ComplianceFrameworkEntityType))
|
||||
|
||||
return v.Error()
|
||||
}
|
||||
|
||||
func (r *DeleteComplianceFrameworkRequest) Validate() error {
|
||||
v := validator.New()
|
||||
|
||||
v.Check(r.ID, "id", validator.Required(), validator.GID(coredata.ComplianceFrameworkEntityType))
|
||||
|
||||
return v.Error()
|
||||
}
|
||||
|
||||
func (s ComplianceFrameworkService) ListWithHiddenForTrustCenterID(
|
||||
ctx context.Context,
|
||||
trustCenterID gid.GID,
|
||||
cursor *page.Cursor[coredata.ComplianceFrameworkOrderField],
|
||||
) (*page.Page[*coredata.ComplianceFramework, coredata.ComplianceFrameworkOrderField], error) {
|
||||
var cfs coredata.ComplianceFrameworks
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
if err := cfs.LoadWithHiddenByTrustCenterID(ctx, conn, s.svc.scope, trustCenterID, cursor); err != nil {
|
||||
return fmt.Errorf("cannot load compliance frameworks with hidden: %w", err)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(cfs, cursor), nil
|
||||
}
|
||||
|
||||
func (s ComplianceFrameworkService) Create(
|
||||
ctx context.Context,
|
||||
req *CreateComplianceFrameworkRequest,
|
||||
) (*coredata.ComplianceFramework, error) {
|
||||
if err := req.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
cfID := gid.New(s.svc.scope.GetTenantID(), coredata.ComplianceFrameworkEntityType)
|
||||
|
||||
var cf *coredata.ComplianceFramework
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
cf = &coredata.ComplianceFramework{
|
||||
ID: cfID,
|
||||
OrganizationID: trustCenter.OrganizationID,
|
||||
TrustCenterID: req.TrustCenterID,
|
||||
FrameworkID: req.FrameworkID,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
|
||||
if err := cf.Insert(ctx, tx, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot insert compliance framework: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cf, nil
|
||||
}
|
||||
|
||||
func (s ComplianceFrameworkService) Update(
|
||||
ctx context.Context,
|
||||
req *UpdateComplianceFrameworkRequest,
|
||||
) (*coredata.ComplianceFramework, error) {
|
||||
if err := req.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var cf *coredata.ComplianceFramework
|
||||
|
||||
err := s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(tx pg.Conn) error {
|
||||
cf = &coredata.ComplianceFramework{}
|
||||
|
||||
if err := cf.LoadByID(ctx, tx, s.svc.scope, req.ID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance framework: %w", err)
|
||||
}
|
||||
|
||||
cf.Rank = req.Rank
|
||||
cf.UpdatedAt = time.Now()
|
||||
|
||||
if err := cf.UpdateRank(ctx, tx, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot update compliance framework rank: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cf, nil
|
||||
}
|
||||
|
||||
func (s ComplianceFrameworkService) Delete(
|
||||
ctx context.Context,
|
||||
req *DeleteComplianceFrameworkRequest,
|
||||
) error {
|
||||
if err := req.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.svc.pg.WithTx(
|
||||
ctx,
|
||||
func(tx pg.Conn) error {
|
||||
cf := &coredata.ComplianceFramework{}
|
||||
|
||||
if err := cf.LoadByID(ctx, tx, s.svc.scope, req.ID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance framework: %w", err)
|
||||
}
|
||||
|
||||
if err := cf.Delete(ctx, tx, s.svc.scope); err != nil {
|
||||
return fmt.Errorf("cannot delete compliance framework: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -88,6 +88,7 @@ var ViewerPolicy = policy.NewPolicy(
|
||||
ActionTrustCenterDocumentAccessList,
|
||||
ActionTrustCenterFileGet, ActionTrustCenterFileList, ActionTrustCenterFileGetFileUrl,
|
||||
ActionTrustCenterReferenceList, ActionTrustCenterReferenceGetLogoUrl,
|
||||
ActionComplianceFrameworkList,
|
||||
).WithSID("trust-center-read-access").When(organizationCondition),
|
||||
|
||||
policy.Allow(ActionCustomDomainGet).WithSID("custom-domain-read").When(organizationCondition),
|
||||
|
||||
@@ -101,6 +101,7 @@ type (
|
||||
TrustCenterAccesses *TrustCenterAccessService
|
||||
TrustCenterReferences *TrustCenterReferenceService
|
||||
TrustCenterFiles *TrustCenterFileService
|
||||
ComplianceFrameworks *ComplianceFrameworkService
|
||||
Nonconformities *NonconformityService
|
||||
Obligations *ObligationService
|
||||
Snapshots *SnapshotService
|
||||
@@ -225,6 +226,7 @@ func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService {
|
||||
tenantService.TrustCenters = &TrustCenterService{svc: tenantService}
|
||||
tenantService.TrustCenterAccesses = &TrustCenterAccessService{svc: tenantService}
|
||||
tenantService.TrustCenterReferences = &TrustCenterReferenceService{svc: tenantService}
|
||||
tenantService.ComplianceFrameworks = &ComplianceFrameworkService{svc: tenantService}
|
||||
tenantService.TrustCenterFiles = &TrustCenterFileService{
|
||||
svc: tenantService,
|
||||
fileValidator: filevalidation.NewValidator(
|
||||
|
||||
@@ -1227,6 +1227,34 @@ enum TrustCenterReferenceOrderField
|
||||
)
|
||||
}
|
||||
|
||||
enum ComplianceFrameworkOrderField
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkOrderField"
|
||||
) {
|
||||
CREATED_AT
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkOrderFieldCreatedAt"
|
||||
)
|
||||
RANK
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkOrderFieldRank"
|
||||
)
|
||||
}
|
||||
|
||||
enum ComplianceFrameworkVisibility
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkVisibility"
|
||||
) {
|
||||
NONE
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkVisibilityNone"
|
||||
)
|
||||
PUBLIC
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.ComplianceFrameworkVisibilityPublic"
|
||||
)
|
||||
}
|
||||
|
||||
enum TrustCenterFileOrderField
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.TrustCenterFileOrderField"
|
||||
@@ -1463,6 +1491,14 @@ input TrustCenterFileOrder
|
||||
field: TrustCenterFileOrderField!
|
||||
}
|
||||
|
||||
input ComplianceFrameworkOrder
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFrameworkOrderBy"
|
||||
) {
|
||||
direction: OrderDirection!
|
||||
field: ComplianceFrameworkOrderField!
|
||||
}
|
||||
|
||||
input EvidenceOrder
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.EvidenceOrderBy"
|
||||
@@ -1614,6 +1650,14 @@ type TrustCenter implements Node {
|
||||
orderBy: TrustCenterReferenceOrder
|
||||
): TrustCenterReferenceConnection! @goField(forceResolver: true)
|
||||
|
||||
complianceFrameworks(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: ComplianceFrameworkOrder
|
||||
): ComplianceFrameworkConnection! @goField(forceResolver: true)
|
||||
|
||||
permission(action: String!): Boolean! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
@@ -2806,6 +2850,31 @@ type TrustCenterReferenceEdge {
|
||||
node: TrustCenterReference!
|
||||
}
|
||||
|
||||
type ComplianceFramework implements Node
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFramework"
|
||||
) {
|
||||
id: ID!
|
||||
framework: Framework! @goField(forceResolver: true)
|
||||
rank: Int!
|
||||
visibility: ComplianceFrameworkVisibility!
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
}
|
||||
|
||||
type ComplianceFrameworkConnection
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.ComplianceFrameworkConnection"
|
||||
) {
|
||||
edges: [ComplianceFrameworkEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type ComplianceFrameworkEdge {
|
||||
cursor: CursorKey!
|
||||
node: ComplianceFramework!
|
||||
}
|
||||
|
||||
type TrustCenterFile implements Node {
|
||||
id: ID!
|
||||
name: String!
|
||||
@@ -3247,6 +3316,16 @@ type Mutation {
|
||||
deleteTrustCenterReference(
|
||||
input: DeleteTrustCenterReferenceInput!
|
||||
): DeleteTrustCenterReferencePayload!
|
||||
# Compliance Framework mutations
|
||||
createComplianceFramework(
|
||||
input: CreateComplianceFrameworkInput!
|
||||
): CreateComplianceFrameworkPayload!
|
||||
updateComplianceFramework(
|
||||
input: UpdateComplianceFrameworkInput!
|
||||
): UpdateComplianceFrameworkPayload!
|
||||
deleteComplianceFramework(
|
||||
input: DeleteComplianceFrameworkInput!
|
||||
): DeleteComplianceFrameworkPayload!
|
||||
# Trust Center File mutations
|
||||
createTrustCenterFile(
|
||||
input: CreateTrustCenterFileInput!
|
||||
@@ -3647,6 +3726,20 @@ input DeleteTrustCenterReferenceInput {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
input CreateComplianceFrameworkInput {
|
||||
trustCenterId: ID!
|
||||
frameworkId: ID!
|
||||
}
|
||||
|
||||
input UpdateComplianceFrameworkInput {
|
||||
id: ID!
|
||||
rank: Int!
|
||||
}
|
||||
|
||||
input DeleteComplianceFrameworkInput {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
input CreateTrustCenterFileInput {
|
||||
organizationId: ID!
|
||||
name: String!
|
||||
@@ -4462,6 +4555,18 @@ type DeleteTrustCenterReferencePayload {
|
||||
deletedTrustCenterReferenceId: ID!
|
||||
}
|
||||
|
||||
type CreateComplianceFrameworkPayload {
|
||||
complianceFrameworkEdge: ComplianceFrameworkEdge!
|
||||
}
|
||||
|
||||
type UpdateComplianceFrameworkPayload {
|
||||
complianceFramework: ComplianceFramework!
|
||||
}
|
||||
|
||||
type DeleteComplianceFrameworkPayload {
|
||||
deletedComplianceFrameworkId: ID!
|
||||
}
|
||||
|
||||
type CreateTrustCenterFilePayload {
|
||||
trustCenterFileEdge: TrustCenterFileEdge!
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
76
pkg/server/api/console/v1/types/compliance_framework.go
Normal file
76
pkg/server/api/console/v1/types/compliance_framework.go
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// 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 (
|
||||
"time"
|
||||
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
type ComplianceFrameworkOrderBy = OrderBy[coredata.ComplianceFrameworkOrderField]
|
||||
|
||||
type ComplianceFramework struct {
|
||||
ID gid.GID `json:"id"`
|
||||
Framework *Framework `json:"framework"`
|
||||
Rank int `json:"rank"`
|
||||
Visibility coredata.ComplianceFrameworkVisibility `json:"visibility"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
FrameworkID gid.GID `json:"-"`
|
||||
}
|
||||
|
||||
func (ComplianceFramework) IsNode() {}
|
||||
func (c ComplianceFramework) GetID() gid.GID { return c.ID }
|
||||
|
||||
type ComplianceFrameworkConnection struct {
|
||||
Edges []*ComplianceFrameworkEdge `json:"edges"`
|
||||
PageInfo *PageInfo `json:"pageInfo"`
|
||||
}
|
||||
|
||||
func NewComplianceFramework(cf *coredata.ComplianceFramework) *ComplianceFramework {
|
||||
return &ComplianceFramework{
|
||||
ID: cf.ID,
|
||||
FrameworkID: cf.FrameworkID,
|
||||
Rank: cf.Rank,
|
||||
Visibility: cf.Visibility,
|
||||
CreatedAt: cf.CreatedAt,
|
||||
UpdatedAt: cf.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func NewComplianceFrameworkConnection(
|
||||
p *page.Page[*coredata.ComplianceFramework, coredata.ComplianceFrameworkOrderField],
|
||||
) *ComplianceFrameworkConnection {
|
||||
edges := make([]*ComplianceFrameworkEdge, len(p.Data))
|
||||
|
||||
for i := range edges {
|
||||
edges[i] = NewComplianceFrameworkEdge(p.Data[i], p.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &ComplianceFrameworkConnection{
|
||||
Edges: edges,
|
||||
PageInfo: NewPageInfo(p),
|
||||
}
|
||||
}
|
||||
|
||||
func NewComplianceFrameworkEdge(cf *coredata.ComplianceFramework, orderBy coredata.ComplianceFrameworkOrderField) *ComplianceFrameworkEdge {
|
||||
return &ComplianceFrameworkEdge{
|
||||
Cursor: cf.CursorKey(orderBy),
|
||||
Node: NewComplianceFramework(cf),
|
||||
}
|
||||
}
|
||||
@@ -149,6 +149,11 @@ type CancelSignatureRequestPayload struct {
|
||||
DeletedDocumentVersionSignatureID gid.GID `json:"deletedDocumentVersionSignatureId"`
|
||||
}
|
||||
|
||||
type ComplianceFrameworkEdge struct {
|
||||
Cursor page.CursorKey `json:"cursor"`
|
||||
Node *ComplianceFramework `json:"node"`
|
||||
}
|
||||
|
||||
type ContinualImprovement struct {
|
||||
ID gid.GID `json:"id"`
|
||||
SnapshotID *gid.GID `json:"snapshotId,omitempty"`
|
||||
@@ -250,6 +255,15 @@ type CreateAuditPayload struct {
|
||||
AuditEdge *AuditEdge `json:"auditEdge"`
|
||||
}
|
||||
|
||||
type CreateComplianceFrameworkInput struct {
|
||||
TrustCenterID gid.GID `json:"trustCenterId"`
|
||||
FrameworkID gid.GID `json:"frameworkId"`
|
||||
}
|
||||
|
||||
type CreateComplianceFrameworkPayload struct {
|
||||
ComplianceFrameworkEdge *ComplianceFrameworkEdge `json:"complianceFrameworkEdge"`
|
||||
}
|
||||
|
||||
type CreateContinualImprovementInput struct {
|
||||
OrganizationID gid.GID `json:"organizationId"`
|
||||
ReferenceID string `json:"referenceId"`
|
||||
@@ -789,6 +803,14 @@ type DeleteAuditReportPayload struct {
|
||||
Audit *Audit `json:"audit"`
|
||||
}
|
||||
|
||||
type DeleteComplianceFrameworkInput struct {
|
||||
ID gid.GID `json:"id"`
|
||||
}
|
||||
|
||||
type DeleteComplianceFrameworkPayload struct {
|
||||
DeletedComplianceFrameworkID gid.GID `json:"deletedComplianceFrameworkId"`
|
||||
}
|
||||
|
||||
type DeleteContinualImprovementInput struct {
|
||||
ContinualImprovementID gid.GID `json:"continualImprovementId"`
|
||||
}
|
||||
@@ -1851,18 +1873,19 @@ 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"`
|
||||
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"`
|
||||
Permission bool `json:"permission"`
|
||||
}
|
||||
|
||||
func (TrustCenter) IsNode() {}
|
||||
@@ -1994,6 +2017,15 @@ type UpdateAuditPayload struct {
|
||||
Audit *Audit `json:"audit"`
|
||||
}
|
||||
|
||||
type UpdateComplianceFrameworkInput struct {
|
||||
ID gid.GID `json:"id"`
|
||||
Rank int `json:"rank"`
|
||||
}
|
||||
|
||||
type UpdateComplianceFrameworkPayload struct {
|
||||
ComplianceFramework *ComplianceFramework `json:"complianceFramework"`
|
||||
}
|
||||
|
||||
type UpdateContinualImprovementInput struct {
|
||||
ID gid.GID `json:"id"`
|
||||
ReferenceID *string `json:"referenceId,omitempty"`
|
||||
|
||||
@@ -324,6 +324,23 @@ func (r *auditConnectionResolver) TotalCount(ctx context.Context, obj *types.Aud
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.FrameworkID.TenantID())
|
||||
|
||||
framework, err := prb.Frameworks.Get(ctx, obj.FrameworkID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot load framework", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewFramework(framework), nil
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *continualImprovementResolver) Organization(ctx context.Context, obj *types.ContinualImprovement) (*types.Organization, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil {
|
||||
@@ -2098,6 +2115,77 @@ func (r *mutationResolver) DeleteTrustCenterReference(ctx context.Context, input
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateComplianceFramework is the resolver for the createComplianceFramework field.
|
||||
func (r *mutationResolver) CreateComplianceFramework(ctx context.Context, input types.CreateComplianceFrameworkInput) (*types.CreateComplianceFrameworkPayload, error) {
|
||||
if err := r.authorize(ctx, input.TrustCenterID, probo.ActionComplianceFrameworkCreate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, input.TrustCenterID.TenantID())
|
||||
|
||||
cf, err := prb.ComplianceFrameworks.Create(
|
||||
ctx,
|
||||
&probo.CreateComplianceFrameworkRequest{
|
||||
TrustCenterID: input.TrustCenterID,
|
||||
FrameworkID: input.FrameworkID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot create compliance framework", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.CreateComplianceFrameworkPayload{
|
||||
ComplianceFrameworkEdge: types.NewComplianceFrameworkEdge(cf, coredata.ComplianceFrameworkOrderFieldRank),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateComplianceFramework is the resolver for the updateComplianceFramework field.
|
||||
func (r *mutationResolver) UpdateComplianceFramework(ctx context.Context, input types.UpdateComplianceFrameworkInput) (*types.UpdateComplianceFrameworkPayload, error) {
|
||||
if err := r.authorize(ctx, input.ID, probo.ActionComplianceFrameworkUpdateRank); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, input.ID.TenantID())
|
||||
|
||||
cf, err := prb.ComplianceFrameworks.Update(ctx, &probo.UpdateComplianceFrameworkRequest{
|
||||
ID: input.ID,
|
||||
Rank: input.Rank,
|
||||
})
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot update compliance framework", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.UpdateComplianceFrameworkPayload{
|
||||
ComplianceFramework: types.NewComplianceFramework(cf),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteComplianceFramework is the resolver for the deleteComplianceFramework field.
|
||||
func (r *mutationResolver) DeleteComplianceFramework(ctx context.Context, input types.DeleteComplianceFrameworkInput) (*types.DeleteComplianceFrameworkPayload, error) {
|
||||
if err := r.authorize(ctx, input.ID, probo.ActionComplianceFrameworkDelete); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, input.ID.TenantID())
|
||||
|
||||
err := prb.ComplianceFrameworks.Delete(
|
||||
ctx,
|
||||
&probo.DeleteComplianceFrameworkRequest{
|
||||
ID: input.ID,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot delete compliance framework", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.DeleteComplianceFrameworkPayload{
|
||||
DeletedComplianceFrameworkID: 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 {
|
||||
@@ -7814,6 +7902,36 @@ func (r *trustCenterResolver) References(ctx context.Context, obj *types.TrustCe
|
||||
return types.NewTrustCenterReferenceConnection(result, obj.ID), nil
|
||||
}
|
||||
|
||||
// ComplianceFrameworks is the resolver for the complianceFrameworks field.
|
||||
func (r *trustCenterResolver) 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) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionComplianceFrameworkList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prb := r.ProboService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.ComplianceFrameworkOrderField]{
|
||||
Field: coredata.ComplianceFrameworkOrderFieldRank,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.ComplianceFrameworkOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
result, err := prb.ComplianceFrameworks.ListWithHiddenForTrustCenterID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list compliance frameworks", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewComplianceFrameworkConnection(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)
|
||||
@@ -8776,6 +8894,11 @@ func (r *Resolver) AuditConnection() schema.AuditConnectionResolver {
|
||||
return &auditConnectionResolver{r}
|
||||
}
|
||||
|
||||
// ComplianceFramework returns schema.ComplianceFrameworkResolver implementation.
|
||||
func (r *Resolver) ComplianceFramework() schema.ComplianceFrameworkResolver {
|
||||
return &complianceFrameworkResolver{r}
|
||||
}
|
||||
|
||||
// ContinualImprovement returns schema.ContinualImprovementResolver implementation.
|
||||
func (r *Resolver) ContinualImprovement() schema.ContinualImprovementResolver {
|
||||
return &continualImprovementResolver{r}
|
||||
@@ -9078,6 +9201,7 @@ type assetResolver struct{ *Resolver }
|
||||
type assetConnectionResolver struct{ *Resolver }
|
||||
type auditResolver struct{ *Resolver }
|
||||
type auditConnectionResolver struct{ *Resolver }
|
||||
type complianceFrameworkResolver struct{ *Resolver }
|
||||
type continualImprovementResolver struct{ *Resolver }
|
||||
type continualImprovementConnectionResolver struct{ *Resolver }
|
||||
type controlResolver struct{ *Resolver }
|
||||
|
||||
@@ -107,6 +107,21 @@ type AuditEdge @nda {
|
||||
node: Audit!
|
||||
}
|
||||
|
||||
type ComplianceFramework implements Node {
|
||||
id: ID!
|
||||
framework: Framework! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type ComplianceFrameworkConnection {
|
||||
edges: [ComplianceFrameworkEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type ComplianceFrameworkEdge {
|
||||
cursor: CursorKey!
|
||||
node: ComplianceFramework!
|
||||
}
|
||||
|
||||
enum CountryCode
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.CountryCode") {
|
||||
AD @goEnum(value: "go.probo.inc/probo/pkg/coredata.CountryCodeAD")
|
||||
@@ -542,6 +557,13 @@ type TrustCenter implements Node {
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): TrustCenterFileConnection! @goField(forceResolver: true)
|
||||
|
||||
complianceFrameworks(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): ComplianceFrameworkConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type TrustCenterAccess implements Node {
|
||||
|
||||
@@ -37,6 +37,7 @@ type Config = graphql.Config[ResolverRoot, DirectiveRoot, ComplexityRoot]
|
||||
|
||||
type ResolverRoot interface {
|
||||
Audit() AuditResolver
|
||||
ComplianceFramework() ComplianceFrameworkResolver
|
||||
Document() DocumentResolver
|
||||
Framework() FrameworkResolver
|
||||
Mutation() MutationResolver
|
||||
@@ -77,6 +78,21 @@ type ComplexityRoot struct {
|
||||
Node func(childComplexity int) int
|
||||
}
|
||||
|
||||
ComplianceFramework struct {
|
||||
Framework func(childComplexity int) int
|
||||
ID func(childComplexity int) int
|
||||
}
|
||||
|
||||
ComplianceFrameworkConnection struct {
|
||||
Edges func(childComplexity int) int
|
||||
PageInfo func(childComplexity int) int
|
||||
}
|
||||
|
||||
ComplianceFrameworkEdge struct {
|
||||
Cursor func(childComplexity int) int
|
||||
Node func(childComplexity int) int
|
||||
}
|
||||
|
||||
Document struct {
|
||||
Access func(childComplexity int) int
|
||||
DocumentType func(childComplexity int) int
|
||||
@@ -216,6 +232,7 @@ type ComplexityRoot struct {
|
||||
TrustCenter struct {
|
||||
Active func(childComplexity int) int
|
||||
Audits func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey) int
|
||||
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
|
||||
ID func(childComplexity int) int
|
||||
@@ -302,6 +319,9 @@ type AuditResolver interface {
|
||||
Framework(ctx context.Context, obj *types.Audit) (*types.Framework, error)
|
||||
Report(ctx context.Context, obj *types.Audit) (*types.Report, error)
|
||||
}
|
||||
type ComplianceFrameworkResolver interface {
|
||||
Framework(ctx context.Context, obj *types.ComplianceFramework) (*types.Framework, error)
|
||||
}
|
||||
type DocumentResolver interface {
|
||||
IsUserAuthorized(ctx context.Context, obj *types.Document) (bool, error)
|
||||
Access(ctx context.Context, obj *types.Document) (*types.DocumentAccess, error)
|
||||
@@ -349,6 +369,7 @@ type TrustCenterResolver interface {
|
||||
Vendors(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.VendorConnection, error)
|
||||
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)
|
||||
}
|
||||
type TrustCenterFileResolver interface {
|
||||
IsUserAuthorized(ctx context.Context, obj *types.TrustCenterFile) (bool, error)
|
||||
@@ -433,6 +454,45 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
|
||||
return e.ComplexityRoot.AuditEdge.Node(childComplexity), true
|
||||
|
||||
case "ComplianceFramework.framework":
|
||||
if e.ComplexityRoot.ComplianceFramework.Framework == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.ComplexityRoot.ComplianceFramework.Framework(childComplexity), true
|
||||
case "ComplianceFramework.id":
|
||||
if e.ComplexityRoot.ComplianceFramework.ID == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.ComplexityRoot.ComplianceFramework.ID(childComplexity), true
|
||||
|
||||
case "ComplianceFrameworkConnection.edges":
|
||||
if e.ComplexityRoot.ComplianceFrameworkConnection.Edges == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.ComplexityRoot.ComplianceFrameworkConnection.Edges(childComplexity), true
|
||||
case "ComplianceFrameworkConnection.pageInfo":
|
||||
if e.ComplexityRoot.ComplianceFrameworkConnection.PageInfo == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.ComplexityRoot.ComplianceFrameworkConnection.PageInfo(childComplexity), true
|
||||
|
||||
case "ComplianceFrameworkEdge.cursor":
|
||||
if e.ComplexityRoot.ComplianceFrameworkEdge.Cursor == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.ComplexityRoot.ComplianceFrameworkEdge.Cursor(childComplexity), true
|
||||
case "ComplianceFrameworkEdge.node":
|
||||
if e.ComplexityRoot.ComplianceFrameworkEdge.Node == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.ComplexityRoot.ComplianceFrameworkEdge.Node(childComplexity), true
|
||||
|
||||
case "Document.access":
|
||||
if e.ComplexityRoot.Document.Access == nil {
|
||||
break
|
||||
@@ -948,6 +1008,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
||||
}
|
||||
|
||||
return e.ComplexityRoot.TrustCenter.Audits(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey)), true
|
||||
case "TrustCenter.complianceFrameworks":
|
||||
if e.ComplexityRoot.TrustCenter.ComplianceFrameworks == nil {
|
||||
break
|
||||
}
|
||||
|
||||
args, err := ec.field_TrustCenter_complianceFrameworks_args(ctx, rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.ComplexityRoot.TrustCenter.ComplianceFrameworks(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey)), true
|
||||
case "TrustCenter.darkLogoFileUrl":
|
||||
if e.ComplexityRoot.TrustCenter.DarkLogoFileURL == nil {
|
||||
break
|
||||
@@ -1458,6 +1529,21 @@ type AuditEdge @nda {
|
||||
node: Audit!
|
||||
}
|
||||
|
||||
type ComplianceFramework implements Node {
|
||||
id: ID!
|
||||
framework: Framework! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type ComplianceFrameworkConnection {
|
||||
edges: [ComplianceFrameworkEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type ComplianceFrameworkEdge {
|
||||
cursor: CursorKey!
|
||||
node: ComplianceFramework!
|
||||
}
|
||||
|
||||
enum CountryCode
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.CountryCode") {
|
||||
AD @goEnum(value: "go.probo.inc/probo/pkg/coredata.CountryCodeAD")
|
||||
@@ -1893,6 +1979,13 @@ type TrustCenter implements Node {
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): TrustCenterFileConnection! @goField(forceResolver: true)
|
||||
|
||||
complianceFrameworks(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
): ComplianceFrameworkConnection! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type TrustCenterAccess implements Node {
|
||||
@@ -2396,6 +2489,32 @@ func (ec *executionContext) field_TrustCenter_audits_args(ctx context.Context, r
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_TrustCenter_complianceFrameworks_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_documents_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
||||
var err error
|
||||
args := map[string]any{}
|
||||
@@ -2929,6 +3048,212 @@ func (ec *executionContext) fieldContext_AuditEdge_node(_ context.Context, field
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _ComplianceFramework_id(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFramework) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
ec.OperationContext,
|
||||
field,
|
||||
ec.fieldContext_ComplianceFramework_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_ComplianceFramework_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "ComplianceFramework",
|
||||
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) _ComplianceFramework_framework(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFramework) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
ec.OperationContext,
|
||||
field,
|
||||
ec.fieldContext_ComplianceFramework_framework,
|
||||
func(ctx context.Context) (any, error) {
|
||||
return ec.Resolvers.ComplianceFramework().Framework(ctx, obj)
|
||||
},
|
||||
nil,
|
||||
ec.marshalNFramework2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐFramework,
|
||||
true,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_ComplianceFramework_framework(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "ComplianceFramework",
|
||||
Field: field,
|
||||
IsMethod: true,
|
||||
IsResolver: true,
|
||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||
switch field.Name {
|
||||
case "id":
|
||||
return ec.fieldContext_Framework_id(ctx, field)
|
||||
case "name":
|
||||
return ec.fieldContext_Framework_name(ctx, field)
|
||||
case "lightLogoURL":
|
||||
return ec.fieldContext_Framework_lightLogoURL(ctx, field)
|
||||
case "darkLogoURL":
|
||||
return ec.fieldContext_Framework_darkLogoURL(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type Framework", field.Name)
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _ComplianceFrameworkConnection_edges(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFrameworkConnection) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
ec.OperationContext,
|
||||
field,
|
||||
ec.fieldContext_ComplianceFrameworkConnection_edges,
|
||||
func(ctx context.Context) (any, error) {
|
||||
return obj.Edges, nil
|
||||
},
|
||||
nil,
|
||||
ec.marshalNComplianceFrameworkEdge2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkEdgeᚄ,
|
||||
true,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_ComplianceFrameworkConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "ComplianceFrameworkConnection",
|
||||
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_ComplianceFrameworkEdge_cursor(ctx, field)
|
||||
case "node":
|
||||
return ec.fieldContext_ComplianceFrameworkEdge_node(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type ComplianceFrameworkEdge", field.Name)
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _ComplianceFrameworkConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFrameworkConnection) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
ec.OperationContext,
|
||||
field,
|
||||
ec.fieldContext_ComplianceFrameworkConnection_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_ComplianceFrameworkConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "ComplianceFrameworkConnection",
|
||||
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) _ComplianceFrameworkEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFrameworkEdge) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
ec.OperationContext,
|
||||
field,
|
||||
ec.fieldContext_ComplianceFrameworkEdge_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_ComplianceFrameworkEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "ComplianceFrameworkEdge",
|
||||
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) _ComplianceFrameworkEdge_node(ctx context.Context, field graphql.CollectedField, obj *types.ComplianceFrameworkEdge) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
ec.OperationContext,
|
||||
field,
|
||||
ec.fieldContext_ComplianceFrameworkEdge_node,
|
||||
func(ctx context.Context) (any, error) {
|
||||
return obj.Node, nil
|
||||
},
|
||||
nil,
|
||||
ec.marshalNComplianceFramework2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFramework,
|
||||
true,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_ComplianceFrameworkEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||
fc = &graphql.FieldContext{
|
||||
Object: "ComplianceFrameworkEdge",
|
||||
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_ComplianceFramework_id(ctx, field)
|
||||
case "framework":
|
||||
return ec.fieldContext_ComplianceFramework_framework(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type ComplianceFramework", field.Name)
|
||||
},
|
||||
}
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Document_id(ctx context.Context, field graphql.CollectedField, obj *types.Document) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
@@ -5203,6 +5528,8 @@ func (ec *executionContext) fieldContext_Query_currentTrustCenter(_ context.Cont
|
||||
return ec.fieldContext_TrustCenter_references(ctx, field)
|
||||
case "trustCenterFiles":
|
||||
return ec.fieldContext_TrustCenter_trustCenterFiles(ctx, field)
|
||||
case "complianceFrameworks":
|
||||
return ec.fieldContext_TrustCenter_complianceFrameworks(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type TrustCenter", field.Name)
|
||||
},
|
||||
@@ -6228,6 +6555,53 @@ func (ec *executionContext) fieldContext_TrustCenter_trustCenterFiles(ctx contex
|
||||
return fc, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) _TrustCenter_complianceFrameworks(ctx context.Context, field graphql.CollectedField, obj *types.TrustCenter) (ret graphql.Marshaler) {
|
||||
return graphql.ResolveField(
|
||||
ctx,
|
||||
ec.OperationContext,
|
||||
field,
|
||||
ec.fieldContext_TrustCenter_complianceFrameworks,
|
||||
func(ctx context.Context) (any, error) {
|
||||
fc := graphql.GetFieldContext(ctx)
|
||||
return ec.Resolvers.TrustCenter().ComplianceFrameworks(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey))
|
||||
},
|
||||
nil,
|
||||
ec.marshalNComplianceFrameworkConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkConnection,
|
||||
true,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
func (ec *executionContext) fieldContext_TrustCenter_complianceFrameworks(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_ComplianceFrameworkConnection_edges(ctx, field)
|
||||
case "pageInfo":
|
||||
return ec.fieldContext_ComplianceFrameworkConnection_pageInfo(ctx, field)
|
||||
}
|
||||
return nil, fmt.Errorf("no field named %q was found under type ComplianceFrameworkConnection", 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_complianceFrameworks_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,
|
||||
@@ -9263,6 +9637,13 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj
|
||||
return graphql.Null
|
||||
}
|
||||
return ec._Document(ctx, sel, obj)
|
||||
case types.ComplianceFramework:
|
||||
return ec._ComplianceFramework(ctx, sel, &obj)
|
||||
case *types.ComplianceFramework:
|
||||
if obj == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
return ec._ComplianceFramework(ctx, sel, obj)
|
||||
case types.Audit:
|
||||
return ec._Audit(ctx, sel, &obj)
|
||||
case *types.Audit:
|
||||
@@ -9520,6 +9901,169 @@ func (ec *executionContext) _AuditEdge(ctx context.Context, sel ast.SelectionSet
|
||||
return out
|
||||
}
|
||||
|
||||
var complianceFrameworkImplementors = []string{"ComplianceFramework", "Node"}
|
||||
|
||||
func (ec *executionContext) _ComplianceFramework(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceFramework) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.OperationContext, sel, complianceFrameworkImplementors)
|
||||
|
||||
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("ComplianceFramework")
|
||||
case "id":
|
||||
out.Values[i] = ec._ComplianceFramework_id(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
atomic.AddUint32(&out.Invalids, 1)
|
||||
}
|
||||
case "framework":
|
||||
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._ComplianceFramework_framework(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 complianceFrameworkConnectionImplementors = []string{"ComplianceFrameworkConnection"}
|
||||
|
||||
func (ec *executionContext) _ComplianceFrameworkConnection(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceFrameworkConnection) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.OperationContext, sel, complianceFrameworkConnectionImplementors)
|
||||
|
||||
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("ComplianceFrameworkConnection")
|
||||
case "edges":
|
||||
out.Values[i] = ec._ComplianceFrameworkConnection_edges(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
out.Invalids++
|
||||
}
|
||||
case "pageInfo":
|
||||
out.Values[i] = ec._ComplianceFrameworkConnection_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 complianceFrameworkEdgeImplementors = []string{"ComplianceFrameworkEdge"}
|
||||
|
||||
func (ec *executionContext) _ComplianceFrameworkEdge(ctx context.Context, sel ast.SelectionSet, obj *types.ComplianceFrameworkEdge) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.OperationContext, sel, complianceFrameworkEdgeImplementors)
|
||||
|
||||
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("ComplianceFrameworkEdge")
|
||||
case "cursor":
|
||||
out.Values[i] = ec._ComplianceFrameworkEdge_cursor(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
out.Invalids++
|
||||
}
|
||||
case "node":
|
||||
out.Values[i] = ec._ComplianceFrameworkEdge_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 documentImplementors = []string{"Document", "Node"}
|
||||
|
||||
func (ec *executionContext) _Document(ctx context.Context, sel ast.SelectionSet, obj *types.Document) graphql.Marshaler {
|
||||
@@ -11265,6 +11809,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 "complianceFrameworks":
|
||||
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_complianceFrameworks(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))
|
||||
@@ -12355,6 +12935,56 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se
|
||||
return res
|
||||
}
|
||||
|
||||
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)) {
|
||||
graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
return ec._ComplianceFramework(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNComplianceFrameworkConnection2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkConnection(ctx context.Context, sel ast.SelectionSet, v types.ComplianceFrameworkConnection) graphql.Marshaler {
|
||||
return ec._ComplianceFrameworkConnection(ctx, sel, &v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNComplianceFrameworkConnection2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkConnection(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceFrameworkConnection) 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._ComplianceFrameworkConnection(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNComplianceFrameworkEdge2ᚕᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []*types.ComplianceFrameworkEdge) 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.marshalNComplianceFrameworkEdge2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkEdge(ctx, sel, v[i])
|
||||
})
|
||||
|
||||
for _, e := range ret {
|
||||
if e == graphql.Null {
|
||||
return graphql.Null
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNComplianceFrameworkEdge2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐComplianceFrameworkEdge(ctx context.Context, sel ast.SelectionSet, v *types.ComplianceFrameworkEdge) 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._ComplianceFrameworkEdge(ctx, sel, v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalNCountryCode2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐCountryCode(ctx context.Context, v any) (coredata.CountryCode, error) {
|
||||
tmp, err := graphql.UnmarshalString(v)
|
||||
res := unmarshalNCountryCode2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐCountryCode[tmp]
|
||||
|
||||
@@ -16,6 +16,7 @@ package types
|
||||
|
||||
import (
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
func NewFramework(f *coredata.Framework) *Framework {
|
||||
@@ -24,3 +25,31 @@ func NewFramework(f *coredata.Framework) *Framework {
|
||||
Name: f.Name,
|
||||
}
|
||||
}
|
||||
|
||||
func NewComplianceFramework(cf *coredata.ComplianceFramework) *ComplianceFramework {
|
||||
return &ComplianceFramework{
|
||||
ID: cf.ID,
|
||||
FrameworkID: cf.FrameworkID,
|
||||
}
|
||||
}
|
||||
|
||||
func NewComplianceFrameworkEdge(cf *coredata.ComplianceFramework) *ComplianceFrameworkEdge {
|
||||
return &ComplianceFrameworkEdge{
|
||||
Cursor: cf.CursorKey(coredata.ComplianceFrameworkOrderFieldRank),
|
||||
Node: NewComplianceFramework(cf),
|
||||
}
|
||||
}
|
||||
|
||||
func NewComplianceFrameworkConnection(
|
||||
p *page.Page[*coredata.ComplianceFramework, coredata.ComplianceFrameworkOrderField],
|
||||
) *ComplianceFrameworkConnection {
|
||||
edges := make([]*ComplianceFrameworkEdge, len(p.Data))
|
||||
for i, cf := range p.Data {
|
||||
edges[i] = NewComplianceFrameworkEdge(cf)
|
||||
}
|
||||
|
||||
return &ComplianceFrameworkConnection{
|
||||
Edges: edges,
|
||||
PageInfo: NewPageInfo(p),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,26 @@ type AuditEdge struct {
|
||||
Node *Audit `json:"node"`
|
||||
}
|
||||
|
||||
type ComplianceFramework struct {
|
||||
ID gid.GID `json:"id"`
|
||||
// FrameworkID is a non-schema field used by the Framework resolver to avoid an extra DB lookup.
|
||||
FrameworkID gid.GID `json:"-"`
|
||||
Framework *Framework `json:"framework"`
|
||||
}
|
||||
|
||||
func (ComplianceFramework) IsNode() {}
|
||||
func (this ComplianceFramework) GetID() gid.GID { return this.ID }
|
||||
|
||||
type ComplianceFrameworkConnection struct {
|
||||
Edges []*ComplianceFrameworkEdge `json:"edges"`
|
||||
PageInfo *PageInfo `json:"pageInfo"`
|
||||
}
|
||||
|
||||
type ComplianceFrameworkEdge struct {
|
||||
Cursor page.CursorKey `json:"cursor"`
|
||||
Node *ComplianceFramework `json:"node"`
|
||||
}
|
||||
|
||||
type Document struct {
|
||||
ID gid.GID `json:"id"`
|
||||
Title string `json:"title"`
|
||||
@@ -235,6 +255,7 @@ type TrustCenter struct {
|
||||
Vendors *VendorConnection `json:"vendors"`
|
||||
References *TrustCenterReferenceConnection `json:"references"`
|
||||
TrustCenterFiles *TrustCenterFileConnection `json:"trustCenterFiles"`
|
||||
ComplianceFrameworks *ComplianceFrameworkConnection `json:"complianceFrameworks"`
|
||||
}
|
||||
|
||||
func (TrustCenter) IsNode() {}
|
||||
|
||||
@@ -71,6 +71,19 @@ func (r *auditResolver) Report(ctx context.Context, obj *types.Audit) (*types.Re
|
||||
return types.NewReport(report), nil
|
||||
}
|
||||
|
||||
// Framework is the resolver for the framework field on ComplianceFramework.
|
||||
func (r *complianceFrameworkResolver) Framework(ctx context.Context, obj *types.ComplianceFramework) (*types.Framework, error) {
|
||||
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
||||
|
||||
framework, err := trustService.Frameworks.Get(ctx, obj.FrameworkID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot load framework", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewFramework(framework), nil
|
||||
}
|
||||
|
||||
// IsUserAuthorized is the resolver for the isUserAuthorized field.
|
||||
func (r *documentResolver) IsUserAuthorized(ctx context.Context, obj *types.Document) (bool, error) {
|
||||
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
||||
@@ -1014,6 +1027,25 @@ func (r *trustCenterResolver) TrustCenterFiles(ctx context.Context, obj *types.T
|
||||
return types.NewTrustCenterFileConnection(trustCenterFilePage), nil
|
||||
}
|
||||
|
||||
// ComplianceFrameworks is the resolver for the complianceFrameworks field.
|
||||
func (r *trustCenterResolver) ComplianceFrameworks(ctx context.Context, obj *types.TrustCenter, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.ComplianceFrameworkConnection, error) {
|
||||
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.ComplianceFrameworkOrderField]{
|
||||
Field: coredata.ComplianceFrameworkOrderFieldRank,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
}
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
cfPage, err := trustService.ComplianceFrameworks.ListByTrustCenterID(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list compliance frameworks", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewComplianceFrameworkConnection(cfPage), 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())
|
||||
@@ -1124,6 +1156,11 @@ func (r *vendorConnectionResolver) TotalCount(ctx context.Context, obj *types.Ve
|
||||
// Audit returns schema.AuditResolver implementation.
|
||||
func (r *Resolver) Audit() schema.AuditResolver { return &auditResolver{r} }
|
||||
|
||||
// ComplianceFramework returns schema.ComplianceFrameworkResolver implementation.
|
||||
func (r *Resolver) ComplianceFramework() schema.ComplianceFrameworkResolver {
|
||||
return &complianceFrameworkResolver{r}
|
||||
}
|
||||
|
||||
// Document returns schema.DocumentResolver implementation.
|
||||
func (r *Resolver) Document() schema.DocumentResolver { return &documentResolver{r} }
|
||||
|
||||
@@ -1166,6 +1203,7 @@ func (r *Resolver) VendorConnection() schema.VendorConnectionResolver {
|
||||
}
|
||||
|
||||
type auditResolver struct{ *Resolver }
|
||||
type complianceFrameworkResolver struct{ *Resolver }
|
||||
type documentResolver struct{ *Resolver }
|
||||
type frameworkResolver struct{ *Resolver }
|
||||
type mutationResolver struct{ *Resolver }
|
||||
|
||||
55
pkg/trust/compliance_framework_service.go
Normal file
55
pkg/trust/compliance_framework_service.go
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// 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 ComplianceFrameworkService struct {
|
||||
svc *TenantService
|
||||
}
|
||||
|
||||
func (s ComplianceFrameworkService) ListByTrustCenterID(
|
||||
ctx context.Context,
|
||||
trustCenterID gid.GID,
|
||||
cursor *page.Cursor[coredata.ComplianceFrameworkOrderField],
|
||||
) (*page.Page[*coredata.ComplianceFramework, coredata.ComplianceFrameworkOrderField], error) {
|
||||
var complianceFrameworks coredata.ComplianceFrameworks
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
err := complianceFrameworks.LoadByTrustCenterID(ctx, conn, s.svc.scope, trustCenterID, cursor)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load compliance frameworks: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(complianceFrameworks, cursor), nil
|
||||
}
|
||||
@@ -70,6 +70,7 @@ type (
|
||||
Audits *AuditService
|
||||
Vendors *VendorService
|
||||
Frameworks *FrameworkService
|
||||
ComplianceFrameworks *ComplianceFrameworkService
|
||||
TrustCenterAccesses *TrustCenterAccessService
|
||||
TrustCenterReferences *TrustCenterReferenceService
|
||||
TrustCenterFiles *TrustCenterFileService
|
||||
@@ -130,6 +131,7 @@ func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService {
|
||||
tenantService.Audits = &AuditService{svc: tenantService}
|
||||
tenantService.Vendors = &VendorService{svc: tenantService}
|
||||
tenantService.Frameworks = &FrameworkService{svc: tenantService}
|
||||
tenantService.ComplianceFrameworks = &ComplianceFrameworkService{svc: tenantService}
|
||||
tenantService.TrustCenterAccesses = &TrustCenterAccessService{svc: tenantService, iamSvc: s.iam, logger: s.logger}
|
||||
tenantService.TrustCenterReferences = &TrustCenterReferenceService{svc: tenantService}
|
||||
tenantService.TrustCenterFiles = &TrustCenterFileService{svc: tenantService}
|
||||
|
||||
Reference in New Issue
Block a user