Skip to content

Commit

Permalink
Merge pull request #1992 from bcgov/allow-applicant-to-delete-drafts-…
Browse files Browse the repository at this point in the history
…on-dashboard

allow applicant to delete drafts on dashboard
  • Loading branch information
rafasdc authored Aug 2, 2023
2 parents d9d14dc + b36f500 commit 5f64ff1
Show file tree
Hide file tree
Showing 11 changed files with 547 additions and 185 deletions.
99 changes: 99 additions & 0 deletions app/components/Dashboard/ArchiveModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { useState } from 'react';
import Button from '@button-inc/bcgov-theme/Button';
import Modal from '@button-inc/bcgov-theme/Modal';
import styled from 'styled-components';

import { useArchiveApplicationMutation } from 'schema/mutations/application/archiveApplication';
import { ConnectionHandler } from 'relay-runtime';
import X from './XIcon';

const StyledModal = styled(Modal)`
display: flex;
align-items: center;
z-index: 2;
`;

const ModalButtons = styled('div')`
& button {
margin-right: 1em;
}
`;

const StyledConfirmBox = styled('div')`
position: absolute;
left: 40px;
bottom: 3.5em;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
background: #1a5a96;
border-radius: 4px;
color: #ffffff;
padding: 16px 24px;
& div:first-child {
margin-right: 1em;
}
`;

const ArchiveModal = ({ applications, id }) => {
const [successModal, setSuccessModal] = useState(false);
const relayId = applications.allApplications.__id;

const [archiveApplication] = useArchiveApplicationMutation();

const handleWithdraw = async () => {
archiveApplication({
variables: {
input: {
applicationRowId: id.rowId,
},
},
onCompleted: () => setSuccessModal(true),
updater: (store) => {
const connection = store.get(relayId);
store.delete(id.id);
ConnectionHandler.deleteNode(connection, id.id);
},
});
};

return (
<>
<StyledModal id="delete-application">
<Modal.Header>
Delete draft
<Modal.Close>
<X />
</Modal.Close>
</Modal.Header>
<Modal.Content>
<p>Are you sure you want to delete this draft application?</p>
<ModalButtons>
<Modal.Close>
<Button onClick={handleWithdraw} data-testid="archive-yes-btn">
Yes, delete
</Button>
</Modal.Close>

<Modal.Close>
<Button variant="secondary">No, keep</Button>
</Modal.Close>
</ModalButtons>
</Modal.Content>
</StyledModal>
{successModal && (
<StyledConfirmBox>
<div>Application deleted</div>
<button type="button" onClick={() => setSuccessModal(false)}>
<X />
</button>
</StyledConfirmBox>
)}
</>
);
};

export default ArchiveModal;
32 changes: 29 additions & 3 deletions app/components/Dashboard/Row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,22 @@ const StyledBtns = styled('div')`
}
`;

