diff --git a/api.planx.uk/package.json b/api.planx.uk/package.json index 3f17c1f479..27b1560166 100644 --- a/api.planx.uk/package.json +++ b/api.planx.uk/package.json @@ -13,7 +13,7 @@ "@airbrake/node": "^2.1.8", "@aws-sdk/client-s3": "^3.696.0", "@aws-sdk/s3-request-presigner": "^3.701.0", - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#ccf9ac3", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#29b4851", "@types/isomorphic-fetch": "^0.0.36", "adm-zip": "^0.5.10", "axios": "^1.7.4", diff --git a/api.planx.uk/pnpm-lock.yaml b/api.planx.uk/pnpm-lock.yaml index e1beae8474..9279cf8f9e 100644 --- a/api.planx.uk/pnpm-lock.yaml +++ b/api.planx.uk/pnpm-lock.yaml @@ -21,8 +21,8 @@ dependencies: specifier: ^3.701.0 version: 3.701.0 '@opensystemslab/planx-core': - specifier: git+https://github.com/theopensystemslab/planx-core#ccf9ac3 - version: github.com/theopensystemslab/planx-core/ccf9ac3 + specifier: git+https://github.com/theopensystemslab/planx-core#29b4851 + version: github.com/theopensystemslab/planx-core/29b4851 '@types/isomorphic-fetch': specifier: ^0.0.36 version: 0.0.36 @@ -3959,8 +3959,8 @@ packages: dependencies: esutils: 2.0.3 - /docx@9.0.3: - resolution: {integrity: sha512-Ao/8v1BIRL0+uhzoqk6uvAPIjxNR5+uqQMphVWe8egxGdohkd/PgDLn1/+/c/te1DlnX1Chz9lIxuNi0Hs+Dbg==} + /docx@9.1.0: + resolution: {integrity: sha512-XOtseSTRrkKN/sV5jNBqyLazyhNpWfaUhpuKc22cs+5DavNjRQvchnohb0g0S+x/96/D06U/i0/U/Gc4E5kwuQ==} engines: {node: '>=10'} dependencies: '@types/node': 22.9.0 @@ -5225,7 +5225,7 @@ packages: js-yaml: 4.1.0 lodash: 4.17.21 minimist: 1.2.8 - prettier: 3.3.3 + prettier: 3.4.2 tinyglobby: 0.2.10 dev: false @@ -5481,8 +5481,8 @@ packages: semver: 7.6.3 dev: true - /marked@14.1.4: - resolution: {integrity: sha512-vkVZ8ONmUdPnjCKc5uTRvmkRbx4EAi2OkTOXmfTDhZz3OFqMNBM1oTTWwTr4HY4uAEojhzPf+Fy8F1DWa3Sndg==} + /marked@15.0.3: + resolution: {integrity: sha512-Ai0cepvl2NHnTcO9jYDtcOEtVBNVYR31XnEA3BndO7f5As1wzpcOceSUM8FDkNLJNIODcLpDTWay/qQhqbuMvg==} engines: {node: '>= 18'} hasBin: true dev: false @@ -6059,8 +6059,8 @@ packages: hasBin: true dev: true - /prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + /prettier@3.4.2: + resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} engines: {node: '>=14'} hasBin: true dev: false @@ -6891,8 +6891,8 @@ packages: engines: {node: '>=16'} dev: false - /type-fest@4.27.0: - resolution: {integrity: sha512-3IMSWgP7C5KSQqmo1wjhKrwsvXAtF33jO3QY+Uy++ia7hqvgSK6iXbbg5PbDBc1P2ZbNEDgejOrN4YooXvhwCw==} + /type-fest@4.30.0: + resolution: {integrity: sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==} engines: {node: '>=16'} dev: false @@ -7306,8 +7306,8 @@ packages: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} dev: false - github.com/theopensystemslab/planx-core/ccf9ac3: - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/ccf9ac3} + github.com/theopensystemslab/planx-core/29b4851: + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/29b4851} name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true @@ -7322,18 +7322,18 @@ packages: ajv-formats: 2.1.1(ajv@8.17.1) cheerio: 1.0.0 copyfiles: 2.4.1 - docx: 9.0.3 + docx: 9.1.0 eslint: 8.57.1 fast-xml-parser: 4.5.0 graphql: 16.9.0 graphql-request: 6.1.0(graphql@16.9.0) json-schema-to-typescript: 15.0.3 lodash: 4.17.21 - marked: 14.1.4 - prettier: 3.3.3 + marked: 15.0.3 + prettier: 3.4.2 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - type-fest: 4.27.0 + type-fest: 4.30.0 uuid: 11.0.3 zod: 3.23.8 transitivePeerDependencies: diff --git a/e2e/tests/api-driven/package.json b/e2e/tests/api-driven/package.json index 074c8c301b..606a64005e 100644 --- a/e2e/tests/api-driven/package.json +++ b/e2e/tests/api-driven/package.json @@ -7,7 +7,7 @@ "packageManager": "pnpm@8.6.6", "dependencies": { "@cucumber/cucumber": "^9.3.0", - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#ccf9ac3", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#29b4851", "axios": "^1.7.4", "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 26645a568a..e9f30826e1 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#ccf9ac3 - version: github.com/theopensystemslab/planx-core/ccf9ac3 + specifier: git+https://github.com/theopensystemslab/planx-core#29b4851 + version: github.com/theopensystemslab/planx-core/29b4851 axios: specifier: ^1.7.4 version: 1.7.4 @@ -1209,8 +1209,8 @@ packages: esutils: 2.0.3 dev: false - /docx@9.0.3: - resolution: {integrity: sha512-Ao/8v1BIRL0+uhzoqk6uvAPIjxNR5+uqQMphVWe8egxGdohkd/PgDLn1/+/c/te1DlnX1Chz9lIxuNi0Hs+Dbg==} + /docx@9.1.0: + resolution: {integrity: sha512-XOtseSTRrkKN/sV5jNBqyLazyhNpWfaUhpuKc22cs+5DavNjRQvchnohb0g0S+x/96/D06U/i0/U/Gc4E5kwuQ==} engines: {node: '>=10'} dependencies: '@types/node': 22.9.0 @@ -1785,7 +1785,7 @@ packages: js-yaml: 4.1.0 lodash: 4.17.21 minimist: 1.2.8 - prettier: 3.3.3 + prettier: 3.4.2 tinyglobby: 0.2.10 dev: false @@ -1955,8 +1955,8 @@ packages: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: true - /marked@14.1.4: - resolution: {integrity: sha512-vkVZ8ONmUdPnjCKc5uTRvmkRbx4EAi2OkTOXmfTDhZz3OFqMNBM1oTTWwTr4HY4uAEojhzPf+Fy8F1DWa3Sndg==} + /marked@15.0.3: + resolution: {integrity: sha512-Ai0cepvl2NHnTcO9jYDtcOEtVBNVYR31XnEA3BndO7f5As1wzpcOceSUM8FDkNLJNIODcLpDTWay/qQhqbuMvg==} engines: {node: '>= 18'} hasBin: true dev: false @@ -2191,8 +2191,8 @@ packages: engines: {node: '>= 0.8.0'} dev: false - /prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + /prettier@3.4.2: + resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} engines: {node: '>=14'} hasBin: true dev: false @@ -2607,8 +2607,8 @@ packages: engines: {node: '>=10'} dev: false - /type-fest@4.27.0: - resolution: {integrity: sha512-3IMSWgP7C5KSQqmo1wjhKrwsvXAtF33jO3QY+Uy++ia7hqvgSK6iXbbg5PbDBc1P2ZbNEDgejOrN4YooXvhwCw==} + /type-fest@4.30.0: + resolution: {integrity: sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==} engines: {node: '>=16'} dev: false @@ -2810,8 +2810,8 @@ packages: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} dev: false - github.com/theopensystemslab/planx-core/ccf9ac3: - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/ccf9ac3} + github.com/theopensystemslab/planx-core/29b4851: + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/29b4851} name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true @@ -2826,18 +2826,18 @@ packages: ajv-formats: 2.1.1(ajv@8.17.1) cheerio: 1.0.0 copyfiles: 2.4.1 - docx: 9.0.3 + docx: 9.1.0 eslint: 8.57.1 fast-xml-parser: 4.5.0 graphql: 16.9.0 graphql-request: 6.1.0(graphql@16.9.0) json-schema-to-typescript: 15.0.3 lodash: 4.17.21 - marked: 14.1.4 - prettier: 3.3.3 + marked: 15.0.3 + prettier: 3.4.2 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - type-fest: 4.27.0 + type-fest: 4.30.0 uuid: 11.0.3 zod: 3.23.8 transitivePeerDependencies: diff --git a/e2e/tests/ui-driven/package.json b/e2e/tests/ui-driven/package.json index b5aaa364e3..514b990987 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#ccf9ac3", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#29b4851", "axios": "^1.7.4", "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 75407766b7..4552b235fd 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#ccf9ac3 - version: github.com/theopensystemslab/planx-core/ccf9ac3 + specifier: git+https://github.com/theopensystemslab/planx-core#29b4851 + version: github.com/theopensystemslab/planx-core/29b4851 axios: specifier: ^1.7.4 version: 1.7.4 @@ -1090,8 +1090,8 @@ packages: dependencies: esutils: 2.0.3 - /docx@9.0.3: - resolution: {integrity: sha512-Ao/8v1BIRL0+uhzoqk6uvAPIjxNR5+uqQMphVWe8egxGdohkd/PgDLn1/+/c/te1DlnX1Chz9lIxuNi0Hs+Dbg==} + /docx@9.1.0: + resolution: {integrity: sha512-XOtseSTRrkKN/sV5jNBqyLazyhNpWfaUhpuKc22cs+5DavNjRQvchnohb0g0S+x/96/D06U/i0/U/Gc4E5kwuQ==} engines: {node: '>=10'} dependencies: '@types/node': 22.9.0 @@ -1690,7 +1690,7 @@ packages: js-yaml: 4.1.0 lodash: 4.17.21 minimist: 1.2.8 - prettier: 3.3.3 + prettier: 3.4.2 tinyglobby: 0.2.10 dev: false @@ -1814,8 +1814,8 @@ packages: js-tokens: 4.0.0 dev: false - /marked@14.1.4: - resolution: {integrity: sha512-vkVZ8ONmUdPnjCKc5uTRvmkRbx4EAi2OkTOXmfTDhZz3OFqMNBM1oTTWwTr4HY4uAEojhzPf+Fy8F1DWa3Sndg==} + /marked@15.0.3: + resolution: {integrity: sha512-Ai0cepvl2NHnTcO9jYDtcOEtVBNVYR31XnEA3BndO7f5As1wzpcOceSUM8FDkNLJNIODcLpDTWay/qQhqbuMvg==} engines: {node: '>= 18'} hasBin: true dev: false @@ -2072,8 +2072,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - /prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + /prettier@3.4.2: + resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} engines: {node: '>=14'} hasBin: true dev: false @@ -2431,8 +2431,8 @@ packages: engines: {node: '>=12.20'} dev: false - /type-fest@4.27.0: - resolution: {integrity: sha512-3IMSWgP7C5KSQqmo1wjhKrwsvXAtF33jO3QY+Uy++ia7hqvgSK6iXbbg5PbDBc1P2ZbNEDgejOrN4YooXvhwCw==} + /type-fest@4.30.0: + resolution: {integrity: sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==} engines: {node: '>=16'} dev: false @@ -2599,8 +2599,8 @@ packages: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} dev: false - github.com/theopensystemslab/planx-core/ccf9ac3: - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/ccf9ac3} + github.com/theopensystemslab/planx-core/29b4851: + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/29b4851} name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true @@ -2615,18 +2615,18 @@ packages: ajv-formats: 2.1.1(ajv@8.17.1) cheerio: 1.0.0 copyfiles: 2.4.1 - docx: 9.0.3 + docx: 9.1.0 eslint: 8.57.1 fast-xml-parser: 4.5.0 graphql: 16.9.0 graphql-request: 6.1.0(graphql@16.9.0) json-schema-to-typescript: 15.0.3 lodash: 4.17.21 - marked: 14.1.4 - prettier: 3.3.3 + marked: 15.0.3 + prettier: 3.4.2 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - type-fest: 4.27.0 + type-fest: 4.30.0 uuid: 11.0.3 zod: 3.23.8 transitivePeerDependencies: diff --git a/e2e/tests/ui-driven/src/create-flow.spec.ts b/e2e/tests/ui-driven/src/create-flow.spec.ts index f681ad01de..921e2a54a9 100644 --- a/e2e/tests/ui-driven/src/create-flow.spec.ts +++ b/e2e/tests/ui-driven/src/create-flow.spec.ts @@ -5,7 +5,11 @@ import { tearDownTestContext, } from "./helpers/context"; import { getTeamPage } from "./helpers/getPage"; -import { createAuthenticatedSession } from "./helpers/globalHelpers"; +import { + createAuthenticatedSession, + filterFlags, + selectedFlag, +} from "./helpers/globalHelpers"; import { answerAddressInput, answerChecklist, @@ -79,7 +83,7 @@ test.describe("Flow creation, publish and preview", () => { await editor.createList(); await editor.createTaskList(); await editor.createContent(); - + await editor.createFilter(); await editor.createResult(); await editor.createNextSteps(); await editor.createReview(); @@ -99,6 +103,7 @@ test.describe("Flow creation, publish and preview", () => { "A list title", "What you should do next", "Some content", + ...filterFlags, "Planning permission", // default result flag "Next steps", "Check your answers before sending your application", @@ -336,6 +341,14 @@ test.describe("Flow creation, publish and preview", () => { await expect(page.locator("p", { hasText: "Some content" })).toBeVisible(); await clickContinue({ page }); + // this is the content placed in the filtered branch + await expect( + page.locator("p", { + hasText: `This is the ${selectedFlag} filter`, + }), + ).toBeVisible(); + await clickContinue({ page }); + await expect(page.locator("h1", { hasText: "No result" })).toBeVisible(); await clickContinue({ page }); diff --git a/e2e/tests/ui-driven/src/helpers/addComponent.ts b/e2e/tests/ui-driven/src/helpers/addComponent.ts index d6d523b0fa..0ad8f252d1 100644 --- a/e2e/tests/ui-driven/src/helpers/addComponent.ts +++ b/e2e/tests/ui-driven/src/helpers/addComponent.ts @@ -3,6 +3,7 @@ import { expect, Locator, Page } from "@playwright/test"; import { contextDefaults } from "./context"; import { externalPortalServiceProps } from "./serviceData"; import { OptionWithDataValues } from "./types"; +import { selectedFlag } from "./globalHelpers"; const createBaseComponent = async ( page: Page, @@ -123,6 +124,10 @@ const createBaseComponent = async ( .fill(options?.[0] || ""); break; case ComponentType.Filter: + await page + .getByTestId("flagset-category-select") + .selectOption(selectedFlag); + break; case ComponentType.Feedback: break; case ComponentType.InternalPortal: @@ -359,6 +364,9 @@ async function createComponentOptions( await page.getByPlaceholder("Option").nth(index).fill(option); index++; } + + await page.getByPlaceholder("Flags (up to one per category)").nth(1).click(); + await page.getByRole("option", { name: selectedFlag, exact: true }).click(); } async function createComponentOptionsWithDataValues( diff --git a/e2e/tests/ui-driven/src/helpers/globalHelpers.ts b/e2e/tests/ui-driven/src/helpers/globalHelpers.ts index f580449673..ec39631eae 100644 --- a/e2e/tests/ui-driven/src/helpers/globalHelpers.ts +++ b/e2e/tests/ui-driven/src/helpers/globalHelpers.ts @@ -1,8 +1,9 @@ import { FlowGraph } from "@opensystemslab/planx-core/types"; -import type { Browser, Page, Request } from "@playwright/test"; +import { type Browser, type Page, type Request } from "@playwright/test"; import { gql } from "graphql-request"; import { generateAuthenticationToken, getGraphQLClient } from "./context"; import { TestContext } from "./types"; +import { flatFlags } from "@opensystemslab/planx-core/types"; // Test card numbers to be used in gov.uk sandbox environment // reference: https://docs.payments.service.gov.uk/testing_govuk_pay/#if-you-39-re-using-a-test-39-sandbox-39-account @@ -80,6 +81,11 @@ export async function setFeatureFlag(page: Page, featureFlag: string) { ); } +export const selectedFlag = "Material change of use"; +export const filterFlags = flatFlags + .filter((flag) => flag.category === selectedFlag) + .map((flag) => flag.text); + export async function getSessionId(page: Page): Promise { // @ts-expect-error - Property api does not exist on type Window & typeof globalThis const sessionId = page.evaluate(() => window.api.getState().sessionId); diff --git a/e2e/tests/ui-driven/src/pages/Editor.ts b/e2e/tests/ui-driven/src/pages/Editor.ts index 0439cd71ce..779304e23d 100644 --- a/e2e/tests/ui-driven/src/pages/Editor.ts +++ b/e2e/tests/ui-driven/src/pages/Editor.ts @@ -30,6 +30,7 @@ import { createUploadAndLabel, } from "../helpers/addComponent"; import { OptionWithDataValues } from "../helpers/types"; +import { selectedFlag } from "../helpers/globalHelpers"; export class PlaywrightEditor { readonly page: Page; @@ -246,6 +247,18 @@ export class PlaywrightEditor { async createFilter() { await createFilter(this.page, this.getNextNode()); + // select the branch filter and add some content + const filteredBranch = this.page + .locator("li") + .filter({ hasText: /Material change of use$/ }) + .getByRole("listitem") + .getByRole("link"); + + await createContent( + this.page, + filteredBranch, + `This is the ${selectedFlag} filter`, + ); } async createInternalPortal() { diff --git a/editor.planx.uk/package.json b/editor.planx.uk/package.json index 637e6d9f84..d81643d9a0 100644 --- a/editor.planx.uk/package.json +++ b/editor.planx.uk/package.json @@ -15,7 +15,7 @@ "@mui/material": "^5.15.10", "@mui/utils": "^5.15.11", "@opensystemslab/map": "1.0.0-alpha.4", - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#ccf9ac3", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#29b4851", "@tiptap/core": "^2.4.0", "@tiptap/extension-bold": "^2.0.3", "@tiptap/extension-bubble-menu": "^2.1.13", diff --git a/editor.planx.uk/pnpm-lock.yaml b/editor.planx.uk/pnpm-lock.yaml index c985baee32..c683e55797 100644 --- a/editor.planx.uk/pnpm-lock.yaml +++ b/editor.planx.uk/pnpm-lock.yaml @@ -48,8 +48,8 @@ dependencies: specifier: 1.0.0-alpha.4 version: 1.0.0-alpha.4 '@opensystemslab/planx-core': - specifier: git+https://github.com/theopensystemslab/planx-core#ccf9ac3 - version: github.com/theopensystemslab/planx-core/ccf9ac3(@types/react@18.2.45) + specifier: git+https://github.com/theopensystemslab/planx-core#29b4851 + version: github.com/theopensystemslab/planx-core/29b4851(@types/react@18.2.45) '@tiptap/core': specifier: ^2.4.0 version: 2.4.0(@tiptap/pm@2.0.3) @@ -3291,7 +3291,7 @@ packages: '@babel/runtime': 7.26.0 '@floating-ui/react-dom': 2.1.2(react-dom@18.2.0)(react@18.2.0) '@mui/types': 7.2.19(@types/react@18.2.45) - '@mui/utils': 5.15.11(@types/react@18.2.45)(react@18.2.0) + '@mui/utils': 5.16.6(@types/react@18.2.45)(react@18.2.0) '@popperjs/core': 2.11.8 '@types/react': 18.2.45 clsx: 2.1.1 @@ -3314,7 +3314,7 @@ packages: '@babel/runtime': 7.26.0 '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1)(react@18.3.1) '@mui/types': 7.2.19(@types/react@18.2.45) - '@mui/utils': 5.15.11(@types/react@18.2.45)(react@18.3.1) + '@mui/utils': 5.16.6(@types/react@18.2.45)(react@18.3.1) '@popperjs/core': 2.11.8 '@types/react': 18.2.45 clsx: 2.1.1 @@ -4279,7 +4279,7 @@ packages: '@storybook/csf': 0.1.11 '@storybook/global': 5.0.0 '@storybook/icons': 1.2.12(react-dom@18.2.0)(react@18.2.0) - '@types/lodash': 4.14.202 + '@types/lodash': 4.17.13 color-convert: 2.0.1 dequal: 2.0.3 lodash: 4.17.21 @@ -5490,7 +5490,6 @@ packages: /@types/lodash@4.17.13: resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==} - dev: false /@types/markdown-it@14.1.2: resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} @@ -7634,8 +7633,8 @@ packages: dependencies: esutils: 2.0.3 - /docx@9.0.3: - resolution: {integrity: sha512-Ao/8v1BIRL0+uhzoqk6uvAPIjxNR5+uqQMphVWe8egxGdohkd/PgDLn1/+/c/te1DlnX1Chz9lIxuNi0Hs+Dbg==} + /docx@9.1.0: + resolution: {integrity: sha512-XOtseSTRrkKN/sV5jNBqyLazyhNpWfaUhpuKc22cs+5DavNjRQvchnohb0g0S+x/96/D06U/i0/U/Gc4E5kwuQ==} engines: {node: '>=10'} dependencies: '@types/node': 22.9.0 @@ -10023,7 +10022,7 @@ packages: js-yaml: 4.1.0 lodash: 4.17.21 minimist: 1.2.8 - prettier: 3.3.3 + prettier: 3.4.2 tinyglobby: 0.2.10 dev: false @@ -10450,8 +10449,8 @@ packages: react: 18.2.0 dev: true - /marked@14.1.4: - resolution: {integrity: sha512-vkVZ8ONmUdPnjCKc5uTRvmkRbx4EAi2OkTOXmfTDhZz3OFqMNBM1oTTWwTr4HY4uAEojhzPf+Fy8F1DWa3Sndg==} + /marked@15.0.3: + resolution: {integrity: sha512-Ai0cepvl2NHnTcO9jYDtcOEtVBNVYR31XnEA3BndO7f5As1wzpcOceSUM8FDkNLJNIODcLpDTWay/qQhqbuMvg==} engines: {node: '>= 18'} hasBin: true dev: false @@ -11438,8 +11437,8 @@ packages: hasBin: true dev: true - /prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + /prettier@3.4.2: + resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} engines: {node: '>=14'} hasBin: true dev: false @@ -13523,6 +13522,11 @@ packages: engines: {node: '>=16'} dev: false + /type-fest@4.30.0: + resolution: {integrity: sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==} + engines: {node: '>=16'} + dev: false + /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -14462,9 +14466,9 @@ packages: use-sync-external-store: 1.2.0(react@18.2.0) dev: false - github.com/theopensystemslab/planx-core/ccf9ac3(@types/react@18.2.45): - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/ccf9ac3} - id: github.com/theopensystemslab/planx-core/ccf9ac3 + github.com/theopensystemslab/planx-core/29b4851(@types/react@18.2.45): + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/29b4851} + id: github.com/theopensystemslab/planx-core/29b4851 name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true @@ -14479,18 +14483,18 @@ packages: ajv-formats: 2.1.1(ajv@8.17.1) cheerio: 1.0.0 copyfiles: 2.4.1 - docx: 9.0.3 + docx: 9.1.0 eslint: 8.57.1 fast-xml-parser: 4.5.0 graphql: 16.9.0 graphql-request: 6.1.0(graphql@16.9.0) json-schema-to-typescript: 15.0.3 lodash: 4.17.21 - marked: 14.1.4 - prettier: 3.3.3 + marked: 15.0.3 + prettier: 3.4.2 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - type-fest: 4.27.0 + type-fest: 4.30.0 uuid: 11.0.3 zod: 3.23.8 transitivePeerDependencies: diff --git a/editor.planx.uk/src/@planx/components/Checklist/Checklist.stories.tsx b/editor.planx.uk/src/@planx/components/Checklist/Checklist.stories.tsx index daafdc024c..bc4d495353 100644 --- a/editor.planx.uk/src/@planx/components/Checklist/Checklist.stories.tsx +++ b/editor.planx.uk/src/@planx/components/Checklist/Checklist.stories.tsx @@ -1,6 +1,6 @@ import { Meta, StoryObj } from "@storybook/react"; -import Checklist from "./Public"; +import Checklist from "./Public/Public"; const meta = { title: "PlanX Components/Checklist", diff --git a/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx b/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx deleted file mode 100644 index 0afc79ade7..0000000000 --- a/editor.planx.uk/src/@planx/components/Checklist/Editor.tsx +++ /dev/null @@ -1,429 +0,0 @@ -import Delete from "@mui/icons-material/Delete"; -import Box from "@mui/material/Box"; -import Button from "@mui/material/Button"; -import IconButton from "@mui/material/IconButton"; -import { ComponentType as TYPES } from "@opensystemslab/planx-core/types"; -import { FormikErrors, FormikValues, useFormik } from "formik"; -import adjust from "ramda/src/adjust"; -import compose from "ramda/src/compose"; -import remove from "ramda/src/remove"; -import React, { useEffect, useRef } from "react"; -import { FormikHookReturn } from "types"; -import ImgInput from "ui/editor/ImgInput/ImgInput"; -import InputGroup from "ui/editor/InputGroup"; -import ListManager from "ui/editor/ListManager/ListManager"; -import { ModalFooter } from "ui/editor/ModalFooter"; -import ModalSection from "ui/editor/ModalSection"; -import ModalSectionContent from "ui/editor/ModalSectionContent"; -import RichTextInput from "ui/editor/RichTextInput/RichTextInput"; -import SimpleMenu from "ui/editor/SimpleMenu"; -import Input from "ui/shared/Input/Input"; -import InputRow from "ui/shared/InputRow"; -import InputRowItem from "ui/shared/InputRowItem"; -import { Switch } from "ui/shared/Switch"; - -import { Option, parseBaseNodeData } from "../shared"; -import { FlagsSelect } from "../shared/FlagsSelect"; -import { ICONS } from "../shared/icons"; -import type { Checklist, Group } from "./model"; -import { toggleExpandableChecklist } from "./model"; -import { ChecklistProps, OptionEditorProps } from "./types"; - -const OptionEditor: React.FC = (props) => { - return ( -
- - {props.value.id ? ( - - ) : null} - - { - props.onChange({ - ...props.value, - data: { - ...props.value.data, - text: ev.target.value, - }, - }); - }} - placeholder="Option" - /> - - - { - props.onChange({ - ...props.value, - data: { - ...props.value.data, - img, - }, - }); - }} - /> - - {typeof props.index !== "undefined" && - props.groups && - props.onMoveToGroup && ( - ({ - label: `Move to ${group || `group ${groupIndex}`}`, - onClick: () => { - props.onMoveToGroup && - typeof props.index === "number" && - props.onMoveToGroup(props.index, groupIndex); - }, - disabled: groupIndex === props.groupIndex, - }))} - /> - )} - - - {props.showValueField && ( - - { - props.onChange({ - ...props.value, - data: { - ...props.value.data, - val: ev.target.value, - }, - }); - }} - /> - - )} - - { - props.onChange({ - ...props.value, - data: { - ...props.value.data, - flag: ev, - }, - }); - }} - /> -
- ); -}; - -const Options: React.FC<{ formik: FormikHookReturn }> = ({ formik }) => { - return ( - - {formik.values.groupedOptions ? ( - - {formik.values.groupedOptions.map( - (groupedOption: Group - ) : ( - { - formik.setFieldValue("options", newOptions); - }} - newValueLabel="add new option" - newValue={() => - ({ - data: { - text: "", - description: "", - val: "", - }, - }) as Option - } - Editor={OptionEditor} - editorExtraProps={{ showValueField: !!formik.values.fn }} - /> - )} - - ); -}; - -export const ChecklistComponent: React.FC = (props) => { - const type = TYPES.Checklist; - - const formik = useFormik({ - initialValues: { - allRequired: props.node?.data?.allRequired || false, - neverAutoAnswer: props.node?.data?.neverAutoAnswer || false, - description: props.node?.data?.description || "", - fn: props.node?.data?.fn || "", - groupedOptions: props.groupedOptions, - img: props.node?.data?.img || "", - options: props.options, - text: props.node?.data?.text || "", - ...parseBaseNodeData(props.node?.data), - }, - onSubmit: ({ options, groupedOptions, ...values }) => { - const sourceOptions = options?.length - ? options - : groupedOptions?.flatMap((group) => group.children); - - const filteredOptions = (sourceOptions || []).filter( - (option) => option.data.text, - ); - - const processedOptions = filteredOptions.map((option) => ({ - ...option, - id: option.id || undefined, - type: TYPES.Answer, - })); - - if (props.handleSubmit) { - props.handleSubmit( - { - type, - data: { - ...values, - ...(groupedOptions - ? { - categories: groupedOptions.map((group) => ({ - title: group.title, - count: group.children.length, - })), - } - : { - categories: undefined, - }), - }, - }, - processedOptions, - ); - } else { - alert(JSON.stringify({ type, ...values, options }, null, 2)); - } - }, - validate: ({ options, ...values }) => { - const errors: FormikErrors = {}; - 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"; - } - return errors; - }, - }); - - const focusRef = useRef(null); - - // horrible hack to remove focus from Rich Text Editor - useEffect(() => { - setTimeout(() => { - (document.activeElement as any).blur(); - focusRef.current?.focus(); - }, 50); - }, []); - - return ( -