Decouple users from people

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-09-22 15:02:08 +02:00
parent 104330d3fd
commit 533822b60d
35 changed files with 296 additions and 872 deletions

View File

@@ -4,6 +4,7 @@ import {
DialogContent, DialogContent,
DialogFooter, DialogFooter,
Field, Field,
Checkbox,
useDialogRef, useDialogRef,
} from "@probo/ui"; } from "@probo/ui";
import type { PropsWithChildren } from "react"; import type { PropsWithChildren } from "react";
@@ -13,6 +14,7 @@ import { useOrganizationId } from "/hooks/useOrganizationId";
import { useMutationWithToasts } from "/hooks/useMutationWithToasts"; import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
import { z } from "zod"; import { z } from "zod";
import { useFormWithSchema } from "/hooks/useFormWithSchema"; import { useFormWithSchema } from "/hooks/useFormWithSchema";
import { Controller } from "react-hook-form";
const inviteMutation = graphql` const inviteMutation = graphql`
mutation InviteUserDialogMutation($input: InviteUserInput!) { mutation InviteUserDialogMutation($input: InviteUserInput!) {
@@ -25,6 +27,7 @@ const inviteMutation = graphql`
const schema = z.object({ const schema = z.object({
email: z.string().email(), email: z.string().email(),
fullName: z.string(), fullName: z.string(),
createPeople: z.boolean().default(false),
}); });
export function InviteUserDialog({ children }: PropsWithChildren) { export function InviteUserDialog({ children }: PropsWithChildren) {
@@ -34,9 +37,9 @@ export function InviteUserDialog({ children }: PropsWithChildren) {
successMessage: __("User invited successfully"), successMessage: __("User invited successfully"),
errorMessage: __("Failed to invite user"), errorMessage: __("Failed to invite user"),
}); });
const { register, handleSubmit, formState, reset } = useFormWithSchema( const { register, handleSubmit, formState, reset, control } = useFormWithSchema(
schema, schema,
{}, { defaultValues: { createPeople: false } },
); );
const dialogRef = useDialogRef(); const dialogRef = useDialogRef();
@@ -48,6 +51,7 @@ export function InviteUserDialog({ children }: PropsWithChildren) {
organizationId, organizationId,
email: data.email, email: data.email,
fullName: data.fullName, fullName: data.fullName,
createPeople: data.createPeople,
}, },
}, },
onSuccess: () => { onSuccess: () => {
@@ -83,6 +87,31 @@ export function InviteUserDialog({ children }: PropsWithChildren) {
{...register("fullName")} {...register("fullName")}
error={formState.errors.fullName?.message} error={formState.errors.fullName?.message}
/> />
<div className="space-y-2">
<div className="flex items-center space-x-3">
<Controller
name="createPeople"
control={control}
render={({ field }) => (
<>
<Checkbox
checked={field.value}
onChange={field.onChange}
/>
<label
className="text-sm font-medium cursor-pointer"
onClick={() => field.onChange(!field.value)}
>
{__("Create people record")}
</label>
</>
)}
/>
</div>
<p className="text-xs text-txt-secondary ml-7">
{__("Creates a people record for this user in addition to the user account")}
</p>
</div>
</DialogContent> </DialogContent>
<DialogFooter> <DialogFooter>
<Button type="submit" disabled={isInviting}> <Button type="submit" disabled={isInviting}>

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<1cf40085b2959d7ebb48ee4a90be41b1>> * @generated SignedSource<<9ed3f33dde5f6a00c742b8db245ba03b>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -10,6 +10,7 @@
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
export type InviteUserInput = { export type InviteUserInput = {
createPeople: boolean;
email: string; email: string;
fullName: string; fullName: string;
organizationId: string; organizationId: string;

View File

@@ -128,12 +128,12 @@ export const paginatedVendorsFragment = graphql`
updatedAt updatedAt
riskAssessments( riskAssessments(
first: 1 first: 1
orderBy: { direction: DESC, field: ASSESSED_AT } orderBy: { direction: DESC, field: CREATED_AT }
) { ) {
edges { edges {
node { node {
id id
assessedAt createdAt
expiresAt expiresAt
dataSensitivity dataSensitivity
businessImpact businessImpact
@@ -165,6 +165,7 @@ export const vendorNodeQuery = graphql`
} }
viewer { viewer {
user { user {
id
people(organizationId: $organizationId) { people(organizationId: $organizationId) {
id id
} }

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<85c6bcb5e086b05009ccfaf8ac21a23e>> * @generated SignedSource<<ad33fa2c4266cca92954782c7805effc>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -387,19 +387,6 @@ return {
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "publishedBy",
"plural": false,
"selections": [
(v4/*: any*/),
(v3/*: any*/)
],
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": (v11/*: any*/), "args": (v11/*: any*/),
@@ -520,12 +507,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "fbfe2cc393b8fc5349a92f3443f12e0e", "cacheID": "ef08fbd3755a6ab5eff7786164842da8",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "DocumentGraphNodeQuery", "name": "DocumentGraphNodeQuery",
"operationKind": "query", "operationKind": "query",
"text": "query DocumentGraphNodeQuery(\n $documentId: ID!\n) {\n node(id: $documentId) {\n __typename\n ... on Document {\n ...DocumentDetailPageDocumentFragment\n }\n id\n }\n}\n\nfragment DocumentControlsTabFragment on Document {\n id\n controls(first: 20) {\n edges {\n node {\n id\n ...LinkedControlsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment DocumentDetailPageDocumentFragment on Document {\n id\n title\n documentType\n owner {\n id\n fullName\n }\n ...DocumentControlsTabFragment\n controlsInfo: controls(first: 0) {\n totalCount\n }\n versions(first: 20) {\n edges {\n node {\n id\n content\n status\n publishedAt\n version\n updatedAt\n publishedBy {\n fullName\n id\n }\n signatures(first: 100) {\n edges {\n node {\n id\n state\n signedBy {\n id\n }\n ...DocumentSignaturesTab_signature\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment DocumentSignaturesTab_signature on DocumentVersionSignature {\n id\n state\n signedAt\n requestedAt\n signedBy {\n fullName\n primaryEmailAddress\n id\n }\n}\n\nfragment LinkedControlsCardFragment on Control {\n id\n name\n sectionTitle\n framework {\n id\n name\n }\n}\n" "text": "query DocumentGraphNodeQuery(\n $documentId: ID!\n) {\n node(id: $documentId) {\n __typename\n ... on Document {\n ...DocumentDetailPageDocumentFragment\n }\n id\n }\n}\n\nfragment DocumentControlsTabFragment on Document {\n id\n controls(first: 20) {\n edges {\n node {\n id\n ...LinkedControlsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment DocumentDetailPageDocumentFragment on Document {\n id\n title\n documentType\n owner {\n id\n fullName\n }\n ...DocumentControlsTabFragment\n controlsInfo: controls(first: 0) {\n totalCount\n }\n versions(first: 20) {\n edges {\n node {\n id\n content\n status\n publishedAt\n version\n updatedAt\n signatures(first: 100) {\n edges {\n node {\n id\n state\n signedBy {\n id\n }\n ...DocumentSignaturesTab_signature\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment DocumentSignaturesTab_signature on DocumentVersionSignature {\n id\n state\n signedAt\n requestedAt\n signedBy {\n fullName\n primaryEmailAddress\n id\n }\n}\n\nfragment LinkedControlsCardFragment on Control {\n id\n name\n sectionTitle\n framework {\n id\n name\n }\n}\n"
} }
}; };
})(); })();

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<5b8f324da8c4dc9302cb6f821062757d>> * @generated SignedSource<<46d46472ea11f58c00df8b8827afab98>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -13,7 +13,6 @@ import { FragmentRefs } from "relay-runtime";
export type DocumentType = "ISMS" | "OTHER" | "POLICY"; export type DocumentType = "ISMS" | "OTHER" | "POLICY";
export type UpdateDocumentInput = { export type UpdateDocumentInput = {
content?: string | null | undefined; content?: string | null | undefined;
createdBy?: string | null | undefined;
documentType?: DocumentType | null | undefined; documentType?: DocumentType | null | undefined;
id: string; id: string;
ownerId?: string | null | undefined; ownerId?: string | null | undefined;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<8b1614888dac560deff871232f91995d>> * @generated SignedSource<<554f3a594f825db3f7f7da0c5c1d8b1f>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -198,7 +198,7 @@ return {
"name": "orderBy", "name": "orderBy",
"value": { "value": {
"direction": "DESC", "direction": "DESC",
"field": "ASSESSED_AT" "field": "CREATED_AT"
} }
} }
], ],
@@ -228,7 +228,7 @@ return {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "assessedAt", "name": "createdAt",
"storageKey": null "storageKey": null
}, },
{ {
@@ -259,7 +259,7 @@ return {
"storageKey": null "storageKey": null
} }
], ],
"storageKey": "riskAssessments(first:1,orderBy:{\"direction\":\"DESC\",\"field\":\"ASSESSED_AT\"})" "storageKey": "riskAssessments(first:1,orderBy:{\"direction\":\"DESC\",\"field\":\"CREATED_AT\"})"
}, },
(v4/*: any*/) (v4/*: any*/)
], ],
@@ -350,12 +350,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "4b19f6f4be47c38d8b68601ec95315a6", "cacheID": "998ad60d132157090312ac11e318b2e5",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "VendorGraphListQuery", "name": "VendorGraphListQuery",
"operationKind": "query", "operationKind": "query",
"text": "query VendorGraphListQuery(\n $organizationId: ID!\n $snapshotId: ID\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n ...VendorGraphPaginatedFragment_3iomuz\n }\n id\n }\n}\n\nfragment VendorGraphPaginatedFragment_3iomuz on Organization {\n vendors(first: 50, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n snapshotId\n name\n websiteUrl\n updatedAt\n riskAssessments(first: 1, orderBy: {direction: DESC, field: ASSESSED_AT}) {\n edges {\n node {\n id\n assessedAt\n expiresAt\n dataSensitivity\n businessImpact\n }\n }\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n" "text": "query VendorGraphListQuery(\n $organizationId: ID!\n $snapshotId: ID\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n ...VendorGraphPaginatedFragment_3iomuz\n }\n id\n }\n}\n\nfragment VendorGraphPaginatedFragment_3iomuz on Organization {\n vendors(first: 50, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n snapshotId\n name\n websiteUrl\n updatedAt\n riskAssessments(first: 1, orderBy: {direction: DESC, field: CREATED_AT}) {\n edges {\n node {\n id\n createdAt\n expiresAt\n dataSensitivity\n businessImpact\n }\n }\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
} }
}; };
})(); })();

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<15c7796ac43c03708488ba03ef9d76a6>> * @generated SignedSource<<d72032da6df08b84ce9c7ec87b950d08>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -24,6 +24,7 @@ export type VendorGraphNodeQuery$data = {
}; };
readonly viewer: { readonly viewer: {
readonly user: { readonly user: {
readonly id: string;
readonly people: { readonly people: {
readonly id: string; readonly id: string;
} | null | undefined; } | null | undefined;
@@ -86,18 +87,30 @@ v7 = [
], ],
v8 = { v8 = {
"alias": null, "alias": null,
"args": [ "args": null,
"concreteType": "User",
"kind": "LinkedField",
"name": "user",
"plural": false,
"selections": [
(v3/*: any*/),
{ {
"kind": "Variable", "alias": null,
"name": "organizationId", "args": [
"variableName": "organizationId" {
"kind": "Variable",
"name": "organizationId",
"variableName": "organizationId"
}
],
"concreteType": "People",
"kind": "LinkedField",
"name": "people",
"plural": false,
"selections": (v7/*: any*/),
"storageKey": null
} }
], ],
"concreteType": "People",
"kind": "LinkedField",
"name": "people",
"plural": false,
"selections": (v7/*: any*/),
"storageKey": null "storageKey": null
}, },
v9 = { v9 = {
@@ -204,24 +217,17 @@ v22 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "fullName", "name": "createdAt",
"storageKey": null "storageKey": null
}, },
v23 = { v23 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "createdAt",
"storageKey": null
},
v24 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "storageKey": null
}, },
v25 = [ v24 = [
(v3/*: any*/), (v3/*: any*/),
{ {
"alias": null, "alias": null,
@@ -239,7 +245,7 @@ v25 = [
"storageKey": null "storageKey": null
}, },
(v12/*: any*/), (v12/*: any*/),
(v23/*: any*/) (v22/*: any*/)
]; ];
return { return {
"fragment": { "fragment": {
@@ -316,18 +322,7 @@ return {
"name": "viewer", "name": "viewer",
"plural": false, "plural": false,
"selections": [ "selections": [
{ (v8/*: any*/)
"alias": null,
"args": null,
"concreteType": "User",
"kind": "LinkedField",
"name": "user",
"plural": false,
"selections": [
(v8/*: any*/)
],
"storageKey": null
}
], ],
"storageKey": null "storageKey": null
} }
@@ -560,7 +555,13 @@ return {
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/), (v3/*: any*/),
(v22/*: any*/), {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -582,8 +583,8 @@ return {
"name": "role", "name": "role",
"storageKey": null "storageKey": null
}, },
(v22/*: any*/),
(v23/*: any*/), (v23/*: any*/),
(v24/*: any*/),
(v9/*: any*/) (v9/*: any*/)
], ],
"storageKey": null "storageKey": null
@@ -633,8 +634,8 @@ return {
(v3/*: any*/), (v3/*: any*/),
(v5/*: any*/), (v5/*: any*/),
(v10/*: any*/), (v10/*: any*/),
(v22/*: any*/),
(v23/*: any*/), (v23/*: any*/),
(v24/*: any*/),
(v9/*: any*/) (v9/*: any*/)
], ],
"storageKey": null "storageKey": null
@@ -682,26 +683,7 @@ return {
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/), (v3/*: any*/),
{ (v22/*: any*/),
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "assessedAt",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "assessedBy",
"plural": false,
"selections": [
(v3/*: any*/),
(v22/*: any*/)
],
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -773,7 +755,7 @@ return {
"kind": "LinkedField", "kind": "LinkedField",
"name": "businessAssociateAgreement", "name": "businessAssociateAgreement",
"plural": false, "plural": false,
"selections": (v25/*: any*/), "selections": (v24/*: any*/),
"storageKey": null "storageKey": null
}, },
{ {
@@ -783,7 +765,7 @@ return {
"kind": "LinkedField", "kind": "LinkedField",
"name": "dataPrivacyAgreement", "name": "dataPrivacyAgreement",
"plural": false, "plural": false,
"selections": (v25/*: any*/), "selections": (v24/*: any*/),
"storageKey": null "storageKey": null
} }
], ],
@@ -801,19 +783,7 @@ return {
"name": "viewer", "name": "viewer",
"plural": false, "plural": false,
"selections": [ "selections": [
{ (v8/*: any*/),
"alias": null,
"args": null,
"concreteType": "User",
"kind": "LinkedField",
"name": "user",
"plural": false,
"selections": [
(v8/*: any*/),
(v3/*: any*/)
],
"storageKey": null
},
(v3/*: any*/) (v3/*: any*/)
], ],
"storageKey": null "storageKey": null
@@ -821,16 +791,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "90924936acacd1851e8e81b1d94d6655", "cacheID": "4a112f861864990f5022d279ba8d43d4",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "VendorGraphNodeQuery", "name": "VendorGraphNodeQuery",
"operationKind": "query", "operationKind": "query",
"text": "query VendorGraphNodeQuery(\n $vendorId: ID!\n $organizationId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n snapshotId\n name\n websiteUrl\n ...useVendorFormFragment\n ...VendorComplianceTabFragment\n ...VendorContactsTabFragment\n ...VendorServicesTabFragment\n ...VendorRiskAssessmentTabFragment\n ...VendorOverviewTabBusinessAssociateAgreementFragment\n ...VendorOverviewTabDataPrivacyAgreementFragment\n }\n id\n }\n viewer {\n user {\n people(organizationId: $organizationId) {\n id\n }\n id\n }\n id\n }\n}\n\nfragment VendorComplianceTabFragment on Vendor {\n complianceReports(first: 50) {\n edges {\n node {\n id\n ...VendorComplianceTabFragment_report\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorComplianceTabFragment_report on VendorComplianceReport {\n id\n reportDate\n validUntil\n reportName\n fileUrl\n fileSize\n}\n\nfragment VendorContactsTabFragment on Vendor {\n contacts(first: 50) {\n edges {\n node {\n id\n ...VendorContactsTabFragment_contact\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorContactsTabFragment_contact on VendorContact {\n id\n fullName\n email\n phone\n role\n createdAt\n updatedAt\n}\n\nfragment VendorOverviewTabBusinessAssociateAgreementFragment on Vendor {\n businessAssociateAgreement {\n id\n fileName\n fileUrl\n validFrom\n validUntil\n createdAt\n }\n}\n\nfragment VendorOverviewTabDataPrivacyAgreementFragment on Vendor {\n dataPrivacyAgreement {\n id\n fileName\n fileUrl\n validFrom\n validUntil\n createdAt\n }\n}\n\nfragment VendorRiskAssessmentTabFragment on Vendor {\n id\n riskAssessments(first: 50) {\n edges {\n node {\n id\n ...VendorRiskAssessmentTabFragment_assessment\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment VendorRiskAssessmentTabFragment_assessment on VendorRiskAssessment {\n id\n assessedAt\n assessedBy {\n id\n fullName\n }\n expiresAt\n dataSensitivity\n businessImpact\n notes\n}\n\nfragment VendorServicesTabFragment on Vendor {\n services(first: 50) {\n edges {\n node {\n id\n ...VendorServicesTabFragment_service\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorServicesTabFragment_service on VendorService {\n id\n name\n description\n createdAt\n updatedAt\n}\n\nfragment useVendorFormFragment on Vendor {\n id\n name\n description\n category\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n websiteUrl\n legalName\n headquarterAddress\n certifications\n countries\n securityPageUrl\n trustPageUrl\n businessOwner {\n id\n }\n securityOwner {\n id\n }\n}\n" "text": "query VendorGraphNodeQuery(\n $vendorId: ID!\n $organizationId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n snapshotId\n name\n websiteUrl\n ...useVendorFormFragment\n ...VendorComplianceTabFragment\n ...VendorContactsTabFragment\n ...VendorServicesTabFragment\n ...VendorRiskAssessmentTabFragment\n ...VendorOverviewTabBusinessAssociateAgreementFragment\n ...VendorOverviewTabDataPrivacyAgreementFragment\n }\n id\n }\n viewer {\n user {\n id\n people(organizationId: $organizationId) {\n id\n }\n }\n id\n }\n}\n\nfragment VendorComplianceTabFragment on Vendor {\n complianceReports(first: 50) {\n edges {\n node {\n id\n ...VendorComplianceTabFragment_report\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorComplianceTabFragment_report on VendorComplianceReport {\n id\n reportDate\n validUntil\n reportName\n fileUrl\n fileSize\n}\n\nfragment VendorContactsTabFragment on Vendor {\n contacts(first: 50) {\n edges {\n node {\n id\n ...VendorContactsTabFragment_contact\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorContactsTabFragment_contact on VendorContact {\n id\n fullName\n email\n phone\n role\n createdAt\n updatedAt\n}\n\nfragment VendorOverviewTabBusinessAssociateAgreementFragment on Vendor {\n businessAssociateAgreement {\n id\n fileName\n fileUrl\n validFrom\n validUntil\n createdAt\n }\n}\n\nfragment VendorOverviewTabDataPrivacyAgreementFragment on Vendor {\n dataPrivacyAgreement {\n id\n fileName\n fileUrl\n validFrom\n validUntil\n createdAt\n }\n}\n\nfragment VendorRiskAssessmentTabFragment on Vendor {\n id\n riskAssessments(first: 50) {\n edges {\n node {\n id\n ...VendorRiskAssessmentTabFragment_assessment\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment VendorRiskAssessmentTabFragment_assessment on VendorRiskAssessment {\n id\n createdAt\n expiresAt\n dataSensitivity\n businessImpact\n notes\n}\n\nfragment VendorServicesTabFragment on Vendor {\n services(first: 50) {\n edges {\n node {\n id\n ...VendorServicesTabFragment_service\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorServicesTabFragment_service on VendorService {\n id\n name\n description\n createdAt\n updatedAt\n}\n\nfragment useVendorFormFragment on Vendor {\n id\n name\n description\n category\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n websiteUrl\n legalName\n headquarterAddress\n certifications\n countries\n securityPageUrl\n trustPageUrl\n businessOwner {\n id\n }\n securityOwner {\n id\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "4af64d92bd85441554a2c6ad8d2ccd77"; (node as any).hash = "5b907e5cc3446745ff2414ee06839aed";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<b6975a3a740bdf7e2c9914fc64770638>> * @generated SignedSource<<1bb16039861951cb1726b506ce33f0ff>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -23,8 +23,8 @@ export type VendorGraphPaginatedFragment$data = {
readonly riskAssessments: { readonly riskAssessments: {
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
readonly node: { readonly node: {
readonly assessedAt: any;
readonly businessImpact: BusinessImpact; readonly businessImpact: BusinessImpact;
readonly createdAt: any;
readonly dataSensitivity: DataSensitivity; readonly dataSensitivity: DataSensitivity;
readonly expiresAt: any; readonly expiresAt: any;
readonly id: string; readonly id: string;
@@ -202,7 +202,7 @@ return {
"name": "orderBy", "name": "orderBy",
"value": { "value": {
"direction": "DESC", "direction": "DESC",
"field": "ASSESSED_AT" "field": "CREATED_AT"
} }
} }
], ],
@@ -232,7 +232,7 @@ return {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "assessedAt", "name": "createdAt",
"storageKey": null "storageKey": null
}, },
{ {
@@ -263,7 +263,7 @@ return {
"storageKey": null "storageKey": null
} }
], ],
"storageKey": "riskAssessments(first:1,orderBy:{\"direction\":\"DESC\",\"field\":\"ASSESSED_AT\"})" "storageKey": "riskAssessments(first:1,orderBy:{\"direction\":\"DESC\",\"field\":\"CREATED_AT\"})"
}, },
{ {
"alias": null, "alias": null,
@@ -346,6 +346,6 @@ return {
}; };
})(); })();
(node as any).hash = "578772ed7c83ae174d43b0be95a02fd2"; (node as any).hash = "bf222e31d20ebe7c9dfdedff7d5a9c68";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<f98b10bd4f5fb03b55b46e2554480590>> * @generated SignedSource<<f55e24dc95c48a67d7908bdd7f037272>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -274,7 +274,7 @@ return {
"name": "orderBy", "name": "orderBy",
"value": { "value": {
"direction": "DESC", "direction": "DESC",
"field": "ASSESSED_AT" "field": "CREATED_AT"
} }
} }
], ],
@@ -304,7 +304,7 @@ return {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "assessedAt", "name": "createdAt",
"storageKey": null "storageKey": null
}, },
{ {
@@ -335,7 +335,7 @@ return {
"storageKey": null "storageKey": null
} }
], ],
"storageKey": "riskAssessments(first:1,orderBy:{\"direction\":\"DESC\",\"field\":\"ASSESSED_AT\"})" "storageKey": "riskAssessments(first:1,orderBy:{\"direction\":\"DESC\",\"field\":\"CREATED_AT\"})"
}, },
(v13/*: any*/) (v13/*: any*/)
], ],
@@ -426,16 +426,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "6570f4601f6dea5b7fe738d851a7f1ba", "cacheID": "bf14bba14dba4fb544d431600ea31317",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "VendorsListQuery", "name": "VendorsListQuery",
"operationKind": "query", "operationKind": "query",
"text": "query VendorsListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 50\n $last: Int = null\n $order: VendorOrder = null\n $snapshotId: ID = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...VendorGraphPaginatedFragment_25MC8O\n id\n }\n}\n\nfragment VendorGraphPaginatedFragment_25MC8O on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: $order, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n snapshotId\n name\n websiteUrl\n updatedAt\n riskAssessments(first: 1, orderBy: {direction: DESC, field: ASSESSED_AT}) {\n edges {\n node {\n id\n assessedAt\n expiresAt\n dataSensitivity\n businessImpact\n }\n }\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n" "text": "query VendorsListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 50\n $last: Int = null\n $order: VendorOrder = null\n $snapshotId: ID = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...VendorGraphPaginatedFragment_25MC8O\n id\n }\n}\n\nfragment VendorGraphPaginatedFragment_25MC8O on Organization {\n vendors(first: $first, after: $after, last: $last, before: $before, orderBy: $order, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n snapshotId\n name\n websiteUrl\n updatedAt\n riskAssessments(first: 1, orderBy: {direction: DESC, field: CREATED_AT}) {\n edges {\n node {\n id\n createdAt\n expiresAt\n dataSensitivity\n businessImpact\n }\n }\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
} }
}; };
})(); })();
(node as any).hash = "578772ed7c83ae174d43b0be95a02fd2"; (node as any).hash = "bf222e31d20ebe7c9dfdedff7d5a9c68";
export default node; export default node;

View File

@@ -90,9 +90,6 @@ const documentFragment = graphql`
publishedAt publishedAt
version version
updatedAt updatedAt
publishedBy {
fullName
}
signatures(first: 100) signatures(first: 100)
@connection(key: "DocumentDetailPage_signatures") { @connection(key: "DocumentDetailPage_signatures") {
__id __id
@@ -707,9 +704,6 @@ function VersionItem({
</div> </div>
<div className="flex-1 space-y-[2px] overflow-hidden"> <div className="flex-1 space-y-[2px] overflow-hidden">
<div className="flex items-center gap-2 overflow-hidden"> <div className="flex items-center gap-2 overflow-hidden">
<div className="text-sm text-txt-secondary whitespace-nowrap overflow-hidden text-ellipsis">
{version.publishedBy?.fullName ?? document.owner.fullName}
</div>
{version.status === "DRAFT" && ( {version.status === "DRAFT" && (
<Badge variant="neutral" size="sm"> <Badge variant="neutral" size="sm">
{__("Draft")} {__("Draft")}

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<8db0c7dcd7ff31c01ec5facd5a3b598a>> * @generated SignedSource<<9bec5530e7a90ab3fb9f21c5c2d92286>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -31,9 +31,6 @@ export type DocumentDetailPageDocumentFragment$data = {
readonly content: string; readonly content: string;
readonly id: string; readonly id: string;
readonly publishedAt: any | null | undefined; readonly publishedAt: any | null | undefined;
readonly publishedBy: {
readonly fullName: string;
} | null | undefined;
readonly signatures: { readonly signatures: {
readonly __id: string; readonly __id: string;
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
@@ -73,24 +70,17 @@ v1 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "fullName", "name": "__typename",
"storageKey": null "storageKey": null
}, },
v2 = { v2 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "__typename",
"storageKey": null
},
v3 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "cursor", "name": "cursor",
"storageKey": null "storageKey": null
}, },
v4 = { v3 = {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "PageInfo", "concreteType": "PageInfo",
@@ -115,7 +105,7 @@ v4 = {
], ],
"storageKey": null "storageKey": null
}, },
v5 = { v4 = {
"kind": "ClientExtension", "kind": "ClientExtension",
"selections": [ "selections": [
{ {
@@ -174,7 +164,13 @@ return {
"plural": false, "plural": false,
"selections": [ "selections": [
(v0/*: any*/), (v0/*: any*/),
(v1/*: any*/) {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
}
], ],
"storageKey": null "storageKey": null
}, },
@@ -267,18 +263,6 @@ return {
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "publishedBy",
"plural": false,
"selections": [
(v1/*: any*/)
],
"storageKey": null
},
{ {
"alias": "signatures", "alias": "signatures",
"args": null, "args": null,
@@ -328,29 +312,29 @@ return {
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "DocumentSignaturesTab_signature" "name": "DocumentSignaturesTab_signature"
}, },
(v2/*: any*/) (v1/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v3/*: any*/) (v2/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v4/*: any*/), (v3/*: any*/),
(v5/*: any*/) (v4/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v2/*: any*/) (v1/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v3/*: any*/) (v2/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v4/*: any*/), (v3/*: any*/),
(v5/*: any*/) (v4/*: any*/)
], ],
"storageKey": null "storageKey": null
} }
@@ -360,6 +344,6 @@ return {
}; };
})(); })();
(node as any).hash = "1523ddad229ae2d6bf94d30de5579ae6"; (node as any).hash = "1d06e505efa74bb0b564fcbfc57ce8c9";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<e02cdda6c1c24ac700a79ed236c6dfdc>> * @generated SignedSource<<aa94f8d2cc4c6a5c29de3029d5e6d2ca>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -12,7 +12,6 @@ import { ConcreteRequest } from 'relay-runtime';
export type DocumentType = "ISMS" | "OTHER" | "POLICY"; export type DocumentType = "ISMS" | "OTHER" | "POLICY";
export type UpdateDocumentInput = { export type UpdateDocumentInput = {
content?: string | null | undefined; content?: string | null | undefined;
createdBy?: string | null | undefined;
documentType?: DocumentType | null | undefined; documentType?: DocumentType | null | undefined;
id: string; id: string;
ownerId?: string | null | undefined; ownerId?: string | null | undefined;

View File

@@ -132,7 +132,7 @@ export default function VendorDetailPage(props: Props) {
</TabLink> </TabLink>
</Tabs> </Tabs>
<Outlet context={{ vendor, peopleId: data.viewer.user.people!.id }} /> <Outlet context={{ vendor }} />
</div> </div>
); );
} }

View File

@@ -134,8 +134,8 @@ function VendorRow({
</div> </div>
</Td> </Td>
<Td> <Td>
{latestAssessment?.assessedAt {latestAssessment?.createdAt
? formatDate(latestAssessment.assessedAt) ? formatDate(latestAssessment.createdAt)
: __("Not assessed")} : __("Not assessed")}
</Td> </Td>
<Td> <Td>

View File

@@ -21,7 +21,6 @@ type Props = {
children: ReactNode; children: ReactNode;
connection: string; connection: string;
vendorId: string; vendorId: string;
peopleId: string;
}; };
const createRiskAssessmentMutation = graphql` const createRiskAssessmentMutation = graphql`
@@ -52,7 +51,6 @@ export function CreateRiskAssessmentDialog({
children, children,
connection, connection,
vendorId, vendorId,
peopleId,
}: Props) { }: Props) {
const { __ } = useTranslate(); const { __ } = useTranslate();
@@ -79,7 +77,6 @@ export function CreateRiskAssessmentDialog({
input: { input: {
...data, ...data,
vendorId, vendorId,
assessedBy: peopleId,
expiresAt: nextYear.toISOString(), expiresAt: nextYear.toISOString(),
}, },
connections: [connection!], connections: [connection!],

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<f877423fd1b767f837337e1b8a917e51>> * @generated SignedSource<<2cd3f372cc571cec881b9762e381f1d5>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -13,7 +13,6 @@ import { FragmentRefs } from "relay-runtime";
export type BusinessImpact = "CRITICAL" | "HIGH" | "LOW" | "MEDIUM"; export type BusinessImpact = "CRITICAL" | "HIGH" | "LOW" | "MEDIUM";
export type DataSensitivity = "CRITICAL" | "HIGH" | "LOW" | "MEDIUM" | "NONE"; export type DataSensitivity = "CRITICAL" | "HIGH" | "LOW" | "MEDIUM" | "NONE";
export type CreateVendorRiskAssessmentInput = { export type CreateVendorRiskAssessmentInput = {
assessedBy: string;
businessImpact: BusinessImpact; businessImpact: BusinessImpact;
dataSensitivity: DataSensitivity; dataSensitivity: DataSensitivity;
expiresAt: any; expiresAt: any;
@@ -55,14 +54,7 @@ v2 = [
"name": "input", "name": "input",
"variableName": "input" "variableName": "input"
} }
], ];
v3 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
};
return { return {
"fragment": { "fragment": {
"argumentDefinitions": [ "argumentDefinitions": [
@@ -148,31 +140,18 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "assessedAt", "name": "id",
"storageKey": null "storageKey": null
}, },
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "People", "kind": "ScalarField",
"kind": "LinkedField", "name": "createdAt",
"name": "assessedBy",
"plural": false,
"selections": [
(v3/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
}
],
"storageKey": null "storageKey": null
}, },
{ {
@@ -231,12 +210,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "c55703ef9adb6c6aabf79aafe6cbeb89", "cacheID": "1bd928ac46edc24d7b7cda3e5d7e2cb2",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "CreateRiskAssessmentDialogMutation", "name": "CreateRiskAssessmentDialogMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation CreateRiskAssessmentDialogMutation(\n $input: CreateVendorRiskAssessmentInput!\n) {\n createVendorRiskAssessment(input: $input) {\n vendorRiskAssessmentEdge {\n node {\n ...VendorRiskAssessmentTabFragment_assessment\n id\n }\n }\n }\n}\n\nfragment VendorRiskAssessmentTabFragment_assessment on VendorRiskAssessment {\n id\n assessedAt\n assessedBy {\n id\n fullName\n }\n expiresAt\n dataSensitivity\n businessImpact\n notes\n}\n" "text": "mutation CreateRiskAssessmentDialogMutation(\n $input: CreateVendorRiskAssessmentInput!\n) {\n createVendorRiskAssessment(input: $input) {\n vendorRiskAssessmentEdge {\n node {\n ...VendorRiskAssessmentTabFragment_assessment\n id\n }\n }\n }\n}\n\nfragment VendorRiskAssessmentTabFragment_assessment on VendorRiskAssessment {\n id\n createdAt\n expiresAt\n dataSensitivity\n businessImpact\n notes\n}\n"
} }
}; };
})(); })();

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<6db92ed13cdca3a852d1b7b9c113840e>> * @generated SignedSource<<22e7411298e2df9b5f5eae17bb0a510f>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -447,26 +447,7 @@ return {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "assessedAt", "name": "createdAt",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "assessedBy",
"plural": false,
"selections": [
(v2/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
}
],
"storageKey": null "storageKey": null
}, },
{ {
@@ -542,12 +523,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "025f271f1dca46c6f052f0d59a4315cc", "cacheID": "0cb0f301c3022d933fd9ee0d6319d3e4",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ImportAssessmentDialogMutation", "name": "ImportAssessmentDialogMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation ImportAssessmentDialogMutation(\n $input: AssessVendorInput!\n) {\n assessVendor(input: $input) {\n vendor {\n id\n name\n websiteUrl\n ...useVendorFormFragment\n ...VendorComplianceTabFragment\n ...VendorRiskAssessmentTabFragment\n }\n }\n}\n\nfragment VendorComplianceTabFragment on Vendor {\n complianceReports(first: 50) {\n edges {\n node {\n id\n ...VendorComplianceTabFragment_report\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorComplianceTabFragment_report on VendorComplianceReport {\n id\n reportDate\n validUntil\n reportName\n fileUrl\n fileSize\n}\n\nfragment VendorRiskAssessmentTabFragment on Vendor {\n id\n riskAssessments(first: 50) {\n edges {\n node {\n id\n ...VendorRiskAssessmentTabFragment_assessment\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment VendorRiskAssessmentTabFragment_assessment on VendorRiskAssessment {\n id\n assessedAt\n assessedBy {\n id\n fullName\n }\n expiresAt\n dataSensitivity\n businessImpact\n notes\n}\n\nfragment useVendorFormFragment on Vendor {\n id\n name\n description\n category\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n websiteUrl\n legalName\n headquarterAddress\n certifications\n countries\n securityPageUrl\n trustPageUrl\n businessOwner {\n id\n }\n securityOwner {\n id\n }\n}\n" "text": "mutation ImportAssessmentDialogMutation(\n $input: AssessVendorInput!\n) {\n assessVendor(input: $input) {\n vendor {\n id\n name\n websiteUrl\n ...useVendorFormFragment\n ...VendorComplianceTabFragment\n ...VendorRiskAssessmentTabFragment\n }\n }\n}\n\nfragment VendorComplianceTabFragment on Vendor {\n complianceReports(first: 50) {\n edges {\n node {\n id\n ...VendorComplianceTabFragment_report\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment VendorComplianceTabFragment_report on VendorComplianceReport {\n id\n reportDate\n validUntil\n reportName\n fileUrl\n fileSize\n}\n\nfragment VendorRiskAssessmentTabFragment on Vendor {\n id\n riskAssessments(first: 50) {\n edges {\n node {\n id\n ...VendorRiskAssessmentTabFragment_assessment\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment VendorRiskAssessmentTabFragment_assessment on VendorRiskAssessment {\n id\n createdAt\n expiresAt\n dataSensitivity\n businessImpact\n notes\n}\n\nfragment useVendorFormFragment on Vendor {\n id\n name\n description\n category\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n serviceLevelAgreementUrl\n dataProcessingAgreementUrl\n websiteUrl\n legalName\n headquarterAddress\n certifications\n countries\n securityPageUrl\n trustPageUrl\n businessOwner {\n id\n }\n securityOwner {\n id\n }\n}\n"
} }
}; };
})(); })();

View File

@@ -15,6 +15,7 @@ import {
Badge, Badge,
TrButton, TrButton,
} from "@probo/ui"; } from "@probo/ui";
import { formatDate } from "@probo/helpers";
import { useFragment, useRefetchableFragment } from "react-relay"; import { useFragment, useRefetchableFragment } from "react-relay";
import type { VendorRiskAssessmentTabFragment_assessment$key } from "./__generated__/VendorRiskAssessmentTabFragment_assessment.graphql"; import type { VendorRiskAssessmentTabFragment_assessment$key } from "./__generated__/VendorRiskAssessmentTabFragment_assessment.graphql";
import { SortableTable, SortableTh } from "/components/SortableTable"; import { SortableTable, SortableTh } from "/components/SortableTable";
@@ -59,11 +60,7 @@ const riskAssessmentsFragment = graphql`
const riskAssessmentFragment = graphql` const riskAssessmentFragment = graphql`
fragment VendorRiskAssessmentTabFragment_assessment on VendorRiskAssessment { fragment VendorRiskAssessmentTabFragment_assessment on VendorRiskAssessment {
id id
assessedAt createdAt
assessedBy {
id
fullName
}
expiresAt expiresAt
dataSensitivity dataSensitivity
businessImpact businessImpact
@@ -72,9 +69,8 @@ const riskAssessmentFragment = graphql`
`; `;
export default function VendorRiskAssessmentTab() { export default function VendorRiskAssessmentTab() {
const { vendor, peopleId } = useOutletContext<{ const { vendor } = useOutletContext<{
vendor: VendorRiskAssessmentTabFragment$key & { name: string; id: string }; vendor: VendorRiskAssessmentTabFragment$key & { name: string; id: string };
peopleId: string;
}>(); }>();
const [data, refetch] = useRefetchableFragment( const [data, refetch] = useRefetchableFragment(
riskAssessmentsFragment, riskAssessmentsFragment,
@@ -96,7 +92,6 @@ export default function VendorRiskAssessmentTab() {
<CreateRiskAssessmentDialog <CreateRiskAssessmentDialog
vendorId={vendor.id} vendorId={vendor.id}
connection={data.riskAssessments.__id} connection={data.riskAssessments.__id}
peopleId={peopleId}
> >
<Button icon={IconPlusLarge} variant="secondary"> <Button icon={IconPlusLarge} variant="secondary">
{__("Add Risk Assessment")} {__("Add Risk Assessment")}
@@ -114,7 +109,7 @@ export default function VendorRiskAssessmentTab() {
<SortableTable refetch={refetch}> <SortableTable refetch={refetch}>
<Thead> <Thead>
<Tr> <Tr>
<SortableTh field="ASSESSED_AT">{__("Assessed By")}</SortableTh> <SortableTh field="CREATED_AT">{__("Created At")}</SortableTh>
<SortableTh field="EXPIRES_AT">{__("Expires")}</SortableTh> <SortableTh field="EXPIRES_AT">{__("Expires")}</SortableTh>
<Th>{__("Data sensitivity")}</Th> <Th>{__("Data sensitivity")}</Th>
<Th>{__("Business impact")}</Th> <Th>{__("Business impact")}</Th>
@@ -125,7 +120,6 @@ export default function VendorRiskAssessmentTab() {
<CreateRiskAssessmentDialog <CreateRiskAssessmentDialog
vendorId={vendor.id} vendorId={vendor.id}
connection={data.riskAssessments.__id} connection={data.riskAssessments.__id}
peopleId={peopleId}
> >
<TrButton colspan={5} onClick={() => {}}> <TrButton colspan={5} onClick={() => {}}>
{__("Add Risk Assessment")} {__("Add Risk Assessment")}
@@ -178,9 +172,8 @@ function AssessmentRow(props: AssessmentRowProps) {
onClick={() => props.onClick(assessment.id)} onClick={() => props.onClick(assessment.id)}
> >
<Td> <Td>
{assessment.assessedBy?.fullName}
<span className="text-xs text-txt-secondary ml-1"> <span className="text-xs text-txt-secondary ml-1">
({relativeDateFormat(assessment.assessedAt)}) {formatDate(assessment.createdAt)}
</span> </span>
</Td> </Td>
<Td> <Td>

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<68ddff15cd65f5367f7e9ae6b3c38f34>> * @generated SignedSource<<b6963cdf0e4c8a5c6bb293cb53f8d404>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -13,12 +13,8 @@ export type BusinessImpact = "CRITICAL" | "HIGH" | "LOW" | "MEDIUM";
export type DataSensitivity = "CRITICAL" | "HIGH" | "LOW" | "MEDIUM" | "NONE"; export type DataSensitivity = "CRITICAL" | "HIGH" | "LOW" | "MEDIUM" | "NONE";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type VendorRiskAssessmentTabFragment_assessment$data = { export type VendorRiskAssessmentTabFragment_assessment$data = {
readonly assessedAt: any;
readonly assessedBy: {
readonly fullName: string;
readonly id: string;
};
readonly businessImpact: BusinessImpact; readonly businessImpact: BusinessImpact;
readonly createdAt: any;
readonly dataSensitivity: DataSensitivity; readonly dataSensitivity: DataSensitivity;
readonly expiresAt: any; readonly expiresAt: any;
readonly id: string; readonly id: string;
@@ -30,45 +26,24 @@ export type VendorRiskAssessmentTabFragment_assessment$key = {
readonly " $fragmentSpreads": FragmentRefs<"VendorRiskAssessmentTabFragment_assessment">; readonly " $fragmentSpreads": FragmentRefs<"VendorRiskAssessmentTabFragment_assessment">;
}; };
const node: ReaderFragment = (function(){ const node: ReaderFragment = {
var v0 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
};
return {
"argumentDefinitions": [], "argumentDefinitions": [],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "VendorRiskAssessmentTabFragment_assessment", "name": "VendorRiskAssessmentTabFragment_assessment",
"selections": [ "selections": [
(v0/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "assessedAt", "name": "id",
"storageKey": null "storageKey": null
}, },
{ {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "People", "kind": "ScalarField",
"kind": "LinkedField", "name": "createdAt",
"name": "assessedBy",
"plural": false,
"selections": [
(v0/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
}
],
"storageKey": null "storageKey": null
}, },
{ {
@@ -103,8 +78,7 @@ return {
"type": "VendorRiskAssessment", "type": "VendorRiskAssessment",
"abstractKey": null "abstractKey": null
}; };
})();
(node as any).hash = "08d6de198077f9b5985258466bbc33c0"; (node as any).hash = "533771f5fac9e732556929fa2b1d0dc5";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<0bca6db2c1a834fd326761b3544d00ae>> * @generated SignedSource<<121b4497478f4b5ff67fb8a9daab3774>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -11,7 +11,7 @@
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type OrderDirection = "ASC" | "DESC"; export type OrderDirection = "ASC" | "DESC";
export type VendorRiskAssessmentOrderField = "ASSESSED_AT" | "CREATED_AT" | "EXPIRES_AT"; export type VendorRiskAssessmentOrderField = "CREATED_AT" | "EXPIRES_AT";
export type VendorRiskAssessmentOrder = { export type VendorRiskAssessmentOrder = {
direction: OrderDirection; direction: OrderDirection;
field: VendorRiskAssessmentOrderField; field: VendorRiskAssessmentOrderField;
@@ -216,26 +216,7 @@ return {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "assessedAt", "name": "createdAt",
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "People",
"kind": "LinkedField",
"name": "assessedBy",
"plural": false,
"selections": [
(v12/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "fullName",
"storageKey": null
}
],
"storageKey": null "storageKey": null
}, },
{ {
@@ -355,12 +336,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "26ab0b864c4e22a21c078f70ed7caf93", "cacheID": "5bf6eff01e3ca53e8da78cba59316a0c",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "VendorRiskAssessmentTabQuery", "name": "VendorRiskAssessmentTabQuery",
"operationKind": "query", "operationKind": "query",
"text": "query VendorRiskAssessmentTabQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 50\n $last: Int = null\n $order: VendorRiskAssessmentOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...VendorRiskAssessmentTabFragment_16fISc\n id\n }\n}\n\nfragment VendorRiskAssessmentTabFragment_16fISc on Vendor {\n id\n riskAssessments(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n edges {\n node {\n id\n ...VendorRiskAssessmentTabFragment_assessment\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment VendorRiskAssessmentTabFragment_assessment on VendorRiskAssessment {\n id\n assessedAt\n assessedBy {\n id\n fullName\n }\n expiresAt\n dataSensitivity\n businessImpact\n notes\n}\n" "text": "query VendorRiskAssessmentTabQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 50\n $last: Int = null\n $order: VendorRiskAssessmentOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...VendorRiskAssessmentTabFragment_16fISc\n id\n }\n}\n\nfragment VendorRiskAssessmentTabFragment_16fISc on Vendor {\n id\n riskAssessments(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n edges {\n node {\n id\n ...VendorRiskAssessmentTabFragment_assessment\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment VendorRiskAssessmentTabFragment_assessment on VendorRiskAssessment {\n id\n createdAt\n expiresAt\n dataSensitivity\n businessImpact\n notes\n}\n"
} }
}; };
})(); })();

View File

@@ -35,9 +35,7 @@ type (
VersionNumber int `db:"version_number"` VersionNumber int `db:"version_number"`
Content string `db:"content"` Content string `db:"content"`
Changelog string `db:"changelog"` Changelog string `db:"changelog"`
CreatedBy gid.GID `db:"created_by"`
Status DocumentStatus `db:"status"` Status DocumentStatus `db:"status"`
PublishedBy *gid.GID `db:"published_by"`
PublishedAt *time.Time `db:"published_at"` PublishedAt *time.Time `db:"published_at"`
CreatedAt time.Time `db:"created_at"` CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"` UpdatedAt time.Time `db:"updated_at"`
@@ -62,9 +60,7 @@ SELECT
version_number, version_number,
content, content,
changelog, changelog,
created_by,
status, status,
published_by,
published_at, published_at,
created_at, created_at,
updated_at updated_at
@@ -122,9 +118,7 @@ SELECT
version_number, version_number,
content, content,
changelog, changelog,
created_by,
status, status,
published_by,
published_at, published_at,
created_at, created_at,
updated_at updated_at
@@ -173,7 +167,6 @@ INSERT INTO document_versions (
version_number, version_number,
content, content,
changelog, changelog,
created_by,
status, status,
created_at, created_at,
updated_at updated_at
@@ -187,7 +180,6 @@ VALUES (
@version_number, @version_number,
@content, @content,
@changelog, @changelog,
@created_by,
@status, @status,
@created_at, @created_at,
@updated_at @updated_at
@@ -202,7 +194,6 @@ VALUES (
"version_number": p.VersionNumber, "version_number": p.VersionNumber,
"content": p.Content, "content": p.Content,
"changelog": p.Changelog, "changelog": p.Changelog,
"created_by": p.CreatedBy,
"status": p.Status, "status": p.Status,
"created_at": p.CreatedAt, "created_at": p.CreatedAt,
"updated_at": p.UpdatedAt, "updated_at": p.UpdatedAt,
@@ -232,9 +223,7 @@ SELECT
version_number, version_number,
content, content,
changelog, changelog,
created_by,
status, status,
published_by,
published_at, published_at,
created_at, created_at,
updated_at updated_at
@@ -285,9 +274,7 @@ SELECT
version_number, version_number,
content, content,
changelog, changelog,
created_by,
status, status,
published_by,
published_at, published_at,
created_at, created_at,
updated_at updated_at
@@ -336,9 +323,7 @@ SELECT
version_number, version_number,
content, content,
changelog, changelog,
created_by,
status, status,
published_by,
published_at, published_at,
created_at, created_at,
updated_at updated_at
@@ -386,7 +371,6 @@ UPDATE document_versions SET
changelog = @changelog, changelog = @changelog,
status = @status, status = @status,
content = @content, content = @content,
published_by = @published_by,
published_at = @published_at, published_at = @published_at,
updated_at = @updated_at updated_at = @updated_at
WHERE %s WHERE %s
@@ -402,7 +386,6 @@ WHERE %s
"changelog": p.Changelog, "changelog": p.Changelog,
"status": p.Status, "status": p.Status,
"content": p.Content, "content": p.Content,
"published_by": p.PublishedBy,
"published_at": p.PublishedAt, "published_at": p.PublishedAt,
"updated_at": p.UpdatedAt, "updated_at": p.UpdatedAt,
} }

View File

@@ -0,0 +1,6 @@
ALTER TABLE vendor_risk_assessments DROP COLUMN approved_at;
ALTER TABLE vendor_risk_assessments DROP COLUMN approved_by;
ALTER TABLE vendor_risk_assessments DROP COLUMN assessed_by;
ALTER TABLE vendor_risk_assessments DROP COLUMN assessed_at;
ALTER TABLE document_versions DROP COLUMN created_by;
ALTER TABLE document_versions DROP COLUMN published_by;

View File

@@ -31,10 +31,6 @@ type (
VendorRiskAssessment struct { VendorRiskAssessment struct {
ID gid.GID `db:"id"` ID gid.GID `db:"id"`
VendorID gid.GID `db:"vendor_id"` VendorID gid.GID `db:"vendor_id"`
AssessedAt time.Time `db:"assessed_at"`
AssessedBy gid.GID `db:"assessed_by"`
ApprovedBy *gid.GID `db:"approved_by"`
ApprovedAt *time.Time `db:"approved_at"`
ExpiresAt time.Time `db:"expires_at"` ExpiresAt time.Time `db:"expires_at"`
DataSensitivity DataSensitivity `db:"data_sensitivity"` DataSensitivity DataSensitivity `db:"data_sensitivity"`
BusinessImpact BusinessImpact `db:"business_impact"` BusinessImpact BusinessImpact `db:"business_impact"`
@@ -54,8 +50,6 @@ func (v VendorRiskAssessment) CursorKey(orderBy VendorRiskAssessmentOrderField)
return page.NewCursorKey(v.ID, v.CreatedAt) return page.NewCursorKey(v.ID, v.CreatedAt)
case VendorRiskAssessmentOrderFieldExpiresAt: case VendorRiskAssessmentOrderFieldExpiresAt:
return page.NewCursorKey(v.ID, v.ExpiresAt) return page.NewCursorKey(v.ID, v.ExpiresAt)
case VendorRiskAssessmentOrderFieldAssessedAt:
return page.NewCursorKey(v.ID, v.AssessedAt)
} }
panic(fmt.Sprintf("unsupported order by: %s", orderBy)) panic(fmt.Sprintf("unsupported order by: %s", orderBy))
@@ -73,10 +67,6 @@ INSERT INTO
tenant_id, tenant_id,
id, id,
vendor_id, vendor_id,
assessed_at,
assessed_by,
approved_by,
approved_at,
expires_at, expires_at,
data_sensitivity, data_sensitivity,
business_impact, business_impact,
@@ -88,10 +78,6 @@ VALUES (
@tenant_id, @tenant_id,
@id, @id,
@vendor_id, @vendor_id,
@assessed_at,
@assessed_by,
@approved_by,
@approved_at,
@expires_at, @expires_at,
@data_sensitivity, @data_sensitivity,
@business_impact, @business_impact,
@@ -105,10 +91,6 @@ VALUES (
"tenant_id": scope.GetTenantID(), "tenant_id": scope.GetTenantID(),
"id": r.ID, "id": r.ID,
"vendor_id": r.VendorID, "vendor_id": r.VendorID,
"assessed_at": r.AssessedAt,
"assessed_by": r.AssessedBy,
"approved_by": r.ApprovedBy,
"approved_at": r.ApprovedAt,
"expires_at": r.ExpiresAt, "expires_at": r.ExpiresAt,
"data_sensitivity": r.DataSensitivity, "data_sensitivity": r.DataSensitivity,
"business_impact": r.BusinessImpact, "business_impact": r.BusinessImpact,
@@ -131,10 +113,6 @@ func (r *VendorRiskAssessment) LoadByID(
SELECT SELECT
id, id,
vendor_id, vendor_id,
assessed_at,
assessed_by,
approved_by,
approved_at,
expires_at, expires_at,
data_sensitivity, data_sensitivity,
business_impact, business_impact,
@@ -183,10 +161,6 @@ func (r *VendorRiskAssessment) LoadLatestByVendorID(
SELECT SELECT
id, id,
vendor_id, vendor_id,
assessed_at,
assessed_by,
approved_by,
approved_at,
expires_at, expires_at,
data_sensitivity, data_sensitivity,
business_impact, business_impact,
@@ -201,7 +175,7 @@ WHERE
%s %s
AND vendor_id = @vendor_id AND vendor_id = @vendor_id
ORDER BY ORDER BY
assessed_at DESC created_at DESC
LIMIT 1; LIMIT 1;
` `
@@ -238,10 +212,6 @@ func (r *VendorRiskAssessments) LoadByVendorID(
SELECT SELECT
id, id,
vendor_id, vendor_id,
assessed_at,
assessed_by,
approved_by,
approved_at,
expires_at, expires_at,
data_sensitivity, data_sensitivity,
business_impact, business_impact,
@@ -299,10 +269,6 @@ INSERT INTO vendor_risk_assessments (
snapshot_id, snapshot_id,
source_id, source_id,
vendor_id, vendor_id,
assessed_at,
assessed_by,
approved_by,
approved_at,
expires_at, expires_at,
data_sensitivity, data_sensitivity,
business_impact, business_impact,
@@ -316,10 +282,6 @@ SELECT
@snapshot_id, @snapshot_id,
vra.id, vra.id,
sv.id, sv.id,
vra.assessed_at,
vra.assessed_by,
vra.approved_by,
vra.approved_at,
vra.expires_at, vra.expires_at,
vra.data_sensitivity, vra.data_sensitivity,
vra.business_impact, vra.business_impact,

View File

@@ -19,9 +19,8 @@ type (
) )
const ( const (
VendorRiskAssessmentOrderFieldCreatedAt VendorRiskAssessmentOrderField = "CREATED_AT" VendorRiskAssessmentOrderFieldCreatedAt VendorRiskAssessmentOrderField = "CREATED_AT"
VendorRiskAssessmentOrderFieldExpiresAt VendorRiskAssessmentOrderField = "EXPIRES_AT" VendorRiskAssessmentOrderFieldExpiresAt VendorRiskAssessmentOrderField = "EXPIRES_AT"
VendorRiskAssessmentOrderFieldAssessedAt VendorRiskAssessmentOrderField = "ASSESSED_AT"
) )
func (p VendorRiskAssessmentOrderField) Column() string { func (p VendorRiskAssessmentOrderField) Column() string {

View File

@@ -69,7 +69,6 @@ type (
Approver string Approver string
Description string Description string
PublishedAt *time.Time PublishedAt *time.Time
PublishedBy string
Signatures []SignatureData Signatures []SignatureData
} }

View File

@@ -16,7 +16,7 @@
color: #666; color: #666;
} }
} }
body { body {
font-family: 'Times New Roman', Times, serif; font-family: 'Times New Roman', Times, serif;
font-size: 11pt; font-size: 11pt;
@@ -26,7 +26,7 @@
padding: 20px 0; padding: 20px 0;
background: #f5f5f5; background: #f5f5f5;
} }
/* Document container that simulates A4 pages */ /* Document container that simulates A4 pages */
.document-container { .document-container {
width: 21cm; width: 21cm;
@@ -34,7 +34,7 @@
background: white; background: white;
box-shadow: 0 0 10px rgba(0,0,0,0.1); box-shadow: 0 0 10px rgba(0,0,0,0.1);
} }
/* Individual page sections */ /* Individual page sections */
.page-section { .page-section {
padding: 2.5cm; padding: 2.5cm;
@@ -43,21 +43,21 @@
border-bottom: 2px dashed #ddd; border-bottom: 2px dashed #ddd;
page-break-after: always; page-break-after: always;
} }
.page-section:last-child { .page-section:last-child {
border-bottom: none; border-bottom: none;
page-break-after: auto; page-break-after: auto;
} }
.document-header { .document-header {
border-bottom: 1px solid #333; border-bottom: 1px solid #333;
padding-bottom: 15px; padding-bottom: 15px;
margin-bottom: 25px; margin-bottom: 25px;
page-break-after: avoid; page-break-after: avoid;
} }
.document-title { .document-title {
font-size: 18pt; font-size: 18pt;
font-weight: bold; font-weight: bold;
@@ -65,7 +65,7 @@
margin: 0 0 10px 0; margin: 0 0 10px 0;
text-align: center; text-align: center;
} }
.document-meta { .document-meta {
background: #f9f9f9; background: #f9f9f9;
padding: 12px; padding: 12px;
@@ -73,35 +73,35 @@
margin: 15px 0; margin: 15px 0;
font-size: 9pt; font-size: 9pt;
} }
.meta-table { .meta-table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
} }
.meta-table td { .meta-table td {
padding: 4px 8px; padding: 4px 8px;
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
vertical-align: top; vertical-align: top;
} }
.meta-table td:first-child { .meta-table td:first-child {
font-weight: bold; font-weight: bold;
color: #333; color: #333;
width: 120px; width: 120px;
} }
.classification { .classification {
font-weight: bold; font-weight: bold;
text-transform: uppercase; text-transform: uppercase;
} }
/* Content styling with page break controls */ /* Content styling with page break controls */
.document-content { .document-content {
orphans: 3; orphans: 3;
widows: 3; widows: 3;
} }
.document-content h1 { .document-content h1 {
font-size: 14pt; font-size: 14pt;
font-weight: bold; font-weight: bold;
@@ -112,7 +112,7 @@
page-break-after: avoid; page-break-after: avoid;
page-break-inside: avoid; page-break-inside: avoid;
} }
.document-content h2 { .document-content h2 {
font-size: 13pt; font-size: 13pt;
font-weight: bold; font-weight: bold;
@@ -121,7 +121,7 @@
page-break-after: avoid; page-break-after: avoid;
page-break-inside: avoid; page-break-inside: avoid;
} }
.document-content h3 { .document-content h3 {
font-size: 12pt; font-size: 12pt;
font-weight: bold; font-weight: bold;
@@ -130,7 +130,7 @@
page-break-after: avoid; page-break-after: avoid;
page-break-inside: avoid; page-break-inside: avoid;
} }
.document-content h4 { .document-content h4 {
font-size: 11pt; font-size: 11pt;
font-weight: bold; font-weight: bold;
@@ -139,33 +139,33 @@
page-break-after: avoid; page-break-after: avoid;
page-break-inside: avoid; page-break-inside: avoid;
} }
.document-content p { .document-content p {
margin-bottom: 12px; margin-bottom: 12px;
text-align: justify; text-align: justify;
orphans: 3; orphans: 3;
widows: 3; widows: 3;
} }
.document-content ul, .document-content ul,
.document-content ol { .document-content ol {
padding-left: 20px; padding-left: 20px;
margin: 12px 0; margin: 12px 0;
page-break-inside: avoid; page-break-inside: avoid;
} }
.document-content li { .document-content li {
margin-bottom: 4px; margin-bottom: 4px;
} }
.document-content strong { .document-content strong {
font-weight: bold; font-weight: bold;
} }
.document-content em { .document-content em {
font-style: italic; font-style: italic;
} }
/* Force page breaks at strategic points */ /* Force page breaks at strategic points */
.document-content h2:nth-of-type(3), .document-content h2:nth-of-type(3),
.document-content h2:nth-of-type(5), .document-content h2:nth-of-type(5),
@@ -173,7 +173,7 @@
.document-content h2:nth-of-type(9) { .document-content h2:nth-of-type(9) {
page-break-before: always; page-break-before: always;
} }
/* Signatures section */ /* Signatures section */
.signatures-section { .signatures-section {
margin-top: 30px; margin-top: 30px;
@@ -182,7 +182,7 @@
page-break-before: always; page-break-before: always;
page-break-inside: avoid; page-break-inside: avoid;
} }
.signatures-title { .signatures-title {
font-size: 13pt; font-size: 13pt;
font-weight: bold; font-weight: bold;
@@ -190,7 +190,7 @@
margin-bottom: 15px; margin-bottom: 15px;
page-break-after: avoid; page-break-after: avoid;
} }
.signatures-table { .signatures-table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
@@ -198,34 +198,34 @@
margin-top: 10px; margin-top: 10px;
page-break-inside: avoid; page-break-inside: avoid;
} }
.signatures-table th, .signatures-table th,
.signatures-table td { .signatures-table td {
padding: 6px 8px; padding: 6px 8px;
text-align: left; text-align: left;
border: 1px solid #ddd; border: 1px solid #ddd;
} }
.signatures-table th { .signatures-table th {
background: #f5f5f5; background: #f5f5f5;
font-weight: bold; font-weight: bold;
color: #333; color: #333;
} }
.signatures-table tr { .signatures-table tr {
page-break-inside: avoid; page-break-inside: avoid;
} }
.signature-signed { .signature-signed {
color: #000; color: #000;
font-weight: bold; font-weight: bold;
} }
.signature-requested { .signature-requested {
color: #666; color: #666;
font-style: italic; font-style: italic;
} }
.footer { .footer {
margin-top: 30px; margin-top: 30px;
padding-top: 15px; padding-top: 15px;
@@ -234,42 +234,42 @@
color: #666; color: #666;
text-align: center; text-align: center;
} }
/* Prevent bad page breaks */ /* Prevent bad page breaks */
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
page-break-after: avoid; page-break-after: avoid;
page-break-inside: avoid; page-break-inside: avoid;
} }
p, li { p, li {
page-break-inside: avoid; page-break-inside: avoid;
} }
table, .signatures-section { table, .signatures-section {
page-break-inside: avoid; page-break-inside: avoid;
} }
@media print { @media print {
body { body {
background: white; background: white;
padding: 0; padding: 0;
} }
.document-container { .document-container {
box-shadow: none; box-shadow: none;
width: auto; width: auto;
} }
.page-section { .page-section {
box-shadow: none; box-shadow: none;
border-bottom: none; border-bottom: none;
padding: 0; padding: 0;
min-height: auto; min-height: auto;
} }
} }
@media screen and (max-width: 21cm) { @media screen and (max-width: 21cm) {
.document-container { .document-container {
width: 95%; width: 95%;
@@ -313,7 +313,7 @@
<div class="page-section"> <div class="page-section">
<div class="document-header"> <div class="document-header">
<h1 class="document-title">{{.Title}}</h1> <h1 class="document-title">{{.Title}}</h1>
<div class="document-meta"> <div class="document-meta">
<table class="meta-table"> <table class="meta-table">
<tr> <tr>
@@ -337,7 +337,7 @@
{{- if .PublishedAt}} {{- if .PublishedAt}}
<tr> <tr>
<td>Published:</td> <td>Published:</td>
<td>{{.PublishedAt.Format "January 2, 2006"}}{{if .PublishedBy}} ({{.PublishedBy}}){{end}}</td> <td>{{.PublishedAt.Format "January 2, 2006"}}</td>
</tr> </tr>
{{- end}} {{- end}}
</table> </table>

View File

@@ -42,7 +42,6 @@ type (
Title string Title string
Content string Content string
OwnerID gid.GID OwnerID gid.GID
CreatedBy gid.GID
DocumentType coredata.DocumentType DocumentType coredata.DocumentType
} }
@@ -186,13 +185,8 @@ func (s *DocumentService) BulkPublishVersions(
err := s.svc.pg.WithTx( err := s.svc.pg.WithTx(
ctx, ctx,
func(tx pg.Conn) error { func(tx pg.Conn) error {
people := &coredata.People{}
if err := people.LoadByID(ctx, tx, s.svc.scope, req.PublishedBy); err != nil {
return fmt.Errorf("cannot load people: %w", err)
}
for _, documentID := range req.DocumentIDs { for _, documentID := range req.DocumentIDs {
document, version, err := s.publishVersionInTx(ctx, tx, documentID, people, &req.Changelog, true) document, version, err := s.publishVersionInTx(ctx, tx, documentID, req.PublishedBy, &req.Changelog, true)
if err != nil { if err != nil {
return fmt.Errorf("cannot publish document %q: %w", documentID, err) return fmt.Errorf("cannot publish document %q: %w", documentID, err)
} }
@@ -226,12 +220,7 @@ func (s *DocumentService) PublishVersion(
func(tx pg.Conn) error { func(tx pg.Conn) error {
var err error var err error
people := &coredata.People{} document, documentVersion, err = s.publishVersionInTx(ctx, tx, documentID, publishedBy, changelog, false)
if err := people.LoadByID(ctx, tx, s.svc.scope, publishedBy); err != nil {
return fmt.Errorf("cannot load people: %w", err)
}
document, documentVersion, err = s.publishVersionInTx(ctx, tx, documentID, people, changelog, false)
if err != nil { if err != nil {
return fmt.Errorf("cannot publish version: %w", err) return fmt.Errorf("cannot publish version: %w", err)
} }
@@ -251,7 +240,7 @@ func (s *DocumentService) publishVersionInTx(
ctx context.Context, ctx context.Context,
tx pg.Conn, tx pg.Conn,
documentID gid.GID, documentID gid.GID,
publishedBy *coredata.People, publishedBy gid.GID,
changelog *string, changelog *string,
ignoreExisting bool, ignoreExisting bool,
) (*coredata.Document, *coredata.DocumentVersion, error) { ) (*coredata.Document, *coredata.DocumentVersion, error) {
@@ -296,7 +285,6 @@ func (s *DocumentService) publishVersionInTx(
documentVersion.Status = coredata.DocumentStatusPublished documentVersion.Status = coredata.DocumentStatusPublished
documentVersion.PublishedAt = &now documentVersion.PublishedAt = &now
documentVersion.PublishedBy = &publishedBy.ID
documentVersion.UpdatedAt = now documentVersion.UpdatedAt = now
if err := document.Update(ctx, tx, s.svc.scope); err != nil { if err := document.Update(ctx, tx, s.svc.scope); err != nil {
@@ -338,7 +326,6 @@ func (s *DocumentService) Create(
VersionNumber: 1, VersionNumber: 1,
Content: req.Content, Content: req.Content,
Status: coredata.DocumentStatusDraft, Status: coredata.DocumentStatusDraft,
CreatedBy: req.CreatedBy,
CreatedAt: now, CreatedAt: now,
UpdatedAt: now, UpdatedAt: now,
} }
@@ -745,7 +732,6 @@ func (s *DocumentService) ListSignatures(
func (s *DocumentService) CreateDraft( func (s *DocumentService) CreateDraft(
ctx context.Context, ctx context.Context,
documentID gid.GID, documentID gid.GID,
createdBy gid.GID,
) (*coredata.DocumentVersion, error) { ) (*coredata.DocumentVersion, error) {
draftVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType) draftVersionID := gid.New(s.svc.scope.GetTenantID(), coredata.DocumentVersionEntityType)
@@ -776,7 +762,6 @@ func (s *DocumentService) CreateDraft(
draftVersion.VersionNumber = latestVersion.VersionNumber + 1 draftVersion.VersionNumber = latestVersion.VersionNumber + 1
draftVersion.Content = latestVersion.Content draftVersion.Content = latestVersion.Content
draftVersion.Status = coredata.DocumentStatusDraft draftVersion.Status = coredata.DocumentStatusDraft
draftVersion.CreatedBy = createdBy
draftVersion.CreatedAt = now draftVersion.CreatedAt = now
draftVersion.UpdatedAt = now draftVersion.UpdatedAt = now
@@ -1314,7 +1299,6 @@ func exportDocumentPDF(
document := &coredata.Document{} document := &coredata.Document{}
version := &coredata.DocumentVersion{} version := &coredata.DocumentVersion{}
owner := &coredata.People{} owner := &coredata.People{}
publishedBy := &coredata.People{}
signatures := coredata.DocumentVersionSignatures{} signatures := coredata.DocumentVersionSignatures{}
peopleMap := make(map[gid.GID]*coredata.People) peopleMap := make(map[gid.GID]*coredata.People)
@@ -1326,12 +1310,6 @@ func exportDocumentPDF(
return nil, fmt.Errorf("cannot load document: %w", err) return nil, fmt.Errorf("cannot load document: %w", err)
} }
if version.PublishedBy != nil {
if err := publishedBy.LoadByID(ctx, conn, scope, *version.PublishedBy); err != nil {
return nil, fmt.Errorf("cannot load published by person: %w", err)
}
}
cursor := page.NewCursor( cursor := page.NewCursor(
100, 100,
nil, nil,
@@ -1385,7 +1363,6 @@ func exportDocumentPDF(
Approver: owner.FullName, Approver: owner.FullName,
Description: version.Changelog, Description: version.Changelog,
PublishedAt: version.PublishedAt, PublishedAt: version.PublishedAt,
PublishedBy: publishedBy.FullName,
Signatures: make([]docgen.SignatureData, len(signatures)), Signatures: make([]docgen.SignatureData, len(signatures)),
} }

View File

@@ -84,7 +84,6 @@ type (
CreateVendorRiskAssessmentRequest struct { CreateVendorRiskAssessmentRequest struct {
VendorID gid.GID VendorID gid.GID
AssessedByID gid.GID
ExpiresAt time.Time ExpiresAt time.Time
DataSensitivity coredata.DataSensitivity DataSensitivity coredata.DataSensitivity
BusinessImpact coredata.BusinessImpact BusinessImpact coredata.BusinessImpact
@@ -536,8 +535,6 @@ func (s VendorService) CreateRiskAssessment(
vendorRiskAssessment := &coredata.VendorRiskAssessment{ vendorRiskAssessment := &coredata.VendorRiskAssessment{
ID: vendorRiskAssessmentID, ID: vendorRiskAssessmentID,
VendorID: req.VendorID, VendorID: req.VendorID,
AssessedBy: req.AssessedByID,
AssessedAt: now,
ExpiresAt: req.ExpiresAt, ExpiresAt: req.ExpiresAt,
DataSensitivity: req.DataSensitivity, DataSensitivity: req.DataSensitivity,
BusinessImpact: req.BusinessImpact, BusinessImpact: req.BusinessImpact,

View File

@@ -3187,7 +3187,6 @@ input UpdateDocumentInput {
title: String title: String
content: String content: String
ownerId: ID ownerId: ID
createdBy: ID
documentType: DocumentType documentType: DocumentType
showOnTrustCenter: Boolean showOnTrustCenter: Boolean
} }
@@ -3208,6 +3207,7 @@ input InviteUserInput {
organizationId: ID! organizationId: ID!
email: String! email: String!
fullName: String! fullName: String!
createPeople: Boolean!
} }
input RemoveUserInput { input RemoveUserInput {
@@ -3719,8 +3719,6 @@ input VendorRiskAssessmentOrder {
type VendorRiskAssessment implements Node { type VendorRiskAssessment implements Node {
id: ID! id: ID!
vendor: Vendor! @goField(forceResolver: true) vendor: Vendor! @goField(forceResolver: true)
assessedAt: Datetime!
assessedBy: People! @goField(forceResolver: true)
expiresAt: Datetime! expiresAt: Datetime!
dataSensitivity: DataSensitivity! dataSensitivity: DataSensitivity!
businessImpact: BusinessImpact! businessImpact: BusinessImpact!
@@ -3741,15 +3739,10 @@ enum VendorRiskAssessmentOrderField
@goEnum( @goEnum(
value: "github.com/getprobo/probo/pkg/coredata.VendorRiskAssessmentOrderFieldExpiresAt" value: "github.com/getprobo/probo/pkg/coredata.VendorRiskAssessmentOrderFieldExpiresAt"
) )
ASSESSED_AT
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.VendorRiskAssessmentOrderFieldAssessedAt"
)
} }
input CreateVendorRiskAssessmentInput { input CreateVendorRiskAssessmentInput {
vendorId: ID! vendorId: ID!
assessedBy: ID!
expiresAt: Datetime! expiresAt: Datetime!
dataSensitivity: DataSensitivity! dataSensitivity: DataSensitivity!
businessImpact: BusinessImpact! businessImpact: BusinessImpact!
@@ -3786,7 +3779,6 @@ type DocumentVersion implements Node {
orderBy: DocumentVersionSignatureOrder orderBy: DocumentVersionSignatureOrder
): DocumentVersionSignatureConnection! @goField(forceResolver: true) ): DocumentVersionSignatureConnection! @goField(forceResolver: true)
publishedBy: People @goField(forceResolver: true)
publishedAt: Datetime publishedAt: Datetime
createdAt: Datetime! createdAt: Datetime!
updatedAt: Datetime! updatedAt: Datetime!

View File

@@ -574,7 +574,6 @@ type ComplexityRoot struct {
ID func(childComplexity int) int ID func(childComplexity int) int
Owner func(childComplexity int) int Owner func(childComplexity int) int
PublishedAt func(childComplexity int) int PublishedAt func(childComplexity int) int
PublishedBy func(childComplexity int) int
Signatures func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionSignatureOrder) int Signatures func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionSignatureOrder) int
Status func(childComplexity int) int Status func(childComplexity int) int
Title func(childComplexity int) int Title func(childComplexity int) int
@@ -1422,8 +1421,6 @@ type ComplexityRoot struct {
} }
VendorRiskAssessment struct { VendorRiskAssessment struct {
AssessedAt func(childComplexity int) int
AssessedBy func(childComplexity int) int
BusinessImpact func(childComplexity int) int BusinessImpact func(childComplexity int) int
CreatedAt func(childComplexity int) int CreatedAt func(childComplexity int) int
DataSensitivity func(childComplexity int) int DataSensitivity func(childComplexity int) int
@@ -1533,7 +1530,6 @@ type DocumentVersionResolver interface {
Owner(ctx context.Context, obj *types.DocumentVersion) (*types.People, error) Owner(ctx context.Context, obj *types.DocumentVersion) (*types.People, error)
Signatures(ctx context.Context, obj *types.DocumentVersion, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionSignatureOrder) (*types.DocumentVersionSignatureConnection, error) Signatures(ctx context.Context, obj *types.DocumentVersion, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.DocumentVersionSignatureOrder) (*types.DocumentVersionSignatureConnection, error)
PublishedBy(ctx context.Context, obj *types.DocumentVersion) (*types.People, error)
} }
type DocumentVersionSignatureResolver interface { type DocumentVersionSignatureResolver interface {
DocumentVersion(ctx context.Context, obj *types.DocumentVersionSignature) (*types.DocumentVersion, error) DocumentVersion(ctx context.Context, obj *types.DocumentVersionSignature) (*types.DocumentVersion, error)
@@ -1809,8 +1805,6 @@ type VendorDataPrivacyAgreementResolver interface {
} }
type VendorRiskAssessmentResolver interface { type VendorRiskAssessmentResolver interface {
Vendor(ctx context.Context, obj *types.VendorRiskAssessment) (*types.Vendor, error) Vendor(ctx context.Context, obj *types.VendorRiskAssessment) (*types.Vendor, error)
AssessedBy(ctx context.Context, obj *types.VendorRiskAssessment) (*types.People, error)
} }
type VendorServiceResolver interface { type VendorServiceResolver interface {
Vendor(ctx context.Context, obj *types.VendorService) (*types.Vendor, error) Vendor(ctx context.Context, obj *types.VendorService) (*types.Vendor, error)
@@ -3297,13 +3291,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.DocumentVersion.PublishedAt(childComplexity), true return e.complexity.DocumentVersion.PublishedAt(childComplexity), true
case "DocumentVersion.publishedBy":
if e.complexity.DocumentVersion.PublishedBy == nil {
break
}
return e.complexity.DocumentVersion.PublishedBy(childComplexity), true
case "DocumentVersion.signatures": case "DocumentVersion.signatures":
if e.complexity.DocumentVersion.Signatures == nil { if e.complexity.DocumentVersion.Signatures == nil {
break break
@@ -7710,20 +7697,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.VendorEdge.Node(childComplexity), true return e.complexity.VendorEdge.Node(childComplexity), true
case "VendorRiskAssessment.assessedAt":
if e.complexity.VendorRiskAssessment.AssessedAt == nil {
break
}
return e.complexity.VendorRiskAssessment.AssessedAt(childComplexity), true
case "VendorRiskAssessment.assessedBy":
if e.complexity.VendorRiskAssessment.AssessedBy == nil {
break
}
return e.complexity.VendorRiskAssessment.AssessedBy(childComplexity), true
case "VendorRiskAssessment.businessImpact": case "VendorRiskAssessment.businessImpact":
if e.complexity.VendorRiskAssessment.BusinessImpact == nil { if e.complexity.VendorRiskAssessment.BusinessImpact == nil {
break break
@@ -11353,7 +11326,6 @@ input UpdateDocumentInput {
title: String title: String
content: String content: String
ownerId: ID ownerId: ID
createdBy: ID
documentType: DocumentType documentType: DocumentType
showOnTrustCenter: Boolean showOnTrustCenter: Boolean
} }
@@ -11374,6 +11346,7 @@ input InviteUserInput {
organizationId: ID! organizationId: ID!
email: String! email: String!
fullName: String! fullName: String!
createPeople: Boolean!
} }
input RemoveUserInput { input RemoveUserInput {
@@ -11885,8 +11858,6 @@ input VendorRiskAssessmentOrder {
type VendorRiskAssessment implements Node { type VendorRiskAssessment implements Node {
id: ID! id: ID!
vendor: Vendor! @goField(forceResolver: true) vendor: Vendor! @goField(forceResolver: true)
assessedAt: Datetime!
assessedBy: People! @goField(forceResolver: true)
expiresAt: Datetime! expiresAt: Datetime!
dataSensitivity: DataSensitivity! dataSensitivity: DataSensitivity!
businessImpact: BusinessImpact! businessImpact: BusinessImpact!
@@ -11907,15 +11878,10 @@ enum VendorRiskAssessmentOrderField
@goEnum( @goEnum(
value: "github.com/getprobo/probo/pkg/coredata.VendorRiskAssessmentOrderFieldExpiresAt" value: "github.com/getprobo/probo/pkg/coredata.VendorRiskAssessmentOrderFieldExpiresAt"
) )
ASSESSED_AT
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.VendorRiskAssessmentOrderFieldAssessedAt"
)
} }
input CreateVendorRiskAssessmentInput { input CreateVendorRiskAssessmentInput {
vendorId: ID! vendorId: ID!
assessedBy: ID!
expiresAt: Datetime! expiresAt: Datetime!
dataSensitivity: DataSensitivity! dataSensitivity: DataSensitivity!
businessImpact: BusinessImpact! businessImpact: BusinessImpact!
@@ -11952,7 +11918,6 @@ type DocumentVersion implements Node {
orderBy: DocumentVersionSignatureOrder orderBy: DocumentVersionSignatureOrder
): DocumentVersionSignatureConnection! @goField(forceResolver: true) ): DocumentVersionSignatureConnection! @goField(forceResolver: true)
publishedBy: People @goField(forceResolver: true)
publishedAt: Datetime publishedAt: Datetime
createdAt: Datetime! createdAt: Datetime!
updatedAt: Datetime! updatedAt: Datetime!
@@ -30012,69 +29977,6 @@ func (ec *executionContext) fieldContext_DocumentVersion_signatures(ctx context.
return fc, nil return fc, nil
} }
func (ec *executionContext) _DocumentVersion_publishedBy(ctx context.Context, field graphql.CollectedField, obj *types.DocumentVersion) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_DocumentVersion_publishedBy(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.DocumentVersion().PublishedBy(rctx, obj)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*types.People)
fc.Result = res
return ec.marshalOPeople2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐPeople(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_DocumentVersion_publishedBy(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "DocumentVersion",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "id":
return ec.fieldContext_People_id(ctx, field)
case "fullName":
return ec.fieldContext_People_fullName(ctx, field)
case "primaryEmailAddress":
return ec.fieldContext_People_primaryEmailAddress(ctx, field)
case "additionalEmailAddresses":
return ec.fieldContext_People_additionalEmailAddresses(ctx, field)
case "kind":
return ec.fieldContext_People_kind(ctx, field)
case "position":
return ec.fieldContext_People_position(ctx, field)
case "contractStartDate":
return ec.fieldContext_People_contractStartDate(ctx, field)
case "contractEndDate":
return ec.fieldContext_People_contractEndDate(ctx, field)
case "createdAt":
return ec.fieldContext_People_createdAt(ctx, field)
case "updatedAt":
return ec.fieldContext_People_updatedAt(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type People", field.Name)
},
}
return fc, nil
}
func (ec *executionContext) _DocumentVersion_publishedAt(ctx context.Context, field graphql.CollectedField, obj *types.DocumentVersion) (ret graphql.Marshaler) { func (ec *executionContext) _DocumentVersion_publishedAt(ctx context.Context, field graphql.CollectedField, obj *types.DocumentVersion) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_DocumentVersion_publishedAt(ctx, field) fc, err := ec.fieldContext_DocumentVersion_publishedAt(ctx, field)
if err != nil { if err != nil {
@@ -30409,8 +30311,6 @@ func (ec *executionContext) fieldContext_DocumentVersionEdge_node(_ context.Cont
return ec.fieldContext_DocumentVersion_owner(ctx, field) return ec.fieldContext_DocumentVersion_owner(ctx, field)
case "signatures": case "signatures":
return ec.fieldContext_DocumentVersion_signatures(ctx, field) return ec.fieldContext_DocumentVersion_signatures(ctx, field)
case "publishedBy":
return ec.fieldContext_DocumentVersion_publishedBy(ctx, field)
case "publishedAt": case "publishedAt":
return ec.fieldContext_DocumentVersion_publishedAt(ctx, field) return ec.fieldContext_DocumentVersion_publishedAt(ctx, field)
case "createdAt": case "createdAt":
@@ -30525,8 +30425,6 @@ func (ec *executionContext) fieldContext_DocumentVersionSignature_documentVersio
return ec.fieldContext_DocumentVersion_owner(ctx, field) return ec.fieldContext_DocumentVersion_owner(ctx, field)
case "signatures": case "signatures":
return ec.fieldContext_DocumentVersion_signatures(ctx, field) return ec.fieldContext_DocumentVersion_signatures(ctx, field)
case "publishedBy":
return ec.fieldContext_DocumentVersion_publishedBy(ctx, field)
case "publishedAt": case "publishedAt":
return ec.fieldContext_DocumentVersion_publishedAt(ctx, field) return ec.fieldContext_DocumentVersion_publishedAt(ctx, field)
case "createdAt": case "createdAt":
@@ -46514,8 +46412,6 @@ func (ec *executionContext) fieldContext_PublishDocumentVersionPayload_documentV
return ec.fieldContext_DocumentVersion_owner(ctx, field) return ec.fieldContext_DocumentVersion_owner(ctx, field)
case "signatures": case "signatures":
return ec.fieldContext_DocumentVersion_signatures(ctx, field) return ec.fieldContext_DocumentVersion_signatures(ctx, field)
case "publishedBy":
return ec.fieldContext_DocumentVersion_publishedBy(ctx, field)
case "publishedAt": case "publishedAt":
return ec.fieldContext_DocumentVersion_publishedAt(ctx, field) return ec.fieldContext_DocumentVersion_publishedAt(ctx, field)
case "createdAt": case "createdAt":
@@ -52026,8 +51922,6 @@ func (ec *executionContext) fieldContext_UpdateDocumentVersionPayload_documentVe
return ec.fieldContext_DocumentVersion_owner(ctx, field) return ec.fieldContext_DocumentVersion_owner(ctx, field)
case "signatures": case "signatures":
return ec.fieldContext_DocumentVersion_signatures(ctx, field) return ec.fieldContext_DocumentVersion_signatures(ctx, field)
case "publishedBy":
return ec.fieldContext_DocumentVersion_publishedBy(ctx, field)
case "publishedAt": case "publishedAt":
return ec.fieldContext_DocumentVersion_publishedAt(ctx, field) return ec.fieldContext_DocumentVersion_publishedAt(ctx, field)
case "createdAt": case "createdAt":
@@ -58292,116 +58186,6 @@ func (ec *executionContext) fieldContext_VendorRiskAssessment_vendor(_ context.C
return fc, nil return fc, nil
} }
func (ec *executionContext) _VendorRiskAssessment_assessedAt(ctx context.Context, field graphql.CollectedField, obj *types.VendorRiskAssessment) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_VendorRiskAssessment_assessedAt(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.AssessedAt, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(time.Time)
fc.Result = res
return ec.marshalNDatetime2timeᚐTime(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_VendorRiskAssessment_assessedAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "VendorRiskAssessment",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Datetime does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _VendorRiskAssessment_assessedBy(ctx context.Context, field graphql.CollectedField, obj *types.VendorRiskAssessment) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_VendorRiskAssessment_assessedBy(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.VendorRiskAssessment().AssessedBy(rctx, obj)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*types.People)
fc.Result = res
return ec.marshalNPeople2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐPeople(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_VendorRiskAssessment_assessedBy(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "VendorRiskAssessment",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "id":
return ec.fieldContext_People_id(ctx, field)
case "fullName":
return ec.fieldContext_People_fullName(ctx, field)
case "primaryEmailAddress":
return ec.fieldContext_People_primaryEmailAddress(ctx, field)
case "additionalEmailAddresses":
return ec.fieldContext_People_additionalEmailAddresses(ctx, field)
case "kind":
return ec.fieldContext_People_kind(ctx, field)
case "position":
return ec.fieldContext_People_position(ctx, field)
case "contractStartDate":
return ec.fieldContext_People_contractStartDate(ctx, field)
case "contractEndDate":
return ec.fieldContext_People_contractEndDate(ctx, field)
case "createdAt":
return ec.fieldContext_People_createdAt(ctx, field)
case "updatedAt":
return ec.fieldContext_People_updatedAt(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type People", field.Name)
},
}
return fc, nil
}
func (ec *executionContext) _VendorRiskAssessment_expiresAt(ctx context.Context, field graphql.CollectedField, obj *types.VendorRiskAssessment) (ret graphql.Marshaler) { func (ec *executionContext) _VendorRiskAssessment_expiresAt(ctx context.Context, field graphql.CollectedField, obj *types.VendorRiskAssessment) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_VendorRiskAssessment_expiresAt(ctx, field) fc, err := ec.fieldContext_VendorRiskAssessment_expiresAt(ctx, field)
if err != nil { if err != nil {
@@ -58854,10 +58638,6 @@ func (ec *executionContext) fieldContext_VendorRiskAssessmentEdge_node(_ context
return ec.fieldContext_VendorRiskAssessment_id(ctx, field) return ec.fieldContext_VendorRiskAssessment_id(ctx, field)
case "vendor": case "vendor":
return ec.fieldContext_VendorRiskAssessment_vendor(ctx, field) return ec.fieldContext_VendorRiskAssessment_vendor(ctx, field)
case "assessedAt":
return ec.fieldContext_VendorRiskAssessment_assessedAt(ctx, field)
case "assessedBy":
return ec.fieldContext_VendorRiskAssessment_assessedBy(ctx, field)
case "expiresAt": case "expiresAt":
return ec.fieldContext_VendorRiskAssessment_expiresAt(ctx, field) return ec.fieldContext_VendorRiskAssessment_expiresAt(ctx, field)
case "dataSensitivity": case "dataSensitivity":
@@ -63702,7 +63482,7 @@ func (ec *executionContext) unmarshalInputCreateVendorRiskAssessmentInput(ctx co
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"vendorId", "assessedBy", "expiresAt", "dataSensitivity", "businessImpact", "notes"} fieldsInOrder := [...]string{"vendorId", "expiresAt", "dataSensitivity", "businessImpact", "notes"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -63716,13 +63496,6 @@ func (ec *executionContext) unmarshalInputCreateVendorRiskAssessmentInput(ctx co
return it, err return it, err
} }
it.VendorID = data it.VendorID = data
case "assessedBy":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("assessedBy"))
data, err := ec.unmarshalNID2githubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v)
if err != nil {
return it, err
}
it.AssessedBy = data
case "expiresAt": case "expiresAt":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("expiresAt")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("expiresAt"))
data, err := ec.unmarshalNDatetime2timeᚐTime(ctx, v) data, err := ec.unmarshalNDatetime2timeᚐTime(ctx, v)
@@ -65261,7 +65034,7 @@ func (ec *executionContext) unmarshalInputInviteUserInput(ctx context.Context, o
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"organizationId", "email", "fullName"} fieldsInOrder := [...]string{"organizationId", "email", "fullName", "createPeople"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -65289,6 +65062,13 @@ func (ec *executionContext) unmarshalInputInviteUserInput(ctx context.Context, o
return it, err return it, err
} }
it.FullName = data it.FullName = data
case "createPeople":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("createPeople"))
data, err := ec.unmarshalNBoolean2bool(ctx, v)
if err != nil {
return it, err
}
it.CreatePeople = data
} }
} }
@@ -66373,7 +66153,7 @@ func (ec *executionContext) unmarshalInputUpdateDocumentInput(ctx context.Contex
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"id", "title", "content", "ownerId", "createdBy", "documentType", "showOnTrustCenter"} fieldsInOrder := [...]string{"id", "title", "content", "ownerId", "documentType", "showOnTrustCenter"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -66408,13 +66188,6 @@ func (ec *executionContext) unmarshalInputUpdateDocumentInput(ctx context.Contex
return it, err return it, err
} }
it.OwnerID = data it.OwnerID = data
case "createdBy":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("createdBy"))
data, err := ec.unmarshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v)
if err != nil {
return it, err
}
it.CreatedBy = data
case "documentType": case "documentType":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("documentType")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("documentType"))
data, err := ec.unmarshalODocumentType2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐDocumentType(ctx, v) data, err := ec.unmarshalODocumentType2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐDocumentType(ctx, v)
@@ -73483,39 +73256,6 @@ func (ec *executionContext) _DocumentVersion(ctx context.Context, sel ast.Select
continue continue
} }
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
case "publishedBy":
field := field
innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
}
}()
res = ec._DocumentVersion_publishedBy(ctx, field, obj)
return res
}
if field.Deferrable != nil {
dfs, ok := deferred[field.Deferrable.Label]
di := 0
if ok {
dfs.AddField(field)
di = len(dfs.Values) - 1
} else {
dfs = graphql.NewFieldSet([]graphql.CollectedField{field})
deferred[field.Deferrable.Label] = dfs
}
dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler {
return innerFunc(ctx, dfs)
})
// don't run the out.Concurrently() call below
out.Values[i] = graphql.Null
continue
}
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
case "publishedAt": case "publishedAt":
out.Values[i] = ec._DocumentVersion_publishedAt(ctx, field, obj) out.Values[i] = ec._DocumentVersion_publishedAt(ctx, field, obj)
@@ -82389,47 +82129,6 @@ func (ec *executionContext) _VendorRiskAssessment(ctx context.Context, sel ast.S
continue continue
} }
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
case "assessedAt":
out.Values[i] = ec._VendorRiskAssessment_assessedAt(ctx, field, obj)
if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1)
}
case "assessedBy":
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._VendorRiskAssessment_assessedBy(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) }) out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
case "expiresAt": case "expiresAt":
out.Values[i] = ec._VendorRiskAssessment_expiresAt(ctx, field, obj) out.Values[i] = ec._VendorRiskAssessment_expiresAt(ctx, field, obj)
@@ -90332,14 +90031,12 @@ func (ec *executionContext) marshalNVendorRiskAssessmentOrderField2githubᚗcom
var ( var (
unmarshalNVendorRiskAssessmentOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorRiskAssessmentOrderField = map[string]coredata.VendorRiskAssessmentOrderField{ unmarshalNVendorRiskAssessmentOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorRiskAssessmentOrderField = map[string]coredata.VendorRiskAssessmentOrderField{
"CREATED_AT": coredata.VendorRiskAssessmentOrderFieldCreatedAt, "CREATED_AT": coredata.VendorRiskAssessmentOrderFieldCreatedAt,
"EXPIRES_AT": coredata.VendorRiskAssessmentOrderFieldExpiresAt, "EXPIRES_AT": coredata.VendorRiskAssessmentOrderFieldExpiresAt,
"ASSESSED_AT": coredata.VendorRiskAssessmentOrderFieldAssessedAt,
} }
marshalNVendorRiskAssessmentOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorRiskAssessmentOrderField = map[coredata.VendorRiskAssessmentOrderField]string{ marshalNVendorRiskAssessmentOrderField2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐVendorRiskAssessmentOrderField = map[coredata.VendorRiskAssessmentOrderField]string{
coredata.VendorRiskAssessmentOrderFieldCreatedAt: "CREATED_AT", coredata.VendorRiskAssessmentOrderFieldCreatedAt: "CREATED_AT",
coredata.VendorRiskAssessmentOrderFieldExpiresAt: "EXPIRES_AT", coredata.VendorRiskAssessmentOrderFieldExpiresAt: "EXPIRES_AT",
coredata.VendorRiskAssessmentOrderFieldAssessedAt: "ASSESSED_AT",
} }
) )

View File

@@ -578,7 +578,6 @@ type CreateVendorPayload struct {
type CreateVendorRiskAssessmentInput struct { type CreateVendorRiskAssessmentInput struct {
VendorID gid.GID `json:"vendorId"` VendorID gid.GID `json:"vendorId"`
AssessedBy gid.GID `json:"assessedBy"`
ExpiresAt time.Time `json:"expiresAt"` ExpiresAt time.Time `json:"expiresAt"`
DataSensitivity coredata.DataSensitivity `json:"dataSensitivity"` DataSensitivity coredata.DataSensitivity `json:"dataSensitivity"`
BusinessImpact coredata.BusinessImpact `json:"businessImpact"` BusinessImpact coredata.BusinessImpact `json:"businessImpact"`
@@ -938,7 +937,6 @@ type DocumentVersion struct {
Title string `json:"title"` Title string `json:"title"`
Owner *People `json:"owner"` Owner *People `json:"owner"`
Signatures *DocumentVersionSignatureConnection `json:"signatures"` Signatures *DocumentVersionSignatureConnection `json:"signatures"`
PublishedBy *People `json:"publishedBy,omitempty"`
PublishedAt *time.Time `json:"publishedAt,omitempty"` PublishedAt *time.Time `json:"publishedAt,omitempty"`
CreatedAt time.Time `json:"createdAt"` CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"` UpdatedAt time.Time `json:"updatedAt"`
@@ -1098,6 +1096,7 @@ type InviteUserInput struct {
OrganizationID gid.GID `json:"organizationId"` OrganizationID gid.GID `json:"organizationId"`
Email string `json:"email"` Email string `json:"email"`
FullName string `json:"fullName"` FullName string `json:"fullName"`
CreatePeople bool `json:"createPeople"`
} }
type InviteUserPayload struct { type InviteUserPayload struct {
@@ -1590,7 +1589,6 @@ type UpdateDocumentInput struct {
Title *string `json:"title,omitempty"` Title *string `json:"title,omitempty"`
Content *string `json:"content,omitempty"` Content *string `json:"content,omitempty"`
OwnerID *gid.GID `json:"ownerId,omitempty"` OwnerID *gid.GID `json:"ownerId,omitempty"`
CreatedBy *gid.GID `json:"createdBy,omitempty"`
DocumentType *coredata.DocumentType `json:"documentType,omitempty"` DocumentType *coredata.DocumentType `json:"documentType,omitempty"`
ShowOnTrustCenter *bool `json:"showOnTrustCenter,omitempty"` ShowOnTrustCenter *bool `json:"showOnTrustCenter,omitempty"`
} }
@@ -2064,8 +2062,6 @@ type VendorFilter struct {
type VendorRiskAssessment struct { type VendorRiskAssessment struct {
ID gid.GID `json:"id"` ID gid.GID `json:"id"`
Vendor *Vendor `json:"vendor"` Vendor *Vendor `json:"vendor"`
AssessedAt time.Time `json:"assessedAt"`
AssessedBy *People `json:"assessedBy"`
ExpiresAt time.Time `json:"expiresAt"` ExpiresAt time.Time `json:"expiresAt"`
DataSensitivity coredata.DataSensitivity `json:"dataSensitivity"` DataSensitivity coredata.DataSensitivity `json:"dataSensitivity"`
BusinessImpact coredata.BusinessImpact `json:"businessImpact"` BusinessImpact coredata.BusinessImpact `json:"businessImpact"`

View File

@@ -46,7 +46,6 @@ func NewVendorRiskAssessmentEdge(c *coredata.VendorRiskAssessment, orderBy cored
func NewVendorRiskAssessment(c *coredata.VendorRiskAssessment) *VendorRiskAssessment { func NewVendorRiskAssessment(c *coredata.VendorRiskAssessment) *VendorRiskAssessment {
return &VendorRiskAssessment{ return &VendorRiskAssessment{
ID: c.ID, ID: c.ID,
AssessedAt: c.AssessedAt,
ExpiresAt: c.ExpiresAt, ExpiresAt: c.ExpiresAt,
DataSensitivity: c.DataSensitivity, DataSensitivity: c.DataSensitivity,
BusinessImpact: c.BusinessImpact, BusinessImpact: c.BusinessImpact,

View File

@@ -700,27 +700,6 @@ func (r *documentVersionResolver) Signatures(ctx context.Context, obj *types.Doc
return types.NewDocumentVersionSignatureConnection(page), nil return types.NewDocumentVersionSignatureConnection(page), nil
} }
// PublishedBy is the resolver for the publishedBy field.
func (r *documentVersionResolver) PublishedBy(ctx context.Context, obj *types.DocumentVersion) (*types.People, error) {
prb := r.ProboService(ctx, obj.ID.TenantID())
documentVersion, err := prb.Documents.GetVersion(ctx, obj.ID)
if err != nil {
panic(fmt.Errorf("cannot get document version: %w", err))
}
if documentVersion.PublishedBy == nil {
return nil, nil
}
people, err := prb.Peoples.Get(ctx, *documentVersion.PublishedBy)
if err != nil {
panic(fmt.Errorf("cannot get people: %w", err))
}
return types.NewPeople(people), nil
}
// DocumentVersion is the resolver for the documentVersion field. // DocumentVersion is the resolver for the documentVersion field.
func (r *documentVersionSignatureResolver) DocumentVersion(ctx context.Context, obj *types.DocumentVersionSignature) (*types.DocumentVersion, error) { func (r *documentVersionSignatureResolver) DocumentVersion(ctx context.Context, obj *types.DocumentVersionSignature) (*types.DocumentVersion, error) {
prb := r.ProboService(ctx, obj.ID.TenantID()) prb := r.ProboService(ctx, obj.ID.TenantID())
@@ -1272,7 +1251,9 @@ func (r *mutationResolver) InviteUser(ctx context.Context, input types.InviteUse
for _, organization := range organizations { for _, organization := range organizations {
if organization.ID == input.OrganizationID { if organization.ID == input.OrganizationID {
err := r.usrmgrSvc.InviteUser(ctx, input.OrganizationID, input.FullName, input.Email) createPeople := input.CreatePeople
err := r.usrmgrSvc.InviteUser(ctx, input.OrganizationID, input.FullName, input.Email, createPeople)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -2427,12 +2408,6 @@ func (r *mutationResolver) DeleteVendorDataPrivacyAgreement(ctx context.Context,
func (r *mutationResolver) CreateDocument(ctx context.Context, input types.CreateDocumentInput) (*types.CreateDocumentPayload, error) { func (r *mutationResolver) CreateDocument(ctx context.Context, input types.CreateDocumentInput) (*types.CreateDocumentPayload, error) {
prb := r.ProboService(ctx, input.OrganizationID.TenantID()) prb := r.ProboService(ctx, input.OrganizationID.TenantID())
user := UserFromContext(ctx)
people, err := prb.Peoples.GetByUserID(ctx, user.ID)
if err != nil {
panic(fmt.Errorf("cannot get people: %w", err))
}
document, documentVersion, err := prb.Documents.Create( document, documentVersion, err := prb.Documents.Create(
ctx, ctx,
probo.CreateDocumentRequest{ probo.CreateDocumentRequest{
@@ -2441,7 +2416,6 @@ func (r *mutationResolver) CreateDocument(ctx context.Context, input types.Creat
Title: input.Title, Title: input.Title,
OwnerID: input.OwnerID, OwnerID: input.OwnerID,
Content: input.Content, Content: input.Content,
CreatedBy: people.ID,
}, },
) )
if err != nil { if err != nil {
@@ -2495,12 +2469,7 @@ func (r *mutationResolver) PublishDocumentVersion(ctx context.Context, input typ
prb := r.ProboService(ctx, input.DocumentID.TenantID()) prb := r.ProboService(ctx, input.DocumentID.TenantID())
user := UserFromContext(ctx) user := UserFromContext(ctx)
people, err := prb.Peoples.GetByUserID(ctx, user.ID) document, documentVersion, err := prb.Documents.PublishVersion(ctx, input.DocumentID, user.ID, input.Changelog)
if err != nil {
panic(fmt.Errorf("cannot get people: %w", err))
}
document, documentVersion, err := prb.Documents.PublishVersion(ctx, input.DocumentID, people.ID, input.Changelog)
if err != nil { if err != nil {
panic(fmt.Errorf("cannot publish document version: %w", err)) panic(fmt.Errorf("cannot publish document version: %w", err))
} }
@@ -2524,16 +2493,11 @@ func (r *mutationResolver) BulkPublishDocumentVersions(ctx context.Context, inpu
user := UserFromContext(ctx) user := UserFromContext(ctx)
people, err := prb.Peoples.GetByUserID(ctx, user.ID)
if err != nil {
panic(fmt.Errorf("cannot get people: %w", err))
}
documentVersions, documents, err := prb.Documents.BulkPublishVersions( documentVersions, documents, err := prb.Documents.BulkPublishVersions(
ctx, ctx,
probo.BulkPublishVersionsRequest{ probo.BulkPublishVersionsRequest{
DocumentIDs: input.DocumentIds, DocumentIDs: input.DocumentIds,
PublishedBy: people.ID, PublishedBy: user.ID,
Changelog: input.Changelog, Changelog: input.Changelog,
}, },
) )
@@ -2608,13 +2572,7 @@ func (r *mutationResolver) GenerateDocumentChangelog(ctx context.Context, input
func (r *mutationResolver) CreateDraftDocumentVersion(ctx context.Context, input types.CreateDraftDocumentVersionInput) (*types.CreateDraftDocumentVersionPayload, error) { func (r *mutationResolver) CreateDraftDocumentVersion(ctx context.Context, input types.CreateDraftDocumentVersionInput) (*types.CreateDraftDocumentVersionPayload, error) {
prb := r.ProboService(ctx, input.DocumentID.TenantID()) prb := r.ProboService(ctx, input.DocumentID.TenantID())
user := UserFromContext(ctx) documentVersion, err := prb.Documents.CreateDraft(ctx, input.DocumentID)
people, err := prb.Peoples.GetByUserID(ctx, user.ID)
if err != nil {
panic(fmt.Errorf("cannot get people: %w", err))
}
documentVersion, err := prb.Documents.CreateDraft(ctx, input.DocumentID, people.ID)
if err != nil { if err != nil {
panic(fmt.Errorf("cannot create draft document version: %w", err)) panic(fmt.Errorf("cannot create draft document version: %w", err))
} }
@@ -2767,7 +2725,6 @@ func (r *mutationResolver) CreateVendorRiskAssessment(ctx context.Context, input
ctx, ctx,
probo.CreateVendorRiskAssessmentRequest{ probo.CreateVendorRiskAssessmentRequest{
VendorID: input.VendorID, VendorID: input.VendorID,
AssessedByID: input.AssessedBy,
ExpiresAt: input.ExpiresAt, ExpiresAt: input.ExpiresAt,
DataSensitivity: input.DataSensitivity, DataSensitivity: input.DataSensitivity,
BusinessImpact: input.BusinessImpact, BusinessImpact: input.BusinessImpact,
@@ -4601,6 +4558,10 @@ func (r *userResolver) People(ctx context.Context, obj *types.User, organization
people, err := prb.Peoples.GetByUserID(ctx, obj.ID) people, err := prb.Peoples.GetByUserID(ctx, obj.ID)
if err != nil { if err != nil {
var errPeopleNotFound *coredata.ErrPeopleNotFound
if errors.As(err, &errPeopleNotFound) {
return nil, nil
}
panic(fmt.Errorf("failed to get people: %w", err)) panic(fmt.Errorf("failed to get people: %w", err))
} }
@@ -4927,23 +4888,6 @@ func (r *vendorRiskAssessmentResolver) Vendor(ctx context.Context, obj *types.Ve
return types.NewVendor(vendor), nil return types.NewVendor(vendor), nil
} }
// AssessedBy is the resolver for the assessedBy field.
func (r *vendorRiskAssessmentResolver) AssessedBy(ctx context.Context, obj *types.VendorRiskAssessment) (*types.People, error) {
prb := r.ProboService(ctx, obj.ID.TenantID())
vendorRiskAssessment, err := prb.Vendors.GetRiskAssessment(ctx, obj.ID)
if err != nil {
panic(fmt.Errorf("failed to get vendor risk assessment: %w", err))
}
people, err := prb.Peoples.Get(ctx, vendorRiskAssessment.AssessedBy)
if err != nil {
panic(fmt.Errorf("failed to get assessed by: %w", err))
}
return types.NewPeople(people), nil
}
// Vendor is the resolver for the vendor field. // Vendor is the resolver for the vendor field.
func (r *vendorServiceResolver) Vendor(ctx context.Context, obj *types.VendorService) (*types.Vendor, error) { func (r *vendorServiceResolver) Vendor(ctx context.Context, obj *types.VendorService) (*types.Vendor, error) {
prb := r.ProboService(ctx, obj.ID.TenantID()) prb := r.ProboService(ctx, obj.ID.TenantID())

View File

@@ -92,7 +92,6 @@ func (s *DocumentService) ExportPDF(
document := &coredata.Document{} document := &coredata.Document{}
version := &coredata.DocumentVersion{} version := &coredata.DocumentVersion{}
owner := &coredata.People{} owner := &coredata.People{}
publishedBy := &coredata.People{}
err := s.svc.pg.WithConn( err := s.svc.pg.WithConn(
ctx, ctx,
@@ -109,12 +108,6 @@ func (s *DocumentService) ExportPDF(
return fmt.Errorf("cannot load latest published document version: %w", err) return fmt.Errorf("cannot load latest published document version: %w", err)
} }
if version.PublishedBy != nil {
if err := publishedBy.LoadByID(ctx, conn, s.svc.scope, *version.PublishedBy); err != nil {
return fmt.Errorf("cannot load published by person: %w", err)
}
}
if err := owner.LoadByID(ctx, conn, s.svc.scope, document.OwnerID); err != nil { if err := owner.LoadByID(ctx, conn, s.svc.scope, document.OwnerID); err != nil {
return fmt.Errorf("cannot load document owner: %w", err) return fmt.Errorf("cannot load document owner: %w", err)
} }
@@ -143,7 +136,6 @@ func (s *DocumentService) ExportPDF(
Approver: owner.FullName, Approver: owner.FullName,
Description: version.Changelog, Description: version.Changelog,
PublishedAt: version.PublishedAt, PublishedAt: version.PublishedAt,
PublishedBy: publishedBy.FullName,
} }
htmlContent, err := docgen.RenderHTML(docData) htmlContent, err := docgen.RenderHTML(docData)

View File

@@ -84,6 +84,7 @@ type (
OrganizationID gid.GID `json:"organization_id"` OrganizationID gid.GID `json:"organization_id"`
Email string `json:"email"` Email string `json:"email"`
FullName string `json:"full_name"` FullName string `json:"full_name"`
CreatePeople bool `json:"create_people"`
} }
PasswordResetData struct { PasswordResetData struct {
@@ -661,6 +662,7 @@ func (s Service) InviteUser(
organizationID gid.GID, organizationID gid.GID,
fullName string, fullName string,
emailAddress string, emailAddress string,
createPeople bool,
) error { ) error {
if _, err := mail.ParseAddress(emailAddress); err != nil { if _, err := mail.ParseAddress(emailAddress); err != nil {
return &ErrInvalidEmail{emailAddress} return &ErrInvalidEmail{emailAddress}
@@ -697,32 +699,40 @@ func (s Service) InviteUser(
return fmt.Errorf("cannot insert user organization: %w", err) return fmt.Errorf("cannot insert user organization: %w", err)
} }
people := &coredata.People{} if createPeople {
scope := coredata.NewScope(organizationID.TenantID()) people := &coredata.People{}
if err := people.LoadByEmail(ctx, tx, scope, emailAddress); err != nil { scope := coredata.NewScope(organizationID.TenantID())
var errPeopleNotFound *coredata.ErrPeopleNotFound if err := people.LoadByEmail(ctx, tx, scope, emailAddress); err != nil {
var errPeopleNotFound *coredata.ErrPeopleNotFound
if errors.As(err, &errPeopleNotFound) { if errors.As(err, &errPeopleNotFound) {
people = &coredata.People{ people = &coredata.People{
ID: gid.New(organizationID.TenantID(), coredata.PeopleEntityType), ID: gid.New(organizationID.TenantID(), coredata.PeopleEntityType),
OrganizationID: organizationID, OrganizationID: organizationID,
UserID: &user.ID, UserID: &user.ID,
FullName: fullName, FullName: fullName,
PrimaryEmailAddress: emailAddress, PrimaryEmailAddress: emailAddress,
Kind: coredata.PeopleKindContractor, Kind: coredata.PeopleKindContractor,
AdditionalEmailAddresses: []string{}, AdditionalEmailAddresses: []string{},
CreatedAt: time.Now(), CreatedAt: time.Now(),
UpdatedAt: time.Now(), UpdatedAt: time.Now(),
}
if err := people.Insert(ctx, tx, scope); err != nil {
return fmt.Errorf("cannot insert people: %w", err)
}
} else {
return fmt.Errorf("cannot load people by email: %w", err)
} }
} else {
people.UserID = &user.ID
people.FullName = fullName
people.UpdatedAt = time.Now()
if err := people.Insert(ctx, tx, scope); err != nil { if err := people.Update(ctx, tx, scope); err != nil {
return fmt.Errorf("cannot insert people: %w", err) return fmt.Errorf("cannot update people: %w", err)
} }
return nil
} }
return fmt.Errorf("cannot load people by email: %w", err)
} }
return nil return nil
@@ -741,7 +751,7 @@ func (s Service) InviteUser(
s.tokenSecret, s.tokenSecret,
TokenTypeOrganizationInvitation, TokenTypeOrganizationInvitation,
s.invitationTokenValidity, s.invitationTokenValidity,
InvitationData{OrganizationID: organizationID, Email: emailAddress, FullName: fullName}, InvitationData{OrganizationID: organizationID, Email: emailAddress, FullName: fullName, CreatePeople: createPeople},
) )
if err != nil { if err != nil {
return fmt.Errorf("cannot generate confirmation token: %w", err) return fmt.Errorf("cannot generate confirmation token: %w", err)
@@ -832,39 +842,41 @@ func (s Service) ConfirmInvitation(ctx context.Context, tokenString string, pass
return fmt.Errorf("cannot insert user organization: %w", err) return fmt.Errorf("cannot insert user organization: %w", err)
} }
people := &coredata.People{} if token.Data.CreatePeople {
scope := coredata.NewScope(token.Data.OrganizationID.TenantID()) people := &coredata.People{}
scope := coredata.NewScope(token.Data.OrganizationID.TenantID())
if err := people.LoadByEmail(ctx, tx, scope, token.Data.Email); err != nil { if err := people.LoadByEmail(ctx, tx, scope, token.Data.Email); err != nil {
var errPeopleNotFound *coredata.ErrPeopleNotFound var errPeopleNotFound *coredata.ErrPeopleNotFound
if errors.As(err, &errPeopleNotFound) { if errors.As(err, &errPeopleNotFound) {
peopleID := gid.New(token.Data.OrganizationID.TenantID(), coredata.PeopleEntityType) peopleID := gid.New(token.Data.OrganizationID.TenantID(), coredata.PeopleEntityType)
people = &coredata.People{ people = &coredata.People{
ID: peopleID, ID: peopleID,
OrganizationID: token.Data.OrganizationID, OrganizationID: token.Data.OrganizationID,
UserID: &user.ID, UserID: &user.ID,
FullName: token.Data.FullName, FullName: token.Data.FullName,
PrimaryEmailAddress: token.Data.Email, PrimaryEmailAddress: token.Data.Email,
Kind: coredata.PeopleKindEmployee, Kind: coredata.PeopleKindEmployee,
AdditionalEmailAddresses: []string{}, AdditionalEmailAddresses: []string{},
CreatedAt: now, CreatedAt: now,
UpdatedAt: now, UpdatedAt: now,
} }
if err := people.Insert(ctx, tx, scope); err != nil { if err := people.Insert(ctx, tx, scope); err != nil {
return fmt.Errorf("cannot insert people: %w", err) return fmt.Errorf("cannot insert people: %w", err)
}
} else {
return fmt.Errorf("cannot load people by email: %w", err)
} }
} else { } else {
return fmt.Errorf("cannot load people by email: %w", err) people.UserID = &user.ID
} people.FullName = token.Data.FullName
} else { people.UpdatedAt = now
people.UserID = &user.ID
people.FullName = token.Data.FullName
people.UpdatedAt = now
if err := people.Update(ctx, tx, scope); err != nil { if err := people.Update(ctx, tx, scope); err != nil {
return fmt.Errorf("cannot update people: %w", err) return fmt.Errorf("cannot update people: %w", err)
}
} }
} }