From ead15745170e95762c6dfe809cc17416e338a520 Mon Sep 17 00:00:00 2001 From: prosdev Date: Tue, 21 Oct 2025 11:37:04 -0700 Subject: [PATCH 1/7] bug(deps): downgrade @types/react to v18 to match React version Downgrade @types/react and @types/react-dom to ^18.2.0 in experience-editor. Add resolutions in root package.json to force all packages to use React 18 types. Fix TypeScript errors in targetFlow.ts by removing invalid fieldsToShow properties. Update moduleResolution to 'bundler' and add skipLibCheck to fix Vite type issues. All typecheck errors now resolved. --- package.json | 4 +++- packages/experience-editor/package.json | 4 ++-- .../src/data/fields/targetFlow.ts | 2 -- packages/experience-editor/tsconfig.json | 5 +++-- yarn.lock | 22 +++++-------------- 5 files changed, 13 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index 0673371..6e5a3a9 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,9 @@ "minimist": "^1.2.8", "qs": "^6.11.2", "string-width": "^4.2.0", - "wrap-ansi": "^7.0.0" + "wrap-ansi": "^7.0.0", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0" }, "volta": { "node": "22.20.0", diff --git a/packages/experience-editor/package.json b/packages/experience-editor/package.json index e605de8..f2e73ea 100644 --- a/packages/experience-editor/package.json +++ b/packages/experience-editor/package.json @@ -33,7 +33,7 @@ "yarn": "1.22.18" }, "devDependencies": { - "@types/react": "^19.2.0", - "@types/react-dom": "^19.2.0" + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0" } } diff --git a/packages/experience-editor/src/data/fields/targetFlow.ts b/packages/experience-editor/src/data/fields/targetFlow.ts index ee3190a..a6b2be9 100644 --- a/packages/experience-editor/src/data/fields/targetFlow.ts +++ b/packages/experience-editor/src/data/fields/targetFlow.ts @@ -19,7 +19,6 @@ export const TargetFlowVersion: Field = { hidden: true, type: "string", method: "select", - fieldsToShow: [TargetFlowStep.id], render: "details.target.flow.version", }; @@ -31,7 +30,6 @@ export const TargetFlow: Field = { hidden: true, type: "string", method: "select", - fieldsToShow: [TargetFlowVersion.id], render: "details.target.flow.id", }; diff --git a/packages/experience-editor/tsconfig.json b/packages/experience-editor/tsconfig.json index 7f32712..592f7ec 100644 --- a/packages/experience-editor/tsconfig.json +++ b/packages/experience-editor/tsconfig.json @@ -6,8 +6,9 @@ "esModuleInterop": true, "allowJs": true, "outDir": "./dist", - "moduleResolution": "node", - "jsx": "react-jsx" + "moduleResolution": "bundler", + "jsx": "react-jsx", + "skipLibCheck": true }, "include": ["src/**/*"] } diff --git a/yarn.lock b/yarn.lock index 1aca2dc..575f228 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3479,16 +3479,11 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== -"@types/react-dom@^18.0.0": +"@types/react-dom@^18.0.0", "@types/react-dom@^18.2.0": version "18.3.7" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.7.tgz#b89ddf2cd83b4feafcc4e2ea41afdfb95a0d194f" integrity sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ== -"@types/react-dom@^19.2.0": - version "19.2.0" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.2.0.tgz#97ebfc8400702db00d1177b06ade6720dda641c1" - integrity sha512-brtBs0MnE9SMx7px208g39lRmC5uHZs96caOJfTjFcYSLHNamvaSMfJNagChVNkup2SdtOxKX1FDBkRSJe1ZAg== - "@types/react-transition-group@^4.4.10": version "4.4.11" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.11.tgz#d963253a611d757de01ebb241143b1017d5d63d5" @@ -3501,21 +3496,14 @@ resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044" integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w== -"@types/react@*", "@types/react@>=16": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f" - integrity sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw== +"@types/react@*", "@types/react@>=16", "@types/react@^18.2.0": + version "18.3.26" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.26.tgz#4c5970878d30db3d2a0bca1e4eb5f258e391bbeb" + integrity sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA== dependencies: "@types/prop-types" "*" csstype "^3.0.2" -"@types/react@^19.2.0": - version "19.2.0" - resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.0.tgz#8412946e7e1efb0de9bb59b3aa87676d96add385" - integrity sha512-1LOH8xovvsKsCBq1wnT4ntDUdCJKmnEakhsuoUSy6ExlHCkGP2hqnatagYTgFk6oeL0VU31u7SNjunPN+GchtA== - dependencies: - csstype "^3.0.2" - "@types/resolve@^1.20.2": version "1.20.6" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.6.tgz#e6e60dad29c2c8c206c026e6dd8d6d1bdda850b8" From 71f46aae26b2e0a3b50d40bfe850fcbc1869288a Mon Sep 17 00:00:00 2001 From: prosdev Date: Tue, 21 Oct 2025 11:38:40 -0700 Subject: [PATCH 2/7] maint(repo): add Biome for unified linting and formatting Install @biomejs/biome v2.2.6 as devDependency. Create biome.json configuration matching existing ESLint and Prettier rules: - Formatting: 80 char width, semicolons, double quotes, 2 space indent, trailing commas - Linting: recommended rules with customizations for React/TypeScript - Disable strict rules for any, forEach, non-null assertions - Special rules for test and story files --- biome.json | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + yarn.lock | 54 +++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 biome.json diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..d84ddfb --- /dev/null +++ b/biome.json @@ -0,0 +1,81 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.2.6/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": false, + "experimentalScannerIgnores": [ + "node_modules", + "dist", + "build", + ".nx", + "coverage", + "*.min.js", + "yarn.lock", + "package-lock.json" + ] + }, + "formatter": { + "enabled": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 80, + "attributePosition": "auto" + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "complexity": { + "noForEach": "off", + "noStaticOnlyClass": "off" + }, + "style": { + "noNonNullAssertion": "off", + "useImportType": "off", + "useNodejsImportProtocol": "off" + }, + "suspicious": { + "noExplicitAny": "off", + "noArrayIndexKey": "off" + }, + "correctness": { + "useExhaustiveDependencies": "off", + "noUnusedVariables": "error" + }, + "a11y": { + "useKeyWithClickEvents": "off" + } + } + }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "all", + "semicolons": "always", + "arrowParentheses": "always", + "bracketSpacing": true, + "bracketSameLine": false, + "quoteStyle": "double", + "attributePosition": "auto" + } + }, + "overrides": [ + { + "includes": ["*.stories.*", "*.test.*", "*.spec.*"], + "linter": { + "rules": { + "suspicious": { + "noExplicitAny": "off" + } + } + } + } + ] +} diff --git a/package.json b/package.json index 6e5a3a9..b2bc822 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "chromatic": "chromatic" }, "devDependencies": { + "@biomejs/biome": "^2.2.6", "@codemirror/lang-javascript": "^6.2.2", "@codemirror/view": "^6.32.0", "@emotion/react": "^11.13.0", diff --git a/yarn.lock b/yarn.lock index 575f228..782b08c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1062,6 +1062,60 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@biomejs/biome@^2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-2.2.6.tgz#76d8afbdd609a5dbace84bc982ae974a24b70b62" + integrity sha512-yKTCNGhek0rL5OEW1jbLeZX8LHaM8yk7+3JRGv08my+gkpmtb5dDE+54r2ZjZx0ediFEn1pYBOJSmOdDP9xtFw== + optionalDependencies: + "@biomejs/cli-darwin-arm64" "2.2.6" + "@biomejs/cli-darwin-x64" "2.2.6" + "@biomejs/cli-linux-arm64" "2.2.6" + "@biomejs/cli-linux-arm64-musl" "2.2.6" + "@biomejs/cli-linux-x64" "2.2.6" + "@biomejs/cli-linux-x64-musl" "2.2.6" + "@biomejs/cli-win32-arm64" "2.2.6" + "@biomejs/cli-win32-x64" "2.2.6" + +"@biomejs/cli-darwin-arm64@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.2.6.tgz#b232a7d92c0b28884c1cf99d4348e1a52f95931f" + integrity sha512-UZPmn3M45CjTYulgcrFJFZv7YmK3pTxTJDrFYlNElT2FNnkkX4fsxjExTSMeWKQYoZjvekpH5cvrYZZlWu3yfA== + +"@biomejs/cli-darwin-x64@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.2.6.tgz#3a2d1582037735f8ed5243aa6d3cc4f4082c5f42" + integrity sha512-HOUIquhHVgh/jvxyClpwlpl/oeMqntlteL89YqjuFDiZ091P0vhHccwz+8muu3nTyHWM5FQslt+4Jdcd67+xWQ== + +"@biomejs/cli-linux-arm64-musl@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.6.tgz#2bfe0859c55c840c0648f2b307efccca2527d655" + integrity sha512-TjCenQq3N6g1C+5UT3jE1bIiJb5MWQvulpUngTIpFsL4StVAUXucWD0SL9MCW89Tm6awWfeXBbZBAhJwjyFbRQ== + +"@biomejs/cli-linux-arm64@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.2.6.tgz#aa1817296d84bda6ea972a54b139d1664580c190" + integrity sha512-BpGtuMJGN+o8pQjvYsUKZ+4JEErxdSmcRD/JG3mXoWc6zrcA7OkuyGFN1mDggO0Q1n7qXxo/PcupHk8gzijt5g== + +"@biomejs/cli-linux-x64-musl@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.6.tgz#b65f9191420e3384e287b21a8b1769795ee2c4c1" + integrity sha512-1ZcBux8zVM3JhWN2ZCPaYf0+ogxXG316uaoXJdgoPZcdK/rmRcRY7PqHdAos2ExzvjIdvhQp72UcveI98hgOog== + +"@biomejs/cli-linux-x64@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-2.2.6.tgz#5c5f07264bed31a436db60577c77ea9f64a62d2b" + integrity sha512-1HaM/dpI/1Z68zp8ZdT6EiBq+/O/z97a2AiHMl+VAdv5/ELckFt9EvRb8hDHpk8hUMoz03gXkC7VPXOVtU7faA== + +"@biomejs/cli-win32-arm64@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.2.6.tgz#a47ef2d6bec694df088ba70ffd6e89839c9c2304" + integrity sha512-h3A88G8PGM1ryTeZyLlSdfC/gz3e95EJw9BZmA6Po412DRqwqPBa2Y9U+4ZSGUAXCsnSQE00jLV8Pyrh0d+jQw== + +"@biomejs/cli-win32-x64@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-2.2.6.tgz#cec00e860d9f20d820a48db4a6c7ab3b35c83ac6" + integrity sha512-yx0CqeOhPjYQ5ZXgPfu8QYkgBhVJyvWe36as7jRuPrKPO5ylVDfwVtPQ+K/mooNTADW0IhxOZm3aPu16dP8yNQ== + "@codemirror/autocomplete@^6.0.0": version "6.18.0" resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.18.0.tgz#5f39b05daca04c95e990b70024144df47b2aa635" From 6710172e061a70860f39caae7d1725ab08817d0c Mon Sep 17 00:00:00 2001 From: prosdev Date: Tue, 21 Oct 2025 11:43:29 -0700 Subject: [PATCH 3/7] maint(repo): format codebase with Biome Apply Biome formatting and linting fixes across the entire codebase. Organize imports, fix unused imports, and apply consistent code style. --- .prettierrc.json | 26 +-- .storybook/preview.tsx | 8 +- .storybook/storyshots.test.ts | 9 +- .storybook/vite.config.ts | 1 - packages/experience-editor/main.tsx | 2 +- packages/experience-editor/src/App.tsx | 10 +- .../src/components/branding.tsx | 18 +- .../src/components/displayRules.tsx | 53 +++--- .../form/__tests__/radioGroup.test.tsx | 6 +- .../src/components/form/callbackFn.tsx | 2 +- .../src/components/form/checkbox.tsx | 2 +- .../src/components/form/codeEditor.tsx | 14 +- .../src/components/form/color.tsx | 2 +- .../src/components/form/colorPicker.tsx | 2 +- .../src/components/form/conditionGroup.tsx | 2 +- .../src/components/form/datePicker.tsx | 5 +- .../components/form/displayConditionItem.tsx | 4 +- .../src/components/form/input.tsx | 3 +- .../src/components/form/numberedSection.tsx | 4 +- .../src/components/form/radioGroup.tsx | 8 +- .../src/components/form/sectionHeader.tsx | 2 +- .../src/components/form/select.tsx | 4 +- .../src/components/form/selectMultiple.tsx | 8 +- .../src/components/form/textarea.tsx | 2 +- .../src/components/formBuilder.tsx | 26 +-- .../src/components/messaging.tsx | 25 ++- .../src/components/position.tsx | 18 +- .../src/components/recommendation.tsx | 26 ++- .../src/components/targeting.tsx | 17 +- .../src/components/widgetWizard.tsx | 158 +++++++++--------- .../src/data/fields/audience.ts | 2 +- .../src/data/fields/layout.ts | 4 +- .../src/data/fields/okLinkNewTab.ts | 5 +- .../src/data/fields/okLinkURL.ts | 5 +- .../src/data/fields/origin.ts | 2 +- .../src/data/fields/personalizationKeys.ts | 2 +- .../src/data/fields/position.ts | 2 +- .../src/data/fields/recommend.ts | 2 +- .../src/data/fields/targetFlow.ts | 6 +- .../src/data/fields/targetMethod.ts | 2 +- .../src/data/fields/theme.ts | 8 +- .../experience-editor/src/data/fields/type.ts | 10 -- .../src/data/fields/widgetStatus.ts | 3 +- .../experience-editor/src/data/pfa-fields.ts | 122 +++++++------- .../src/utility/__tests__/fieldLogic.test.ts | 4 +- .../src/utility/__tests__/objects.test.ts | 4 +- .../src/utility/emptyState.tsx | 2 +- .../experience-editor/src/utility/objects.ts | 4 +- .../src/utility/pathforaInterface.ts | 16 +- packages/experience-editor/vite.config.js | 3 +- packages/experience-editor/vitest.config.ts | 2 +- .../src/api-recommendation.ts | 4 +- packages/recommendation-block/vite.config.js | 4 +- 53 files changed, 329 insertions(+), 356 deletions(-) diff --git a/.prettierrc.json b/.prettierrc.json index 9d8dc7c..9d0dd2d 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,15 +1,15 @@ { - "$schema": "http://json.schemastore.org/prettierrc", - "arrowParens": "always", - "bracketSpacing": true, - "jsxBracketSameLine": false, - "jsxSingleQuote": false, - "printWidth": 80, - "proseWrap": "always", - "quoteProps": "as-needed", - "semi": true, - "singleQuote": false, - "tabWidth": 2, - "trailingComma": "all", - "useTabs": false + "$schema": "http://json.schemastore.org/prettierrc", + "arrowParens": "always", + "bracketSpacing": true, + "jsxBracketSameLine": false, + "jsxSingleQuote": false, + "printWidth": 80, + "proseWrap": "always", + "quoteProps": "as-needed", + "semi": true, + "singleQuote": false, + "tabWidth": 2, + "trailingComma": "all", + "useTabs": false } diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index b964a06..cdd76d3 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,11 +1,5 @@ -import React from "react"; - const defaultDecorator = (Story: any, context: any) => { - return ( - <> - - - ); + return ; }; export const decorators = [defaultDecorator]; diff --git a/.storybook/storyshots.test.ts b/.storybook/storyshots.test.ts index 20a5ead..ac174b5 100644 --- a/.storybook/storyshots.test.ts +++ b/.storybook/storyshots.test.ts @@ -1,9 +1,10 @@ /// /// -import { describe, expect, test } from "vitest"; + +import { composeStories, Meta, StoryFn } from "@storybook/react"; import { render, waitForElementToBeRemoved } from "@testing-library/react"; -import { Meta, StoryFn, composeStories } from "@storybook/react"; import { parseISO } from "date-fns"; +import { describe, expect, test } from "vitest"; import * as globalConfig from "./preview"; vi?.useFakeTimers().setSystemTime(parseISO("2020-01-01")); @@ -23,13 +24,13 @@ describe("Storybook Snapshots", async () => { modules .filter((module) => !/skip-storyshots/.test(module.default.title!)) .map((module) => [module.default.title!, module]), - )("%s", (moduleName, module) => { + )("%s", (_moduleName, module) => { test.each( Object.values(composeStories(module, globalConfig)).map((Story) => [ Story.storyName!, Story, ]), - )("%s", async (storyName, Story) => { + )("%s", async (_storyName, Story) => { const { container } = await render(Story({})); if (container.querySelector(".MuiCircularProgress-indeterminate")) { await waitForElementToBeRemoved(() => diff --git a/.storybook/vite.config.ts b/.storybook/vite.config.ts index bc6acf5..7bcec0b 100644 --- a/.storybook/vite.config.ts +++ b/.storybook/vite.config.ts @@ -2,7 +2,6 @@ import { mergeConfig } from "vite"; import { default as base } from "../config/entrypoint/vite.config"; - export default mergeConfig(base, { test: { environment: "happy-dom", diff --git a/packages/experience-editor/main.tsx b/packages/experience-editor/main.tsx index cfb9f7a..d8b5f3a 100644 --- a/packages/experience-editor/main.tsx +++ b/packages/experience-editor/main.tsx @@ -1,6 +1,6 @@ -import r2wc from "react-to-webcomponent"; import React from "react"; import * as ReactDOM from "react-dom/client"; +import r2wc from "react-to-webcomponent"; import WidgetWizard from "./src/App"; const LyticswidgetWizardWC = r2wc(WidgetWizard, React, ReactDOM, { diff --git a/packages/experience-editor/src/App.tsx b/packages/experience-editor/src/App.tsx index 0a234a7..7b73bc3 100644 --- a/packages/experience-editor/src/App.tsx +++ b/packages/experience-editor/src/App.tsx @@ -1,9 +1,9 @@ -import React from "react"; import { Box } from "@mui/material"; -import WidgetWizard from "./components/widgetWizard"; -import { createTheme, ThemeProvider, styled } from "@mui/material/styles"; -import { LightBlueGray, DarkestBlueGray } from "./utility/colors"; +import { createTheme, ThemeProvider } from "@mui/material/styles"; import type {} from "@mui/x-date-pickers/themeAugmentation"; +import React from "react"; +import WidgetWizard from "./components/widgetWizard"; +import { DarkestBlueGray, LightBlueGray } from "./utility/colors"; const theme = createTheme({ components: { @@ -135,7 +135,7 @@ const CoreWidgetWizard: React.FC = ({ // url decode the pathfora config try { pathforaconfig = atob(pathforaconfig); - } catch (e) { + } catch (_e) { pathforaconfig = ""; } diff --git a/packages/experience-editor/src/components/branding.tsx b/packages/experience-editor/src/components/branding.tsx index ecce668..d69e19d 100644 --- a/packages/experience-editor/src/components/branding.tsx +++ b/packages/experience-editor/src/components/branding.tsx @@ -1,21 +1,21 @@ -import React, { useEffect, useState } from "react"; -import { SelectInput } from "../components/form/select"; +import { Home } from "@mui/icons-material"; +import React from "react"; import { ColorInput } from "../components/form/color"; -import { NumberedSection } from "../components/form/numberedSection"; import { ColorPicker } from "../components/form/colorPicker"; -import { Home } from "@mui/icons-material"; +import { NumberedSection } from "../components/form/numberedSection"; +import { SelectInput } from "../components/form/select"; import { - theme, - backgroundColor, - textColor, - headlineColor, - closeColor, actionBackgroundColor, actionTextColor, + backgroundColor, cancelBackgroundColor, cancelTextColor, + closeColor, fieldBackgroundColor, + headlineColor, + textColor, + theme, } from "../data/pfa-fields"; interface BrandingSectionProps { diff --git a/packages/experience-editor/src/components/displayRules.tsx b/packages/experience-editor/src/components/displayRules.tsx index 9f2c7d2..25085b7 100644 --- a/packages/experience-editor/src/components/displayRules.tsx +++ b/packages/experience-editor/src/components/displayRules.tsx @@ -1,41 +1,46 @@ +import { RemoveRedEye } from "@mui/icons-material"; +import { + Box, + Checkbox, + FormControlLabel, + FormGroup, + Stack, +} from "@mui/material"; +import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; +import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; import React from "react"; -import { Stack } from "@mui/material"; -import { SelectInput } from "../components/form/select"; -import { NumberedSection } from "../components/form/numberedSection"; -import { TextInput } from "../components/form/input"; -import { SelectMultipleInput } from "../components/form/selectMultiple"; import { ConditionGroup } from "../components/form/conditionGroup"; +import { TextInput } from "../components/form/input"; +import { NumberedSection } from "../components/form/numberedSection"; import { SectionHeader } from "../components/form/sectionHeader"; -import { EmptyState } from "../utility/emptyState"; -import { RemoveRedEye } from "@mui/icons-material"; +import { SelectInput } from "../components/form/select"; +import { SelectMultipleInput } from "../components/form/selectMultiple"; import { - layout, + dateRangeEnd, + dateRangeIndefinite, + dateRangeStart, displayConditions, hideAfter, - pageVisits, - scrollPercentageToDisplay, - showDelay, - showOnExitIntent, + hideAfterActionCancelHideCount, + hideAfterActionCancelHideDuration, + hideAfterActionClosedHideCount, + hideAfterActionClosedHideDuration, + hideAfterActionConfirmHideCount, + hideAfterActionConfirmHideDuration, impressionsGlobalDuration, impressionsGlobalSession, impressionsGlobalTotal, impressionsWidgetDuration, impressionsWidgetSession, impressionsWidgetTotal, - hideAfterActionClosedHideCount, - hideAfterActionClosedHideDuration, - hideAfterActionConfirmHideCount, - hideAfterActionConfirmHideDuration, - hideAfterActionCancelHideCount, - hideAfterActionCancelHideDuration, - dateRangeStart, - dateRangeEnd, - dateRangeIndefinite, + layout, + pageVisits, + scrollPercentageToDisplay, + showDelay, + showOnExitIntent, } from "../data/pfa-fields"; +import { EmptyState } from "../utility/emptyState"; import { DatePickerInput } from "./form/datePicker"; -import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; -import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; -import { Checkbox, FormGroup, Box, FormControlLabel } from "@mui/material"; interface DisplayRulesSectionProps { formValues: { [key: string]: string }; diff --git a/packages/experience-editor/src/components/form/__tests__/radioGroup.test.tsx b/packages/experience-editor/src/components/form/__tests__/radioGroup.test.tsx index 9ba1ce1..5880ff6 100644 --- a/packages/experience-editor/src/components/form/__tests__/radioGroup.test.tsx +++ b/packages/experience-editor/src/components/form/__tests__/radioGroup.test.tsx @@ -1,7 +1,7 @@ -import { describe, it, expect, vi } from "vitest"; -import { render, screen, fireEvent } from "@testing-library/react"; -import { RadioGroupInput } from "../radioGroup"; +import { fireEvent, render, screen } from "@testing-library/react"; +import { describe, expect, it, vi } from "vitest"; import { Field } from "../../../data/pfa-fields"; +import { RadioGroupInput } from "../radioGroup"; describe("RadioGroupInput", () => { const mockField: Field = { diff --git a/packages/experience-editor/src/components/form/callbackFn.tsx b/packages/experience-editor/src/components/form/callbackFn.tsx index 4831170..8ff33e2 100644 --- a/packages/experience-editor/src/components/form/callbackFn.tsx +++ b/packages/experience-editor/src/components/form/callbackFn.tsx @@ -1,5 +1,5 @@ -import React from "react"; import { Box, Stack, Typography } from "@mui/material"; +import React from "react"; import { Field } from "../../data/pfa-fields"; import { CodeEditor } from "./codeEditor"; diff --git a/packages/experience-editor/src/components/form/checkbox.tsx b/packages/experience-editor/src/components/form/checkbox.tsx index 0ccb0bb..47e22e6 100644 --- a/packages/experience-editor/src/components/form/checkbox.tsx +++ b/packages/experience-editor/src/components/form/checkbox.tsx @@ -1,5 +1,5 @@ +import { Checkbox, FormControlLabel } from "@mui/material"; import React, { useEffect } from "react"; -import { FormControlLabel, Checkbox } from "@mui/material"; import { Field } from "../../data/pfa-fields"; export interface CheckboxInputProps { diff --git a/packages/experience-editor/src/components/form/codeEditor.tsx b/packages/experience-editor/src/components/form/codeEditor.tsx index 8fb26b9..2acb42b 100644 --- a/packages/experience-editor/src/components/form/codeEditor.tsx +++ b/packages/experience-editor/src/components/form/codeEditor.tsx @@ -1,8 +1,8 @@ -import React, { useState, useEffect } from "react"; -import CodeMirror from "@uiw/react-codemirror"; import { javascript } from "@codemirror/lang-javascript"; -import { Box, Chip, LinearProgress } from "@mui/material"; import { CheckCircle } from "@mui/icons-material"; +import { Box, Chip, LinearProgress } from "@mui/material"; +import CodeMirror from "@uiw/react-codemirror"; +import React, { useEffect, useState } from "react"; interface CodeEditorProps { value: string; @@ -26,7 +26,7 @@ export const CodeEditor: React.FC = ({ setCodeString(value); }, [value]); - const onInputChange = React.useCallback((val, viewUpdate) => { + const onInputChange = React.useCallback((val, _viewUpdate) => { setCodeString(val); setIsDirty(true); @@ -41,14 +41,14 @@ export const CodeEditor: React.FC = ({ onChange(val); setShowSaveAlert(true); setIsDirty(false); - const newTimer2 = setTimeout(() => { + const _newTimer2 = setTimeout(() => { setShowSaveAlert(false); }, 1000); - } catch (error) { + } catch (_error) { setProgressColor("error"); setShowErrorAlert(true); setIsDirty(true); - const newTimer2 = setTimeout(() => { + const _newTimer2 = setTimeout(() => { setShowErrorAlert(false); }, 1000); } diff --git a/packages/experience-editor/src/components/form/color.tsx b/packages/experience-editor/src/components/form/color.tsx index ae47ded..05e4205 100644 --- a/packages/experience-editor/src/components/form/color.tsx +++ b/packages/experience-editor/src/components/form/color.tsx @@ -1,5 +1,5 @@ -import React from "react"; import { Stack, Typography } from "@mui/material"; +import React from "react"; import { Field } from "../../data/pfa-fields"; import { helperTextStyles } from "../styles/inputLabel"; diff --git a/packages/experience-editor/src/components/form/colorPicker.tsx b/packages/experience-editor/src/components/form/colorPicker.tsx index 95562ec..ff3b601 100644 --- a/packages/experience-editor/src/components/form/colorPicker.tsx +++ b/packages/experience-editor/src/components/form/colorPicker.tsx @@ -1,5 +1,5 @@ -import React, { ReactNode } from "react"; import { Grid } from "@mui/material"; // Importing necessary components from Material-UI +import React, { ReactNode } from "react"; interface ColorPickerProps { children: ReactNode | ReactNode[]; diff --git a/packages/experience-editor/src/components/form/conditionGroup.tsx b/packages/experience-editor/src/components/form/conditionGroup.tsx index aea6ab0..2dd7946 100644 --- a/packages/experience-editor/src/components/form/conditionGroup.tsx +++ b/packages/experience-editor/src/components/form/conditionGroup.tsx @@ -1,5 +1,5 @@ -import React, { ReactNode } from "react"; import { Box, Stack } from "@mui/material"; // Importing necessary components from Material-UI +import React, { ReactNode } from "react"; interface ConditionGroupProps { label: string; diff --git a/packages/experience-editor/src/components/form/datePicker.tsx b/packages/experience-editor/src/components/form/datePicker.tsx index 6170c23..b49ea52 100644 --- a/packages/experience-editor/src/components/form/datePicker.tsx +++ b/packages/experience-editor/src/components/form/datePicker.tsx @@ -1,9 +1,8 @@ +import { Typography } from "@mui/material"; +import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker"; import React from "react"; import { Field } from "../../data/pfa-fields"; -import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker"; import { helperTextStyles } from "../styles/inputLabel"; -import { Typography } from "@mui/material"; -import { parseISO } from "date-fns"; export interface DatePickerInputProps { field: Field; diff --git a/packages/experience-editor/src/components/form/displayConditionItem.tsx b/packages/experience-editor/src/components/form/displayConditionItem.tsx index 890be1a..944399a 100644 --- a/packages/experience-editor/src/components/form/displayConditionItem.tsx +++ b/packages/experience-editor/src/components/form/displayConditionItem.tsx @@ -1,5 +1,5 @@ -import React, { useEffect } from "react"; -import { Box, Grid, Stack } from "@mui/material"; +import { Box, Stack } from "@mui/material"; +import React from "react"; export interface DisplayConditionItemProps { children: React.ReactNode[]; diff --git a/packages/experience-editor/src/components/form/input.tsx b/packages/experience-editor/src/components/form/input.tsx index 1035bff..a3626b8 100644 --- a/packages/experience-editor/src/components/form/input.tsx +++ b/packages/experience-editor/src/components/form/input.tsx @@ -1,7 +1,6 @@ -import React, { useEffect } from "react"; import { TextField } from "@mui/material"; +import React, { useEffect } from "react"; import { Field } from "../../data/pfa-fields"; -import { helperTextStyles } from "../styles/inputLabel"; export interface TextInputProps { field: Field; diff --git a/packages/experience-editor/src/components/form/numberedSection.tsx b/packages/experience-editor/src/components/form/numberedSection.tsx index cd8dd0f..bbe733a 100644 --- a/packages/experience-editor/src/components/form/numberedSection.tsx +++ b/packages/experience-editor/src/components/form/numberedSection.tsx @@ -1,6 +1,6 @@ -import React from "react"; -import { Avatar, Box, Stack, Typography } from "@mui/material"; import { Label } from "@mui/icons-material"; +import { Avatar, Stack, Typography } from "@mui/material"; +import React from "react"; export interface NumberedSectionProps { icon: React.ReactNode; diff --git a/packages/experience-editor/src/components/form/radioGroup.tsx b/packages/experience-editor/src/components/form/radioGroup.tsx index 2f162e8..ac8109c 100644 --- a/packages/experience-editor/src/components/form/radioGroup.tsx +++ b/packages/experience-editor/src/components/form/radioGroup.tsx @@ -1,12 +1,12 @@ -import React from "react"; import { FormControl, - FormLabel, - FormHelperText, - RadioGroup, FormControlLabel, + FormHelperText, + FormLabel, Radio, + RadioGroup, } from "@mui/material"; +import React from "react"; import { Field } from "../../data/pfa-fields"; export interface RadioGroupInputProps { diff --git a/packages/experience-editor/src/components/form/sectionHeader.tsx b/packages/experience-editor/src/components/form/sectionHeader.tsx index 55b1d07..6d0e335 100644 --- a/packages/experience-editor/src/components/form/sectionHeader.tsx +++ b/packages/experience-editor/src/components/form/sectionHeader.tsx @@ -1,5 +1,5 @@ -import React from "react"; import { Box, Typography } from "@mui/material"; +import React from "react"; export interface SectionHeaderProps { headline: string; diff --git a/packages/experience-editor/src/components/form/select.tsx b/packages/experience-editor/src/components/form/select.tsx index a613b86..eb1c13b 100644 --- a/packages/experience-editor/src/components/form/select.tsx +++ b/packages/experience-editor/src/components/form/select.tsx @@ -1,4 +1,3 @@ -import React from "react"; import { FormControl, FormHelperText, @@ -6,6 +5,7 @@ import { MenuItem, Select, } from "@mui/material"; +import React from "react"; import { Field } from "../../data/pfa-fields"; export interface SelectInputProps { @@ -39,7 +39,7 @@ export const SelectInput: React.FC = ({ required={field.required} renderValue={(selected) => { const selectedOption = field.options?.find( - (option) => option.value === selected + (option) => option.value === selected, ); return selectedOption?.label || ""; }} diff --git a/packages/experience-editor/src/components/form/selectMultiple.tsx b/packages/experience-editor/src/components/form/selectMultiple.tsx index 31ce628..d606e8c 100644 --- a/packages/experience-editor/src/components/form/selectMultiple.tsx +++ b/packages/experience-editor/src/components/form/selectMultiple.tsx @@ -1,14 +1,14 @@ -import React, { useEffect } from "react"; import { Checkbox, - ListItemText, FormControl, FormHelperText, InputLabel, + ListItemText, MenuItem, Select, SelectChangeEvent, } from "@mui/material"; +import React, { useEffect } from "react"; import { Field } from "../../data/pfa-fields"; export interface SelectMultipleInputProps { @@ -20,7 +20,7 @@ export interface SelectMultipleInputProps { } export const SelectMultipleInput: React.FC = ( - selectMultipleInputProps + selectMultipleInputProps, ) => { const { field, formValues, handleChange, position, visible } = selectMultipleInputProps; @@ -38,7 +38,7 @@ export const SelectMultipleInput: React.FC = ( }, [formValues]); const handleSelectCheckChange = ( - event: SelectChangeEvent + event: SelectChangeEvent, ) => { const { target: { value }, diff --git a/packages/experience-editor/src/components/form/textarea.tsx b/packages/experience-editor/src/components/form/textarea.tsx index 3a1af3b..ff02c0e 100644 --- a/packages/experience-editor/src/components/form/textarea.tsx +++ b/packages/experience-editor/src/components/form/textarea.tsx @@ -1,5 +1,5 @@ -import React from "react"; import { TextField } from "@mui/material"; +import React from "react"; import { Field } from "../../data/pfa-fields"; export interface TextAreaProps { diff --git a/packages/experience-editor/src/components/formBuilder.tsx b/packages/experience-editor/src/components/formBuilder.tsx index d4082f1..b62923c 100644 --- a/packages/experience-editor/src/components/formBuilder.tsx +++ b/packages/experience-editor/src/components/formBuilder.tsx @@ -1,24 +1,24 @@ -import React, { useEffect, useState } from "react"; +import { + ArrowCircleDown, + ArrowCircleUp, + Delete, + Edit, + EditNote, + Save, +} from "@mui/icons-material"; import { Box, Button, Checkbox, Chip, - FormGroup, FormControlLabel, + FormGroup, IconButton, Stack, TextField, Typography, } from "@mui/material"; -import { - ArrowCircleDown, - ArrowCircleUp, - Delete, - Edit, - Save, - EditNote, -} from "@mui/icons-material"; +import React, { useEffect, useState } from "react"; import { NumberedSection } from "../components/form/numberedSection"; import { formElements as formElementsData } from "../data/pfa-fields"; import { EmptyState } from "../utility/emptyState"; @@ -104,7 +104,7 @@ export const FormNodeEditor: React.FC = ({ const handleOptionChange = ( index: number, field: keyof FormValue, - value: string + value: string, ) => { const newOptions = options.map((option, i) => { if (i === index) { @@ -124,7 +124,7 @@ export const FormNodeEditor: React.FC = ({ setOptions(newOptions); }; - const handleOpenToggle = (field: FormElement) => { + const handleOpenToggle = (_field: FormElement) => { setOpen(!open); }; @@ -484,7 +484,7 @@ export const FormBuilder: React.FC = ({ message={"Add form elements using the buttons to the right."} /> )} - {formElements.map((element, index) => ( + {formElements.map((element, _index) => ( { = ({ spacing, collections, }) => { - const [collectionField, setCollectionField] = useState(null); + const [_collectionField, setCollectionField] = useState(null); useEffect(() => { setCollectionField(contentCollectionWithOptions(collections)); diff --git a/packages/experience-editor/src/components/targeting.tsx b/packages/experience-editor/src/components/targeting.tsx index cc2eebd..ca8a2d5 100644 --- a/packages/experience-editor/src/components/targeting.tsx +++ b/packages/experience-editor/src/components/targeting.tsx @@ -1,23 +1,22 @@ +import { AdsClick, FindInPage } from "@mui/icons-material"; import React, { useEffect, useState } from "react"; +import { ConditionGroup } from "../components/form/conditionGroup"; +import { NumberedSection } from "../components/form/numberedSection"; +import { SelectInput } from "../components/form/select"; import { URLContainsBuilder, URLContainsItem, } from "../components/form/urlContains"; -import { SelectInput } from "../components/form/select"; -import { ConditionGroup } from "../components/form/conditionGroup"; import { - type, - urlContains, + attributeRule, audienceWithOptions, Field, + personalizationKeyWithOptions, SelectOption, - Flow, targetMethod, - attributeRule, - personalizationKeyWithOptions, + type, + urlContains, } from "../data/pfa-fields"; -import { NumberedSection } from "../components/form/numberedSection"; -import { AdsClick, FindInPage } from "@mui/icons-material"; import { CallbackFnEditor } from "./form/callbackFn"; interface TargetingSectionProps { diff --git a/packages/experience-editor/src/components/widgetWizard.tsx b/packages/experience-editor/src/components/widgetWizard.tsx index 49d6e9e..74bbd52 100644 --- a/packages/experience-editor/src/components/widgetWizard.tsx +++ b/packages/experience-editor/src/components/widgetWizard.tsx @@ -1,100 +1,96 @@ +import { Box, Button, Stack, Tab, Tabs } from "@mui/material"; import React, { useEffect, useState } from "react"; -import { Box, Button, Stack, Tab, Tabs, Typography } from "@mui/material"; - import { - Field, - SelectOption, - type, - headline, - layout, - theme, - backgroundColor, - textColor, - headlineColor, - closeColor, actionBackgroundColor, actionTextColor, + attributeRule, + audience, + backgroundColor, + cancelAction, cancelBackgroundColor, - cancelTextColor, - fieldBackgroundColor, - message, - okShow, - okMessage, - cancelShow, cancelMessage, - image, - positionSelector, - position, - origin, - pushDown, - widgetTitle, - widgetDescription, - widgetSlug, - widgetStatus, + cancelShow, + cancelTextColor, + closeAction, + closeColor, + confirmAction, + contentCollection, + contentDisplayDescription, + contentDisplayDescriptionLimit, + contentDisplayImage, + contentDisplayTitle, + contentRank, + contentShuffle, + contentVisited, + dateRangeEnd, + dateRangeIndefinite, + dateRangeStart, displayConditions, + Field, + Flow, + fieldBackgroundColor, + formElements, + headline, + headlineColor, hideAfter, - pageVisits, - scrollPercentageToDisplay, - showDelay, - showOnExitIntent, + hideAfterActionCancelHideCount, + hideAfterActionCancelHideDuration, + hideAfterActionClosedHideCount, + hideAfterActionClosedHideDuration, + hideAfterActionConfirmHideCount, + hideAfterActionConfirmHideDuration, + image, impressionsGlobalDuration, impressionsGlobalSession, impressionsGlobalTotal, impressionsWidgetDuration, impressionsWidgetSession, impressionsWidgetTotal, - hideAfterActionClosedHideCount, - hideAfterActionClosedHideDuration, - hideAfterActionConfirmHideCount, - hideAfterActionConfirmHideDuration, - hideAfterActionCancelHideCount, - hideAfterActionCancelHideDuration, - dateRangeStart, - dateRangeEnd, - dateRangeIndefinite, - urlContains, - confirmAction, - cancelAction, - closeAction, - onInit, - onLoad, - audience, - formElements, - contentCollection, - contentRank, - contentVisited, - contentShuffle, - contentDisplayTitle, - contentDisplayImage, - contentDisplayDescription, - contentDisplayDescriptionLimit, - targetMethod, - attributeRule, - Flow, + layout, + message, okLinkNewTab, - okShowLink, okLinkURL, + okMessage, + okShow, + okShowLink, + onInit, + onLoad, + origin, + pageVisits, personalizationKey, + position, + positionSelector, + pushDown, + SelectOption, + scrollPercentageToDisplay, + showDelay, + showOnExitIntent, + targetMethod, + textColor, + theme, + type, + urlContains, + widgetDescription, + widgetSlug, + widgetStatus, + widgetTitle, } from "../data/pfa-fields"; - -import { TextAreaInput } from "./form/textarea"; +import { findFieldById, shouldApplyDefaultValue } from "../utility/fieldLogic"; +import { getValueByDotNotation, removeEmptyObjects } from "../utility/objects"; +import { PathforaHandler } from "../utility/pathforaInterface"; +import { BrandingSection } from "./branding"; +import { DisplayRulesSection } from "./displayRules"; +import { CallbackFnEditor } from "./form/callbackFn"; +import { CodeEditor } from "./form/codeEditor"; import { TextInput } from "./form/input"; -import { SelectInput } from "./form/select"; import { SectionHeader } from "./form/sectionHeader"; -import { CodeEditor } from "./form/codeEditor"; +import { SelectInput } from "./form/select"; +import { TextAreaInput } from "./form/textarea"; +import { FormBuilder } from "./formBuilder"; import { MessagingSection } from "./messaging"; -import { TargetingSection } from "./targeting"; import { PositionSection } from "./position"; -import { BrandingSection } from "./branding"; -import { DisplayRulesSection } from "./displayRules"; import { RecommendationSection } from "./recommendation"; -import { PathforaHandler } from "../utility/pathforaInterface"; -import { CallbackFnEditor } from "./form/callbackFn"; -import { FormBuilder } from "./formBuilder"; - -import { removeEmptyObjects, getValueByDotNotation } from "../utility/objects"; -import { shouldApplyDefaultValue, findFieldById } from "../utility/fieldLogic"; -import { Visibility } from "@mui/icons-material"; +import { TargetingSection } from "./targeting"; interface WidgetWizardProps { accountid: string; @@ -168,7 +164,7 @@ const WidgetWizard: React.FC = ({ const [pathfora, setPathfora] = useState(); const [audiences, setAudiences] = useState([]); const [collections, setCollections] = useState([]); - const [flows, setFlows] = useState([]); + const [_flows, setFlows] = useState([]); const [personalizationKeys, setPersonalizationKeys] = useState< SelectOption[] >([]); @@ -318,7 +314,7 @@ const WidgetWizard: React.FC = ({ }, [formValues]); const handlePathforaPreview = () => { - let config = JSON.parse(renderedConfig); + const config = JSON.parse(renderedConfig); const widget = pathfora?.deserializeWidget(config); pathfora?.testWidget(widget); }; @@ -355,17 +351,17 @@ const WidgetWizard: React.FC = ({ }); }; - const handleEditorTypeTabChange = (event, newValue) => { + const handleEditorTypeTabChange = (_event, newValue) => { setEditorTypeTabValue(newValue); }; - const handleBasicEditorTabChange = (event, newValue) => { + const handleBasicEditorTabChange = (event, _newValue) => { const id = event.target.id; const value = tabToValueMapping[id]; setBasicEditorTabValue(value); }; - const handleAdvancedEditorTabChange = (event, newValue) => { + const handleAdvancedEditorTabChange = (_event, newValue) => { setAdvancedEditorTabValue(newValue); }; @@ -640,7 +636,7 @@ const WidgetWizard: React.FC = ({ } let callback; try { - callback = Function('"use strict";return (' + value + ")")(); + callback = Function(`"use strict";return (${value})`)(); } catch (error) { console.warn("Invalid function:", error); return; @@ -671,7 +667,7 @@ const WidgetWizard: React.FC = ({ })); }; - const handleSubmit = (event: React.FormEvent): void => { + const handleSubmit = (_event: React.FormEvent): void => { // no op for now }; diff --git a/packages/experience-editor/src/data/fields/audience.ts b/packages/experience-editor/src/data/fields/audience.ts index 75ba3f5..2a0f7b5 100644 --- a/packages/experience-editor/src/data/fields/audience.ts +++ b/packages/experience-editor/src/data/fields/audience.ts @@ -13,7 +13,7 @@ export const Audience: Field = { }; export const AudienceWithOptions = (audiences: SelectOption[]) => { - let payload = Audience; + const payload = Audience; payload.options = audiences; return payload; }; diff --git a/packages/experience-editor/src/data/fields/layout.ts b/packages/experience-editor/src/data/fields/layout.ts index 7fbee44..2f5aa9e 100644 --- a/packages/experience-editor/src/data/fields/layout.ts +++ b/packages/experience-editor/src/data/fields/layout.ts @@ -15,7 +15,7 @@ const OptionBar: SelectOption = { value: "bar", }; -const OptionButton: SelectOption = { +const _OptionButton: SelectOption = { label: "Button", value: "button", }; @@ -75,7 +75,7 @@ export const Layout: Field = { }; export const LayoutWithOptions: (type: string) => Field = (type: string) => { - let payload = Layout; + const payload = Layout; payload.options = getSelectOptions(type); return payload; }; diff --git a/packages/experience-editor/src/data/fields/okLinkNewTab.ts b/packages/experience-editor/src/data/fields/okLinkNewTab.ts index ea3647d..830f018 100644 --- a/packages/experience-editor/src/data/fields/okLinkNewTab.ts +++ b/packages/experience-editor/src/data/fields/okLinkNewTab.ts @@ -11,8 +11,7 @@ export const OKLinkNewTab: Field = { render: "details.cta.newTab", translate: { render: "config.confirmAction.callback", - renderValue: function (newTab, config) { - return renderConfirmActionCallbackLink(config.details.cta?.url, newTab); - }, + renderValue: (newTab, config) => + renderConfirmActionCallbackLink(config.details.cta?.url, newTab), }, }; diff --git a/packages/experience-editor/src/data/fields/okLinkURL.ts b/packages/experience-editor/src/data/fields/okLinkURL.ts index 77030cb..85edd29 100644 --- a/packages/experience-editor/src/data/fields/okLinkURL.ts +++ b/packages/experience-editor/src/data/fields/okLinkURL.ts @@ -12,8 +12,7 @@ export const OKLinkURL: Field = { render: "details.cta.url", translate: { render: "config.confirmAction.callback", - renderValue: function (value, config) { - return renderConfirmActionCallbackLink(value, config.details.cta?.newTab); - }, + renderValue: (value, config) => + renderConfirmActionCallbackLink(value, config.details.cta?.newTab), }, }; diff --git a/packages/experience-editor/src/data/fields/origin.ts b/packages/experience-editor/src/data/fields/origin.ts index 1463686..56a2316 100644 --- a/packages/experience-editor/src/data/fields/origin.ts +++ b/packages/experience-editor/src/data/fields/origin.ts @@ -38,7 +38,7 @@ export const Origin: Field = { }; export const OriginWithOptions: (type: string) => Field = (type: string) => { - let payload = Origin; + const payload = Origin; payload.options = getSelectOptions(type); return payload; }; diff --git a/packages/experience-editor/src/data/fields/personalizationKeys.ts b/packages/experience-editor/src/data/fields/personalizationKeys.ts index 4befdc1..679c66d 100644 --- a/packages/experience-editor/src/data/fields/personalizationKeys.ts +++ b/packages/experience-editor/src/data/fields/personalizationKeys.ts @@ -14,7 +14,7 @@ export const PersonalizationKey: Field = { }; export const PersonalizationKeyWithOptions = (pk: SelectOption[]) => { - let payload = PersonalizationKey; + const payload = PersonalizationKey; payload.options = pk; return payload; }; diff --git a/packages/experience-editor/src/data/fields/position.ts b/packages/experience-editor/src/data/fields/position.ts index 978c8d1..0566fd8 100644 --- a/packages/experience-editor/src/data/fields/position.ts +++ b/packages/experience-editor/src/data/fields/position.ts @@ -94,7 +94,7 @@ export const Position: Field = { }; export const PositionWithOptions: (type: string) => Field = (type: string) => { - let payload = Position; + const payload = Position; payload.options = getSelectOptions(type); return payload; }; diff --git a/packages/experience-editor/src/data/fields/recommend.ts b/packages/experience-editor/src/data/fields/recommend.ts index 1e44848..86e788a 100644 --- a/packages/experience-editor/src/data/fields/recommend.ts +++ b/packages/experience-editor/src/data/fields/recommend.ts @@ -13,7 +13,7 @@ export const ContentCollection: Field = { }; export const ContentCollectionWithOptions = (collections: SelectOption[]) => { - let payload = ContentCollection; + const payload = ContentCollection; payload.options = collections; return payload; }; diff --git a/packages/experience-editor/src/data/fields/targetFlow.ts b/packages/experience-editor/src/data/fields/targetFlow.ts index a6b2be9..3b78980 100644 --- a/packages/experience-editor/src/data/fields/targetFlow.ts +++ b/packages/experience-editor/src/data/fields/targetFlow.ts @@ -34,7 +34,7 @@ export const TargetFlow: Field = { }; export const TargetFlowWithOptions = (flows: Flow[]) => { - let payload = TargetFlow; + const payload = TargetFlow; payload.options = flows.reduce((acc, flow) => { acc.push({ label: flow.label, value: flow.value }); return acc; @@ -43,7 +43,7 @@ export const TargetFlowWithOptions = (flows: Flow[]) => { }; export const TargetFlowVersionWithOptions = (flows: Flow[], id: string) => { - let payload = TargetFlowVersion; + const payload = TargetFlowVersion; payload.options = flows .find((flow) => flow.value === id) .versions.map((v) => ({ @@ -58,7 +58,7 @@ export const TargetFlowStepWithOptions = ( id: string, version: string, ) => { - let payload = TargetFlowStep; + const payload = TargetFlowStep; payload.options = flows .find((flow) => flow.value === id) .versions.find((v) => v.version.toString() === version).steps; diff --git a/packages/experience-editor/src/data/fields/targetMethod.ts b/packages/experience-editor/src/data/fields/targetMethod.ts index fa0d74a..2d410cc 100644 --- a/packages/experience-editor/src/data/fields/targetMethod.ts +++ b/packages/experience-editor/src/data/fields/targetMethod.ts @@ -1,6 +1,6 @@ import { Field } from "../pfa-fields"; -import { Audience } from "./audience"; import { AttributeRule } from "./attributeRule"; +import { Audience } from "./audience"; import { PersonalizationKey } from "./personalizationKeys"; export const TargetMethod: Field = { diff --git a/packages/experience-editor/src/data/fields/theme.ts b/packages/experience-editor/src/data/fields/theme.ts index b756c60..eea7bb3 100644 --- a/packages/experience-editor/src/data/fields/theme.ts +++ b/packages/experience-editor/src/data/fields/theme.ts @@ -1,14 +1,14 @@ import { Field } from "../pfa-fields"; import { - BackgroundColor, - HeadlineColor, - TextColor, - CloseColor, ActionBackgroundColor, ActionTextColor, + BackgroundColor, CancelBackgroundColor, CancelTextColor, + CloseColor, FieldBackgroundColor, + HeadlineColor, + TextColor, } from "./colors"; export const Theme: Field = { diff --git a/packages/experience-editor/src/data/fields/type.ts b/packages/experience-editor/src/data/fields/type.ts index 1376688..45dd39d 100644 --- a/packages/experience-editor/src/data/fields/type.ts +++ b/packages/experience-editor/src/data/fields/type.ts @@ -1,14 +1,4 @@ import { Field } from "../pfa-fields"; -import { - contentCollection, - contentRank, - contentVisited, - contentShuffle, - contentDisplayTitle, - contentDisplayImage, - contentDisplayDescription, - contentDisplayDescriptionLimit, -} from "../pfa-fields"; export const Type: Field = { id: "type", diff --git a/packages/experience-editor/src/data/fields/widgetStatus.ts b/packages/experience-editor/src/data/fields/widgetStatus.ts index d8a654a..d6719db 100644 --- a/packages/experience-editor/src/data/fields/widgetStatus.ts +++ b/packages/experience-editor/src/data/fields/widgetStatus.ts @@ -1,5 +1,4 @@ -import { Field } from "../pfa-fields"; -import { SelectOption } from "../pfa-fields"; +import { Field, SelectOption } from "../pfa-fields"; const OptionDraft: SelectOption = { label: "Draft", diff --git a/packages/experience-editor/src/data/pfa-fields.ts b/packages/experience-editor/src/data/pfa-fields.ts index 5a7353b..44650c2 100644 --- a/packages/experience-editor/src/data/pfa-fields.ts +++ b/packages/experience-editor/src/data/pfa-fields.ts @@ -1,41 +1,38 @@ -import { Type } from "./fields/type"; -import { Headline } from "./fields/headline"; -import { Layout, LayoutWithOptions } from "./fields/layout"; -import { Theme } from "./fields/theme"; +import { AttributeRule } from "./fields/attributeRule"; +import { Audience, AudienceWithOptions } from "./fields/audience"; +import { CancelAction } from "./fields/callbacks/cancelAction"; +import { CloseAction } from "./fields/callbacks/closeAction"; +import { ConfirmAction } from "./fields/callbacks/confirmAction"; +import { OnInit } from "./fields/callbacks/onInit"; +import { OnLoad } from "./fields/callbacks/onLoad"; +import { CancelMessage } from "./fields/cancelMessage"; +import { CancelShow } from "./fields/cancelShow"; import { - BackgroundColor, - TextColor, - HeadlineColor, - CloseColor, ActionBackgroundColor, ActionTextColor, + BackgroundColor, CancelBackgroundColor, CancelTextColor, + CloseColor, FieldBackgroundColor, + HeadlineColor, + TextColor, } from "./fields/colors"; -import { Message } from "./fields/msg"; -import { OKShow } from "./fields/okShow"; -import { OKShowLink } from "./fields/okShowLink"; -import { OKLinkURL } from "./fields/okLinkURL"; -import { OKLinkNewTab } from "./fields/okLinkNewTab"; -import { OKMessage } from "./fields/okMessage"; -import { CancelShow } from "./fields/cancelShow"; -import { CancelMessage } from "./fields/cancelMessage"; -import { Image } from "./fields/image"; -import { PositionSelector } from "./fields/positionSelector"; -import { Position, PositionWithOptions } from "./fields/position"; -import { Origin, OriginWithOptions } from "./fields/origin"; -import { PushDown } from "./fields/pushDown"; -import { WidgetTitle } from "./fields/widgetTitle"; -import { WidgetDescription } from "./fields/widgetDescription"; -import { WidgetSlug } from "./fields/widgetSlug"; -import { WidgetStatus } from "./fields/widgetStatus"; import { DisplayConditions } from "./fields/displayConditions"; +import { + DateRangeEnd, + DateRangeIndefinite, + DateRangeStart, +} from "./fields/displayConditions/dateRange"; import { HideAfter } from "./fields/displayConditions/hideAfter"; -import { PageVisits } from "./fields/displayConditions/pageVisits"; -import { ScrollPercentageToDisplay } from "./fields/displayConditions/scrollPercentageToDisplay"; -import { ShowDelay } from "./fields/displayConditions/showDelay"; -import { ShowOnExitIntent } from "./fields/displayConditions/showOnExitIntent"; +import { + HideAfterActionCancelHideCount, + HideAfterActionCancelHideDuration, + HideAfterActionClosedHideCount, + HideAfterActionClosedHideDuration, + HideAfterActionConfirmHideCount, + HideAfterActionConfirmHideDuration, +} from "./fields/displayConditions/hideAfterAction"; import { ImpressionsGlobalDuration, ImpressionsGlobalSession, @@ -44,52 +41,55 @@ import { ImpressionsWidgetSession, ImpressionsWidgetTotal, } from "./fields/displayConditions/impressions"; -import { - HideAfterActionClosedHideCount, - HideAfterActionClosedHideDuration, - HideAfterActionConfirmHideCount, - HideAfterActionConfirmHideDuration, - HideAfterActionCancelHideCount, - HideAfterActionCancelHideDuration, -} from "./fields/displayConditions/hideAfterAction"; -import { - DateRangeStart, - DateRangeEnd, - DateRangeIndefinite, -} from "./fields/displayConditions/dateRange"; +import { PageVisits } from "./fields/displayConditions/pageVisits"; +import { ScrollPercentageToDisplay } from "./fields/displayConditions/scrollPercentageToDisplay"; +import { ShowDelay } from "./fields/displayConditions/showDelay"; +import { ShowOnExitIntent } from "./fields/displayConditions/showOnExitIntent"; import { URLContains } from "./fields/displayConditions/urlContains"; -import { ConfirmAction } from "./fields/callbacks/confirmAction"; -import { CancelAction } from "./fields/callbacks/cancelAction"; -import { CloseAction } from "./fields/callbacks/closeAction"; -import { OnInit } from "./fields/callbacks/onInit"; -import { OnLoad } from "./fields/callbacks/onLoad"; -import { Audience, AudienceWithOptions } from "./fields/audience"; import { FormElements } from "./fields/formElements"; -import { TargetMethod } from "./fields/targetMethod"; -import { AttributeRule } from "./fields/attributeRule"; +import { Headline } from "./fields/headline"; +import { Image } from "./fields/image"; +import { Layout, LayoutWithOptions } from "./fields/layout"; +import { Message } from "./fields/msg"; +import { OKLinkNewTab } from "./fields/okLinkNewTab"; +import { OKLinkURL } from "./fields/okLinkURL"; +import { OKMessage } from "./fields/okMessage"; +import { OKShow } from "./fields/okShow"; +import { OKShowLink } from "./fields/okShowLink"; +import { Origin, OriginWithOptions } from "./fields/origin"; +import { + PersonalizationKey, + PersonalizationKeyWithOptions, +} from "./fields/personalizationKeys"; +import { Position, PositionWithOptions } from "./fields/position"; +import { PositionSelector } from "./fields/positionSelector"; +import { PushDown } from "./fields/pushDown"; import { ContentCollection, ContentCollectionWithOptions, - ContentVisited, - ContentShuffle, - ContentDisplayTitle, - ContentDisplayImage, ContentDisplayDescription, ContentDisplayDescriptionLimit, + ContentDisplayImage, + ContentDisplayTitle, ContentRank, + ContentShuffle, + ContentVisited, } from "./fields/recommend"; import { TargetFlow, - TargetFlowVersion, - TargetFlowWithOptions, - TargetFlowVersionWithOptions, TargetFlowStep, TargetFlowStepWithOptions, + TargetFlowVersion, + TargetFlowVersionWithOptions, + TargetFlowWithOptions, } from "./fields/targetFlow"; -import { - PersonalizationKey, - PersonalizationKeyWithOptions, -} from "./fields/personalizationKeys"; +import { TargetMethod } from "./fields/targetMethod"; +import { Theme } from "./fields/theme"; +import { Type } from "./fields/type"; +import { WidgetDescription } from "./fields/widgetDescription"; +import { WidgetSlug } from "./fields/widgetSlug"; +import { WidgetStatus } from "./fields/widgetStatus"; +import { WidgetTitle } from "./fields/widgetTitle"; export interface Field { id: string; diff --git a/packages/experience-editor/src/utility/__tests__/fieldLogic.test.ts b/packages/experience-editor/src/utility/__tests__/fieldLogic.test.ts index cd70abf..848f6f3 100644 --- a/packages/experience-editor/src/utility/__tests__/fieldLogic.test.ts +++ b/packages/experience-editor/src/utility/__tests__/fieldLogic.test.ts @@ -1,6 +1,6 @@ -import { describe, it, expect } from "vitest"; -import { shouldApplyDefaultValue, findFieldById } from "../fieldLogic"; +import { describe, expect, it } from "vitest"; import { Field } from "../../data/pfa-fields"; +import { findFieldById, shouldApplyDefaultValue } from "../fieldLogic"; describe("fieldLogic", () => { describe("shouldApplyDefaultValue", () => { diff --git a/packages/experience-editor/src/utility/__tests__/objects.test.ts b/packages/experience-editor/src/utility/__tests__/objects.test.ts index be5f558..fe72cea 100644 --- a/packages/experience-editor/src/utility/__tests__/objects.test.ts +++ b/packages/experience-editor/src/utility/__tests__/objects.test.ts @@ -1,5 +1,5 @@ -import { describe, it, expect } from "vitest"; -import { removeEmptyObjects, getValueByDotNotation } from "../objects"; +import { describe, expect, it } from "vitest"; +import { getValueByDotNotation, removeEmptyObjects } from "../objects"; describe("objects utility", () => { describe("removeEmptyObjects", () => { diff --git a/packages/experience-editor/src/utility/emptyState.tsx b/packages/experience-editor/src/utility/emptyState.tsx index 60c1996..7733395 100644 --- a/packages/experience-editor/src/utility/emptyState.tsx +++ b/packages/experience-editor/src/utility/emptyState.tsx @@ -1,5 +1,5 @@ -import React from "react"; import { Stack, Typography } from "@mui/material"; +import React from "react"; export interface EmptyStateProps { message: string; diff --git a/packages/experience-editor/src/utility/objects.ts b/packages/experience-editor/src/utility/objects.ts index e6674d8..8c130ae 100644 --- a/packages/experience-editor/src/utility/objects.ts +++ b/packages/experience-editor/src/utility/objects.ts @@ -1,6 +1,6 @@ export const removeEmptyObjects = (object: any) => { for (const key in object) { - if (object.hasOwnProperty(key)) { + if (Object.hasOwn(object, key)) { const value = object[key]; if (value && typeof value === "object") { removeEmptyObjects(value); @@ -22,5 +22,5 @@ export const removeEmptyObjects = (object: any) => { }; export const getValueByDotNotation = (obj, path) => { - return path.split(".").reduce((acc, part) => acc && acc[part], obj); + return path.split(".").reduce((acc, part) => acc?.[part], obj); }; diff --git a/packages/experience-editor/src/utility/pathforaInterface.ts b/packages/experience-editor/src/utility/pathforaInterface.ts index 09217cb..166acbb 100644 --- a/packages/experience-editor/src/utility/pathforaInterface.ts +++ b/packages/experience-editor/src/utility/pathforaInterface.ts @@ -41,7 +41,7 @@ export class PathforaHandler { } loadJSTAGLibrary(accountid: string): Promise { - return new Promise((resolve, reject) => { + return new Promise((resolve, _reject) => { const jstagShim = { config: { cid: [accountid], @@ -50,7 +50,7 @@ export class PathforaHandler { getid: (callback: (id: string) => void) => { callback("test-lytics-uid"); }, - send: (stream: string, payload: any, callback: () => void) => { + send: (stream: string, _payload: any, _callback: () => void) => { console.log("(MOCK) Lytics JStag send request made.", stream); }, getEntity: (callback: (entity: any) => void) => { @@ -86,7 +86,7 @@ export class PathforaHandler { }, }; - var expires = new Date(new Date().valueOf() + 1000 * 60 * 60 * 1); + var expires = new Date(Date.now() + 1000 * 60 * 60 * 1); document.cookie = "test-seerid=test-lytics-uid; expires=" + expires.toUTCString() + @@ -100,19 +100,19 @@ export class PathforaHandler { serializeWidget(widget: any): any { // confirmAction.callback - if (widget.config.confirmAction && widget.config.confirmAction.callback) { + if (widget.config.confirmAction?.callback) { widget.config.confirmAction.callback = widget.config.confirmAction.callback.toString(); } // cancelAction.callback - if (widget.config.cancelAction && widget.config.cancelAction.callback) { + if (widget.config.cancelAction?.callback) { widget.config.cancelAction.callback = widget.config.cancelAction.callback.toString(); } // closeAction.callback - if (widget.config.closeAction && widget.config.closeAction.callback) { + if (widget.config.closeAction?.callback) { widget.config.closeAction.callback = widget.config.closeAction.callback.toString(); } @@ -203,8 +203,8 @@ export class PathforaHandler { } testWidget(widget): void { - let config = widget.config; - let details = widget.details; + const config = widget.config; + const _details = widget.details; config.id = "test-widget"; diff --git a/packages/experience-editor/vite.config.js b/packages/experience-editor/vite.config.js index 1e64c3e..dcec308 100644 --- a/packages/experience-editor/vite.config.js +++ b/packages/experience-editor/vite.config.js @@ -1,7 +1,6 @@ -import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; +import { defineConfig, loadEnv } from "vite"; import { createHtmlPlugin } from "vite-plugin-html"; -import { loadEnv } from "vite"; export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd()); diff --git a/packages/experience-editor/vitest.config.ts b/packages/experience-editor/vitest.config.ts index 8508196..c80aef4 100644 --- a/packages/experience-editor/vitest.config.ts +++ b/packages/experience-editor/vitest.config.ts @@ -1,5 +1,5 @@ -import { defineConfig } from "vitest/config"; import react from "@vitejs/plugin-react"; +import { defineConfig } from "vitest/config"; export default defineConfig({ plugins: [react()], diff --git a/packages/recommendation-block/src/api-recommendation.ts b/packages/recommendation-block/src/api-recommendation.ts index 65788fe..b4640b5 100644 --- a/packages/recommendation-block/src/api-recommendation.ts +++ b/packages/recommendation-block/src/api-recommendation.ts @@ -23,12 +23,12 @@ export async function getRecommendation( uid: string, options: RecommendationOptions, ): Promise { - let baseURL = `https://api.lytics.io/api/content/recommend/${accountId}/user/_uid/${uid}`; + const baseURL = `https://api.lytics.io/api/content/recommend/${accountId}/user/_uid/${uid}`; // if (options.segment !== "") { // baseURL = `https://api.lytics.io/api/content/recommend/${accountId}/segment/${options.segment}`; // } - let parts = []; + const parts = []; // add account id if (!accountId) { console.error("Account ID is required to generate recommendations."); diff --git a/packages/recommendation-block/vite.config.js b/packages/recommendation-block/vite.config.js index dd07580..66e5312 100644 --- a/packages/recommendation-block/vite.config.js +++ b/packages/recommendation-block/vite.config.js @@ -1,7 +1,7 @@ // vite.config.ts -import { defineConfig } from "vite"; import path from "path"; +import { defineConfig } from "vite"; export default defineConfig({ build: { @@ -9,7 +9,7 @@ export default defineConfig({ entry: path.resolve(__dirname, "src/index.ts"), formats: ["es"], name: "LyticsRecommendationBlock", - fileName: (format) => `lytics-recommendation-block.js`, + fileName: (_format) => `lytics-recommendation-block.js`, }, outDir: "dist", }, From 8bec3a8ffad9c54717d7981ff0b7c311e015c0dd Mon Sep 17 00:00:00 2001 From: prosdev Date: Tue, 21 Oct 2025 11:45:13 -0700 Subject: [PATCH 4/7] maint(repo): migrate from ESLint + Prettier to Biome Remove ESLint and Prettier configuration files: - Delete .eslintrc.js, .eslintignore - Delete .prettierrc.json, .prettierignore Update package.json scripts to use Biome: - lint: biome check . - lint:fix: biome check --write . - format: biome format --write . Update .lintstagedrc.json to run Biome on pre-commit. --- .eslintignore | 20 -------------------- .eslintrc.js | 34 ---------------------------------- .lintstagedrc.json | 5 +++-- .prettierignore | 17 ----------------- .prettierrc.json | 15 --------------- package.json | 5 +++-- 6 files changed, 6 insertions(+), 90 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc.js delete mode 100644 .prettierignore delete mode 100644 .prettierrc.json diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index eb97907..0000000 --- a/.eslintignore +++ /dev/null @@ -1,20 +0,0 @@ - -**/bin -**/coverage -**/dist -**/node_modules -**/patches -**/static -**/vendor -**/.storybook -.github -yarn-error.log -.prettierignore -.prettier.json -.eslintrc.js -.yaml -.git -.eslintcache -**/rollup.config.js -packages/segast/src/filterql.js -**/*.hbs diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 8659105..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,34 +0,0 @@ -module.exports = { - extends: [ - "eslint:recommended", - "plugin:react/recommended", - "plugin:import/recommended", - "plugin:import/typescript", - "plugin:@typescript-eslint/recommended", - "plugin:prettier/recommended", - ], - parser: "@typescript-eslint/parser", - parserOptions: { - ecmaVersion: "latest", - sourceType: "module", - project: ["./tsconfig.json", "./packages/*/tsconfig.json"], - }, - rules: { - "prettier/prettier": ["error", { parser: "typescript" }], - "max-len": "off", - "import/extensions": "off", - "import/no-unresolved": "off", - "react/react-in-jsx-scope": "off", - "func-style": ["error", "declaration", { allowArrowFunctions: true }], - "@typescript-eslint/no-unused-vars": "error", - "react/prop-types": "off", - }, - overrides: [ - { - files: ["**/*.stories.*"], - rules: { - "import/no-anonymous-default-export": "off", - }, - }, - ], -}; diff --git a/.lintstagedrc.json b/.lintstagedrc.json index 28fce1f..ff10055 100644 --- a/.lintstagedrc.json +++ b/.lintstagedrc.json @@ -1,4 +1,5 @@ { - "{packages,entrypoints,web-components,viz-service}/**/*.{js,jsx,ts,tsx,json,css,scss,md}": "prettier --write", - "{packages,entrypoints,web-components,viz-service}/**/*.+(js,jsx,ts,tsx,json,css,scss,md)": "eslint" + "{packages}/**/*.{js,jsx,ts,tsx,json,css,md}": [ + "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true" + ] } diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 3077314..0000000 --- a/.prettierignore +++ /dev/null @@ -1,17 +0,0 @@ -**/bin -**/coverage -**/dist -**/node_modules -**/patches -**/vendor -.github -yarn-error.log -.eslintignore -.eslint.json -.yaml -.git -.eslintcache -packages/segast/src/filterql.js -**/*.hbs -**/public -**/static \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 9d0dd2d..0000000 --- a/.prettierrc.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/prettierrc", - "arrowParens": "always", - "bracketSpacing": true, - "jsxBracketSameLine": false, - "jsxSingleQuote": false, - "printWidth": 80, - "proseWrap": "always", - "quoteProps": "as-needed", - "semi": true, - "singleQuote": false, - "tabWidth": 2, - "trailingComma": "all", - "useTabs": false -} diff --git a/package.json b/package.json index b2bc822..b5e685f 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,9 @@ "create-entrypoint": "bash -e ./scripts/create-package -e", "create-package": "bash -e ./scripts/create-package", "sync-env": "bash -e ./scripts/sync-env", - "lint": "eslint {packages,entrypoints,web-components,viz-service}/*/src -c .eslintrc.js --ext js,jsx,ts,tsx --fix && yarn eslint {packages,entrypoints,web-components,viz-service}/*/spec -c .eslintrc.js --ext js,jsx,ts,tsx --fix", - "format": "run prettier -w {packages,entrypoints,web-components,viz-service}/*/src/**/*.{ts,js,tsx} && yarn run prettier -w {packages,entrypoints,web-components,viz-service}/*/spec/*.{ts,tsx}", + "lint": "biome check .", + "lint:fix": "biome check --write .", + "format": "biome format --write .", "test": "vitest run --workspace=vitest.workspace.ts", "test:ui": "vitest --workspace=vitest.workspace.ts --ui", "test:watch": "vitest --workspace=vitest.workspace.ts", From ed0e928e6e233d59fb9d6bb041d5223a7605d4f8 Mon Sep 17 00:00:00 2001 From: prosdev Date: Tue, 21 Oct 2025 11:45:58 -0700 Subject: [PATCH 5/7] feat(ci): add lint and typecheck steps to CI pipeline Add quality checks to CI workflow: - Lint step: runs Biome linter on all source files - Type check step: runs TypeScript type checking across all packages Update .github/CI.md documentation: - Document new lint and typecheck steps - Add instructions for running checks locally - Include lint:fix command for auto-fixing issues Closes #24 --- .github/CI.md | 17 ++++++++++++----- .github/workflows/ci.yml | 6 ++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/.github/CI.md b/.github/CI.md index 5ae2d3d..e977438 100644 --- a/.github/CI.md +++ b/.github/CI.md @@ -7,13 +7,13 @@ This project uses GitHub Actions for continuous integration. The CI workflow run The CI workflow (`.github/workflows/ci.yml`) runs the following checks in sequence: 1. **Install dependencies** - `yarn install --frozen-lockfile` -2. **Test** - `yarn test` - Runs all unit tests (currently 39 tests) -3. **Build** - `yarn build` - Verifies all packages build successfully +2. **Lint** - `yarn lint` - Runs Biome linter on all source files +3. **Type check** - `yarn typecheck` - Runs TypeScript type checking across all packages +4. **Test** - `yarn test` - Runs all unit tests (currently 39 tests) +5. **Build** - `yarn build` - Verifies all packages build successfully All checks must pass before code can be merged to `main`. -> **Note:** Linting and type checking will be added after resolving existing type errors and migrating to Biome. - ## Environment - **Node version:** 22.20.0 - **Yarn version:** 1.22.18 @@ -23,12 +23,19 @@ All checks must pass before code can be merged to `main`. Before pushing your changes, you can run the same checks locally: ```bash -# Run all checks +# Run all checks in sequence yarn install --frozen-lockfile +yarn lint +yarn typecheck yarn test yarn build # Or run them individually as needed +yarn lint # Check code quality with Biome +yarn lint:fix # Fix auto-fixable linting issues +yarn typecheck # Check TypeScript types +yarn test # Run unit tests +yarn build # Build all packages ``` ## Troubleshooting diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba8be33..e06ef62 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,6 +34,12 @@ jobs: restore-keys: | ${{ runner.os }}-nx- + - name: Lint + run: yarn lint + + - name: Type check + run: yarn typecheck + - name: Test run: yarn test From 0aea31cb9c39268e48a9d78643ea570b284bf673 Mon Sep 17 00:00:00 2001 From: prosdev Date: Tue, 21 Oct 2025 12:01:40 -0700 Subject: [PATCH 6/7] bug(experience-editor): fix all linting errors Fix 11 linting errors across 6 files: - Remove useless empty fragment in formBuilder - Remove unused function parameter (spacing) in messaging component - Fix comma operator in useEffect dependency array - Remove unused variable (position) in selectMultiple - Add useId hooks for TextField components to avoid hardcoded IDs - Add missing key prop in map iteration - Add type annotations for implicit any variables - Remove unreachable return statement - Escape // in JSX to avoid comment interpretation Lint now passes with only 1 non-blocking warning about document.cookie. --- .../src/components/form/selectMultiple.tsx | 3 +-- .../src/components/form/urlContains.tsx | 7 ++++--- .../src/components/formBuilder.tsx | 17 +++++++++-------- .../src/components/messaging.tsx | 1 - .../src/components/widgetWizard.tsx | 8 +++----- .../src/utility/pathforaInterface.ts | 2 +- 6 files changed, 18 insertions(+), 20 deletions(-) diff --git a/packages/experience-editor/src/components/form/selectMultiple.tsx b/packages/experience-editor/src/components/form/selectMultiple.tsx index d606e8c..c4a6c99 100644 --- a/packages/experience-editor/src/components/form/selectMultiple.tsx +++ b/packages/experience-editor/src/components/form/selectMultiple.tsx @@ -22,8 +22,7 @@ export interface SelectMultipleInputProps { export const SelectMultipleInput: React.FC = ( selectMultipleInputProps, ) => { - const { field, formValues, handleChange, position, visible } = - selectMultipleInputProps; + const { field, formValues, handleChange, visible } = selectMultipleInputProps; const [activeConditions, setActiveConditions] = React.useState([]); diff --git a/packages/experience-editor/src/components/form/urlContains.tsx b/packages/experience-editor/src/components/form/urlContains.tsx index a5938da..1354a1f 100644 --- a/packages/experience-editor/src/components/form/urlContains.tsx +++ b/packages/experience-editor/src/components/form/urlContains.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import DeleteIcon from "@mui/icons-material/Delete"; import { Box, Button, @@ -10,7 +10,7 @@ import { Stack, TextField, } from "@mui/material"; -import DeleteIcon from "@mui/icons-material/Delete"; +import React, { useEffect, useState } from "react"; import { Field } from "../../data/pfa-fields"; import { PinkHighlight } from "../../utility/colors"; @@ -88,7 +88,8 @@ export const URLContainsBuilder: React.FC = ({ Enter a value that should match the domain and path of your target URL. For example, entering{" "} test.com/my/path will match - https://test.com/my/path + https: + {"//"}test.com/my/path ?query=param ); diff --git a/packages/experience-editor/src/components/formBuilder.tsx b/packages/experience-editor/src/components/formBuilder.tsx index b62923c..c1e6bdd 100644 --- a/packages/experience-editor/src/components/formBuilder.tsx +++ b/packages/experience-editor/src/components/formBuilder.tsx @@ -18,7 +18,7 @@ import { TextField, Typography, } from "@mui/material"; -import React, { useEffect, useState } from "react"; +import React, { useEffect, useId, useState } from "react"; import { NumberedSection } from "../components/form/numberedSection"; import { formElements as formElementsData } from "../data/pfa-fields"; import { EmptyState } from "../utility/emptyState"; @@ -58,6 +58,9 @@ export const FormNodeEditor: React.FC = ({ onShift, onDelete, }): JSX.Element => { + const nameId = useId(); + const labelId = useId(); + const placeholderId = useId(); const [options, setOptions] = useState([]); const [label, setLabel] = useState(""); const [placeholder, setPlaceholder] = useState(""); @@ -265,7 +268,7 @@ export const FormNodeEditor: React.FC = ({ {/* Name input */} = ({ {/* Label input */} = ({ {/* Placeholder input */} = ({ {options.map((option, index) => ( - + = ({ - ) : ( - <> - )} + ) : null} )} diff --git a/packages/experience-editor/src/components/messaging.tsx b/packages/experience-editor/src/components/messaging.tsx index f8a3acc..579b014 100644 --- a/packages/experience-editor/src/components/messaging.tsx +++ b/packages/experience-editor/src/components/messaging.tsx @@ -30,7 +30,6 @@ export const MessagingSection: React.FC = ({ formValues, handleChange, formFieldVisibility, - spacing, isFieldSet, }) => { return ( diff --git a/packages/experience-editor/src/components/widgetWizard.tsx b/packages/experience-editor/src/components/widgetWizard.tsx index 74bbd52..6271158 100644 --- a/packages/experience-editor/src/components/widgetWizard.tsx +++ b/packages/experience-editor/src/components/widgetWizard.tsx @@ -301,8 +301,7 @@ const WidgetWizard: React.FC = ({ // update source fields when any value changes useEffect(() => { checkSourceLink(); - }), - [formValues]; + }, [formValues]); useEffect(() => { const editConfig = document.getElementById( @@ -407,7 +406,7 @@ const WidgetWizard: React.FC = ({ const renderConfiguration = () => { let config = {}; - let renderedConfigObject; + let renderedConfigObject: any; try { renderedConfigObject = JSON.parse(renderedConfig); @@ -634,7 +633,7 @@ const WidgetWizard: React.FC = ({ if (!value) { return false; } - let callback; + let callback: any; try { callback = Function(`"use strict";return (${value})`)(); } catch (error) { @@ -655,7 +654,6 @@ const WidgetWizard: React.FC = ({ const callbackFn = renderCallbackFunction(value); if (!callbackFn) { throw new Error("Callback function is not defined."); - return; } callbackFnString = callbackFn.toString(); diff --git a/packages/experience-editor/src/utility/pathforaInterface.ts b/packages/experience-editor/src/utility/pathforaInterface.ts index 166acbb..eb509dc 100644 --- a/packages/experience-editor/src/utility/pathforaInterface.ts +++ b/packages/experience-editor/src/utility/pathforaInterface.ts @@ -232,7 +232,7 @@ export class PathforaHandler { config.displayConditions.scrollPercentageToDisplay = 0; } - let module; + let module: any; switch (widget.details.type) { case "message": From a2f56cf3a797e1044b77b9b25bd1d0ea01061ee7 Mon Sep 17 00:00:00 2001 From: prosdev Date: Tue, 21 Oct 2025 12:02:38 -0700 Subject: [PATCH 7/7] bug(experience-editor): add es2022 lib for Object.hasOwn support Add es2022 and dom to lib in tsconfig to support Object.hasOwn method used in objects.ts. This fixes typecheck errors while maintaining es5 as the compile target. --- packages/experience-editor/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/experience-editor/tsconfig.json b/packages/experience-editor/tsconfig.json index 592f7ec..cb305ed 100644 --- a/packages/experience-editor/tsconfig.json +++ b/packages/experience-editor/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "target": "es5", + "lib": ["es2022", "dom"], "module": "ESNext", "strict": false, "esModuleInterop": true,