From 43a4139664e4e947e1cc468c63b62df63d36373f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dafydd=20Ll=C5=B7r=20Pearson?= Date: Fri, 24 May 2024 16:30:11 +0100 Subject: [PATCH 1/6] chore: Restrict public access to offline flows --- api.planx.uk/helpers.ts | 6 ++--- hasura.planx.uk/metadata/tables.yaml | 34 ++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/api.planx.uk/helpers.ts b/api.planx.uk/helpers.ts index 6bbcf5b71e..05242581c3 100644 --- a/api.planx.uk/helpers.ts +++ b/api.planx.uk/helpers.ts @@ -2,7 +2,7 @@ import { gql } from "graphql-request"; import { capitalize } from "lodash"; import { Flow, Node } from "./types"; import { ComponentType, FlowGraph } from "@opensystemslab/planx-core/types"; -import { $public, getClient } from "./client"; +import { $api, $public, getClient } from "./client"; export interface FlowData { slug: string; @@ -22,7 +22,7 @@ export interface FlowData { // Get a flow's data (unflattened, without external portal nodes) const getFlowData = async (id: string): Promise => { - const { flow } = await $public.client.request<{ flow: FlowData | null }>( + const { flow } = await $api.client.request<{ flow: FlowData | null }>( gql` query GetFlowData($id: uuid!) { flow: flows_by_pk(id: $id) { @@ -146,7 +146,7 @@ interface PublishedFlows { const getMostRecentPublishedFlow = async ( id: string, ): Promise => { - const { flow } = await $public.client.request( + const { flow } = await $api.client.request( gql` query GetMostRecentPublishedFlow($id: uuid!) { flow: flows_by_pk(id: $id) { diff --git a/hasura.planx.uk/metadata/tables.yaml b/hasura.planx.uk/metadata/tables.yaml index e8c8717c4b..cc092977ef 100644 --- a/hasura.planx.uk/metadata/tables.yaml +++ b/hasura.planx.uk/metadata/tables.yaml @@ -1,10 +1,17 @@ - table: name: analytics schema: public + object_relationships: + - name: flow + using: + foreign_key_constraint_on: flow_id insert_permissions: - role: public permission: - check: {} + check: + flow: + status: + _eq: online columns: - created_at - flow_id @@ -23,15 +30,26 @@ permission: columns: - ended_at - filter: {} + filter: + flow: + status: + _eq: online check: null - table: name: analytics_logs schema: public + object_relationships: + - name: analytic + using: + foreign_key_constraint_on: analytics_id insert_permissions: - role: public permission: - check: {} + check: + analytic: + flow: + status: + _eq: online columns: - analytics_id - created_at @@ -65,7 +83,11 @@ - metadata - next_log_created_at - user_exit - filter: {} + filter: + analytic: + flow: + status: + _eq: online check: null - table: name: analytics_summary @@ -543,7 +565,9 @@ - version computed_fields: - data_merged - filter: {} + filter: + status: + _eq: online allow_aggregations: true - role: teamEditor permission: From 95235e633d16ca82666a518f1fc420a941f10337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dafydd=20Ll=C5=B7r=20Pearson?= Date: Fri, 24 May 2024 16:30:44 +0100 Subject: [PATCH 2/6] test(e2e): Update tests to account for flow status --- e2e/tests/api-driven/package.json | 2 +- e2e/tests/api-driven/pnpm-lock.yaml | 8 ++-- .../api-driven/src/invite-to-pay/helpers.ts | 1 + e2e/tests/ui-driven/package.json | 2 +- e2e/tests/ui-driven/pnpm-lock.yaml | 8 ++-- e2e/tests/ui-driven/src/context.ts | 1 + .../src/create-flow/create-flow.spec.ts | 46 +++++++++++++++++++ 7 files changed, 58 insertions(+), 10 deletions(-) diff --git a/e2e/tests/api-driven/package.json b/e2e/tests/api-driven/package.json index 3f52e24cc1..5421a8e761 100644 --- a/e2e/tests/api-driven/package.json +++ b/e2e/tests/api-driven/package.json @@ -6,7 +6,7 @@ }, "dependencies": { "@cucumber/cucumber": "^9.3.0", - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#550634a", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#5710d52", "axios": "^1.6.8", "dotenv": "^16.3.1", "dotenv-expand": "^10.0.0", diff --git a/e2e/tests/api-driven/pnpm-lock.yaml b/e2e/tests/api-driven/pnpm-lock.yaml index 184f04ac00..3005fa893d 100644 --- a/e2e/tests/api-driven/pnpm-lock.yaml +++ b/e2e/tests/api-driven/pnpm-lock.yaml @@ -9,8 +9,8 @@ dependencies: specifier: ^9.3.0 version: 9.3.0 '@opensystemslab/planx-core': - specifier: git+https://github.com/theopensystemslab/planx-core#550634a - version: github.com/theopensystemslab/planx-core/550634a + specifier: git+https://github.com/theopensystemslab/planx-core#5710d52 + version: github.com/theopensystemslab/planx-core/5710d52 axios: specifier: ^1.6.8 version: 1.6.8 @@ -2935,8 +2935,8 @@ packages: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} dev: false - github.com/theopensystemslab/planx-core/550634a: - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/550634a} + github.com/theopensystemslab/planx-core/5710d52: + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/5710d52} name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true diff --git a/e2e/tests/api-driven/src/invite-to-pay/helpers.ts b/e2e/tests/api-driven/src/invite-to-pay/helpers.ts index c12649c4d9..302be5dd57 100644 --- a/e2e/tests/api-driven/src/invite-to-pay/helpers.ts +++ b/e2e/tests/api-driven/src/invite-to-pay/helpers.ts @@ -45,6 +45,7 @@ export async function buildITPFlow({ const flowId: string = await $admin.flow.create({ teamId, slug: `test-invite-to-pay-flow-with-send-to-${destination.toLowerCase()}`, + status: "online", data: flowGraph, }); const publishedFlowId = await $admin.flow.publish({ diff --git a/e2e/tests/ui-driven/package.json b/e2e/tests/ui-driven/package.json index e472938bcd..7957fa2819 100644 --- a/e2e/tests/ui-driven/package.json +++ b/e2e/tests/ui-driven/package.json @@ -8,7 +8,7 @@ "postinstall": "./install-dependencies.sh" }, "dependencies": { - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#550634a", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#5710d52", "axios": "^1.6.8", "dotenv": "^16.3.1", "eslint": "^8.56.0", diff --git a/e2e/tests/ui-driven/pnpm-lock.yaml b/e2e/tests/ui-driven/pnpm-lock.yaml index a0e6dbe733..551c17f74f 100644 --- a/e2e/tests/ui-driven/pnpm-lock.yaml +++ b/e2e/tests/ui-driven/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: '@opensystemslab/planx-core': - specifier: git+https://github.com/theopensystemslab/planx-core#550634a - version: github.com/theopensystemslab/planx-core/550634a + specifier: git+https://github.com/theopensystemslab/planx-core#5710d52 + version: github.com/theopensystemslab/planx-core/5710d52 axios: specifier: ^1.6.8 version: 1.6.8 @@ -2684,8 +2684,8 @@ packages: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} dev: false - github.com/theopensystemslab/planx-core/550634a: - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/550634a} + github.com/theopensystemslab/planx-core/5710d52: + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/5710d52} name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true diff --git a/e2e/tests/ui-driven/src/context.ts b/e2e/tests/ui-driven/src/context.ts index ac06eab02e..b9369b6e02 100644 --- a/e2e/tests/ui-driven/src/context.ts +++ b/e2e/tests/ui-driven/src/context.ts @@ -74,6 +74,7 @@ export async function setUpTestContext( slug: context.flow.slug, teamId: context.team.id, data: context.flow!.data!, + status: "online", }); context.flow.publishedId = await $admin.flow.publish({ flow: { diff --git a/e2e/tests/ui-driven/src/create-flow/create-flow.spec.ts b/e2e/tests/ui-driven/src/create-flow/create-flow.spec.ts index 8c10cffec2..f003cb5045 100644 --- a/e2e/tests/ui-driven/src/create-flow/create-flow.spec.ts +++ b/e2e/tests/ui-driven/src/create-flow/create-flow.spec.ts @@ -179,6 +179,52 @@ test.describe("Navigation", () => { await expect(previewLink).toBeVisible(); }); + test("Cannot preview an offline flow", async ({ + browser, + }: { + browser: Browser; + }) => { + const page = await createAuthenticatedSession({ + browser, + userId: context.user!.id!, + }); + + await page.goto( + `/${context.team.slug}/${serviceProps.slug}/published?analytics=false`, + ); + + await expect(page.getByText("Not Found")).toBeVisible(); + }); + + test("Turn a flow online", async ({ browser }) => { + const page = await createAuthenticatedSession({ + browser, + userId: context.user!.id!, + }); + + await page.goto(`/${context.team.slug}/${serviceProps.slug}`); + + // Open flow settings + // TODO: Access via sidebar when EDITOR_NAVIGATION flag is removed + page.getByLabel("Toggle Menu").click(); + page.getByText("Flow Settings").click(); + + // Toggle flow online + page.getByLabel("Offline").click(); + page.getByRole("button", { name: "Save", disabled: false }).click(); + await expect( + page.getByText("Service settings updated successfully"), + ).toBeVisible(); + + // Exit back to main Editor page + page.getByRole("link", { name: "Close" }).click(); + + const previewLink = page.getByRole("link", { + name: "Open published service", + }); + await expect(previewLink).toBeVisible(); + }); + test("Can preview a published flow", async ({ browser, }: { From d1456b627ae38e1a3a13683f727930c0b7e31811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dafydd=20Ll=C5=B7r=20Pearson?= Date: Tue, 28 May 2024 18:21:11 +0100 Subject: [PATCH 3/6] revert: Restrictions on flow.status via Hasura permissions --- api.planx.uk/helpers.ts | 6 +++--- hasura.planx.uk/metadata/tables.yaml | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/api.planx.uk/helpers.ts b/api.planx.uk/helpers.ts index 05242581c3..6bbcf5b71e 100644 --- a/api.planx.uk/helpers.ts +++ b/api.planx.uk/helpers.ts @@ -2,7 +2,7 @@ import { gql } from "graphql-request"; import { capitalize } from "lodash"; import { Flow, Node } from "./types"; import { ComponentType, FlowGraph } from "@opensystemslab/planx-core/types"; -import { $api, $public, getClient } from "./client"; +import { $public, getClient } from "./client"; export interface FlowData { slug: string; @@ -22,7 +22,7 @@ export interface FlowData { // Get a flow's data (unflattened, without external portal nodes) const getFlowData = async (id: string): Promise => { - const { flow } = await $api.client.request<{ flow: FlowData | null }>( + const { flow } = await $public.client.request<{ flow: FlowData | null }>( gql` query GetFlowData($id: uuid!) { flow: flows_by_pk(id: $id) { @@ -146,7 +146,7 @@ interface PublishedFlows { const getMostRecentPublishedFlow = async ( id: string, ): Promise => { - const { flow } = await $api.client.request( + const { flow } = await $public.client.request( gql` query GetMostRecentPublishedFlow($id: uuid!) { flow: flows_by_pk(id: $id) { diff --git a/hasura.planx.uk/metadata/tables.yaml b/hasura.planx.uk/metadata/tables.yaml index cc092977ef..cd5f0e6376 100644 --- a/hasura.planx.uk/metadata/tables.yaml +++ b/hasura.planx.uk/metadata/tables.yaml @@ -565,9 +565,7 @@ - version computed_fields: - data_merged - filter: - status: - _eq: online + filter: {} allow_aggregations: true - role: teamEditor permission: From 4efcdac997f600e3079cf0924a840325595b34a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dafydd=20Ll=C5=B7r=20Pearson?= Date: Wed, 29 May 2024 11:05:00 +0100 Subject: [PATCH 4/6] feat: Route to offline page based on flow status --- .../ui-driven/src/create-flow/create-flow.spec.ts | 4 +++- .../src/pages/FlowEditor/lib/store/shared.ts | 7 +++++-- editor.planx.uk/src/pages/OfflinePage.tsx | 11 +++++++++++ editor.planx.uk/src/routes/published.tsx | 12 +++++++++++- editor.planx.uk/src/routes/views/published.tsx | 8 +++++++- editor.planx.uk/src/types.ts | 6 ++++-- 6 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 editor.planx.uk/src/pages/OfflinePage.tsx diff --git a/e2e/tests/ui-driven/src/create-flow/create-flow.spec.ts b/e2e/tests/ui-driven/src/create-flow/create-flow.spec.ts index f003cb5045..7d86cb19a9 100644 --- a/e2e/tests/ui-driven/src/create-flow/create-flow.spec.ts +++ b/e2e/tests/ui-driven/src/create-flow/create-flow.spec.ts @@ -193,7 +193,9 @@ test.describe("Navigation", () => { `/${context.team.slug}/${serviceProps.slug}/published?analytics=false`, ); - await expect(page.getByText("Not Found")).toBeVisible(); + await expect( + page.getByRole("heading", { level: 1, name: "Offline" }), + ).toBeVisible(); }); test("Turn a flow online", async ({ browser }) => { diff --git a/editor.planx.uk/src/pages/FlowEditor/lib/store/shared.ts b/editor.planx.uk/src/pages/FlowEditor/lib/store/shared.ts index d7143dfa3e..3b4381a463 100644 --- a/editor.planx.uk/src/pages/FlowEditor/lib/store/shared.ts +++ b/editor.planx.uk/src/pages/FlowEditor/lib/store/shared.ts @@ -1,5 +1,6 @@ import { CoreDomainClient } from "@opensystemslab/planx-core"; import { Auth } from "@opensystemslab/planx-core/dist/requests/graphql"; +import { FlowStatus } from "@opensystemslab/planx-core/types"; import { ROOT_NODE_KEY } from "@planx/graph"; import { capitalize } from "lodash"; import { removeSessionIdSearchParam } from "utils"; @@ -23,10 +24,12 @@ export interface SharedStore extends Store.Store { id, flow, flowSlug, + flowStatus, }: { id: string; flow: Store.flow; flowSlug: string; + flowStatus?: FlowStatus; }) => void; wasVisited: (id: Store.nodeId) => boolean; previewEnvironment: PreviewEnvironment; @@ -88,9 +91,9 @@ export const sharedStore: StateCreator< removeSessionIdSearchParam(); }, - setFlow({ id, flow, flowSlug }) { + setFlow({ id, flow, flowSlug, flowStatus }) { this.setFlowNameFromSlug(flowSlug); - set({ id, flow, flowSlug }); + set({ id, flow, flowSlug, flowStatus }); get().initNavigationStore(); }, diff --git a/editor.planx.uk/src/pages/OfflinePage.tsx b/editor.planx.uk/src/pages/OfflinePage.tsx new file mode 100644 index 0000000000..ede316160b --- /dev/null +++ b/editor.planx.uk/src/pages/OfflinePage.tsx @@ -0,0 +1,11 @@ +import Typography from "@mui/material/Typography"; +import StatusPage from "pages/Preview/StatusPage"; +import React from "react"; + +export const OfflinePage: React.FC = () => ( + + + This service is not currently available. Please check back later. + + +); diff --git a/editor.planx.uk/src/routes/published.tsx b/editor.planx.uk/src/routes/published.tsx index 0a14cc6073..bcf02182fe 100644 --- a/editor.planx.uk/src/routes/published.tsx +++ b/editor.planx.uk/src/routes/published.tsx @@ -1,4 +1,6 @@ import { compose, map, mount, route, withData, withView } from "navi"; +import { useStore } from "pages/FlowEditor/lib/store"; +import { OfflinePage } from "pages/OfflinePage"; import ContentPage from "pages/Preview/ContentPage"; import Questions from "pages/Preview/Questions"; import React from "react"; @@ -25,7 +27,15 @@ const routes = compose( mount({ "/": route({ - view: , + view: () => { + const isOnline = useStore.getState().flowStatus === "online"; + + return isOnline ? ( + + ) : ( + + ); + }, }), "/pages/:page": map((req) => { return route({ diff --git a/editor.planx.uk/src/routes/views/published.tsx b/editor.planx.uk/src/routes/views/published.tsx index d22deb94b7..adaf717083 100644 --- a/editor.planx.uk/src/routes/views/published.tsx +++ b/editor.planx.uk/src/routes/views/published.tsx @@ -43,7 +43,12 @@ export const publishedView = async (req: NaviRequest) => { const state = useStore.getState(); // XXX: necessary as long as not every flow is published; aim to remove dataMergedHotfix.ts in future // load pre-flattened published flow if exists, else load & flatten flow - state.setFlow({ id: flow.id, flow: publishedFlow, flowSlug }); + state.setFlow({ + id: flow.id, + flow: publishedFlow, + flowSlug, + flowStatus: flow.status, + }); state.setGlobalSettings(data.globalSettings[0]); state.setFlowSettings(flow.settings); state.setTeam(flow.team); @@ -94,6 +99,7 @@ export const fetchSettingsForPublishedView = async ( boundaryBBox: boundary_bbox } settings + status publishedFlows: published_flows( limit: 1 order_by: { created_at: desc } diff --git a/editor.planx.uk/src/types.ts b/editor.planx.uk/src/types.ts index c2b0b36e3d..ccb534ba1e 100644 --- a/editor.planx.uk/src/types.ts +++ b/editor.planx.uk/src/types.ts @@ -1,13 +1,14 @@ import { + FlowStatus, GovUKPayment, NotifyPersonalisation, Team, } from "@opensystemslab/planx-core/types"; +import { OT } from "@planx/graph/types"; import { useFormik } from "formik"; import { Store } from "./pages/FlowEditor/lib/store/index"; import { SharedStore } from "./pages/FlowEditor/lib/store/shared"; -import { OT } from "@planx/graph/types"; export type Maybe = T | undefined; @@ -18,6 +19,7 @@ export interface Flow { slug: string; team: Team; settings?: FlowSettings; + status?: FlowStatus; } export interface GlobalSettings { footerContent?: { [key: string]: TextContent }; @@ -133,4 +135,4 @@ export interface Operation { lastName: string; }; data: Array; -} \ No newline at end of file +} From 3bd10499e065c0cbfe595ef5a84425aeca562869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dafydd=20Ll=C5=B7r=20Pearson?= Date: Thu, 30 May 2024 13:14:36 +0100 Subject: [PATCH 5/6] feat: Allow users to complete S&R on offline flows --- editor.planx.uk/src/pages/OfflinePage.tsx | 7 ++++++- editor.planx.uk/src/routes/published.tsx | 12 ++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/editor.planx.uk/src/pages/OfflinePage.tsx b/editor.planx.uk/src/pages/OfflinePage.tsx index ede316160b..7ffcc9c85c 100644 --- a/editor.planx.uk/src/pages/OfflinePage.tsx +++ b/editor.planx.uk/src/pages/OfflinePage.tsx @@ -5,7 +5,12 @@ import React from "react"; export const OfflinePage: React.FC = () => ( - This service is not currently available. Please check back later. + This service is not currently available to new applicants. Please check + back later. + + + If you're resuming an application you previously started, please use the + link sent to you via email. ); diff --git a/editor.planx.uk/src/routes/published.tsx b/editor.planx.uk/src/routes/published.tsx index bcf02182fe..cfe85ddb82 100644 --- a/editor.planx.uk/src/routes/published.tsx +++ b/editor.planx.uk/src/routes/published.tsx @@ -26,17 +26,21 @@ const routes = compose( }), mount({ - "/": route({ + "/": route((req) => ({ view: () => { - const isOnline = useStore.getState().flowStatus === "online"; + const isFlowOnline = useStore.getState().flowStatus === "online"; + const isUserResuming = Boolean(req.params.sessionId); - return isOnline ? ( + // Allow users to complete Save & Return journeys, even if a flow is offline + const isFlowAccessible = isFlowOnline || isUserResuming; + + return isFlowAccessible ? ( ) : ( ); }, - }), + })), "/pages/:page": map((req) => { return route({ view: () => , From 587de80187531163da059832f235696c28c7e3c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dafydd=20Ll=C5=B7r=20Pearson?= Date: Fri, 31 May 2024 14:01:14 +0100 Subject: [PATCH 6/6] fix: Handle S&R by adding layout wrapper --- .../src/pages/layout/OfflineLayout.tsx | 16 +++++++++++++++ editor.planx.uk/src/routes/published.tsx | 20 +++---------------- .../src/routes/views/published.tsx | 9 ++++++--- 3 files changed, 25 insertions(+), 20 deletions(-) create mode 100644 editor.planx.uk/src/pages/layout/OfflineLayout.tsx diff --git a/editor.planx.uk/src/pages/layout/OfflineLayout.tsx b/editor.planx.uk/src/pages/layout/OfflineLayout.tsx new file mode 100644 index 0000000000..2279c28f58 --- /dev/null +++ b/editor.planx.uk/src/pages/layout/OfflineLayout.tsx @@ -0,0 +1,16 @@ +import { useStore } from "pages/FlowEditor/lib/store"; +import { OfflinePage } from "pages/OfflinePage"; +import React, { PropsWithChildren } from "react"; + +const OfflineLayout = ({ children }: PropsWithChildren) => { + const isFlowOnline = useStore.getState().flowStatus === "online"; + const searchParams = new URLSearchParams(window.location.search); + const isUserResuming = Boolean(searchParams.get("sessionId")); + + // Allow users to complete Save & Return journeys, even if a flow is offline + const isFlowAccessible = isFlowOnline || isUserResuming; + + return isFlowAccessible ? children : ; +}; + +export default OfflineLayout; diff --git a/editor.planx.uk/src/routes/published.tsx b/editor.planx.uk/src/routes/published.tsx index cfe85ddb82..0a14cc6073 100644 --- a/editor.planx.uk/src/routes/published.tsx +++ b/editor.planx.uk/src/routes/published.tsx @@ -1,6 +1,4 @@ import { compose, map, mount, route, withData, withView } from "navi"; -import { useStore } from "pages/FlowEditor/lib/store"; -import { OfflinePage } from "pages/OfflinePage"; import ContentPage from "pages/Preview/ContentPage"; import Questions from "pages/Preview/Questions"; import React from "react"; @@ -26,21 +24,9 @@ const routes = compose( }), mount({ - "/": route((req) => ({ - view: () => { - const isFlowOnline = useStore.getState().flowStatus === "online"; - const isUserResuming = Boolean(req.params.sessionId); - - // Allow users to complete Save & Return journeys, even if a flow is offline - const isFlowAccessible = isFlowOnline || isUserResuming; - - return isFlowAccessible ? ( - - ) : ( - - ); - }, - })), + "/": route({ + view: , + }), "/pages/:page": map((req) => { return route({ view: () => , diff --git a/editor.planx.uk/src/routes/views/published.tsx b/editor.planx.uk/src/routes/views/published.tsx index adaf717083..5f2b26e470 100644 --- a/editor.planx.uk/src/routes/views/published.tsx +++ b/editor.planx.uk/src/routes/views/published.tsx @@ -4,6 +4,7 @@ import { NaviRequest } from "navi"; import { NotFoundError } from "navi"; import { useStore } from "pages/FlowEditor/lib/store"; import { Store } from "pages/FlowEditor/lib/store"; +import OfflineLayout from "pages/layout/OfflineLayout"; import PublicLayout from "pages/layout/PublicLayout"; import SaveAndReturnLayout from "pages/layout/SaveAndReturnLayout"; import React from "react"; @@ -55,9 +56,11 @@ export const publishedView = async (req: NaviRequest) => { return ( - - - + + + + + ); };