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

Production deploy #4164

Merged
merged 6 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions api.planx.uk/modules/send/uniform/uniform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,10 @@ export const sendToUniform: SendIntegrationController = async (
const errorMessage = isAxiosError(error)
? JSON.stringify(error.response?.data)
: (error as Error).message;
return next({
error,
message: `Failed to send to Uniform (${localAuthority}): ${errorMessage}`,
});

throw Error(
`Failed to send to Uniform (${localAuthority}): ${errorMessage}`,
);
}
};

Expand Down
1 change: 1 addition & 0 deletions editor.planx.uk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"subscriptions-transport-ws": "^0.11.0",
"swr": "^2.2.4",
"tippy.js": "^6.3.7",
"type-fest": "^4.32.0",
"uuid": "^9.0.1",
"vite": "^5.4.6",
"vite-jest": "^0.1.4",
Expand Down
10 changes: 4 additions & 6 deletions editor.planx.uk/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 14 additions & 12 deletions editor.planx.uk/src/@planx/components/Checklist/Editor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ export const ChecklistEditor: React.FC<ChecklistProps> = (props) => {
...values,
...(groupedOptions
? {
categories: groupedOptions.map((group) => ({
title: group.title,
count: group.children.length,
})),
}
categories: groupedOptions.map((group) => ({
title: group.title,
count: group.children.length,
})),
}
: {
categories: undefined,
}),
categories: undefined,
}),
},
},
processedOptions,
Expand All @@ -89,7 +89,7 @@ export const ChecklistEditor: React.FC<ChecklistProps> = (props) => {
}
if (values.fn && !options?.some((option) => option.data.val)) {
errors.fn =
"At least one option must set a data value when the checklist has a data field";
"At least one option must also set a data field";
}
if (exclusiveOptions && exclusiveOptions.length > 1) {
errors.options =
Expand Down Expand Up @@ -139,10 +139,12 @@ export const ChecklistEditor: React.FC<ChecklistProps> = (props) => {
onChange={formik.handleChange}
/>
</InputRow>
<DataFieldAutocomplete
value={formik.values.fn}
onChange={(value) => formik.setFieldValue("fn", value)}
/>
<ErrorWrapper error={formik.errors.fn}>
<DataFieldAutocomplete
value={formik.values.fn}
onChange={(value) => formik.setFieldValue("fn", value)}
/>
</ErrorWrapper>
<InputRow>
<Switch
checked={!!formik.values.groupedOptions}
Expand Down
19 changes: 11 additions & 8 deletions editor.planx.uk/src/@planx/components/Question/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ListManager from "ui/editor/ListManager/ListManager";
import ModalSection from "ui/editor/ModalSection";
import ModalSectionContent from "ui/editor/ModalSectionContent";
import RichTextInput from "ui/editor/RichTextInput/RichTextInput";
import ErrorWrapper from "ui/shared/ErrorWrapper";
import Input from "ui/shared/Input/Input";
import InputRow from "ui/shared/InputRow";
import { Switch } from "ui/shared/Switch";
Expand Down Expand Up @@ -68,7 +69,7 @@ export const Question: React.FC<Props> = (props) => {
const errors: FormikErrors<FormikValues> = {};
if (values.fn && !options.some((option) => option.data.val)) {
errors.fn =
"At least one option must set a data value when the question has a data field";
"At least one option must also set a data field";
}
return errors;
},
Expand Down Expand Up @@ -116,11 +117,13 @@ export const Question: React.FC<Props> = (props) => {
onChange={formik.handleChange}
/>
</InputRow>
<DataFieldAutocomplete
schema={schema?.nodes}
value={formik.values.fn}
onChange={(value) => formik.setFieldValue("fn", value)}
/>
<ErrorWrapper error={formik.errors.fn}>
<DataFieldAutocomplete
schema={schema?.nodes}
value={formik.values.fn}
onChange={(value) => formik.setFieldValue("fn", value)}
/>
</ErrorWrapper>
<InputRow>
<Switch
checked={formik.values.neverAutoAnswer}
Expand Down Expand Up @@ -151,8 +154,8 @@ export const Question: React.FC<Props> = (props) => {
}) as Option
}
Editor={QuestionOptionsEditor}
editorExtraProps={{
showValueField: !!formik.values.fn,
editorExtraProps={{
showValueField: !!formik.values.fn,
schema: getOptionsSchemaByFn(formik.values.fn, schema?.options, initialOptionVals),
}}
/>
Expand Down
9 changes: 7 additions & 2 deletions editor.planx.uk/src/@planx/components/Send/Public.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { SendIntegration } from "@opensystemslab/planx-core/types";
import { waitFor } from "@testing-library/react";
import { screen, waitFor } from "@testing-library/react";
import axios from "axios";
import { FullStore, useStore } from "pages/FlowEditor/lib/store";
import React from "react";
import { act } from "react-dom/test-utils";
import * as ReactNavi from "react-navi";
import { setup } from "testUtils";
import { it,vi } from "vitest";
import { it, vi } from "vitest";
import { axe } from "vitest-axe";

import hasuraEventsResponseMock from "./mocks/hasuraEventsResponseMock";
Expand All @@ -16,6 +17,10 @@ const { getState, setState } = useStore;

let initialState: FullStore;

vi.spyOn(ReactNavi, "useNavigation").mockImplementation(
() => ({ navigate: vi.fn() }) as any,
);

/**
* Adds a small tick to allow MUI to render (e.g. card transitions)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ export const BaseOptionsEditor: React.FC<BaseOptionsEditorProps> = (props) => (
)}
{props.showValueField && (
<DataFieldAutocomplete
key={`${props.value.id}-data-field-autocomplete`}
schema={props.schema}
value={props.value.data.val || ""}
value={props.value.data.val}
onChange={(targetValue) => {
props.onChange({
...props.value,
Expand Down
23 changes: 4 additions & 19 deletions editor.planx.uk/src/@planx/components/shared/Preview/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ import Button from "@mui/material/Button";
import Container from "@mui/material/Container";
import Fade from "@mui/material/Fade";
import { styled, Theme, useTheme } from "@mui/material/styles";
import { ComponentType as TYPES } from "@opensystemslab/planx-core/types";
import { useAnalyticsTracking } from "pages/FlowEditor/lib/analytics/provider";
import { useStore } from "pages/FlowEditor/lib/store";
import React, { useEffect } from "react";
import { ApplicationPath } from "types";

import SaveResumeButton from "./SaveResumeButton";
import OrNavigationButton from "./OrNavigationButton";

interface Props {
children: React.ReactNode;
Expand Down Expand Up @@ -41,6 +39,7 @@ const InnerContainer = styled(Box)(({ theme }) => ({
* @param {object} props Component props
* @param {bool} props.handleSubmit if included then show the Continue button
* @param {bool} props.isValid if falsey then disable Continue button, otherwise enable
* @param {bool} props.isTestWarningWrapper if truthy then show navigate to publish Or button
*/
const Card: React.FC<Props> = ({
children,
Expand All @@ -49,21 +48,7 @@ const Card: React.FC<Props> = ({
...props
}) => {
const theme = useTheme();
const [path, visibleNode, breadcrumbs, flow] = useStore((state) => [
state.path,
state.currentCard,
state.breadcrumbs,
state.flow,
]);

// Check if we have a Send node in our breadcrumbs
// This is a better/more immediate proxy for "submitted" in the frontend because actual send events that populate lowcal_sessions.submitted_at are queued via Hasura
const hasSent = Object.keys(breadcrumbs).some(
(breadcrumbNodeId: string) => flow[breadcrumbNodeId]?.type === TYPES.Send,
);

const showSaveResumeButton =
path === ApplicationPath.SaveAndReturn && handleSubmit && !hasSent;
const [visibleNode] = useStore((state) => [state.currentCard]);
const { track } = useAnalyticsTracking();

useEffect(() => {
Expand Down Expand Up @@ -101,7 +86,7 @@ const Card: React.FC<Props> = ({
Continue
</Button>
)}
{showSaveResumeButton && <SaveResumeButton />}
<OrNavigationButton handleSubmit={handleSubmit} />
</Box>
</InnerContainer>
</Container>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Link from "@mui/material/Link";
import Typography from "@mui/material/Typography";
import { clearLocalFlow } from "lib/local";
import { useStore } from "pages/FlowEditor/lib/store";
import React from "react";
import { useNavigation } from "react-navi";

const NavigateToPublishedButton: React.FC = () => {
const { navigate } = useNavigation();
const id = useStore().id;

const handleClick = () => {
clearLocalFlow(id);
navigate("published?analytics=false");
window.location.reload();
};

return (
<Link onClick={handleClick} component="button">
<Typography variant="body1" textAlign="left">
Go to the published version of this service
</Typography>
</Link>
);
};

export default NavigateToPublishedButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import Box from "@mui/material/Box";
import { styled } from "@mui/material/styles";
import Typography from "@mui/material/Typography";
import { ComponentType as TYPES } from "@opensystemslab/planx-core/types";
import { useStore } from "pages/FlowEditor/lib/store";
import React from "react";
import { ApplicationPath } from "types";

import { contentFlowSpacing } from "./Card";
import NavigateToPublishedButton from "./NavigateToPublishedButton";
import SaveResumeButton from "./SaveResumeButton";

type OrNavigationType = "save-resume" | "navigate-to-published";

export const InnerContainer = styled(Box)(({ theme }) => ({
"& p": {
...contentFlowSpacing(theme),
},
}));

const BUTTON_COMPONENTS = {
"save-resume": SaveResumeButton,
"navigate-to-published": NavigateToPublishedButton,
} as const;

const TEST_ENVIRONMENTS = new Set(["preview", "draft"]);

const OrNavigationButton = ({
handleSubmit,
}: {
handleSubmit: ((data?: unknown) => void) | undefined;
}) => {
const [path, breadcrumbs, flow, hasAcknowledgedWarning] = useStore(
(state) => [
state.path,
state.breadcrumbs,
state.flow,
state.hasAcknowledgedWarning,
],
);

const endOfUrl = window.location.pathname.split("/").slice(-1)[0];

const isTestEnvironment = TEST_ENVIRONMENTS.has(endOfUrl);

const defineNavigationType = (): OrNavigationType | undefined => {
// Check if we have a Send node in our breadcrumbs
// This is a better/more immediate proxy for "submitted" in the frontend because actual send events that populate lowcal_sessions.submitted_at are queued via Hasura
const hasSent = Object.keys(breadcrumbs).some(
(breadcrumbNodeId: string) => flow[breadcrumbNodeId]?.type === TYPES.Send,
);

const showSaveResumeButton =
path === ApplicationPath.SaveAndReturn && handleSubmit && !hasSent;

if (showSaveResumeButton && !isTestEnvironment) {
return "save-resume";
}

if (!showSaveResumeButton && isTestEnvironment && !hasAcknowledgedWarning) {
return "navigate-to-published";
}
};

const orNavigationType = defineNavigationType();

if (!orNavigationType) return null;

const ButtonComponent = BUTTON_COMPONENTS[orNavigationType];

return (
ButtonComponent && (
<InnerContainer>
<Typography variant="body1">or</Typography>
<ButtonComponent />
</InnerContainer>
)
);
};

export default OrNavigationButton;
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
import Box from "@mui/material/Box";
import Link from "@mui/material/Link";
import { styled } from "@mui/material/styles";
import Typography from "@mui/material/Typography";
import { useAnalyticsTracking } from "pages/FlowEditor/lib/analytics/provider";
import { useStore } from "pages/FlowEditor/lib/store";
import React from "react";
import { ApplicationPath } from "types";

import { contentFlowSpacing } from "./Card";

const InnerContainer = styled(Box)(({ theme }) => ({
"& p": {
...contentFlowSpacing(theme),
},
}));

const SaveResumeButton: React.FC = () => {
const saveToEmail = useStore((state) => state.saveToEmail);
const { trackEvent } = useAnalyticsTracking();
Expand All @@ -33,19 +22,14 @@ const SaveResumeButton: React.FC = () => {
}
};

const onClick = () => handleClick();

return (
<InnerContainer>
<Typography variant="body1">or</Typography>
<Link component="button" onClick={onClick}>
<Typography variant="body1" textAlign="left">
{saveToEmail
? "Save and return to this application later"
: "Resume an application you have already started"}
</Typography>
</Link>
</InnerContainer>
<Link component="button" onClick={handleClick}>
<Typography variant="body1" textAlign="left">
{saveToEmail
? "Save and return to this application later"
: "Resume an application you have already started"}
</Typography>
</Link>
);
};

Expand Down
Loading
Loading