diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index d8db9f6b9a..426eacee61 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -209,7 +209,6 @@ jobs: REACT_APP_AIRBRAKE_PROJECT_ID: ${{ secrets.AIRBRAKE_PROJECT_ID }} REACT_APP_AIRBRAKE_PROJECT_KEY: ${{ secrets.AIRBRAKE_PROJECT_KEY }} REACT_APP_API_URL: https://api.${{ env.FULL_DOMAIN }} - REACT_APP_FEEDBACK_FISH_ID: 65f02de00b90d1 REACT_APP_HASURA_URL: https://hasura.${{ env.FULL_DOMAIN }}/v1/graphql REACT_APP_SHAREDB_URL: wss://sharedb.${{ env.FULL_DOMAIN }} # needed because there's no API to change google's allowed OAuth URLs @@ -224,7 +223,6 @@ jobs: REACT_APP_AIRBRAKE_PROJECT_ID: ${{ secrets.AIRBRAKE_PROJECT_ID }} REACT_APP_AIRBRAKE_PROJECT_KEY: ${{ secrets.AIRBRAKE_PROJECT_KEY }} REACT_APP_API_URL: https://api.${{ env.FULL_DOMAIN }} - REACT_APP_FEEDBACK_FISH_ID: 65f02de00b90d1 REACT_APP_HASURA_URL: https://hasura.${{ env.FULL_DOMAIN }}/v1/graphql REACT_APP_SHAREDB_URL: wss://sharedb.${{ env.FULL_DOMAIN }} REACT_APP_GOOGLE_OAUTH_OVERRIDE: https://api.editor.planx.dev diff --git a/.github/workflows/push-main.yml b/.github/workflows/push-main.yml index e8a5dc402e..3b8e619aa4 100644 --- a/.github/workflows/push-main.yml +++ b/.github/workflows/push-main.yml @@ -54,7 +54,6 @@ jobs: working-directory: editor.planx.uk env: REACT_APP_API_URL: https://api.editor.planx.dev - REACT_APP_FEEDBACK_FISH_ID: 65f02de00b90d1 REACT_APP_HASURA_URL: https://hasura.editor.planx.dev/v1/graphql REACT_APP_SHAREDB_URL: wss://sharedb.editor.planx.dev REACT_APP_AIRBRAKE_PROJECT_ID: ${{ secrets.AIRBRAKE_PROJECT_ID }} diff --git a/.github/workflows/push-production.yml b/.github/workflows/push-production.yml index ef3c8b80b5..d5049c841b 100644 --- a/.github/workflows/push-production.yml +++ b/.github/workflows/push-production.yml @@ -54,7 +54,6 @@ jobs: working-directory: editor.planx.uk env: REACT_APP_API_URL: https://api.editor.planx.uk - REACT_APP_FEEDBACK_FISH_ID: 65f02de00b90d1 REACT_APP_HASURA_URL: https://hasura.editor.planx.uk/v1/graphql REACT_APP_SHAREDB_URL: wss://sharedb.editor.planx.uk REACT_APP_AIRBRAKE_PROJECT_ID: ${{ secrets.AIRBRAKE_PROJECT_ID }} diff --git a/api.planx.uk/modules/admin/controller.ts b/api.planx.uk/modules/admin/controller.ts deleted file mode 100644 index 62f8cd3484..0000000000 --- a/api.planx.uk/modules/admin/controller.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { generateFeedbackCSV } from "./service/feedback/downloadFeedbackCSV"; -import { DownloadFeedbackCSVController } from "./service/feedback/types"; - -export const downloadFeedbackCSV: DownloadFeedbackCSVController = async ( - req, - res, - next, -) => { - try { - const feedbackFishCookie = res.locals.parsedReq.query.cookie; - const csvStream = await generateFeedbackCSV(feedbackFishCookie); - res.header("Content-type", "text/csv"); - return csvStream.pipe(res); - } catch (error) { - return next({ - message: - "Failed to generate FeedbackFish CSV: " + (error as Error).message, - }); - } -}; diff --git a/api.planx.uk/modules/admin/docs.yaml b/api.planx.uk/modules/admin/docs.yaml deleted file mode 100644 index 2f02ee33a5..0000000000 --- a/api.planx.uk/modules/admin/docs.yaml +++ /dev/null @@ -1,29 +0,0 @@ -openapi: 3.1.0 -info: - title: Planâś• API - version: 0.1.0 -tags: - - name: admin - description: Admin only utility endpoints -paths: - /admin/feedback: - get: - tags: ["admin"] - security: - - bearerAuth: [] - summary: Download FeedbackFish CSV - parameters: - - in: query - name: cookie - type: string - description: Cookie from FeedbackFish to authenticate request - required: true - allowReserved: true - responses: - "200": - content: - text/csv: - schema: - type: string - "500": - $ref: "#/components/responses/ErrorMessage" diff --git a/api.planx.uk/modules/admin/routes.ts b/api.planx.uk/modules/admin/routes.ts index e3f4d35b9a..b1deaf4051 100644 --- a/api.planx.uk/modules/admin/routes.ts +++ b/api.planx.uk/modules/admin/routes.ts @@ -7,18 +7,10 @@ import { getHTMLExport, getRedactedHTMLExport } from "./session/html"; import { generateZip } from "./session/zip"; import { getSessionSummary } from "./session/summary"; import { getDigitalPlanningApplicationPayload } from "./session/digitalPlanningData"; -import { validate } from "../../shared/middleware/validate"; -import { downloadFeedbackCSVSchema } from "./service/feedback/types"; -import { downloadFeedbackCSV } from "./controller"; const router = Router(); router.use("/admin/", usePlatformAdminAuth); -router.get( - "/admin/feedback", - validate(downloadFeedbackCSVSchema), - downloadFeedbackCSV, -); // TODO: Split the routes below into controller and service components router.get("/admin/session/:sessionId/xml", getOneAppXML); diff --git a/api.planx.uk/modules/admin/service/feedback/downloadFeedbackCSV.test.ts b/api.planx.uk/modules/admin/service/feedback/downloadFeedbackCSV.test.ts deleted file mode 100644 index 508baac373..0000000000 --- a/api.planx.uk/modules/admin/service/feedback/downloadFeedbackCSV.test.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { parseFeedback } from "./downloadFeedbackCSV"; -import supertest from "supertest"; -import app from "../../../../server"; -import { authHeader } from "../../../../tests/mockJWT"; -import Axios from "axios"; -import { Feedback } from "./types"; - -jest.mock("axios"); -const mockAxios = Axios as jest.Mocked; - -const ENDPOINT = "/admin/feedback"; - -const mockFeedback: Feedback = { - id: 123, - text: "Service feedback", - category: "idea", - createdAt: "timestamp", - location: "http://editor.planx.test/team/service", - screenshotUrl: "", - device: { - client: { - name: "Chrome", - version: "123", - }, - os: { - name: "Linux", - version: "123", - }, - }, - metadata: [ - { - key: "project-type", - value: "extension", - }, - { - key: "uprn", - value: "12345", - }, - { - key: "team", - value: "test team", - }, - { - key: "service", - value: "test service", - }, - ], -}; - -describe("Download feedback CSV endpoint", () => { - afterEach(() => jest.clearAllMocks()); - const auth = authHeader({ role: "platformAdmin" }); - - it("requires a user to be logged in", async () => { - await supertest(app) - .get(ENDPOINT) - .expect(401) - .then((res) => - expect(res.body).toEqual({ - error: "No authorization token was found", - }), - ); - }); - - it("requires a user to have the platform admin role", async () => { - await supertest(app) - .get(ENDPOINT) - .set(authHeader({ role: "teamEditor" })) - .expect(403); - }); - - it("requires the 'cookie' query parameter", async () => { - await supertest(app) - .get(ENDPOINT) - .set(auth) - .expect(400) - .then((res) => { - expect(res.body).toHaveProperty("issues"); - expect(res.body).toHaveProperty("name", "ZodError"); - }); - }); - - it("returns an error if request to FeedbackFish fails", async () => { - mockAxios.post.mockRejectedValue(new Error("FeedbackFish query failed!")); - await supertest(app) - .get(ENDPOINT) - .set(auth) - .query({ cookie: "test cookie" }) - .expect(500) - .then((res) => - expect(res.body.error).toMatch(/FeedbackFish query failed!/), - ); - }); - - it("passes the provided cookie to FeedbackFish", async () => { - mockAxios.post.mockResolvedValue({ - data: { data: { feedback: [mockFeedback] } }, - }); - const cookie = "test cookie"; - await supertest(app) - .get(ENDPOINT) - .set(auth) - .query({ cookie }) - .expect(200) - .then(() => { - expect(mockAxios.post).toHaveBeenCalledWith( - expect.stringContaining("https"), - expect.objectContaining({ query: expect.stringContaining("query") }), - { headers: { cookie } }, - ); - }); - }); - - it("returns a CSV file", async () => { - mockAxios.post.mockResolvedValue({ - data: { data: { feedback: [mockFeedback] } }, - }); - const cookie = "test cookie"; - await supertest(app) - .get(ENDPOINT) - .set(auth) - .query({ cookie }) - .expect(200) - .expect("content-type", "text/csv; charset=utf-8"); - }); -}); - -describe("parseFeedback helper function", () => { - it("correctly parses FeedbackFish data", () => { - const { metadata, ...restMockFeedback } = mockFeedback; - const result = parseFeedback([mockFeedback]); - - // Metadata is parsed from query result - expect(result[0]).toMatchObject({ - uprn: "12345", - team: "test team", - service: "test service", - "project-type": "extension", - }); - - // Standard values from FeedbackFish are maintained - expect(result[0]).toMatchObject({ - ...restMockFeedback, - }); - - // Raw metadata from FeedbackFish is stripped out - expect(result[0]).not.toMatchObject({ - metadata, - }); - }); -}); diff --git a/api.planx.uk/modules/admin/service/feedback/downloadFeedbackCSV.ts b/api.planx.uk/modules/admin/service/feedback/downloadFeedbackCSV.ts deleted file mode 100644 index 022270e31b..0000000000 --- a/api.planx.uk/modules/admin/service/feedback/downloadFeedbackCSV.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { gql } from "graphql-request"; -import Axios from "axios"; -import { stringify } from "csv-stringify"; -import { Feedback, METADATA_KEYS, ParsedFeedback } from "./types"; - -export const generateFeedbackCSV = async (feedbackFishCookie: string) => { - const feedback = await fetchFeedback(feedbackFishCookie); - const parsedFeedback = parseFeedback(feedback); - const csvStream = stringify(parsedFeedback, { - header: true, - columns: [ - "id", - "text", - "category", - "createdAt", - "location", - "screenshotUrl", - "device", - ...METADATA_KEYS, - ], - }); - return csvStream; -}; - -const fetchFeedback = async (cookie: string): Promise => { - const feedbackFishGraphQLEndpoint = "https://graphcdn.api.feedback.fish/"; - const body = { - query: gql` - query getFeedback($projectId: String!) { - feedback(projectId: $projectId) { - id - text - category - createdAt - location - screenshotUrl - metadata { - key - value - } - device { - client { - name - version - } - os { - name - version - } - } - } - } - `, - operationName: "getFeedback", - variables: { - projectId: "65f02de00b90d1", - }, - }; - - try { - const result = await Axios.post(feedbackFishGraphQLEndpoint, body, { - headers: { cookie }, - }); - const feedback: Feedback[] = result.data.data.feedback; - return feedback; - } catch (error) { - throw Error( - "Failed to connect to FeedbackFish: " + (error as Error).message, - ); - } -}; - -const generateMetadata = (feedback: ParsedFeedback): ParsedFeedback => { - // Transform metadata into kv pairs - feedback.metadata?.forEach(({ key, value }) => (feedback[key] = value)); - // Drop redundant raw metadata - delete feedback.metadata; - return feedback; -}; - -export const parseFeedback = (feedback: Feedback[]): ParsedFeedback[] => { - const parsedFeedback: ParsedFeedback[] = [...feedback]; - parsedFeedback.map(generateMetadata); - return parsedFeedback; -}; diff --git a/api.planx.uk/modules/admin/service/feedback/types.ts b/api.planx.uk/modules/admin/service/feedback/types.ts deleted file mode 100644 index 00ac41afe5..0000000000 --- a/api.planx.uk/modules/admin/service/feedback/types.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { ValidatedRequestHandler } from "../../../../shared/middleware/validate"; -import { z } from "zod"; - -export interface Feedback { - id: number; - text: string; - category: string; - createdAt: string; - location: string; - screenshotUrl: string; - device: Device; - metadata?: Metadata[]; -} - -export const METADATA_KEYS = [ - "address", - "uprn", - "title", - "data", - "service", - "team", - "component-metadata", - "reason", - "project-type", - "breadcrumbs", -] as const; - -export type MetadataKey = (typeof METADATA_KEYS)[number]; - -export interface Metadata { - key: MetadataKey; - value: string | Record; -} - -export interface Device { - client: Client; - os: Os; -} - -export interface Client { - name: string; - version: string; -} - -export interface Os { - name: string; - version: string; -} - -export type ParsedFeedback = Feedback & { - [key in MetadataKey]?: string | Record; -}; - -export const downloadFeedbackCSVSchema = z.object({ - query: z.object({ - cookie: z.string(), - }), -}); - -export type DownloadFeedbackCSVController = ValidatedRequestHandler< - typeof downloadFeedbackCSVSchema, - NodeJS.ReadableStream ->; diff --git a/editor.planx.uk/package.json b/editor.planx.uk/package.json index bcf762cc02..8d85d6ef70 100644 --- a/editor.planx.uk/package.json +++ b/editor.planx.uk/package.json @@ -8,7 +8,6 @@ "@ctrl/tinycolor": "^4.0.2", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@feedback-fish/react": "^1.2.2", "@mui/icons-material": "^5.15.2", "@mui/material": "^5.15.2", "@mui/styles": "^5.15.2", diff --git a/editor.planx.uk/pnpm-lock.yaml b/editor.planx.uk/pnpm-lock.yaml index 0b83043602..af79cb4cae 100644 --- a/editor.planx.uk/pnpm-lock.yaml +++ b/editor.planx.uk/pnpm-lock.yaml @@ -27,9 +27,6 @@ dependencies: '@emotion/styled': specifier: ^11.11.0 version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.45)(react@18.2.0) - '@feedback-fish/react': - specifier: ^1.2.2 - version: 1.2.2(react@18.2.0) '@mui/icons-material': specifier: ^5.15.2 version: 5.15.2(@mui/material@5.15.2)(@types/react@18.2.45)(react@18.2.0) @@ -3329,7 +3326,7 @@ packages: resolution: {integrity: sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.0.15) postcss: 8.4.32 @@ -3339,7 +3336,7 @@ packages: resolution: {integrity: sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.32) postcss: 8.4.32 @@ -3349,7 +3346,7 @@ packages: resolution: {integrity: sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -3358,7 +3355,7 @@ packages: resolution: {integrity: sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -3367,7 +3364,7 @@ packages: resolution: {integrity: sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.32) postcss: 8.4.32 @@ -3377,7 +3374,7 @@ packages: resolution: {integrity: sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.0.15) postcss: 8.4.32 @@ -3387,7 +3384,7 @@ packages: resolution: {integrity: sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -3396,7 +3393,7 @@ packages: resolution: {integrity: sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -3405,7 +3402,7 @@ packages: resolution: {integrity: sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.32) postcss: 8.4.32 @@ -3415,7 +3412,7 @@ packages: resolution: {integrity: sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.3 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -3424,7 +3421,7 @@ packages: resolution: {integrity: sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -3433,7 +3430,7 @@ packages: resolution: {integrity: sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -3442,7 +3439,7 @@ packages: resolution: {integrity: sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==} engines: {node: ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -3451,7 +3448,7 @@ packages: resolution: {integrity: sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -4187,15 +4184,6 @@ packages: resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==} dev: true - /@feedback-fish/react@1.2.2(react@18.2.0): - resolution: {integrity: sha512-T6VxMM8nNsD3b5ulVsrcvcrNDAc4d73RLYK8Iw+6PFPIdMU2I/mOiuAHvfGauBVIWYHflja4VOdjm3z4CtlvYQ==} - engines: {node: '>=10.16.0'} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - dependencies: - react: 18.2.0 - dev: false - /@floating-ui/core@1.5.3: resolution: {integrity: sha512-O0WKDOo0yhJuugCx6trZQj5jVJ9yR0ystG2JaNAemYUWce+pmM6WUEFIibnWyEJKdrDxhm75NoSRME35FNaM/Q==} dependencies: @@ -8834,7 +8822,7 @@ packages: engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: - postcss: ^8.1.0 + postcss: '>=8.4.31' dependencies: browserslist: 4.22.2 caniuse-lite: 1.0.30001579 @@ -10074,7 +10062,7 @@ packages: engines: {node: ^12 || ^14 || >=16} hasBin: true peerDependencies: - postcss: ^8.4 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -10093,7 +10081,7 @@ packages: resolution: {integrity: sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==} engines: {node: ^10 || ^12 || >=14} peerDependencies: - postcss: ^8.0.9 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -10102,7 +10090,7 @@ packages: engines: {node: ^12 || ^14 || >=16} hasBin: true peerDependencies: - postcss: ^8.4 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -10170,7 +10158,7 @@ packages: engines: {node: ^12 || ^14 || >=16} hasBin: true peerDependencies: - postcss: ^8.4 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -10252,7 +10240,7 @@ packages: resolution: {integrity: sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: css-declaration-sorter: 6.4.1(postcss@8.4.32) cssnano-utils: 3.1.0(postcss@8.4.32) @@ -10289,7 +10277,7 @@ packages: resolution: {integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -10297,7 +10285,7 @@ packages: resolution: {integrity: sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: cssnano-preset-default: 5.2.14(postcss@8.4.32) lilconfig: 2.1.0 @@ -13065,7 +13053,7 @@ packages: resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: - postcss: ^8.1.0 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16248,7 +16236,7 @@ packages: resolution: {integrity: sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -16258,7 +16246,7 @@ packages: engines: {node: '>=8'} peerDependencies: browserslist: '>=4' - postcss: '>=8' + postcss: '>=8.4.31' dependencies: browserslist: 4.22.2 postcss: 8.4.32 @@ -16266,7 +16254,7 @@ packages: /postcss-calc@8.2.4(postcss@8.4.32): resolution: {integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==} peerDependencies: - postcss: ^8.2.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -16276,7 +16264,7 @@ packages: resolution: {integrity: sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==} engines: {node: '>=7.6.0'} peerDependencies: - postcss: ^8.4.6 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16285,7 +16273,7 @@ packages: resolution: {integrity: sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16294,7 +16282,7 @@ packages: resolution: {integrity: sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.4 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16303,7 +16291,7 @@ packages: resolution: {integrity: sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16312,7 +16300,7 @@ packages: resolution: {integrity: sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: browserslist: 4.22.2 caniuse-api: 3.0.0 @@ -16324,7 +16312,7 @@ packages: resolution: {integrity: sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: browserslist: 4.22.2 postcss: 8.4.32 @@ -16334,7 +16322,7 @@ packages: resolution: {integrity: sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.3 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16343,7 +16331,7 @@ packages: resolution: {integrity: sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16352,7 +16340,7 @@ packages: resolution: {integrity: sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.3 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -16361,7 +16349,7 @@ packages: resolution: {integrity: sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -16370,7 +16358,7 @@ packages: resolution: {integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16378,7 +16366,7 @@ packages: resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16386,7 +16374,7 @@ packages: resolution: {integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16394,7 +16382,7 @@ packages: resolution: {integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16402,7 +16390,7 @@ packages: resolution: {integrity: sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.32) postcss: 8.4.32 @@ -16412,7 +16400,7 @@ packages: resolution: {integrity: sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.4 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16420,7 +16408,7 @@ packages: /postcss-flexbugs-fixes@5.0.2(postcss@8.4.32): resolution: {integrity: sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==} peerDependencies: - postcss: ^8.1.4 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16428,7 +16416,7 @@ packages: resolution: {integrity: sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.4 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -16437,7 +16425,7 @@ packages: resolution: {integrity: sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.4 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -16445,7 +16433,7 @@ packages: /postcss-font-variant@5.0.0(postcss@8.4.32): resolution: {integrity: sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==} peerDependencies: - postcss: ^8.1.0 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16453,7 +16441,7 @@ packages: resolution: {integrity: sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16461,7 +16449,7 @@ packages: resolution: {integrity: sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16470,7 +16458,7 @@ packages: resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} peerDependencies: - postcss: ^8.0.0 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16480,7 +16468,7 @@ packages: /postcss-initial@4.0.1(postcss@8.4.32): resolution: {integrity: sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==} peerDependencies: - postcss: ^8.0.0 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16488,7 +16476,7 @@ packages: resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: - postcss: ^8.4.21 + postcss: '>=8.4.31' dependencies: camelcase-css: 2.0.1 postcss: 8.4.32 @@ -16497,7 +16485,7 @@ packages: resolution: {integrity: sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.32) postcss: 8.4.32 @@ -16507,7 +16495,7 @@ packages: resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} engines: {node: '>= 14'} peerDependencies: - postcss: '>=8.0.9' + postcss: '>=8.4.31' ts-node: '>=9.0.0' peerDependenciesMeta: postcss: @@ -16523,7 +16511,7 @@ packages: resolution: {integrity: sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==} engines: {node: '>= 12.13.0'} peerDependencies: - postcss: ^7.0.0 || ^8.0.1 + postcss: '>=8.4.31' webpack: ^5.0.0 dependencies: cosmiconfig: 7.1.0 @@ -16536,7 +16524,7 @@ packages: resolution: {integrity: sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.4 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16544,7 +16532,7 @@ packages: resolution: {integrity: sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==} engines: {node: '>=10.0.0'} peerDependencies: - postcss: ^8.1.0 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16552,7 +16540,7 @@ packages: resolution: {integrity: sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16562,7 +16550,7 @@ packages: resolution: {integrity: sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: browserslist: 4.22.2 caniuse-api: 3.0.0 @@ -16574,7 +16562,7 @@ packages: resolution: {integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16583,7 +16571,7 @@ packages: resolution: {integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: colord: 2.9.3 cssnano-utils: 3.1.0(postcss@8.4.32) @@ -16594,7 +16582,7 @@ packages: resolution: {integrity: sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: browserslist: 4.22.2 cssnano-utils: 3.1.0(postcss@8.4.32) @@ -16605,7 +16593,7 @@ packages: resolution: {integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -16614,7 +16602,7 @@ packages: resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: - postcss: ^8.1.0 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16622,7 +16610,7 @@ packages: resolution: {integrity: sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: - postcss: ^8.1.0 + postcss: '>=8.4.31' dependencies: icss-utils: 5.1.0(postcss@8.4.32) postcss: 8.4.32 @@ -16633,7 +16621,7 @@ packages: resolution: {integrity: sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: - postcss: ^8.1.0 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -16642,7 +16630,7 @@ packages: resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: - postcss: ^8.1.0 + postcss: '>=8.4.31' dependencies: icss-utils: 5.1.0(postcss@8.4.32) postcss: 8.4.32 @@ -16651,7 +16639,7 @@ packages: resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} engines: {node: '>=12.0'} peerDependencies: - postcss: ^8.2.14 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -16660,7 +16648,7 @@ packages: resolution: {integrity: sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.0.15) postcss: 8.4.32 @@ -16670,7 +16658,7 @@ packages: resolution: {integrity: sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16678,7 +16666,7 @@ packages: resolution: {integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16687,7 +16675,7 @@ packages: resolution: {integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16696,7 +16684,7 @@ packages: resolution: {integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16705,7 +16693,7 @@ packages: resolution: {integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16714,7 +16702,7 @@ packages: resolution: {integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16723,7 +16711,7 @@ packages: resolution: {integrity: sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: browserslist: 4.22.2 postcss: 8.4.32 @@ -16733,7 +16721,7 @@ packages: resolution: {integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: normalize-url: 6.1.0 postcss: 8.4.32 @@ -16743,7 +16731,7 @@ packages: resolution: {integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16753,7 +16741,7 @@ packages: engines: {node: '>= 12'} peerDependencies: browserslist: '>= 4' - postcss: '>= 8' + postcss: '>=8.4.31' dependencies: '@csstools/normalize.css': 12.1.1 browserslist: 4.22.2 @@ -16765,7 +16753,7 @@ packages: resolution: {integrity: sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16773,7 +16761,7 @@ packages: resolution: {integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: cssnano-utils: 3.1.0(postcss@8.4.32) postcss: 8.4.32 @@ -16783,7 +16771,7 @@ packages: resolution: {integrity: sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16791,7 +16779,7 @@ packages: /postcss-page-break@3.0.4(postcss@8.4.32): resolution: {integrity: sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==} peerDependencies: - postcss: ^8 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16799,7 +16787,7 @@ packages: resolution: {integrity: sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16808,7 +16796,7 @@ packages: resolution: {integrity: sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: '@csstools/postcss-cascade-layers': 1.1.1(postcss@8.4.32) '@csstools/postcss-color-function': 1.1.1(postcss@8.4.32) @@ -16865,7 +16853,7 @@ packages: resolution: {integrity: sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -16874,7 +16862,7 @@ packages: resolution: {integrity: sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: browserslist: 4.22.2 caniuse-api: 3.0.0 @@ -16884,7 +16872,7 @@ packages: resolution: {integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16892,7 +16880,7 @@ packages: /postcss-replace-overflow-wrap@4.0.0(postcss@8.4.32): resolution: {integrity: sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==} peerDependencies: - postcss: ^8.0.3 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 @@ -16900,7 +16888,7 @@ packages: resolution: {integrity: sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==} engines: {node: ^12 || ^14 || >=16} peerDependencies: - postcss: ^8.2 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -16916,7 +16904,7 @@ packages: resolution: {integrity: sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-value-parser: 4.2.0 @@ -16926,7 +16914,7 @@ packages: resolution: {integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: postcss: 8.4.32 postcss-selector-parser: 6.0.15 @@ -19305,7 +19293,7 @@ packages: resolution: {integrity: sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: - postcss: ^8.2.15 + postcss: '>=8.4.31' dependencies: browserslist: 4.22.2 postcss: 8.4.32 @@ -21084,7 +21072,6 @@ packages: id: github.com/theopensystemslab/planx-core/b184ea9 name: '@opensystemslab/planx-core' version: 1.0.0 - prepare: true requiresBuild: true dependencies: '@emotion/react': 11.11.3(@types/react@18.2.45)(react@18.2.0) diff --git a/editor.planx.uk/src/@planx/components/PlanningConstraints/Public.tsx b/editor.planx.uk/src/@planx/components/PlanningConstraints/Public.tsx index 001c097fa2..cd78e4a803 100644 --- a/editor.planx.uk/src/@planx/components/PlanningConstraints/Public.tsx +++ b/editor.planx.uk/src/@planx/components/PlanningConstraints/Public.tsx @@ -10,7 +10,6 @@ import QuestionHeader from "@planx/components/shared/Preview/QuestionHeader"; import type { PublicProps } from "@planx/components/ui"; import DelayedLoadingIndicator from "components/DelayedLoadingIndicator"; import { useFormik } from "formik"; -import { submitFeedback } from "lib/feedback"; import capitalize from "lodash/capitalize"; import { useStore } from "pages/FlowEditor/lib/store"; import { handleSubmit } from "pages/Preview/Node"; @@ -218,13 +217,6 @@ export function PlanningConstraintsContent( feedback: previousFeedback || "", }, onSubmit: (values) => { - if (values.feedback) { - submitFeedback( - values.feedback, - "Inaccurate planning constraints", - constraints, - ); - } handleSubmit?.(values); }, }); diff --git a/editor.planx.uk/src/@planx/components/PropertyInformation/Public.tsx b/editor.planx.uk/src/@planx/components/PropertyInformation/Public.tsx index dce0573409..021906f9b5 100644 --- a/editor.planx.uk/src/@planx/components/PropertyInformation/Public.tsx +++ b/editor.planx.uk/src/@planx/components/PropertyInformation/Public.tsx @@ -9,7 +9,6 @@ import QuestionHeader from "@planx/components/shared/Preview/QuestionHeader"; import type { PublicProps } from "@planx/components/ui"; import { Feature } from "@turf/helpers"; import { useFormik } from "formik"; -import { submitFeedback } from "lib/feedback"; import { publicClient } from "lib/graphql"; import find from "lodash/find"; import { useAnalyticsTracking } from "pages/FlowEditor/lib/analyticsProvider"; @@ -115,13 +114,6 @@ export function Presentational(props: PresentationalProps) { feedback: previousFeedback || "", }, onSubmit: (values) => { - if (values.feedback) { - submitFeedback( - values.feedback, - "Inaccurate property details", - propertyDetails, - ); - } handleSubmit?.(values); }, }); diff --git a/editor.planx.uk/src/@planx/components/Result/Public/index.tsx b/editor.planx.uk/src/@planx/components/Result/Public/index.tsx index d93e70c246..07e626e8a5 100644 --- a/editor.planx.uk/src/@planx/components/Result/Public/index.tsx +++ b/editor.planx.uk/src/@planx/components/Result/Public/index.tsx @@ -7,7 +7,6 @@ import Card from "@planx/components/shared/Preview/Card"; import SimpleExpand from "@planx/components/shared/Preview/SimpleExpand"; import { WarningContainer } from "@planx/components/shared/Preview/WarningContainer"; import { useFormik } from "formik"; -import { submitFeedback } from "lib/feedback"; import { Store, useStore } from "pages/FlowEditor/lib/store"; import type { handleSubmit } from "pages/Preview/Node"; import React, { useEffect, useState } from "react"; @@ -104,9 +103,6 @@ const Result: React.FC = ({ }, onSubmit: (values, { resetForm }) => { if (values.feedback) { - submitFeedback(values.feedback, "Inaccurate Result", { - responses: responses, - }); resetForm(); } handleSubmit?.({ feedback: values.feedback }); diff --git a/editor.planx.uk/src/components/Footer.tsx b/editor.planx.uk/src/components/Footer.tsx index 5733854906..eaee8e64f7 100644 --- a/editor.planx.uk/src/components/Footer.tsx +++ b/editor.planx.uk/src/components/Footer.tsx @@ -1,14 +1,9 @@ import Box from "@mui/material/Box"; -import Button from "@mui/material/Button"; import Container from "@mui/material/Container"; -import Dialog from "@mui/material/Dialog"; -import DialogActions from "@mui/material/DialogActions"; -import DialogContent from "@mui/material/DialogContent"; import Link from "@mui/material/Link"; import { styled } from "@mui/material/styles"; import Typography from "@mui/material/Typography"; -import { getFeedbackMetadata } from "lib/feedback"; -import React, { useEffect, useState } from "react"; +import React from "react"; import { Link as ReactNaviLink } from "react-navi"; import { FONT_WEIGHT_SEMI_BOLD } from "theme"; @@ -46,85 +41,8 @@ export interface Props { children?: React.ReactNode; } -// XXX: This component is located in the DOM within the Footer component, but as it's appearance is controlled by a global window "message" event. This means that its appearance can be controlled by other instances of the FeedbackFish widget (such as in the PhaseBanner) -const FeedbackPrivacyNote = ({ - onClose, -}: { - onClose: (e: React.MouseEvent) => void; -}) => ( - e.stopPropagation()} - > - - Please do not include any personal or financial information in your - feedback - - - - - -); - export default function Footer(props: Props) { const { items, children } = props; - const [feedbackPrivacyNoteVisible, setFeedbackPrivacyNoteVisible] = - useState(false); - const [metadata, setMetadata] = useState>(); - - const feedbackFishId = process.env.REACT_APP_FEEDBACK_FISH_ID; - - useEffect(() => { - let feedbackFishPostMessageWorkingCorrectly: boolean; - const handleMessage = (event: MessageEvent) => { - setMetadata(getFeedbackMetadata()); - feedbackFishPostMessageWorkingCorrectly = handleFeedbackPrivacyNoteOpen( - event, - feedbackFishPostMessageWorkingCorrectly, - ); - }; - window.addEventListener("message", handleMessage); - return () => { - window.removeEventListener("message", handleMessage); - }; - }, []); - - const handleFeedbackPrivacyNoteClose = (e: React.MouseEvent) => { - setFeedbackPrivacyNoteVisible(false); - // prevent click from propagating to feedback fish listener, - // as it would close the widget otherwise - e.stopPropagation(); - }; - - const handleFeedbackPrivacyNoteOpen = ( - event: MessageEvent, - feedbackFishPostMessageWorkingCorrectly: boolean, - ): boolean => { - try { - // the feedback fish widget posts a message that's either - // {"width":0,"height":0} if the iframe is hidden - // or {"width":320,"height":200} if the iframe is visible - if (event.origin.endsWith("feedback.fish")) { - const { width, height } = JSON.parse(event.data); - // XXX: postMessage not working in firefox as expected - // https://trello.com/c/MX1cpAM8 this disables it in FF - // by checking if the initial {"width":0,"height":0} message - // was received. If not then never show feedback warning msg - if (width === 0 && height === 0) { - feedbackFishPostMessageWorkingCorrectly = true; - } - setFeedbackPrivacyNoteVisible( - width > 0 && height > 0 && feedbackFishPostMessageWorkingCorrectly, - ); - } - } catch (err) {} - return feedbackFishPostMessageWorkingCorrectly; - }; return ( diff --git a/editor.planx.uk/src/components/PhaseBanner.stories.tsx b/editor.planx.uk/src/components/PhaseBanner.stories.tsx deleted file mode 100644 index f1f187c531..0000000000 --- a/editor.planx.uk/src/components/PhaseBanner.stories.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Meta, StoryObj } from "@storybook/react"; -import React from "react"; - -import PhaseBanner from "./PhaseBanner"; - -const meta = { - title: "Design System/Molecules/PhaseBanner", - component: PhaseBanner, -} satisfies Meta; - -type Story = StoryObj; - -export default meta; - -export const Basic = { - render: () => , -} satisfies Story; diff --git a/editor.planx.uk/src/components/PhaseBanner.tsx b/editor.planx.uk/src/components/PhaseBanner.tsx deleted file mode 100644 index ef63a85eab..0000000000 --- a/editor.planx.uk/src/components/PhaseBanner.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import { FeedbackFish } from "@feedback-fish/react"; -import Box from "@mui/material/Box"; -import ButtonBase from "@mui/material/ButtonBase"; -import Container from "@mui/material/Container"; -import Link from "@mui/material/Link"; -import { styled } from "@mui/material/styles"; -import Typography from "@mui/material/Typography"; -import { getFeedbackMetadata } from "lib/feedback"; -import React, { useEffect, useState } from "react"; - -const Root = styled(Box)(({ theme }) => ({ - width: "100%", - border: `solid ${theme.palette.grey[400]}`, - borderWidth: "1px 0", - backgroundColor: "#FFFFFF", -})); - -const Inner = styled(ButtonBase)(({ theme }) => ({ - width: "100%", - display: "flex", - justifyContent: "start", - alignItems: "start", - padding: theme.spacing(1, 0), -})); - -const BetaFlag = styled(Box)(({ theme }) => ({ - betaIcon: { - width: "100%", - "& > *": { - width: "100%", - }, - [theme.breakpoints.up("sm")]: { - width: "auto", - marginRight: theme.spacing(2), - }, - }, -})); - -export default function PhaseBanner(): FCReturn { - const feedbackFishId = process.env.REACT_APP_FEEDBACK_FISH_ID || ""; - const [metadata, setMetadata] = useState>(); - - useEffect(() => { - const handleMessage = () => setMetadata(getFeedbackMetadata()); - window.addEventListener("message", handleMessage); - return () => { - window.removeEventListener("message", handleMessage); - }; - }, []); - - return ( - - - - - - PUBLIC BETA - - - This is a new service. Your feedback will help us - improve it. - - - - - - ); -} diff --git a/editor.planx.uk/src/lib/feedback.ts b/editor.planx.uk/src/lib/feedback.ts index 4f724ce036..5cef2cd2b3 100644 --- a/editor.planx.uk/src/lib/feedback.ts +++ b/editor.planx.uk/src/lib/feedback.ts @@ -5,56 +5,6 @@ import { Store, useStore } from "pages/FlowEditor/lib/store"; import { publicClient } from "./graphql"; -export const submitFeedback = ( - text: string, - reason: string, - componentMetadata?: { [key: string]: any }, -) => { - const standardMetadata = getFeedbackMetadata(); - fetch("https://api.feedback.fish/feedback", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - projectId: process.env.REACT_APP_FEEDBACK_FISH_ID, - text, - reason, - // FeedbackFish requires that Record be passed as metadata - metadata: { - ...standardMetadata, - "component-metadata": JSON.stringify(componentMetadata), - }, - }), - }).catch((err) => console.error(err)); -}; - -export const getFeedbackMetadata = (): Record => { - const { currentCard, computePassport, breadcrumbs } = useStore.getState(); - - const passportData = computePassport().data; - const nodeData = currentCard()?.data; - - const [team, service] = window.location.pathname - .split("/") - .map((value) => value.replaceAll("-", " ")) - .slice(1, 3); - - const feedbackMetadata = { - address: - passportData?._address?.single_line_address || - passportData?._address?.title, - uprn: passportData?._address?.uprn, - "project-type": passportData?.proposal?.projectType, - title: nodeData?.title || nodeData?.text, - data: JSON.stringify(nodeData), - breadcrumbs: JSON.stringify(breadcrumbs), - service, - team, - }; - return feedbackMetadata; -}; - type UserData = { breadcrumbs: Store.breadcrumbs; passport: Store.passport;