const Row = ({ application, formPages, reviewPage, setWithdrawId }) => {
const { ccbcNumber, intakeByIntakeId, formData, projectName, rowId, status } =
application;
const Row = ({
application,
formPages,
reviewPage,
setWithdrawId,
setArchiveId,
}) => {
const {
ccbcNumber,
intakeByIntakeId,
formData,
projectName,
rowId,
status,
id,
} = application;

const lastEditedIndex = formPages.indexOf(formData.lastEditedPage) + 1;

Expand All @@ -44,6 +57,7 @@ const Row = ({ application, formPages, reviewPage, setWithdrawId }) => {

const isWithdrawn = application.status === 'withdrawn';
const isSubmitted = application.status === 'submitted';
const isDraft = application.status === 'draft';

const getApplicationUrl = () => {
if (isWithdrawn) {
Expand Down Expand Up @@ -85,6 +99,18 @@ const Row = ({ application, formPages, reviewPage, setWithdrawId }) => {
<Withdraw />
</button>
)}
{!ccbcNumber && isDraft && (
<button
onClick={() => {
setArchiveId({ rowId, id });
window.location.hash = 'delete-application';
}}
data-testid="archive-btn-test"
type="button"
>
<Link href="#delete-application">Delete</Link>
</button>
)}
{application.hasRfiOpen && (
<Link
href={`/applicantportal/form/${application.rowId}/rfi/${application.rfi.rowId}/`}
Expand Down
13 changes: 9 additions & 4 deletions app/components/Dashboard/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCircleInfo } from '@fortawesome/free-solid-svg-icons';
import Modal from './Modal';
import Row from './Row';
import ArchiveModal from './ArchiveModal';

const StyledFontAwesome = styled(FontAwesomeIcon)`
margin-left: 4px; ;
Expand Down Expand Up @@ -40,8 +41,11 @@ type Props = {

const Table = ({ applications }: Props) => {
const [withdrawId, setWithdrawId] = useState<null | number>(null);
const [archiveId, setArchiveId] = useState({ rowId: null, id: null });

const applicationNodes = applications.allApplications.nodes;
const applicationNodes = applications.allApplications.edges
.map((edge) => edge.node)
.filter((node) => node !== null);

const formPages = Object.keys(schema.properties);

Expand Down Expand Up @@ -70,19 +74,20 @@ const Table = ({ applications }: Props) => {
</StyledTableHead>
<tbody>
{applicationNodes.map((application) => {
return (
return application ? (
<Row
application={application}
key={application.owner}
formPages={formPages}
reviewPage={reviewPage}
setWithdrawId={setWithdrawId}
setArchiveId={setArchiveId}
/>
);
) : null;
})}
</tbody>
</StyledTable>

<ArchiveModal applications={applications} id={archiveId} />
<Modal id={withdrawId} />
</>
);
Expand Down
51 changes: 30 additions & 21 deletions app/pages/applicantportal/dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,35 @@ import { dashboardQuery } from '__generated__/dashboardQuery.graphql';

const getDashboardQuery = graphql`
query dashboardQuery($formOwner: ApplicationCondition!) {
allApplications(condition: $formOwner, orderBy: CREATED_AT_DESC) {
nodes {
id
rowId
owner
status
projectName
ccbcNumber
formData {
lastEditedPage
isEditable
}
intakeByIntakeId {
ccbcIntakeNumber
closeTimestamp
openTimestamp
}
hasRfiOpen
rfi {
allApplications(
condition: $formOwner
orderBy: CREATED_AT_DESC
first: 1000
) @connection(key: "dashboard_allApplications") {
__id
edges {
node {
id
archivedAt
archivedBy
rowId
owner
status
projectName
ccbcNumber
formData {
lastEditedPage
isEditable
}
intakeByIntakeId {
ccbcIntakeNumber
closeTimestamp
openTimestamp
}
hasRfiOpen
rfi {
rowId
}
}
}
}
Expand Down Expand Up @@ -66,7 +75,7 @@ const Dashboard = ({

const sub: string = session?.sub;

const hasApplications = allApplications.nodes.length > 0;
const hasApplications = allApplications.edges.length > 0;

const router = useRouter();

Expand Down Expand Up @@ -167,7 +176,7 @@ export const withRelayOptions = {
const sub: string = ctx?.req?.claims?.sub;

return {
formOwner: { owner: sub },
formOwner: { owner: sub, archivedAt: null, archivedBy: null },
};
},
};
Expand Down
26 changes: 26 additions & 0 deletions app/schema/mutations/application/archiveApplication.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { graphql } from 'react-relay';
import type { archiveApplicationMutation } from '__generated__/archiveApplicationMutation.graphql';
import useMutationWithErrorMessage from '../useMutationWithErrorMessage';

const mutation = graphql`
mutation archiveApplicationMutation($input: ArchiveApplicationInput!) {
archiveApplication(input: $input) {
clientMutationId
application {
id
updatedAt
status
ccbcNumber
intakeId
}
}
}
`;

const useArchiveApplicationMutation = () =>
useMutationWithErrorMessage<archiveApplicationMutation>(
mutation,
() => 'An error occurred while archiveing the application.'
);

export { mutation, useArchiveApplicationMutation };
51 changes: 51 additions & 0 deletions app/schema/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -45839,6 +45839,14 @@ type Mutation {
"""
input: DeleteSowTab8ByRowIdInput!
): DeleteSowTab8Payload

"""Mutation to archive an application and its related data"""
archiveApplication(
"""
The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
"""
input: ArchiveApplicationInput!
): ArchiveApplicationPayload
archiveApplicationSow(
"""
The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields.
Expand Down Expand Up @@ -53443,6 +53451,49 @@ input DeleteSowTab8ByRowIdInput {
rowId: Int!
}

"""The output of our `archiveApplication` mutation."""
type ArchiveApplicationPayload {
"""
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
application: Application

"""
Our root query field type. Allows us to run any query from our mutation payload.
"""
query: Query

"""Reads a single `Intake` that is related to this `Application`."""
intakeByIntakeId: Intake

"""Reads a single `CcbcUser` that is related to this `Application`."""
ccbcUserByCreatedBy: CcbcUser

"""Reads a single `CcbcUser` that is related to this `Application`."""
ccbcUserByUpdatedBy: CcbcUser

"""Reads a single `CcbcUser` that is related to this `Application`."""
ccbcUserByArchivedBy: CcbcUser

"""An edge for our `Application`. May be used by Relay 1."""
applicationEdge(
"""The method to use when ordering `Application`."""
orderBy: [ApplicationsOrderBy!] = [PRIMARY_KEY_ASC]
): ApplicationsEdge
}

"""All input for the `archiveApplication` mutation."""
input ArchiveApplicationInput {
"""
An arbitrary string value with no semantic meaning. Will be included in the
payload verbatim. May be used to track mutations by the client.
"""
clientMutationId: String
applicationRowId: Int!
}

"""The output of our `archiveApplicationSow` mutation."""
type ArchiveApplicationSowPayload {
"""
Expand Down
Loading

0 comments on commit 5f64ff1

Please sign in to comment.