diff --git a/editor.planx.uk/src/pages/FlowEditor/components/Settings/ServiceSettings.tsx b/editor.planx.uk/src/pages/FlowEditor/components/Settings/ServiceSettings.tsx index 641b0566d0..4c9c64dcf3 100644 --- a/editor.planx.uk/src/pages/FlowEditor/components/Settings/ServiceSettings.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/components/Settings/ServiceSettings.tsx @@ -1,11 +1,16 @@ import Alert from "@mui/material/Alert"; import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; +import FormControlLabel, { + formControlLabelClasses, +} from "@mui/material/FormControlLabel"; import Snackbar from "@mui/material/Snackbar"; import Switch, { SwitchProps } from "@mui/material/Switch"; import Typography from "@mui/material/Typography"; +import { FlowStatus } from "@opensystemslab/planx-core/types"; import { useFormik } from "formik"; import React, { useState } from "react"; +import { FONT_WEIGHT_BOLD } from "theme"; import EditorRow from "ui/editor/EditorRow"; import InputGroup from "ui/editor/InputGroup"; import InputLegend from "ui/editor/InputLegend"; @@ -72,7 +77,13 @@ const TextInput: React.FC<{ }; const ServiceSettings: React.FC = () => { - const flowSettings = useStore((state) => state.flowSettings); + const [flowSettings, updateFlowSettings, flowStatus, updateFlowStatus] = + useStore((state) => [ + state.flowSettings, + state.updateFlowSettings, + state.flowStatus, + state.updateFlowStatus, + ]); const [isAlertOpen, setIsAlertOpen] = useState(false); @@ -87,7 +98,7 @@ const ServiceSettings: React.FC = () => { setIsAlertOpen(false); }; - const formik = useFormik({ + const elementsForm = useFormik({ initialValues: { elements: { legalDisclaimer: { @@ -108,15 +119,25 @@ const ServiceSettings: React.FC = () => { }, }, onSubmit: async (values) => { - await useStore.getState().updateFlowSettings(values); + await updateFlowSettings(values); setIsAlertOpen(true); }, validate: () => {}, }); + const statusForm = useFormik<{ status: FlowStatus }>({ + initialValues: { + status: flowStatus || "online", + }, + onSubmit: async ({ status }) => { + await updateFlowStatus(status); + setIsAlertOpen(true); + }, + }); + return ( -
+ Elements @@ -131,18 +152,18 @@ const ServiceSettings: React.FC = () => { description="Displayed before a user submits their application" switchProps={{ name: "elements.legalDisclaimer.show", - checked: formik.values.elements?.legalDisclaimer?.show, - onChange: formik.handleChange, + checked: elementsForm.values.elements?.legalDisclaimer?.show, + onChange: elementsForm.handleChange, }} headingInputProps={{ name: "elements.legalDisclaimer.heading", - value: formik.values.elements?.legalDisclaimer?.heading, - onChange: formik.handleChange, + value: elementsForm.values.elements?.legalDisclaimer?.heading, + onChange: elementsForm.handleChange, }} contentInputProps={{ name: "elements.legalDisclaimer.content", - value: formik.values.elements?.legalDisclaimer?.content, - onChange: formik.handleChange, + value: elementsForm.values.elements?.legalDisclaimer?.content, + onChange: elementsForm.handleChange, }} /> @@ -156,18 +177,18 @@ const ServiceSettings: React.FC = () => { description="A place to communicate FAQs, useful tips, or contact information" switchProps={{ name: "elements.help.show", - checked: formik.values.elements?.help?.show, - onChange: formik.handleChange, + checked: elementsForm.values.elements?.help?.show, + onChange: elementsForm.handleChange, }} headingInputProps={{ name: "elements.help.heading", - value: formik.values.elements?.help?.heading, - onChange: formik.handleChange, + value: elementsForm.values.elements?.help?.heading, + onChange: elementsForm.handleChange, }} contentInputProps={{ name: "elements.help.content", - value: formik.values.elements?.help?.content, - onChange: formik.handleChange, + value: elementsForm.values.elements?.help?.content, + onChange: elementsForm.handleChange, }} /> @@ -178,18 +199,18 @@ const ServiceSettings: React.FC = () => { description="Your privacy policy" switchProps={{ name: "elements.privacy.show", - checked: formik.values.elements?.privacy?.show, - onChange: formik.handleChange, + checked: elementsForm.values.elements?.privacy?.show, + onChange: elementsForm.handleChange, }} headingInputProps={{ name: "elements.privacy.heading", - value: formik.values.elements?.privacy?.heading, - onChange: formik.handleChange, + value: elementsForm.values.elements?.privacy?.heading, + onChange: elementsForm.handleChange, }} contentInputProps={{ name: "elements.privacy.content", - value: formik.values.elements?.privacy?.content, - onChange: formik.handleChange, + value: elementsForm.values.elements?.privacy?.content, + onChange: elementsForm.handleChange, }} /> @@ -200,25 +221,82 @@ const ServiceSettings: React.FC = () => { type="submit" variant="contained" color="primary" - disabled={!formik.dirty} + disabled={!elementsForm.dirty} > Update elements - - - Service settings updated successfully - - - +
+ + + + Status + + + Manage the status of your service. + + + + + statusForm.setFieldValue( + "status", + statusForm.values.status == "online" ? "offline" : "online", + ) + } + /> + } + /> + + Toggle your service between "offline" and "online". + + + A service must be online to be accessed by the public, and to enable + analytics gathering. + + + + + + + + + + Service settings updated successfully + +
); }; diff --git a/editor.planx.uk/src/pages/FlowEditor/lib/store/settings.ts b/editor.planx.uk/src/pages/FlowEditor/lib/store/settings.ts index 6c0d6e3a88..e420fbb4c4 100644 --- a/editor.planx.uk/src/pages/FlowEditor/lib/store/settings.ts +++ b/editor.planx.uk/src/pages/FlowEditor/lib/store/settings.ts @@ -1,4 +1,5 @@ import { gql } from "@apollo/client"; +import { FlowStatus } from "@opensystemslab/planx-core/types"; import camelcaseKeys from "camelcase-keys"; import { client } from "lib/graphql"; import { @@ -15,6 +16,9 @@ import { TeamStore } from "./team"; export interface SettingsStore { flowSettings?: FlowSettings; setFlowSettings: (flowSettings?: FlowSettings) => void; + flowStatus?: FlowStatus; + setFlowStatus: (flowStatus: FlowStatus) => void; + updateFlowStatus: (newStatus: FlowStatus) => Promise; globalSettings?: GlobalSettings; setGlobalSettings: (globalSettings: GlobalSettings) => void; updateFlowSettings: (newSettings: FlowSettings) => Promise; @@ -33,6 +37,19 @@ export const settingsStore: StateCreator< setFlowSettings: (flowSettings) => set({ flowSettings }), + flowStatus: undefined, + + setFlowStatus: (flowStatus) => set({ flowStatus }), + + updateFlowStatus: async (newStatus) => { + const { id, $client } = get(); + const result = await $client.flow.setStatus({ + flow: { id }, + status: newStatus, + }); + return Boolean(result?.id); + }, + globalSettings: undefined, setGlobalSettings: (globalSettings) => { diff --git a/editor.planx.uk/src/routes/flowSettings.tsx b/editor.planx.uk/src/routes/flowSettings.tsx index 38c1f60e7d..b06ce1406e 100644 --- a/editor.planx.uk/src/routes/flowSettings.tsx +++ b/editor.planx.uk/src/routes/flowSettings.tsx @@ -1,5 +1,5 @@ +import { FlowStatus } from "@opensystemslab/planx-core/types"; import gql from "graphql-tag"; -import { publicClient } from "lib/graphql"; import { compose, map, @@ -17,6 +17,7 @@ import Submissions from "pages/FlowEditor/components/Settings/Submissions"; import { useStore } from "pages/FlowEditor/lib/store"; import React from "react"; +import { client } from "../lib/graphql"; import Settings, { SettingsTab } from "../pages/FlowEditor/components/Settings"; import type { FlowSettings } from "../types"; import { makeTitle } from "./utils"; @@ -25,15 +26,16 @@ interface GetFlowSettings { flows: { id: string; settings: FlowSettings; + status: FlowStatus; }[]; } export const getFlowSettings = async (req: NaviRequest) => { const { data: { - flows: [{ settings }], + flows: [{ settings, status }], }, - } = await publicClient.query({ + } = await client.query({ query: gql` query GetFlow($slug: String!, $team_slug: String!) { flows( @@ -42,6 +44,7 @@ export const getFlowSettings = async (req: NaviRequest) => { ) { id settings + status } } `, @@ -52,6 +55,7 @@ export const getFlowSettings = async (req: NaviRequest) => { }); useStore.getState().setFlowSettings(settings); + useStore.getState().setFlowStatus(status); }; const tabs: SettingsTab[] = [