Add name to audit

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-08-14 13:42:47 +02:00
parent ee456aaa0f
commit 215e97d9f5
22 changed files with 276 additions and 122 deletions

View File

@@ -24,6 +24,7 @@ import type { TrustCenterAuditsCardFragment$key } from "./__generated__/TrustCen
const trustCenterAuditFragment = graphql`
fragment TrustCenterAuditsCardFragment on Audit {
id
name
framework {
name
}
@@ -81,6 +82,7 @@ export function TrustCenterAuditsCard<Params>(props: Props<Params>) {
<Thead>
<Tr>
<Th>{__("Framework")}</Th>
<Th>{__("Name")}</Th>
<Th>{__("Valid Until")}</Th>
<Th>{__("State")}</Th>
<Th>{__("Visibility")}</Th>
@@ -90,7 +92,7 @@ export function TrustCenterAuditsCard<Params>(props: Props<Params>) {
<Tbody>
{audits.length === 0 && (
<Tr>
<Td colSpan={5} className="text-center text-txt-secondary">
<Td colSpan={6} className="text-center text-txt-secondary">
{__("No audits available")}
</Td>
</Tr>
@@ -139,6 +141,7 @@ function AuditRow(props: {
{audit.framework.name}
</div>
</Td>
<Td>{audit.name || __("Untitled")}</Td>
<Td>{validUntilFormatted}</Td>
<Td>
<Badge variant={getAuditStateVariant(audit.state)}>

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<794277d17daabd92807ccfaa5a1c2dbb>>
* @generated SignedSource<<b29f60aeb151f0b4ded9ebb02829b67f>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -17,6 +17,7 @@ export type TrustCenterAuditsCardFragment$data = {
readonly name: string;
};
readonly id: string;
readonly name: string | null | undefined;
readonly showOnTrustCenter: boolean;
readonly state: AuditState;
readonly validFrom: any | null | undefined;
@@ -28,7 +29,15 @@ export type TrustCenterAuditsCardFragment$key = {
readonly " $fragmentSpreads": FragmentRefs<"TrustCenterAuditsCardFragment">;
};
const node: ReaderFragment = {
const node: ReaderFragment = (function(){
var v0 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
};
return {
"argumentDefinitions": [],
"kind": "Fragment",
"metadata": null,
@@ -41,6 +50,7 @@ const node: ReaderFragment = {
"name": "id",
"storageKey": null
},
(v0/*: any*/),
{
"alias": null,
"args": null,
@@ -49,13 +59,7 @@ const node: ReaderFragment = {
"name": "framework",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
}
(v0/*: any*/)
],
"storageKey": null
},
@@ -98,7 +102,8 @@ const node: ReaderFragment = {
"type": "Audit",
"abstractKey": null
};
})();
(node as any).hash = "9c9291dffd5c057c0e70e2567a897362";
(node as any).hash = "1c5db1ae603a40619342702f790adfeb";
export default node;

View File

@@ -20,6 +20,7 @@ export const auditNodeQuery = graphql`
node(id: $auditId) {
... on Audit {
id
name
validFrom
validUntil
report {
@@ -56,6 +57,7 @@ export const createAuditMutation = graphql`
auditEdge @prependEdge(connections: $connections) {
node {
id
name
validFrom
validUntil
report {
@@ -79,6 +81,7 @@ export const updateAuditMutation = graphql`
updateAudit(input: $input) {
audit {
id
name
validFrom
validUntil
report {
@@ -148,6 +151,7 @@ export const useCreateAudit = (connectionId: string) => {
return (input: {
organizationId: string;
frameworkId: string;
name?: string;
validFrom?: string;
validUntil?: string;
reportKey?: string;
@@ -165,6 +169,7 @@ export const useCreateAudit = (connectionId: string) => {
input: {
organizationId: input.organizationId,
frameworkId: input.frameworkId,
name: input.name,
validFrom: input.validFrom,
validUntil: input.validUntil,
reportKey: input.reportKey,
@@ -182,6 +187,7 @@ export const useUpdateAudit = () => {
return (input: {
id: string;
name?: string;
validFrom?: string;
validUntil?: string;
state?: string;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<fd92d4fe2e50fc37c5ae6eda9058f650>>
* @generated SignedSource<<a3c134dcea5981e6a45b623ec2905962>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -12,6 +12,7 @@ import { ConcreteRequest } from 'relay-runtime';
export type AuditState = "COMPLETED" | "IN_PROGRESS" | "NOT_STARTED" | "OUTDATED" | "REJECTED";
export type CreateAuditInput = {
frameworkId: string;
name?: string | null | undefined;
organizationId: string;
state?: AuditState | null | undefined;
validFrom?: any | null | undefined;
@@ -31,6 +32,7 @@ export type AuditGraphCreateMutation$data = {
readonly name: string;
};
readonly id: string;
readonly name: string | null | undefined;
readonly report: {
readonly filename: string;
readonly id: string;
@@ -73,6 +75,13 @@ v3 = {
"storageKey": null
},
v4 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
},
v5 = {
"alias": null,
"args": null,
"concreteType": "AuditEdge",
@@ -89,6 +98,7 @@ v4 = {
"plural": false,
"selections": [
(v3/*: any*/),
(v4/*: any*/),
{
"alias": null,
"args": null,
@@ -138,13 +148,7 @@ v4 = {
"plural": false,
"selections": [
(v3/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
}
(v4/*: any*/)
],
"storageKey": null
},
@@ -179,7 +183,7 @@ return {
"name": "createAudit",
"plural": false,
"selections": [
(v4/*: any*/)
(v5/*: any*/)
],
"storageKey": null
}
@@ -204,7 +208,7 @@ return {
"name": "createAudit",
"plural": false,
"selections": [
(v4/*: any*/),
(v5/*: any*/),
{
"alias": null,
"args": null,
@@ -227,16 +231,16 @@ return {
]
},
"params": {
"cacheID": "5c941d42e42700b5e06a5a64c861054b",
"cacheID": "04d44dfd419c2cde11b0138ca175203f",
"id": null,
"metadata": {},
"name": "AuditGraphCreateMutation",
"operationKind": "mutation",
"text": "mutation AuditGraphCreateMutation(\n $input: CreateAuditInput!\n) {\n createAudit(input: $input) {\n auditEdge {\n node {\n id\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\n }\n }\n }\n}\n"
"text": "mutation AuditGraphCreateMutation(\n $input: CreateAuditInput!\n) {\n createAudit(input: $input) {\n auditEdge {\n node {\n id\n name\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\n }\n }\n }\n}\n"
}
};
})();
(node as any).hash = "231fafa942acf107e2f0187bccc844da";
(node as any).hash = "4d014b16e02353df354085a151ccfe06";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<421ff1807db813d87849e15e60fc958e>>
* @generated SignedSource<<145565eb150c67f2f1b3c70fe6f6e748>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -58,7 +58,14 @@ v4 = [
"name": "first",
"value": 10
}
];
],
v5 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
};
return {
"fragment": {
"argumentDefinitions": (v0/*: any*/),
@@ -137,6 +144,7 @@ return {
"plural": false,
"selections": [
(v3/*: any*/),
(v5/*: any*/),
{
"alias": null,
"args": null,
@@ -186,13 +194,7 @@ return {
"plural": false,
"selections": [
(v3/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
}
(v5/*: any*/)
],
"storageKey": null
},
@@ -292,12 +294,12 @@ return {
]
},
"params": {
"cacheID": "1c53759e5b25eb390345fee12e536896",
"cacheID": "d96d2332efb5f43e2dcb09669173ad7e",
"id": null,
"metadata": {},
"name": "AuditGraphListQuery",
"operationKind": "query",
"text": "query AuditGraphListQuery(\n $organizationId: ID!\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n ...AuditsPageFragment\n }\n id\n }\n}\n\nfragment AuditsPageFragment on Organization {\n audits(first: 10) {\n edges {\n node {\n id\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
"text": "query AuditGraphListQuery(\n $organizationId: ID!\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n ...AuditsPageFragment\n }\n id\n }\n}\n\nfragment AuditsPageFragment on Organization {\n audits(first: 10) {\n edges {\n node {\n id\n name\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\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<<597dc89a18faf5837517c12ab6046991>>
* @generated SignedSource<<fc4103e0e8b03c1b6b8ea07c4adcf095>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -21,6 +21,7 @@ export type AuditGraphNodeQuery$data = {
readonly name: string;
};
readonly id?: string;
readonly name?: string | null | undefined;
readonly organization?: {
readonly id: string;
readonly name: string;
@@ -71,24 +72,31 @@ v3 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "validFrom",
"name": "name",
"storageKey": null
},
v4 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "validUntil",
"name": "validFrom",
"storageKey": null
},
v5 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "createdAt",
"name": "validUntil",
"storageKey": null
},
v6 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "createdAt",
"storageKey": null
},
v7 = {
"alias": null,
"args": null,
"concreteType": "Report",
@@ -125,55 +133,49 @@ v6 = {
"name": "downloadUrl",
"storageKey": null
},
(v5/*: any*/)
(v6/*: any*/)
],
"storageKey": null
},
v7 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "reportUrl",
"storageKey": null
},
v8 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "reportUrl",
"storageKey": null
},
v9 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "state",
"storageKey": null
},
v9 = [
v10 = [
(v2/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
}
(v3/*: any*/)
],
v10 = {
v11 = {
"alias": null,
"args": null,
"concreteType": "Framework",
"kind": "LinkedField",
"name": "framework",
"plural": false,
"selections": (v9/*: any*/),
"selections": (v10/*: any*/),
"storageKey": null
},
v11 = {
v12 = {
"alias": null,
"args": null,
"concreteType": "Organization",
"kind": "LinkedField",
"name": "organization",
"plural": false,
"selections": (v9/*: any*/),
"selections": (v10/*: any*/),
"storageKey": null
},
v12 = {
v13 = {
"alias": null,
"args": null,
"kind": "ScalarField",
@@ -201,13 +203,14 @@ return {
(v2/*: any*/),
(v3/*: any*/),
(v4/*: any*/),
(v6/*: any*/),
(v5/*: any*/),
(v7/*: any*/),
(v8/*: any*/),
(v10/*: any*/),
(v9/*: any*/),
(v11/*: any*/),
(v5/*: any*/),
(v12/*: any*/)
(v12/*: any*/),
(v6/*: any*/),
(v13/*: any*/)
],
"type": "Audit",
"abstractKey": null
@@ -246,13 +249,14 @@ return {
"selections": [
(v3/*: any*/),
(v4/*: any*/),
(v6/*: any*/),
(v5/*: any*/),
(v7/*: any*/),
(v8/*: any*/),
(v10/*: any*/),
(v9/*: any*/),
(v11/*: any*/),
(v5/*: any*/),
(v12/*: any*/)
(v12/*: any*/),
(v6/*: any*/),
(v13/*: any*/)
],
"type": "Audit",
"abstractKey": null
@@ -263,16 +267,16 @@ return {
]
},
"params": {
"cacheID": "8cab4d1083ea5990e42dbec0b435b7bd",
"cacheID": "eede00ab53ccd396e92b7fe6c1f1c2a2",
"id": null,
"metadata": {},
"name": "AuditGraphNodeQuery",
"operationKind": "query",
"text": "query AuditGraphNodeQuery(\n $auditId: ID!\n) {\n node(id: $auditId) {\n __typename\n ... on Audit {\n id\n validFrom\n validUntil\n report {\n id\n filename\n mimeType\n size\n downloadUrl\n createdAt\n }\n reportUrl\n state\n framework {\n id\n name\n }\n organization {\n id\n name\n }\n createdAt\n updatedAt\n }\n id\n }\n}\n"
"text": "query AuditGraphNodeQuery(\n $auditId: ID!\n) {\n node(id: $auditId) {\n __typename\n ... on Audit {\n id\n name\n validFrom\n validUntil\n report {\n id\n filename\n mimeType\n size\n downloadUrl\n createdAt\n }\n reportUrl\n state\n framework {\n id\n name\n }\n organization {\n id\n name\n }\n createdAt\n updatedAt\n }\n id\n }\n}\n"
}
};
})();
(node as any).hash = "3263f3b8f244acf3c982464daa078f7b";
(node as any).hash = "c07896ae39a7d16b42c7ee4216dc28fa";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<d2c542541d5bfda5464af2b34ccae603>>
* @generated SignedSource<<4255866a0c7fe3c9c3416fe2603b5f63>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -12,6 +12,7 @@ import { ConcreteRequest } from 'relay-runtime';
export type AuditState = "COMPLETED" | "IN_PROGRESS" | "NOT_STARTED" | "OUTDATED" | "REJECTED";
export type UpdateAuditInput = {
id: string;
name?: string | null | undefined;
showOnTrustCenter?: boolean | null | undefined;
state?: AuditState | null | undefined;
validFrom?: any | null | undefined;
@@ -28,6 +29,7 @@ export type AuditGraphUpdateMutation$data = {
readonly name: string;
};
readonly id: string;
readonly name: string | null | undefined;
readonly report: {
readonly filename: string;
readonly id: string;
@@ -59,7 +61,14 @@ v1 = {
"name": "id",
"storageKey": null
},
v2 = [
v2 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
},
v3 = [
{
"alias": null,
"args": [
@@ -83,6 +92,7 @@ v2 = [
"plural": false,
"selections": [
(v1/*: any*/),
(v2/*: any*/),
{
"alias": null,
"args": null,
@@ -132,13 +142,7 @@ v2 = [
"plural": false,
"selections": [
(v1/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
}
(v2/*: any*/)
],
"storageKey": null
},
@@ -162,7 +166,7 @@ return {
"kind": "Fragment",
"metadata": null,
"name": "AuditGraphUpdateMutation",
"selections": (v2/*: any*/),
"selections": (v3/*: any*/),
"type": "Mutation",
"abstractKey": null
},
@@ -171,19 +175,19 @@ return {
"argumentDefinitions": (v0/*: any*/),
"kind": "Operation",
"name": "AuditGraphUpdateMutation",
"selections": (v2/*: any*/)
"selections": (v3/*: any*/)
},
"params": {
"cacheID": "afd98ba771c6c437c46c275655333eb6",
"cacheID": "7257cd170b7441f3ce85966556e00ac3",
"id": null,
"metadata": {},
"name": "AuditGraphUpdateMutation",
"operationKind": "mutation",
"text": "mutation AuditGraphUpdateMutation(\n $input: UpdateAuditInput!\n) {\n updateAudit(input: $input) {\n audit {\n id\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n updatedAt\n }\n }\n}\n"
"text": "mutation AuditGraphUpdateMutation(\n $input: UpdateAuditInput!\n) {\n updateAudit(input: $input) {\n audit {\n id\n name\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n updatedAt\n }\n }\n}\n"
}
};
})();
(node as any).hash = "3ddd17832768611675505d76da1839a1";
(node as any).hash = "7fb5d28c8c5fdffddb1c8926e66965ec";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<2a5e6cd48ca8a8fd7fe448c3a6190ccc>>
* @generated SignedSource<<5773d0630d11596682d41b4df95716c3>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -13,6 +13,7 @@ import { FragmentRefs } from "relay-runtime";
export type AuditState = "COMPLETED" | "IN_PROGRESS" | "NOT_STARTED" | "OUTDATED" | "REJECTED";
export type UpdateAuditInput = {
id: string;
name?: string | null | undefined;
showOnTrustCenter?: boolean | null | undefined;
state?: AuditState | null | undefined;
validFrom?: any | null | undefined;
@@ -63,6 +64,13 @@ v3 = {
"kind": "ScalarField",
"name": "showOnTrustCenter",
"storageKey": null
},
v4 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
};
return {
"fragment": {
@@ -128,6 +136,7 @@ return {
"selections": [
(v2/*: any*/),
(v3/*: any*/),
(v4/*: any*/),
{
"alias": null,
"args": null,
@@ -136,13 +145,7 @@ return {
"name": "framework",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
},
(v4/*: any*/),
(v2/*: any*/)
],
"storageKey": null
@@ -184,12 +187,12 @@ return {
]
},
"params": {
"cacheID": "9cb78f25506e1a67b5f29d4f742f8773",
"cacheID": "d27b79a065314a22dbcbd8216de1268b",
"id": null,
"metadata": {},
"name": "TrustCenterAuditGraphUpdateMutation",
"operationKind": "mutation",
"text": "mutation TrustCenterAuditGraphUpdateMutation(\n $input: UpdateAuditInput!\n) {\n updateAudit(input: $input) {\n audit {\n id\n showOnTrustCenter\n ...TrustCenterAuditsCardFragment\n }\n }\n}\n\nfragment TrustCenterAuditsCardFragment on Audit {\n id\n framework {\n name\n id\n }\n validFrom\n validUntil\n state\n showOnTrustCenter\n createdAt\n}\n"
"text": "mutation TrustCenterAuditGraphUpdateMutation(\n $input: UpdateAuditInput!\n) {\n updateAudit(input: $input) {\n audit {\n id\n showOnTrustCenter\n ...TrustCenterAuditsCardFragment\n }\n }\n}\n\nfragment TrustCenterAuditsCardFragment on Audit {\n id\n name\n framework {\n name\n id\n }\n validFrom\n validUntil\n state\n showOnTrustCenter\n createdAt\n}\n"
}
};
})();

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<46a922efef96e5c7d015bd0f27467bf3>>
* @generated SignedSource<<25550a93c5459c3b405c782be19ac888>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -437,6 +437,7 @@ return {
"plural": false,
"selections": [
(v2/*: any*/),
(v3/*: any*/),
{
"alias": null,
"args": null,
@@ -543,12 +544,12 @@ return {
]
},
"params": {
"cacheID": "a22d734ee326d24f3f67ffecf4653b2f",
"cacheID": "28c1a32327e2fee9320fd091100ec800",
"id": null,
"metadata": {},
"name": "TrustCenterGraphQuery",
"operationKind": "query",
"text": "query TrustCenterGraphQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n name\n trustCenter {\n id\n active\n slug\n createdAt\n updatedAt\n }\n documents(first: 100) {\n edges {\n node {\n id\n ...TrustCenterDocumentsCardFragment\n }\n }\n }\n audits(first: 100) {\n edges {\n node {\n id\n ...TrustCenterAuditsCardFragment\n }\n }\n }\n vendors(first: 100) {\n edges {\n node {\n id\n ...TrustCenterVendorsCardFragment\n }\n }\n }\n }\n id\n }\n}\n\nfragment TrustCenterAuditsCardFragment on Audit {\n id\n framework {\n name\n id\n }\n validFrom\n validUntil\n state\n showOnTrustCenter\n createdAt\n}\n\nfragment TrustCenterDocumentsCardFragment on Document {\n id\n title\n createdAt\n documentType\n showOnTrustCenter\n versions(first: 1) {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n\nfragment TrustCenterVendorsCardFragment on Vendor {\n id\n name\n category\n description\n showOnTrustCenter\n createdAt\n}\n"
"text": "query TrustCenterGraphQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n name\n trustCenter {\n id\n active\n slug\n createdAt\n updatedAt\n }\n documents(first: 100) {\n edges {\n node {\n id\n ...TrustCenterDocumentsCardFragment\n }\n }\n }\n audits(first: 100) {\n edges {\n node {\n id\n ...TrustCenterAuditsCardFragment\n }\n }\n }\n vendors(first: 100) {\n edges {\n node {\n id\n ...TrustCenterVendorsCardFragment\n }\n }\n }\n }\n id\n }\n}\n\nfragment TrustCenterAuditsCardFragment on Audit {\n id\n name\n framework {\n name\n id\n }\n validFrom\n validUntil\n state\n showOnTrustCenter\n createdAt\n}\n\nfragment TrustCenterDocumentsCardFragment on Document {\n id\n title\n createdAt\n documentType\n showOnTrustCenter\n versions(first: 1) {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n\nfragment TrustCenterVendorsCardFragment on Vendor {\n id\n name\n category\n description\n showOnTrustCenter\n createdAt\n}\n"
}
};
})();

View File

@@ -35,6 +35,7 @@ import { getAuditStateLabel, getAuditStateVariant, auditStates, fileSize, sprint
import type { AuditGraphNodeQuery } from "/hooks/graph/__generated__/AuditGraphNodeQuery.graphql";
const updateAuditSchema = z.object({
name: z.string().optional(),
validFrom: z.string().optional(),
validUntil: z.string().optional(),
state: z.enum(["NOT_STARTED", "IN_PROGRESS", "COMPLETED", "REJECTED", "OUTDATED"]),
@@ -61,6 +62,7 @@ export default function AuditDetailsPage(props: Props) {
const { control, formState, handleSubmit, register, reset } = useFormWithSchema(updateAuditSchema, {
defaultValues: {
name: auditEntry.name || "",
validFrom: auditEntry.validFrom?.split('T')[0] || "",
validUntil: auditEntry.validUntil?.split('T')[0] || "",
state: auditEntry.state || "NOT_STARTED",
@@ -79,6 +81,7 @@ export default function AuditDetailsPage(props: Props) {
try {
await updateAudit({
id: auditEntry.id,
name: formData.name,
validFrom: formatDatetime(formData.validFrom),
validUntil: formatDatetime(formData.validUntil),
state: formData.state,
@@ -125,7 +128,7 @@ export default function AuditDetailsPage(props: Props) {
to: `/organizations/${organizationId}/audits`,
},
{
label: auditEntry.framework?.name ?? __("Unknown Audit"),
label: (auditEntry.name || auditEntry.framework?.name) ?? __("Unknown Audit"),
},
]}
/>
@@ -150,6 +153,10 @@ export default function AuditDetailsPage(props: Props) {
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<form onSubmit={onSubmit} className="space-y-6">
<Field label={__("Name")}>
<Input {...register("name")} placeholder={__("Audit name")} />
</Field>
<ControlledField
control={control}
name="state"

View File

@@ -53,6 +53,7 @@ const paginatedAuditsFragment = graphql`
edges {
node {
id
name
validFrom
validUntil
report {
@@ -103,12 +104,13 @@ export default function AuditsPage(props: Props) {
connection={connectionId}
organizationId={organizationId}
>
<Button icon={IconPlusLarge}>{__("Add audit")}</Button>
<Button icon={IconPlusLarge}>{__("Add audit")}</Button>
</CreateAuditDialog>
</PageHeader>
<SortableTable {...pagination}>
<Thead>
<Tr>
<Th>{__("Name")}</Th>
<Th>{__("Framework")}</Th>
<Th>{__("State")}</Th>
<Th>{__("Valid From")}</Th>
@@ -144,6 +146,7 @@ function AuditRow({
return (
<Tr to={`/organizations/${organizationId}/audits/${entry.id}`}>
<Td>{entry.name || __("Untitled")}</Td>
<Td>{entry.framework?.name ?? __("Unknown Framework")}</Td>
<Td>
<Badge variant={getAuditStateVariant(entry.state)}>

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<273ddcd519e40c3d2af76944a1f93191>>
* @generated SignedSource<<0010416e8a5bda346d415bd80fd70dc8>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -112,6 +112,13 @@ v9 = {
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
v10 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
};
return {
"fragment": {
@@ -198,6 +205,7 @@ return {
"plural": false,
"selections": [
(v9/*: any*/),
(v10/*: any*/),
{
"alias": null,
"args": null,
@@ -247,13 +255,7 @@ return {
"plural": false,
"selections": [
(v9/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
}
(v10/*: any*/)
],
"storageKey": null
},
@@ -353,16 +355,16 @@ return {
]
},
"params": {
"cacheID": "120524c1493bac68d36318259531f84e",
"cacheID": "9d185e504f8c34d5c3fd7211d4e8a2a2",
"id": null,
"metadata": {},
"name": "AuditsListQuery",
"operationKind": "query",
"text": "query AuditsListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 10\n $last: Int = null\n $orderBy: AuditOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...AuditsPageFragment_sdb03\n id\n }\n}\n\nfragment AuditsPageFragment_sdb03 on Organization {\n audits(first: $first, after: $after, last: $last, before: $before, orderBy: $orderBy) {\n edges {\n node {\n id\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n"
"text": "query AuditsListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 10\n $last: Int = null\n $orderBy: AuditOrder = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...AuditsPageFragment_sdb03\n id\n }\n}\n\nfragment AuditsPageFragment_sdb03 on Organization {\n audits(first: $first, after: $after, last: $last, before: $before, orderBy: $orderBy) {\n edges {\n node {\n id\n name\n validFrom\n validUntil\n report {\n id\n filename\n }\n state\n framework {\n id\n name\n }\n createdAt\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 = "ef15955eb51e30372c935dcc7dcd5099";
(node as any).hash = "be8d1f1d8015c16539886bc79c8026f7";
export default node;

View File

@@ -1,5 +1,5 @@
/**
* @generated SignedSource<<168c07116a618dbd9663e4072ec04139>>
* @generated SignedSource<<8c09163f7cf7b3953aed77791b0d3dd1>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -22,6 +22,7 @@ export type AuditsPageFragment$data = {
readonly name: string;
};
readonly id: string;
readonly name: string | null | undefined;
readonly report: {
readonly filename: string;
readonly id: string;
@@ -52,6 +53,13 @@ v1 = {
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
v2 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
};
return {
"argumentDefinitions": [
@@ -146,6 +154,7 @@ return {
"plural": false,
"selections": [
(v1/*: any*/),
(v2/*: any*/),
{
"alias": null,
"args": null,
@@ -195,13 +204,7 @@ return {
"plural": false,
"selections": [
(v1/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
}
(v2/*: any*/)
],
"storageKey": null
},
@@ -293,6 +296,6 @@ return {
};
})();
(node as any).hash = "ef15955eb51e30372c935dcc7dcd5099";
(node as any).hash = "be8d1f1d8015c16539886bc79c8026f7";
export default node;

View File

@@ -42,6 +42,7 @@ const frameworksQuery = graphql`
const schema = z.object({
frameworkId: z.string().min(1, "Framework is required"),
name: z.string().optional(),
validFrom: z.string().optional(),
validUntil: z.string().optional(),
state: z.enum(["NOT_STARTED", "IN_PROGRESS", "COMPLETED", "REJECTED", "OUTDATED"]),
@@ -64,6 +65,7 @@ export function CreateAuditDialog({
useFormWithSchema(schema, {
defaultValues: {
frameworkId: "",
name: "",
validFrom: "",
validUntil: "",
state: "NOT_STARTED",
@@ -77,6 +79,7 @@ export function CreateAuditDialog({
await createAudit({
organizationId,
frameworkId: data.frameworkId,
name: data.name,
validFrom: formatDatetime(data.validFrom),
validUntil: formatDatetime(data.validUntil),
state: data.state,
@@ -115,6 +118,10 @@ export function CreateAuditDialog({
</Suspense>
</Field>
<Field label={__("Name")}>
<Input {...register("name")} placeholder={__("Audit name")} />
</Field>
<ControlledField
control={control}
name="state"

View File

@@ -29,6 +29,7 @@ import (
type (
Audit struct {
ID gid.GID `db:"id"`
Name *string `db:"name"`
OrganizationID gid.GID `db:"organization_id"`
FrameworkID gid.GID `db:"framework_id"`
ReportID *gid.GID `db:"report_id"`
@@ -67,6 +68,7 @@ func (a *Audit) LoadByID(
q := `
SELECT
id,
name,
organization_id,
framework_id,
report_id,
@@ -147,6 +149,7 @@ func (a *Audits) LoadByOrganizationID(
q := `
SELECT
id,
name,
organization_id,
framework_id,
report_id,
@@ -195,6 +198,7 @@ func (a *Audit) Insert(
q := `
INSERT INTO audits (
id,
name,
tenant_id,
organization_id,
framework_id,
@@ -207,6 +211,7 @@ INSERT INTO audits (
updated_at
) VALUES (
@id,
@name,
@tenant_id,
@organization_id,
@framework_id,
@@ -222,6 +227,7 @@ INSERT INTO audits (
args := pgx.StrictNamedArgs{
"id": a.ID,
"name": a.Name,
"tenant_id": scope.GetTenantID(),
"organization_id": a.OrganizationID,
"framework_id": a.FrameworkID,
@@ -250,6 +256,7 @@ func (a *Audit) Update(
q := `
UPDATE audits
SET
name = @name,
report_id = @report_id,
valid_from = @valid_from,
valid_until = @valid_until,
@@ -265,6 +272,7 @@ WHERE
args := pgx.StrictNamedArgs{
"id": a.ID,
"name": a.Name,
"report_id": a.ReportID,
"valid_from": a.ValidFrom,
"valid_until": a.ValidUntil,

View File

@@ -0,0 +1 @@
ALTER TABLE audits ADD COLUMN name TEXT;

View File

@@ -33,6 +33,7 @@ type (
CreateAuditRequest struct {
OrganizationID gid.GID
FrameworkID gid.GID
Name *string
ValidFrom *time.Time
ValidUntil *time.Time
State *coredata.AuditState
@@ -40,6 +41,7 @@ type (
UpdateAuditRequest struct {
ID gid.GID
Name **string
ValidFrom *time.Time
ValidUntil *time.Time
State *coredata.AuditState
@@ -89,6 +91,7 @@ func (s *AuditService) Create(
audit := &coredata.Audit{
ID: gid.New(s.svc.scope.GetTenantID(), coredata.AuditEntityType),
Name: req.Name,
OrganizationID: req.OrganizationID,
FrameworkID: req.FrameworkID,
ValidFrom: req.ValidFrom,
@@ -144,6 +147,9 @@ func (s *AuditService) Update(
return fmt.Errorf("cannot load audit: %w", err)
}
if req.Name != nil {
audit.Name = *req.Name
}
if req.ValidFrom != nil {
audit.ValidFrom = req.ValidFrom
}

View File

@@ -1249,6 +1249,7 @@ type Risk implements Node {
type Audit implements Node {
id: ID!
name: String
organization: Organization! @goField(forceResolver: true)
framework: Framework! @goField(forceResolver: true)
validFrom: Datetime
@@ -2180,6 +2181,7 @@ input DeleteControlInput {
input CreateAuditInput {
organizationId: ID!
frameworkId: ID!
name: String
validFrom: Datetime
validUntil: Datetime
state: AuditState
@@ -2187,6 +2189,7 @@ input CreateAuditInput {
input UpdateAuditInput {
id: ID!
name: String
validFrom: Datetime
validUntil: Datetime
state: AuditState

View File

@@ -124,6 +124,7 @@ type ComplexityRoot struct {
CreatedAt func(childComplexity int) int
Framework func(childComplexity int) int
ID func(childComplexity int) int
Name func(childComplexity int) int
Organization func(childComplexity int) int
Report func(childComplexity int) int
ReportURL func(childComplexity int) int
@@ -1575,6 +1576,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.Audit.ID(childComplexity), true
case "Audit.name":
if e.complexity.Audit.Name == nil {
break
}
return e.complexity.Audit.Name(childComplexity), true
case "Audit.organization":
if e.complexity.Audit.Organization == nil {
break
@@ -7472,6 +7480,7 @@ type Risk implements Node {
type Audit implements Node {
id: ID!
name: String
organization: Organization! @goField(forceResolver: true)
framework: Framework! @goField(forceResolver: true)
validFrom: Datetime
@@ -8403,6 +8412,7 @@ input DeleteControlInput {
input CreateAuditInput {
organizationId: ID!
frameworkId: ID!
name: String
validFrom: Datetime
validUntil: Datetime
state: AuditState
@@ -8410,6 +8420,7 @@ input CreateAuditInput {
input UpdateAuditInput {
id: ID!
name: String
validFrom: Datetime
validUntil: Datetime
state: AuditState
@@ -15896,6 +15907,47 @@ func (ec *executionContext) fieldContext_Audit_id(_ context.Context, field graph
return fc, nil
}
func (ec *executionContext) _Audit_name(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Audit_name(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Name, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Audit_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Audit",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Audit_organization(ctx context.Context, field graphql.CollectedField, obj *types.Audit) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Audit_organization(ctx, field)
if err != nil {
@@ -16631,6 +16683,8 @@ func (ec *executionContext) fieldContext_AuditEdge_node(_ context.Context, field
switch field.Name {
case "id":
return ec.fieldContext_Audit_id(ctx, field)
case "name":
return ec.fieldContext_Audit_name(ctx, field)
case "organization":
return ec.fieldContext_Audit_organization(ctx, field)
case "framework":
@@ -20231,6 +20285,8 @@ func (ec *executionContext) fieldContext_DeleteAuditReportPayload_audit(_ contex
switch field.Name {
case "id":
return ec.fieldContext_Audit_id(ctx, field)
case "name":
return ec.fieldContext_Audit_name(ctx, field)
case "organization":
return ec.fieldContext_Audit_organization(ctx, field)
case "framework":
@@ -38064,6 +38120,8 @@ func (ec *executionContext) fieldContext_UpdateAuditPayload_audit(_ context.Cont
switch field.Name {
case "id":
return ec.fieldContext_Audit_id(ctx, field)
case "name":
return ec.fieldContext_Audit_name(ctx, field)
case "organization":
return ec.fieldContext_Audit_organization(ctx, field)
case "framework":
@@ -39188,6 +39246,8 @@ func (ec *executionContext) fieldContext_UploadAuditReportPayload_audit(_ contex
switch field.Name {
case "id":
return ec.fieldContext_Audit_id(ctx, field)
case "name":
return ec.fieldContext_Audit_name(ctx, field)
case "organization":
return ec.fieldContext_Audit_organization(ctx, field)
case "framework":
@@ -47095,7 +47155,7 @@ func (ec *executionContext) unmarshalInputCreateAuditInput(ctx context.Context,
asMap[k] = v
}
fieldsInOrder := [...]string{"organizationId", "frameworkId", "validFrom", "validUntil", "state"}
fieldsInOrder := [...]string{"organizationId", "frameworkId", "name", "validFrom", "validUntil", "state"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
@@ -47116,6 +47176,13 @@ func (ec *executionContext) unmarshalInputCreateAuditInput(ctx context.Context,
return it, err
}
it.FrameworkID = data
case "name":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name"))
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
it.Name = data
case "validFrom":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("validFrom"))
data, err := ec.unmarshalODatetime2ᚖtimeᚐTime(ctx, v)
@@ -50007,7 +50074,7 @@ func (ec *executionContext) unmarshalInputUpdateAuditInput(ctx context.Context,
asMap[k] = v
}
fieldsInOrder := [...]string{"id", "validFrom", "validUntil", "state", "showOnTrustCenter"}
fieldsInOrder := [...]string{"id", "name", "validFrom", "validUntil", "state", "showOnTrustCenter"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
@@ -50021,6 +50088,13 @@ func (ec *executionContext) unmarshalInputUpdateAuditInput(ctx context.Context,
return it, err
}
it.ID = data
case "name":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name"))
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
it.Name = data
case "validFrom":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("validFrom"))
data, err := ec.unmarshalODatetime2ᚖtimeᚐTime(ctx, v)
@@ -52045,6 +52119,8 @@ func (ec *executionContext) _Audit(ctx context.Context, sel ast.SelectionSet, ob
if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1)
}
case "name":
out.Values[i] = ec._Audit_name(ctx, field, obj)
case "organization":
field := field

View File

@@ -58,6 +58,7 @@ func NewAudit(a *coredata.Audit) *Audit {
ValidFrom: a.ValidFrom,
ValidUntil: a.ValidUntil,
State: a.State,
Name: a.Name,
ShowOnTrustCenter: a.ShowOnTrustCenter,
CreatedAt: a.CreatedAt,
UpdatedAt: a.UpdatedAt,

View File

@@ -58,6 +58,7 @@ type AssignTaskPayload struct {
type Audit struct {
ID gid.GID `json:"id"`
Name *string `json:"name,omitempty"`
Organization *Organization `json:"organization"`
Framework *Framework `json:"framework"`
ValidFrom *time.Time `json:"validFrom,omitempty"`
@@ -183,6 +184,7 @@ type CreateAssetPayload struct {
type CreateAuditInput struct {
OrganizationID gid.GID `json:"organizationId"`
FrameworkID gid.GID `json:"frameworkId"`
Name *string `json:"name,omitempty"`
ValidFrom *time.Time `json:"validFrom,omitempty"`
ValidUntil *time.Time `json:"validUntil,omitempty"`
State *coredata.AuditState `json:"state,omitempty"`
@@ -1146,6 +1148,7 @@ type UpdateAssetPayload struct {
type UpdateAuditInput struct {
ID gid.GID `json:"id"`
Name *string `json:"name,omitempty"`
ValidFrom *time.Time `json:"validFrom,omitempty"`
ValidUntil *time.Time `json:"validUntil,omitempty"`
State *coredata.AuditState `json:"state,omitempty"`

View File

@@ -2537,6 +2537,7 @@ func (r *mutationResolver) CreateAudit(ctx context.Context, input types.CreateAu
req := probo.CreateAuditRequest{
OrganizationID: input.OrganizationID,
FrameworkID: input.FrameworkID,
Name: input.Name,
ValidFrom: input.ValidFrom,
ValidUntil: input.ValidUntil,
State: input.State,
@@ -2558,6 +2559,7 @@ func (r *mutationResolver) UpdateAudit(ctx context.Context, input types.UpdateAu
req := probo.UpdateAuditRequest{
ID: input.ID,
Name: &input.Name,
ValidFrom: input.ValidFrom,
ValidUntil: input.ValidUntil,
State: input.State,