Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1703 hard delete attachments feature #1843

Merged
merged 16 commits into from
Sep 8, 2023
Merged
48 changes: 27 additions & 21 deletions app/components/Attachment/AttachmentTableRow.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
import { Button } from "@button-inc/bcgov-theme";
import useDiscardProjectAttachmentFormChange from "mutations/attachment/discardProjectAttachmentFormChange";
import Link from "next/link";
import { getAttachmentDownloadRoute } from "routes/pageRoutes";
import { graphql, useFragment } from "react-relay";
import useDiscardProjectAttachmentFormChange from "mutations/attachment/discardProjectAttachmentFormChange";
import { getAttachmentDownloadRoute } from "routes/pageRoutes";
import { AttachmentTableRow_attachment$key } from "__generated__/AttachmentTableRow_attachment.graphql";
import hardDeleteAttachment from "./hardDeleteAttachment";
import { useRouter } from "next/router";

interface Props {
attachment: AttachmentTableRow_attachment$key;
connectionId: string;
formChangeRowId: number;
hideDelete?: boolean;
isFirstRevision: boolean;
}

const AttachmentTableRow: React.FC<Props> = ({
attachment,
connectionId,
formChangeRowId,
hideDelete,
isFirstRevision,
}) => {
const [
discardProjectAttachmentFormChange,
isDiscardingProjectAttachmentFormChange,
] = useDiscardProjectAttachmentFormChange();
const {
id,
fileName,
fileType,
fileSize,
createdAt,
cifUserByCreatedBy: { fullName },
} = useFragment(
const attachmentRow = useFragment(
graphql`
fragment AttachmentTableRow_attachment on Attachment {
id
Expand All @@ -45,32 +42,41 @@ const AttachmentTableRow: React.FC<Props> = ({
attachment
);

const handleArchiveAttachment = () => {
discardProjectAttachmentFormChange({
variables: {
input: {
formChangeId: formChangeRowId,
const router = useRouter();
if (!attachmentRow) return null;
const { id, fileName, fileType, fileSize, createdAt, cifUserByCreatedBy } =
attachmentRow;

const handleArchiveAttachment = (attachmentId) => {
if (isFirstRevision) {
hardDeleteAttachment(attachmentId, formChangeRowId);
router.replace(router.asPath);
} else {
discardProjectAttachmentFormChange({
variables: {
input: {
formChangeId: formChangeRowId,
},
connections: [connectionId],
},
connections: [connectionId],
},
});
});
}
};

return (
<>
<tr>
<td>{fileName}</td>
<td>{fileType}</td>
<td>{fileSize}</td>
<td>{fullName}</td>
<td>{cifUserByCreatedBy?.fullName}</td>
<td>{createdAt}</td>
<td className="links">
<Link href={getAttachmentDownloadRoute(id)} passHref>
<Button size="small">Download</Button>
</Link>
{!hideDelete && (
<Button
onClick={handleArchiveAttachment}
onClick={() => handleArchiveAttachment(id)}
disabled={isDiscardingProjectAttachmentFormChange}
size="small"
>
Expand Down
21 changes: 21 additions & 0 deletions app/components/Attachment/hardDeleteAttachment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { getAttachmentDeleteRoute } from "routes/pageRoutes";

const hardDeleteAttachment = async (attachmentId, formChangeRowId) => {
const csrfToken = document.cookie.replace("qwerty=", "");
fetch(getAttachmentDeleteRoute(attachmentId).pathname, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": decodeURIComponent(csrfToken),
},
body: JSON.stringify({
variables: {
input: {
formChangeId: formChangeRowId,
},
},
}),
});
};

export default hardDeleteAttachment;
25 changes: 16 additions & 9 deletions app/components/Form/ProjectAttachmentsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ const ProjectAttachmentsForm: React.FC<Props> = ({
projectRevision,
onSubmit,
}) => {
const { rowId, projectAttachmentFormChanges } = useFragment(
const revision = useFragment(
graphql`
fragment ProjectAttachmentsForm_projectRevision on ProjectRevision {
id
rowId
isFirstRevision
projectAttachmentFormChanges: formChangesFor(
first: 500
formDataTableName: "project_attachment"
Expand All @@ -57,6 +59,7 @@ const ProjectAttachmentsForm: React.FC<Props> = ({
projectRevision
);

const { rowId, projectAttachmentFormChanges, isFirstRevision } = revision;
const attachmentFormChange = projectAttachmentFormChanges.edges[0]?.node;
const [createAttachment, isCreatingAttachment] = useCreateAttachment();
const [createProjectAttachment, isCreatingProjectAttachment] =
Expand Down Expand Up @@ -143,14 +146,18 @@ const ProjectAttachmentsForm: React.FC<Props> = ({
totalRowCount={projectAttachmentFormChanges.totalCount}
filters={tableFilters}
>
{projectAttachmentFormChanges.edges.map(({ node }) => (
<AttachmentTableRow
key={node.id}
attachment={node.asProjectAttachment.attachmentByAttachmentId}
formChangeRowId={node.rowId}
connectionId={projectAttachmentFormChanges.__id}
/>
))}
{projectAttachmentFormChanges.edges.map(({ node }) => {
if (!node) return null;
return (
<AttachmentTableRow
key={node.id}
attachment={node.asProjectAttachment.attachmentByAttachmentId}
formChangeRowId={node.rowId}
connectionId={projectAttachmentFormChanges.__id}
isFirstRevision={isFirstRevision}
/>
);
})}
</Table>
<Button
type="submit"
Expand Down
1 change: 1 addition & 0 deletions app/components/Form/ProjectAttachmentsFormSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ const ProjectAttachmentsFormSummary: React.FC<Props> = ({
formChangeRowId={node.rowId}
connectionId={revision.summaryProjectAttachmentFormChanges.__id}
hideDelete={true}
isFirstRevision={revision.isFirstRevision}
/>
)
)}
Expand Down
1 change: 1 addition & 0 deletions app/lib/relay/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Network, Environment, Store, RecordSource } from "relay-runtime";
import getConfig from "next/config";

const {
serverRuntimeConfig: { PORT },
} = getConfig();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const mutation = graphql`
$connections: [ID!]!
) {
discardProjectAttachmentFormChange(input: $input) {
formChanges {
formChange {
projectRevisionByProjectRevisionId {
...TaskList_projectRevision
}
Expand Down
1 change: 1 addition & 0 deletions app/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const nextConfig = {
SENTRY_RELEASE: config.get("sentryRelease"),
GROWTHBOOK_API_KEY: config.get("growthbookApiKey"),
BYPASS_GROWTHBOOK: config.get("bypassGrowthbook"),
SESSION_SECRET: config.get("sessionSecret"),
},
};

Expand Down
4 changes: 4 additions & 0 deletions app/routes/pageRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ export const getAttachmentDownloadRoute = (attachmentId: string) => ({
pathname: `/download/${attachmentId}`,
});

export const getAttachmentDeleteRoute = (attachmentId: string) => ({
pathname: `/delete/${attachmentId}`,
});

//// External User

export const getExternalUserLandingPageRoute = () => ({
Expand Down
26 changes: 25 additions & 1 deletion app/schema/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -44200,12 +44200,36 @@ input DiscardProjectAttachmentFormChangeInput {

"""The output of our `discardProjectAttachmentFormChange` mutation."""
type DiscardProjectAttachmentFormChangePayload {
"""Reads a single `ChangeStatus` that is related to this `FormChange`."""
changeStatusByChangeStatus: ChangeStatus

"""Reads a single `CifUser` that is related to this `FormChange`."""
cifUserByCreatedBy: CifUser

"""Reads a single `CifUser` that is related to this `FormChange`."""
cifUserByUpdatedBy: CifUser

"""
The exact same `clientMutationId` that was provided in the mutation input,
unchanged and unused. May be used by a client to track mutations.
"""
clientMutationId: String
formChanges: [FormChange]

"""Reads a single `Form` that is related to this `FormChange`."""
formByJsonSchemaName: Form
formChange: FormChange

"""Reads a single `FormChange` that is related to this `FormChange`."""
formChangeByPreviousFormChangeId: FormChange

"""An edge for our `FormChange`. May be used by Relay 1."""
formChangeEdge(
"""The method to use when ordering `FormChange`."""
orderBy: [FormChangesOrderBy!] = [PRIMARY_KEY_ASC]
): FormChangesEdge

"""Reads a single `ProjectRevision` that is related to this `FormChange`."""
projectRevisionByProjectRevisionId: ProjectRevision

"""
Our root query field type. Allows us to run any query from our mutation payload.
Expand Down
113 changes: 106 additions & 7 deletions app/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -146181,6 +146181,42 @@
"name": "DiscardProjectAttachmentFormChangePayload",
"description": "The output of our `discardProjectAttachmentFormChange` mutation.",
"fields": [
{
"name": "changeStatusByChangeStatus",
"description": "Reads a single `ChangeStatus` that is related to this `FormChange`.",
"args": [],
"type": {
"kind": "OBJECT",
"name": "ChangeStatus",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "cifUserByCreatedBy",
"description": "Reads a single `CifUser` that is related to this `FormChange`.",
"args": [],
"type": {
"kind": "OBJECT",
"name": "CifUser",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "cifUserByUpdatedBy",
"description": "Reads a single `CifUser` that is related to this `FormChange`.",
"args": [],
"type": {
"kind": "OBJECT",
"name": "CifUser",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "clientMutationId",
"description": "The exact same `clientMutationId` that was provided in the mutation input,\nunchanged and unused. May be used by a client to track mutations.",
Expand All @@ -146194,17 +146230,80 @@
"deprecationReason": null
},
{
"name": "formChanges",
"name": "formByJsonSchemaName",
"description": "Reads a single `Form` that is related to this `FormChange`.",
"args": [],
"type": {
"kind": "OBJECT",
"name": "Form",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "formChange",
"description": null,
"args": [],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "FormChange",
"ofType": null
"kind": "OBJECT",
"name": "FormChange",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "formChangeByPreviousFormChangeId",
"description": "Reads a single `FormChange` that is related to this `FormChange`.",
"args": [],
"type": {
"kind": "OBJECT",
"name": "FormChange",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "formChangeEdge",
"description": "An edge for our `FormChange`. May be used by Relay 1.",
"args": [
{
"name": "orderBy",
"description": "The method to use when ordering `FormChange`.",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "FormChangesOrderBy",
"ofType": null
}
}
},
"defaultValue": "[PRIMARY_KEY_ASC]"
}
],
"type": {
"kind": "OBJECT",
"name": "FormChangesEdge",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "projectRevisionByProjectRevisionId",
"description": "Reads a single `ProjectRevision` that is related to this `FormChange`.",
"args": [],
"type": {
"kind": "OBJECT",
"name": "ProjectRevision",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
Expand Down
Loading
Loading