From 09e5c83af4e793b89ffce59d3e664a62b6c65565 Mon Sep 17 00:00:00 2001 From: Mike Heneghan Date: Wed, 13 Mar 2024 17:01:26 +0000 Subject: [PATCH 1/4] feat: query submission_services_summary and log result - Setup up the types and function to query the submission_services_summary for the pertinent data - For now simply log the data out in the console --- .../components/Settings/Submissions/index.tsx | 28 ++++++- .../submissionDataTypesAndQueries.ts | 75 +++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionDataTypesAndQueries.ts diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx index cf8cafe475..763f801851 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx @@ -1,9 +1,35 @@ import Box from "@mui/material/Box"; import Typography from "@mui/material/Typography"; -import React from "react"; +import React, { useEffect, useState } from "react"; import { FeaturePlaceholder } from "ui/editor/FeaturePlaceholder"; +import { useStore } from "../../../lib/store"; +import { + fetchSubmittedApplications, + SubmissionData, +} from "./submissionDataTypesAndQueries"; + const Submissions: React.FC = () => { + const flowSlug = useStore.getState().flowSlug; + const teamSlug = useStore.getState().teamSlug; + const [applications, setApplications] = useState(); + const [error, setError] = useState(null); + + useEffect(() => { + if (flowSlug && teamSlug) { + fetchSubmittedApplications(flowSlug, teamSlug) + .then((result) => setApplications(result.submission_services_summary)) + .catch((error) => { + setError(error); + }); + } + }, [flowSlug, teamSlug]); + + useEffect(() => { + console.log(applications); + console.log(error); + }, [applications, error]); + return ( diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionDataTypesAndQueries.ts b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionDataTypesAndQueries.ts new file mode 100644 index 0000000000..6ff39dd869 --- /dev/null +++ b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionDataTypesAndQueries.ts @@ -0,0 +1,75 @@ +import gql from "graphql-tag"; +import { client } from "lib/graphql"; + +type PaymentRequest = { + id: string; + createdAt: string; + paidAt: string; + govPaymentId: string; +}; + +type PaymentStatus = { + govPaymentId: string; + createdAt: string; + status: string; +}; + +type BopsApplication = { + id: string; + submittedAt: string; + destinationUrl: string; +}; + +type EmailApplication = { + id: string; + recipient: string; + submittedAt: string; +}; + +type UniformApplication = { + id: string; + submittedAt: string; +}; + +export type SubmissionData = { + sessionId: string; + submittedAt: Date | string; + paymentRequests: PaymentRequest[] | null; + paymentStatus: PaymentStatus[] | null; + bopsApplications: BopsApplication[] | null; + uniformApplications: UniformApplication[] | null; + emailApplications: EmailApplication[] | null; +}; + +export async function fetchSubmittedApplications( + flowSlug: string, + teamSlug: string, +) { + const { data } = await client.query({ + query: gql` + query SubmittedApplications($service_slug: String!, $team_slug: String!) { + submission_services_summary( + where: { + service_slug: { _eq: $service_slug } + team_slug: { _eq: $team_slug } + submitted_at: { _is_null: false } + } + order_by: { submitted_at: desc } + ) { + sessionId: session_id + submittedAt: submitted_at + paymentRequests: payment_requests + paymentStatus: payment_status + bopsApplications: bops_applications + uniformApplications: uniform_applications + emailApplications: email_applications + } + } + `, + variables: { + service_slug: flowSlug, + team_slug: teamSlug, + }, + }); + return data; +} From 61af3a7e56a550cc5a24ae1eb7fb77a61e57bf09 Mon Sep 17 00:00:00 2001 From: Mike Heneghan Date: Thu, 14 Mar 2024 17:13:14 +0000 Subject: [PATCH 2/4] refactor: update to remove repeated call to useStore - As per: https://github.com/theopensystemslab/planx-new/pull/2885#discussion_r1524748727 --- .../FlowEditor/components/Settings/Submissions/index.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx index 763f801851..277407fa2e 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx @@ -10,8 +10,10 @@ import { } from "./submissionDataTypesAndQueries"; const Submissions: React.FC = () => { - const flowSlug = useStore.getState().flowSlug; - const teamSlug = useStore.getState().teamSlug; + const [flowSlug, teamSlug] = useStore((state) => [ + state.flowSlug, + state.teamSlug, + ]); const [applications, setApplications] = useState(); const [error, setError] = useState(null); From cc2eb174e138a23046a710c38da83bdcc9d63a54 Mon Sep 17 00:00:00 2001 From: Mike Heneghan Date: Thu, 14 Mar 2024 17:21:34 +0000 Subject: [PATCH 3/4] refactor: update case and tighten types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - As per: https://github.com/theopensystemslab/planx-new/pull/2885#discussion_r1524868148 - As per: https://github.com/theopensystemslab/planx-new/pull/2885#discussion_r1524873735 Co-authored-by: Dafydd Llŷr Pearson --- .../FlowEditor/components/Settings/Submissions/index.tsx | 2 +- .../Settings/Submissions/submissionDataTypesAndQueries.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx index 277407fa2e..42e68aabde 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx @@ -20,7 +20,7 @@ const Submissions: React.FC = () => { useEffect(() => { if (flowSlug && teamSlug) { fetchSubmittedApplications(flowSlug, teamSlug) - .then((result) => setApplications(result.submission_services_summary)) + .then((result) => setApplications(result)) .catch((error) => { setError(error); }); diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionDataTypesAndQueries.ts b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionDataTypesAndQueries.ts index 6ff39dd869..987adfff0d 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionDataTypesAndQueries.ts +++ b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionDataTypesAndQueries.ts @@ -44,11 +44,11 @@ export type SubmissionData = { export async function fetchSubmittedApplications( flowSlug: string, teamSlug: string, -) { +): Promise { const { data } = await client.query({ query: gql` query SubmittedApplications($service_slug: String!, $team_slug: String!) { - submission_services_summary( + submissionServicesSummary: submission_services_summary( where: { service_slug: { _eq: $service_slug } team_slug: { _eq: $team_slug } @@ -71,5 +71,5 @@ export async function fetchSubmittedApplications( team_slug: teamSlug, }, }); - return data; + return data.submissionServicesSummary; } From 30b4c0c57c1aaa9240a6b0604aab0cd58d996232 Mon Sep 17 00:00:00 2001 From: Mike Heneghan Date: Fri, 15 Mar 2024 12:04:55 +0000 Subject: [PATCH 4/4] refactor: restructure and use `useQuery` - As per: https://github.com/theopensystemslab/planx-new/pull/2885#discussion_r1524886039 - Separating concerns for readability / ease fo testing --- .../Settings/Submissions/SubmissionsView.tsx | 38 ++++++++ .../components/Settings/Submissions/index.tsx | 36 +++---- .../Settings/Submissions/submissionData.ts | 93 +++++++++++++++++++ .../submissionDataTypesAndQueries.ts | 75 --------------- 4 files changed, 143 insertions(+), 99 deletions(-) create mode 100644 editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/SubmissionsView.tsx create mode 100644 editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionData.ts delete mode 100644 editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionDataTypesAndQueries.ts diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/SubmissionsView.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/SubmissionsView.tsx new file mode 100644 index 0000000000..be0006150a --- /dev/null +++ b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/SubmissionsView.tsx @@ -0,0 +1,38 @@ +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import Typography from "@mui/material/Typography"; +import DelayedLoadingIndicator from "components/DelayedLoadingIndicator"; +import ErrorFallback from "components/ErrorFallback"; +import React from "react"; + +import { SubmissionData } from "./submissionData"; + +interface SubmissionsViewProps { + applications: SubmissionData[]; + loading: boolean; + error: Error | undefined; +} + +const SubmissionsView: React.FC = ({ + applications, + loading, + error, +}) => { + if (loading) return ; + if (error) return ; + if (applications.length === 0) + return ( + + No submitted applications found for this service. + + ); + return ( + + {applications.map((application, index) => ( + {application.sessionId} + ))} + + ); +}; + +export default SubmissionsView; diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx index 42e68aabde..a4d190701b 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/index.tsx @@ -1,36 +1,20 @@ import Box from "@mui/material/Box"; import Typography from "@mui/material/Typography"; -import React, { useEffect, useState } from "react"; -import { FeaturePlaceholder } from "ui/editor/FeaturePlaceholder"; +import React from "react"; import { useStore } from "../../../lib/store"; -import { - fetchSubmittedApplications, - SubmissionData, -} from "./submissionDataTypesAndQueries"; +import { useSubmittedApplications } from "./submissionData"; +import SubmissionsView from "./SubmissionsView"; const Submissions: React.FC = () => { const [flowSlug, teamSlug] = useStore((state) => [ state.flowSlug, state.teamSlug, ]); - const [applications, setApplications] = useState(); - const [error, setError] = useState(null); - - useEffect(() => { - if (flowSlug && teamSlug) { - fetchSubmittedApplications(flowSlug, teamSlug) - .then((result) => setApplications(result)) - .catch((error) => { - setError(error); - }); - } - }, [flowSlug, teamSlug]); - - useEffect(() => { - console.log(applications); - console.log(error); - }, [applications, error]); + const { applications, loading, error } = useSubmittedApplications({ + flowSlug, + teamSlug, + }); return ( @@ -41,7 +25,11 @@ const Submissions: React.FC = () => { View data on the user submitted applications for this service. - + ); diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionData.ts b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionData.ts new file mode 100644 index 0000000000..bf716a6949 --- /dev/null +++ b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionData.ts @@ -0,0 +1,93 @@ +import { useQuery } from "@apollo/client"; +import gql from "graphql-tag"; +import { useMemo } from "react"; + +type PaymentRequest = { + id: string; + createdAt: string; + paidAt: string; + govPaymentId: string; +}; + +type PaymentStatus = { + govPaymentId: string; + createdAt: string; + status: string; +}; + +type BopsApplication = { + id: string; + submittedAt: string; + destinationUrl: string; +}; + +type EmailApplication = { + id: string; + recipient: string; + submittedAt: string; +}; + +type UniformApplication = { + id: string; + submittedAt: string; +}; + +export type SubmissionData = { + sessionId: string; + submittedAt: Date | string; + paymentRequests: PaymentRequest[] | null; + paymentStatus: PaymentStatus[] | null; + bopsApplications: BopsApplication[] | null; + uniformApplications: UniformApplication[] | null; + emailApplications: EmailApplication[] | null; +}; + +export type SubmittedApplicationsQueryResult = { + submissionServicesSummary: SubmissionData[]; +}; + +export const SUBMITTED_APPLICATIONS_QUERY = gql` + query SubmittedApplications($service_slug: String!, $team_slug: String!) { + submissionServicesSummary: submission_services_summary( + where: { + service_slug: { _eq: $service_slug } + team_slug: { _eq: $team_slug } + submitted_at: { _is_null: false } + } + order_by: { submitted_at: desc } + ) { + sessionId: session_id + submittedAt: submitted_at + paymentRequests: payment_requests + paymentStatus: payment_status + bopsApplications: bops_applications + uniformApplications: uniform_applications + emailApplications: email_applications + } + } +`; + +type UseSubmittedApplicationsParams = { + flowSlug?: string; + teamSlug?: string; +}; + +export const useSubmittedApplications = ({ + flowSlug, + teamSlug, +}: UseSubmittedApplicationsParams) => { + const { data, loading, error } = useQuery( + SUBMITTED_APPLICATIONS_QUERY, + { + variables: { service_slug: flowSlug, team_slug: teamSlug }, + skip: !flowSlug || !teamSlug, + }, + ); + + const applications = useMemo( + () => data?.submissionServicesSummary || [], + [data], + ); + + return { applications, loading, error }; +}; diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionDataTypesAndQueries.ts b/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionDataTypesAndQueries.ts deleted file mode 100644 index 987adfff0d..0000000000 --- a/editor.planx.uk/src/pages/FlowEditor/components/Settings/Submissions/submissionDataTypesAndQueries.ts +++ /dev/null @@ -1,75 +0,0 @@ -import gql from "graphql-tag"; -import { client } from "lib/graphql"; - -type PaymentRequest = { - id: string; - createdAt: string; - paidAt: string; - govPaymentId: string; -}; - -type PaymentStatus = { - govPaymentId: string; - createdAt: string; - status: string; -}; - -type BopsApplication = { - id: string; - submittedAt: string; - destinationUrl: string; -}; - -type EmailApplication = { - id: string; - recipient: string; - submittedAt: string; -}; - -type UniformApplication = { - id: string; - submittedAt: string; -}; - -export type SubmissionData = { - sessionId: string; - submittedAt: Date | string; - paymentRequests: PaymentRequest[] | null; - paymentStatus: PaymentStatus[] | null; - bopsApplications: BopsApplication[] | null; - uniformApplications: UniformApplication[] | null; - emailApplications: EmailApplication[] | null; -}; - -export async function fetchSubmittedApplications( - flowSlug: string, - teamSlug: string, -): Promise { - const { data } = await client.query({ - query: gql` - query SubmittedApplications($service_slug: String!, $team_slug: String!) { - submissionServicesSummary: submission_services_summary( - where: { - service_slug: { _eq: $service_slug } - team_slug: { _eq: $team_slug } - submitted_at: { _is_null: false } - } - order_by: { submitted_at: desc } - ) { - sessionId: session_id - submittedAt: submitted_at - paymentRequests: payment_requests - paymentStatus: payment_status - bopsApplications: bops_applications - uniformApplications: uniform_applications - emailApplications: email_applications - } - } - `, - variables: { - service_slug: flowSlug, - team_slug: teamSlug, - }, - }); - return data.submissionServicesSummary; -}