Replace console frontend with unified findings pages
Add FindingsPage, FindingDetailsPage, and CreateFindingDialog supporting all finding kinds (nonconformity, observation, exception) with filtering, sorting, and audit linking. Remove the separate nonconformity and continual improvement pages, routes, and graph hooks. Update sidebar navigation, routes, and components for nullable audit framework field. Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -121,7 +121,7 @@ export const deleteAuditMutation = graphql`
|
||||
`;
|
||||
|
||||
export const useDeleteAudit = (
|
||||
audit: { id: string; framework: { name: string } },
|
||||
audit: { id: string; framework?: { name: string } | null },
|
||||
connectionId: string,
|
||||
onSuccess?: () => void,
|
||||
) => {
|
||||
@@ -150,7 +150,7 @@ export const useDeleteAudit = (
|
||||
__(
|
||||
"This will permanently delete the audit for %s. This action cannot be undone.",
|
||||
),
|
||||
audit.framework.name,
|
||||
audit.framework?.name ?? "",
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,232 +0,0 @@
|
||||
import { promisifyMutation, sprintf } from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { useConfirm } from "@probo/ui";
|
||||
import { useMutation } from "react-relay";
|
||||
import { graphql } from "relay-runtime";
|
||||
|
||||
import { useMutationWithToasts } from "../useMutationWithToasts";
|
||||
|
||||
/* eslint-disable relay/unused-fields, relay/must-colocate-fragment-spreads */
|
||||
|
||||
export const ContinualImprovementsConnectionKey
|
||||
= "ContinualImprovementsPage_continualImprovements";
|
||||
|
||||
export const continualImprovementsQuery = graphql`
|
||||
query ContinualImprovementGraphListQuery(
|
||||
$organizationId: ID!
|
||||
$snapshotId: ID
|
||||
) {
|
||||
node(id: $organizationId) {
|
||||
... on Organization {
|
||||
canCreateContinualImprovement: permission(
|
||||
action: "core:continual-improvement:create"
|
||||
)
|
||||
...ContinualImprovementsPageFragment @arguments(snapshotId: $snapshotId)
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const continualImprovementNodeQuery = graphql`
|
||||
query ContinualImprovementGraphNodeQuery($continualImprovementId: ID!) {
|
||||
node(id: $continualImprovementId) {
|
||||
... on ContinualImprovement {
|
||||
id
|
||||
snapshotId
|
||||
sourceId
|
||||
referenceId
|
||||
description
|
||||
source
|
||||
targetDate
|
||||
status
|
||||
priority
|
||||
owner {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
organization {
|
||||
id
|
||||
name
|
||||
}
|
||||
createdAt
|
||||
updatedAt
|
||||
canUpdate: permission(action: "core:continual-improvement:update")
|
||||
canDelete: permission(action: "core:continual-improvement:delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const createContinualImprovementMutation = graphql`
|
||||
mutation ContinualImprovementGraphCreateMutation(
|
||||
$input: CreateContinualImprovementInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
createContinualImprovement(input: $input) {
|
||||
continualImprovementEdge @prependEdge(connections: $connections) {
|
||||
node {
|
||||
id
|
||||
referenceId
|
||||
description
|
||||
source
|
||||
targetDate
|
||||
status
|
||||
priority
|
||||
owner {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
createdAt
|
||||
canUpdate: permission(action: "core:continual-improvement:update")
|
||||
canDelete: permission(action: "core:continual-improvement:delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const updateContinualImprovementMutation = graphql`
|
||||
mutation ContinualImprovementGraphUpdateMutation(
|
||||
$input: UpdateContinualImprovementInput!
|
||||
) {
|
||||
updateContinualImprovement(input: $input) {
|
||||
continualImprovement {
|
||||
id
|
||||
referenceId
|
||||
description
|
||||
source
|
||||
targetDate
|
||||
status
|
||||
priority
|
||||
owner {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const deleteContinualImprovementMutation = graphql`
|
||||
mutation ContinualImprovementGraphDeleteMutation(
|
||||
$input: DeleteContinualImprovementInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
deleteContinualImprovement(input: $input) {
|
||||
deletedContinualImprovementId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const useDeleteContinualImprovement = (
|
||||
improvement: { id: string; referenceId: string },
|
||||
connectionId: string,
|
||||
) => {
|
||||
const { __ } = useTranslate();
|
||||
const [mutate] = useMutationWithToasts(deleteContinualImprovementMutation, {
|
||||
successMessage: __("Continual improvement deleted successfully"),
|
||||
errorMessage: __("Failed to delete continual improvement"),
|
||||
});
|
||||
const confirm = useConfirm();
|
||||
|
||||
return () => {
|
||||
confirm(
|
||||
() =>
|
||||
mutate({
|
||||
variables: {
|
||||
input: {
|
||||
continualImprovementId: improvement.id,
|
||||
},
|
||||
connections: [connectionId],
|
||||
},
|
||||
}),
|
||||
{
|
||||
message: sprintf(
|
||||
__(
|
||||
"This will permanently delete the continual improvement %s. This action cannot be undone.",
|
||||
),
|
||||
improvement.referenceId,
|
||||
),
|
||||
},
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export const useCreateContinualImprovement = (connectionId: string) => {
|
||||
// eslint-disable-next-line relay/generated-typescript-types
|
||||
const [mutate] = useMutation(createContinualImprovementMutation);
|
||||
const { __ } = useTranslate();
|
||||
|
||||
return (input: {
|
||||
organizationId: string;
|
||||
referenceId: string;
|
||||
description?: string;
|
||||
source?: string;
|
||||
ownerId: string;
|
||||
targetDate?: string;
|
||||
status: string;
|
||||
priority: string;
|
||||
}) => {
|
||||
if (!input.organizationId) {
|
||||
return alert(
|
||||
__("Failed to create continual improvement: organization is required"),
|
||||
);
|
||||
}
|
||||
if (!input.referenceId) {
|
||||
return alert(
|
||||
__("Failed to create continual improvement: reference ID is required"),
|
||||
);
|
||||
}
|
||||
if (!input.ownerId) {
|
||||
return alert(
|
||||
__("Failed to create continual improvement: owner is required"),
|
||||
);
|
||||
}
|
||||
|
||||
return promisifyMutation(mutate)({
|
||||
variables: {
|
||||
input: {
|
||||
organizationId: input.organizationId,
|
||||
referenceId: input.referenceId,
|
||||
description: input.description,
|
||||
source: input.source,
|
||||
ownerId: input.ownerId,
|
||||
targetDate: input.targetDate,
|
||||
status: input.status || "OPEN",
|
||||
priority: input.priority || "MEDIUM",
|
||||
},
|
||||
connections: [connectionId],
|
||||
},
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export const useUpdateContinualImprovement = () => {
|
||||
// eslint-disable-next-line relay/generated-typescript-types
|
||||
const [mutate] = useMutation(updateContinualImprovementMutation);
|
||||
const { __ } = useTranslate();
|
||||
|
||||
return (input: {
|
||||
id: string;
|
||||
referenceId?: string;
|
||||
description?: string;
|
||||
source?: string;
|
||||
ownerId?: string;
|
||||
targetDate?: string | null;
|
||||
status?: string;
|
||||
priority?: string;
|
||||
}) => {
|
||||
if (!input.id) {
|
||||
return alert(
|
||||
__("Failed to update continual improvement: ID is required"),
|
||||
);
|
||||
}
|
||||
|
||||
return promisifyMutation(mutate)({
|
||||
variables: {
|
||||
input,
|
||||
},
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -1,261 +0,0 @@
|
||||
import { promisifyMutation, sprintf } from "@probo/helpers";
|
||||
import { useTranslate } from "@probo/i18n";
|
||||
import { useConfirm } from "@probo/ui";
|
||||
import { useMutation } from "react-relay";
|
||||
import { graphql } from "relay-runtime";
|
||||
|
||||
import { useMutationWithToasts } from "../useMutationWithToasts";
|
||||
|
||||
/* eslint-disable relay/unused-fields, relay/must-colocate-fragment-spreads */
|
||||
|
||||
export const NonconformitiesConnectionKey
|
||||
= "NonconformitiesPage_nonconformities";
|
||||
|
||||
export const nonconformitiesQuery = graphql`
|
||||
query NonconformityGraphListQuery($organizationId: ID!, $snapshotId: ID) {
|
||||
node(id: $organizationId) {
|
||||
... on Organization {
|
||||
canCreateNonconformity: permission(action: "core:nonconformity:create")
|
||||
...NonconformitiesPageFragment @arguments(snapshotId: $snapshotId)
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const nonconformityNodeQuery = graphql`
|
||||
query NonconformityGraphNodeQuery($nonconformityId: ID!) {
|
||||
node(id: $nonconformityId) {
|
||||
... on Nonconformity {
|
||||
id
|
||||
snapshotId
|
||||
referenceId
|
||||
description
|
||||
dateIdentified
|
||||
rootCause
|
||||
correctiveAction
|
||||
dueDate
|
||||
status
|
||||
effectivenessCheck
|
||||
audit {
|
||||
id
|
||||
framework {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
owner {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
organization {
|
||||
id
|
||||
name
|
||||
}
|
||||
createdAt
|
||||
updatedAt
|
||||
canUpdate: permission(action: "core:nonconformity:update")
|
||||
canDelete: permission(action: "core:nonconformity:delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const createNonconformityMutation = graphql`
|
||||
mutation NonconformityGraphCreateMutation(
|
||||
$input: CreateNonconformityInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
createNonconformity(input: $input) {
|
||||
nonconformityEdge @prependEdge(connections: $connections) {
|
||||
node {
|
||||
id
|
||||
referenceId
|
||||
description
|
||||
status
|
||||
dateIdentified
|
||||
dueDate
|
||||
rootCause
|
||||
audit {
|
||||
id
|
||||
framework {
|
||||
name
|
||||
}
|
||||
}
|
||||
owner {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
createdAt
|
||||
canUpdate: permission(action: "core:nonconformity:update")
|
||||
canDelete: permission(action: "core:nonconformity:delete")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const updateNonconformityMutation = graphql`
|
||||
mutation NonconformityGraphUpdateMutation($input: UpdateNonconformityInput!) {
|
||||
updateNonconformity(input: $input) {
|
||||
nonconformity {
|
||||
id
|
||||
referenceId
|
||||
description
|
||||
dateIdentified
|
||||
rootCause
|
||||
correctiveAction
|
||||
dueDate
|
||||
status
|
||||
effectivenessCheck
|
||||
owner {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
audit {
|
||||
id
|
||||
framework {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const deleteNonconformityMutation = graphql`
|
||||
mutation NonconformityGraphDeleteMutation(
|
||||
$input: DeleteNonconformityInput!
|
||||
$connections: [ID!]!
|
||||
) {
|
||||
deleteNonconformity(input: $input) {
|
||||
deletedNonconformityId @deleteEdge(connections: $connections)
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const useDeleteNonconformity = (
|
||||
nonconformity: { id: string; referenceId: string },
|
||||
connectionId: string,
|
||||
) => {
|
||||
const { __ } = useTranslate();
|
||||
const [mutate] = useMutationWithToasts(deleteNonconformityMutation, {
|
||||
successMessage: __("Nonconformity deleted successfully"),
|
||||
errorMessage: __("Failed to delete nonconformity"),
|
||||
});
|
||||
const confirm = useConfirm();
|
||||
|
||||
return () => {
|
||||
confirm(
|
||||
() =>
|
||||
mutate({
|
||||
variables: {
|
||||
input: {
|
||||
nonconformityId: nonconformity.id,
|
||||
},
|
||||
connections: [connectionId],
|
||||
},
|
||||
}),
|
||||
{
|
||||
message: sprintf(
|
||||
__(
|
||||
"This will permanently delete the nonconformity %s. This action cannot be undone.",
|
||||
),
|
||||
nonconformity.referenceId,
|
||||
),
|
||||
},
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
export const useCreateNonconformity = (connectionId: string) => {
|
||||
// eslint-disable-next-line relay/generated-typescript-types
|
||||
const [mutate] = useMutation(createNonconformityMutation);
|
||||
const { __ } = useTranslate();
|
||||
|
||||
return (input: {
|
||||
organizationId: string;
|
||||
referenceId: string;
|
||||
description?: string;
|
||||
auditId?: string;
|
||||
dateIdentified?: string;
|
||||
rootCause: string;
|
||||
correctiveAction?: string;
|
||||
ownerId: string;
|
||||
dueDate?: string;
|
||||
status: string;
|
||||
effectivenessCheck?: string;
|
||||
}) => {
|
||||
if (!input.organizationId) {
|
||||
return alert(
|
||||
__("Failed to create nonconformity: organization is required"),
|
||||
);
|
||||
}
|
||||
if (!input.referenceId) {
|
||||
return alert(
|
||||
__("Failed to create nonconformity: reference ID is required"),
|
||||
);
|
||||
}
|
||||
if (!input.ownerId) {
|
||||
return alert(__("Failed to create nonconformity: owner is required"));
|
||||
}
|
||||
if (!input.rootCause) {
|
||||
return alert(
|
||||
__("Failed to create nonconformity: root cause is required"),
|
||||
);
|
||||
}
|
||||
|
||||
return promisifyMutation(mutate)({
|
||||
variables: {
|
||||
input: {
|
||||
organizationId: input.organizationId,
|
||||
referenceId: input.referenceId,
|
||||
description: input.description,
|
||||
auditId: input.auditId || undefined,
|
||||
dateIdentified: input.dateIdentified,
|
||||
rootCause: input.rootCause,
|
||||
correctiveAction: input.correctiveAction,
|
||||
ownerId: input.ownerId,
|
||||
dueDate: input.dueDate,
|
||||
status: input.status || "OPEN",
|
||||
effectivenessCheck: input.effectivenessCheck,
|
||||
},
|
||||
connections: [connectionId],
|
||||
},
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export const useUpdateNonconformity = () => {
|
||||
// eslint-disable-next-line relay/generated-typescript-types
|
||||
const [mutate] = useMutation(updateNonconformityMutation);
|
||||
const { __ } = useTranslate();
|
||||
|
||||
return (input: {
|
||||
id: string;
|
||||
referenceId?: string;
|
||||
description?: string;
|
||||
dateIdentified?: string | null;
|
||||
rootCause?: string;
|
||||
correctiveAction?: string;
|
||||
ownerId?: string;
|
||||
auditId?: string | null;
|
||||
dueDate?: string | null;
|
||||
status?: string;
|
||||
effectivenessCheck?: string;
|
||||
}) => {
|
||||
if (!input.id) {
|
||||
return alert(__("Failed to update nonconformity: ID is required"));
|
||||
}
|
||||
|
||||
return promisifyMutation(mutate)({
|
||||
variables: {
|
||||
input: {
|
||||
...input,
|
||||
auditId: input.auditId || null,
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user