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

@@ -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"