From 451ffbcacfe4a0417a5642a40eed533565513cd9 Mon Sep 17 00:00:00 2001 From: Baptiste Arnaud Date: Mon, 21 Nov 2022 11:12:43 +0100 Subject: [PATCH] :recycle: Add shared eslint config --- .husky/pre-commit | 4 + apps/builder/.eslintrc.js | 43 +- apps/builder/package.json | 10 +- apps/builder/playwright.config.ts | 2 +- .../src/components/SearchableDropdown.tsx | 1 - .../src/components/VariableSearchInput.tsx | 2 +- .../src/features/account/UserProvider.tsx | 1 - .../features/auth/components/SignInPage.tsx | 2 +- .../UsageContent/UsageContent.tsx | 8 +- .../ChangePlanForm/ChangePlanForm.tsx | 2 +- .../GoogleSheetsSettingsBody.tsx | 14 +- .../WebhookSettings/WebhookSettings.tsx | 6 +- .../integrations/webhook/utils/getDeepKeys.ts | 1 - .../dashboard/components/AnnoucementModal.tsx | 2 +- .../dashboard/components/OnboardingModal.tsx | 4 +- .../src/features/editor/hooks/useUndo.ts | 26 +- .../editor/providers/EditorProvider.tsx | 1 - .../TypebotProvider/TypebotProvider.tsx | 1 - .../features/folders/TypebotDndProvider.tsx | 1 - .../components/Nodes/GroupNode/GroupNode.tsx | 369 ++++---- .../graph/providers/GraphDndProvider.tsx | 1 - .../graph/providers/GraphProvider.tsx | 1 - .../providers/GroupsCoordinateProvider.tsx | 1 - .../src/features/results/ResultsProvider.tsx | 1 - .../ResultsTable/ColumnsSettingsButton.tsx | 10 +- .../ResultsTable/IndeterminateCheckbox.tsx | 23 + .../components/ResultsTable/ResultsTable.tsx | 22 +- .../features/workspace/WorkspaceProvider.tsx | 1 - .../components/WorkspaceSettingsForm.tsx | 2 +- apps/builder/src/hooks/useAutoSave.ts | 3 +- apps/builder/src/lib/theme.ts | 1 - apps/builder/src/pages/_error.tsx | 8 +- .../google-sheets/spreadsheets.ts | 2 - apps/builder/src/pages/api/stripe/webhook.ts | 1 - apps/builder/src/utils/helpers.ts | 6 +- apps/builder/tsconfig.json | 3 +- apps/landing-page/.eslintrc.js | 29 +- .../components/Homepage/EasyEmbed.tsx | 2 +- .../components/Homepage/RealTimeResults.tsx | 4 +- .../Homepage/Testimonials/Testimonials.tsx | 2 +- apps/landing-page/lib/chakraTheme.ts | 1 - apps/landing-page/package.json | 11 +- apps/landing-page/pages/about.tsx | 21 +- apps/landing-page/pages/pricing.tsx | 12 +- apps/landing-page/tsconfig.json | 22 +- apps/viewer/.eslintrc.js | 43 +- apps/viewer/package.json | 12 +- apps/viewer/playwright.config.ts | 2 +- apps/viewer/src/components/TypebotPage.tsx | 10 +- .../answers/queries/upsertAnswerQuery.ts | 4 +- .../src/features/settings/settings.spec.ts | 16 +- apps/viewer/src/pages/_error.tsx | 8 +- .../stripe/createPaymentIntent.ts | 25 +- .../blocks/[blockId]/executeWebhook.ts | 16 +- .../steps/[stepId]/executeWebhook.ts | 7 +- .../blocks/[blockId]/storage/upload-url.ts | 210 +++-- .../[typebotId]/integrations/email.tsx | 10 +- .../pages/api/typebots/[typebotId]/results.ts | 197 ++-- apps/viewer/tsconfig.json | 22 +- package.json | 7 +- packages/bot-engine/.eslintrc.js | 48 +- packages/bot-engine/package.json | 18 +- .../ChatGroup/AvatarSideContainer.tsx | 103 +-- .../ChatGroup/ChatBlock/InputChatBlock.tsx | 2 +- .../src/components/ChatGroup/ChatGroup.tsx | 1 - .../src/components/TypebotViewer.tsx | 7 +- .../src/components/inputs/ShortTextInput.tsx | 34 +- .../src/components/inputs/Textarea.tsx | 12 +- .../PaymentForm/StripePaymentForm.tsx | 4 +- .../inputs/phone/components/PhoneInput.tsx | 1 - packages/bot-engine/src/lib/gtag.ts | 11 +- .../src/providers/AnswersProvider.tsx | 12 +- .../bot-engine/src/providers/ChatProvider.tsx | 1 - .../src/providers/TypebotProvider.tsx | 1 - packages/bot-engine/tsconfig.json | 20 +- packages/bot-engine/tsup.config.js | 2 +- packages/configs/package.json | 12 - packages/configs/playwright/index.ts | 1 - packages/configs/tsconfig.json | 6 - packages/db/package.json | 6 +- packages/emails/.eslintrc.js | 4 + packages/emails/package.json | 12 +- .../emails/{ => src}/components/Button.tsx | 0 packages/emails/{ => src}/components/Head.tsx | 0 .../emails/{ => src}/components/HeroImage.tsx | 0 packages/emails/{ => src}/components/Text.tsx | 0 packages/emails/{ => src}/components/index.ts | 0 .../emails/AlmostReachedChatsLimitEmail.tsx | 10 +- .../emails/AlmostReachedStorageLimitEmail.tsx | 13 +- .../emails/DefaultBotNotificationEmail.tsx | 0 .../{ => src}/emails/GuestInvitationEmail.tsx | 2 +- .../emails/ReachedChatsLimitEmail.tsx | 8 +- .../emails/ReachedStorageLimitEmail.tsx | 6 +- .../emails/WorkspaceMemberInvitationEmail.tsx | 0 packages/emails/{ => src}/emails/index.ts | 0 packages/emails/{ => src}/index.ts | 0 packages/emails/{ => src}/preview.tsx | 0 packages/emails/{ => src}/sendEmail.ts | 0 packages/emails/{ => src}/theme.ts | 0 packages/emails/tsconfig.json | 7 +- packages/eslint-config-custom/index.js | 23 + packages/eslint-config-custom/package.json | 10 + packages/models/.eslintrc.js | 4 + packages/models/src/features/answer.ts | 16 + packages/models/src/features/result.ts | 14 +- packages/scripts/.eslintrc.js | 4 + packages/tsconfig/nextjs.json | 4 +- packages/tsconfig/react-library.json | 11 + packages/typebot-js/.eslintignore | 2 - packages/typebot-js/.eslintrc.js | 15 +- packages/typebot-js/package.json | 15 +- packages/typebot-js/src/index.ts | 4 +- packages/typebot-js/tests/container.spec.ts | 2 - packages/typebot-js/tsconfig.json | 11 +- packages/typebot-js/tsup.config.js | 2 +- packages/utils/.eslintrc.js | 4 + packages/utils/package.json | 5 +- .../playwright/baseConfig.ts | 0 .../playwright/globalSetup.ts | 2 +- packages/utils/pricing.ts | 2 +- packages/utils/results.ts | 9 +- pnpm-lock.yaml | 857 +++++++----------- turbo.json | 3 + 123 files changed, 1145 insertions(+), 1517 deletions(-) create mode 100755 .husky/pre-commit create mode 100644 apps/builder/src/features/results/components/ResultsTable/IndeterminateCheckbox.tsx delete mode 100644 packages/configs/package.json delete mode 100644 packages/configs/playwright/index.ts delete mode 100644 packages/configs/tsconfig.json create mode 100644 packages/emails/.eslintrc.js rename packages/emails/{ => src}/components/Button.tsx (100%) rename packages/emails/{ => src}/components/Head.tsx (100%) rename packages/emails/{ => src}/components/HeroImage.tsx (100%) rename packages/emails/{ => src}/components/Text.tsx (100%) rename packages/emails/{ => src}/components/index.ts (100%) rename packages/emails/{ => src}/emails/AlmostReachedChatsLimitEmail.tsx (85%) rename packages/emails/{ => src}/emails/AlmostReachedStorageLimitEmail.tsx (76%) rename packages/emails/{ => src}/emails/DefaultBotNotificationEmail.tsx (100%) rename packages/emails/{ => src}/emails/GuestInvitationEmail.tsx (96%) rename packages/emails/{ => src}/emails/ReachedChatsLimitEmail.tsx (87%) rename packages/emails/{ => src}/emails/ReachedStorageLimitEmail.tsx (86%) rename packages/emails/{ => src}/emails/WorkspaceMemberInvitationEmail.tsx (100%) rename packages/emails/{ => src}/emails/index.ts (100%) rename packages/emails/{ => src}/index.ts (100%) rename packages/emails/{ => src}/preview.tsx (100%) rename packages/emails/{ => src}/sendEmail.ts (100%) rename packages/emails/{ => src}/theme.ts (100%) create mode 100644 packages/eslint-config-custom/index.js create mode 100644 packages/eslint-config-custom/package.json create mode 100644 packages/models/.eslintrc.js create mode 100644 packages/scripts/.eslintrc.js create mode 100644 packages/tsconfig/react-library.json delete mode 100644 packages/typebot-js/.eslintignore create mode 100644 packages/utils/.eslintrc.js rename packages/{configs => utils}/playwright/baseConfig.ts (100%) rename packages/{configs => utils}/playwright/globalSetup.ts (77%) diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 00000000000..58993aaeefd --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +pnpm lint diff --git a/apps/builder/.eslintrc.js b/apps/builder/.eslintrc.js index c8da3b24fef..b56159ea9c2 100644 --- a/apps/builder/.eslintrc.js +++ b/apps/builder/.eslintrc.js @@ -1,43 +1,4 @@ module.exports = { - ignorePatterns: ['node_modules'], - env: { - browser: true, - es6: true, - }, - extends: [ - 'plugin:@typescript-eslint/recommended', - 'plugin:react/recommended', - 'next/core-web-vitals', - ], - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features - sourceType: 'module', // Allows for the use of imports - ecmaFeatures: { - jsx: true, // Allows for the parsing of JSX - }, - }, - settings: { - react: { - version: 'detect', // Tells eslint-plugin-react to automatically detect the version of React to use - }, - }, - plugins: ['react', '@typescript-eslint'], - rules: { - 'react/no-unescaped-entities': [0], - 'react/display-name': [0], - 'no-restricted-imports': [ - 'error', - { - patterns: [ - '*/src/*', - 'src/*', - '*/src', - '@/features/*/*', - '!@/features/blocks/*', - '!@/features/*/api', - ], - }, - ], - }, + root: true, + extends: ['custom'], } diff --git a/apps/builder/package.json b/apps/builder/package.json index bd2d9a6bdc0..469b163c5eb 100644 --- a/apps/builder/package.json +++ b/apps/builder/package.json @@ -106,20 +106,16 @@ "@types/qs": "6.9.7", "@types/react": "18.0.25", "@types/tinycolor2": "1.4.3", - "@typescript-eslint/eslint-plugin": "5.43.0", - "@typescript-eslint/parser": "5.43.0", - "configs": "workspace:*", "db": "workspace:*", "dotenv": "16.0.3", - "eslint": "8.27.0", - "eslint-config-next": "13.0.3", - "eslint-plugin-react": "7.31.10", "models": "workspace:*", "next-transpile-modules": "10.0.0", "superjson": "^1.11.0", "tsconfig": "workspace:*", "typescript": "4.8.4", "utils": "workspace:*", - "zod": "3.19.1" + "zod": "3.19.1", + "eslint": "8.28.0", + "eslint-config-custom": "workspace:*" } } diff --git a/apps/builder/playwright.config.ts b/apps/builder/playwright.config.ts index d4bed65dd87..bfc5e56baeb 100644 --- a/apps/builder/playwright.config.ts +++ b/apps/builder/playwright.config.ts @@ -1,6 +1,6 @@ import { PlaywrightTestConfig } from '@playwright/test' import path from 'path' -import { playwrightBaseConfig } from 'configs/playwright' +import { playwrightBaseConfig } from 'utils/playwright/baseConfig' const config: PlaywrightTestConfig = { ...playwrightBaseConfig, diff --git a/apps/builder/src/components/SearchableDropdown.tsx b/apps/builder/src/components/SearchableDropdown.tsx index fd7f5979e38..00a00c0b116 100644 --- a/apps/builder/src/components/SearchableDropdown.tsx +++ b/apps/builder/src/components/SearchableDropdown.tsx @@ -36,7 +36,6 @@ export const SearchableDropdown = ({ const { onOpen, onClose, isOpen } = useDisclosure() const [inputValue, setInputValue] = useState(selectedItem ?? '') const debounced = useDebouncedCallback( - // eslint-disable-next-line @typescript-eslint/no-empty-function onValueChange ? onValueChange : () => {}, env('E2E_TEST') === 'true' ? 0 : debounceTimeout ) diff --git a/apps/builder/src/components/VariableSearchInput.tsx b/apps/builder/src/components/VariableSearchInput.tsx index d8e0084bb82..ee0f193418a 100644 --- a/apps/builder/src/components/VariableSearchInput.tsx +++ b/apps/builder/src/components/VariableSearchInput.tsx @@ -209,7 +209,7 @@ export const VariableSearchInput = ({ leftIcon={} bgColor={keyboardFocusIndex === 0 ? 'gray.200' : 'transparent'} > - Create "{inputValue}" + Create "{inputValue}" )} {filteredItems.length > 0 && ( diff --git a/apps/builder/src/features/account/UserProvider.tsx b/apps/builder/src/features/account/UserProvider.tsx index ac046a19636..b1a60e30476 100644 --- a/apps/builder/src/features/account/UserProvider.tsx +++ b/apps/builder/src/features/account/UserProvider.tsx @@ -24,7 +24,6 @@ const userContext = createContext<{ currentWorkspaceId?: string updateUser: (newUser: Partial) => void saveUser: (newUser?: Partial) => Promise - // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore }>({}) diff --git a/apps/builder/src/features/auth/components/SignInPage.tsx b/apps/builder/src/features/auth/components/SignInPage.tsx index d77f4f8e309..b956582399b 100644 --- a/apps/builder/src/features/auth/components/SignInPage.tsx +++ b/apps/builder/src/features/auth/components/SignInPage.tsx @@ -24,7 +24,7 @@ export const SignInPage = ({ type }: Props) => { {type === 'signin' ? ( - Don't have an account?{' '} + Don't have an account?{' '} Sign up for free ) : ( diff --git a/apps/builder/src/features/billing/components/BillingContent/UsageContent/UsageContent.tsx b/apps/builder/src/features/billing/components/BillingContent/UsageContent/UsageContent.tsx index 77a8f797222..3399fae881b 100644 --- a/apps/builder/src/features/billing/components/BillingContent/UsageContent/UsageContent.tsx +++ b/apps/builder/src/features/billing/components/BillingContent/UsageContent/UsageContent.tsx @@ -52,8 +52,8 @@ export const UsageContent = ({ workspace }: Props) => { p="3" label={ - Your typebots are popular! You will soon reach your plan's - chats limit. 🚀 + Your typebots are popular! You will soon reach your + plan's chats limit. 🚀

Make sure to update your plan to increase @@ -111,8 +111,8 @@ export const UsageContent = ({ workspace }: Props) => { p="3" label={ - Your typebots are popular! You will soon reach your plan's - storage limit. 🚀 + Your typebots are popular! You will soon reach your + plan's storage limit. 🚀

Make sure to update your plan in order to diff --git a/apps/builder/src/features/billing/components/ChangePlanForm/ChangePlanForm.tsx b/apps/builder/src/features/billing/components/ChangePlanForm/ChangePlanForm.tsx index 05d193a6765..69db458bf0d 100644 --- a/apps/builder/src/features/billing/components/ChangePlanForm/ChangePlanForm.tsx +++ b/apps/builder/src/features/billing/components/ChangePlanForm/ChangePlanForm.tsx @@ -90,7 +90,7 @@ export const ChangePlanForm = () => { Need custom limits? Specific features?{' '} - Let's chat! + Let's chat! diff --git a/apps/builder/src/features/blocks/integrations/googleSheets/components/GoogleSheetsSettingsBody/GoogleSheetsSettingsBody.tsx b/apps/builder/src/features/blocks/integrations/googleSheets/components/GoogleSheetsSettingsBody/GoogleSheetsSettingsBody.tsx index eeed8b6a99c..0e8622f62fa 100644 --- a/apps/builder/src/features/blocks/integrations/googleSheets/components/GoogleSheetsSettingsBody/GoogleSheetsSettingsBody.tsx +++ b/apps/builder/src/features/blocks/integrations/googleSheets/components/GoogleSheetsSettingsBody/GoogleSheetsSettingsBody.tsx @@ -162,14 +162,20 @@ const ActionOptions = ({ onOptionsChange({ ...options, cellsToExtract } as GoogleSheetsOptions) const UpdatingCellItem = useMemo( - () => (props: TableListItemProps) => - , + () => + function Component(props: TableListItemProps) { + return + }, [sheet?.columns] ) const ExtractingCellItem = useMemo( - () => (props: TableListItemProps) => - , + () => + function Component(props: TableListItemProps) { + return ( + + ) + }, [sheet?.columns] ) diff --git a/apps/builder/src/features/blocks/integrations/webhook/components/WebhookSettings/WebhookSettings.tsx b/apps/builder/src/features/blocks/integrations/webhook/components/WebhookSettings/WebhookSettings.tsx index 19d06e17bc1..991828d6f37 100644 --- a/apps/builder/src/features/blocks/integrations/webhook/components/WebhookSettings/WebhookSettings.tsx +++ b/apps/builder/src/features/blocks/integrations/webhook/components/WebhookSettings/WebhookSettings.tsx @@ -143,8 +143,10 @@ export const WebhookSettings = ({ } const ResponseMappingInputs = useMemo( - () => (props: TableListItemProps) => - , + () => + function Component(props: TableListItemProps) { + return + }, [responseKeys] ) diff --git a/apps/builder/src/features/blocks/integrations/webhook/utils/getDeepKeys.ts b/apps/builder/src/features/blocks/integrations/webhook/utils/getDeepKeys.ts index b4f82088acc..3ceffc65757 100644 --- a/apps/builder/src/features/blocks/integrations/webhook/utils/getDeepKeys.ts +++ b/apps/builder/src/features/blocks/integrations/webhook/utils/getDeepKeys.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const getDeepKeys = (obj: any): string[] => { let keys: string[] = [] for (const key in obj) { diff --git a/apps/builder/src/features/dashboard/components/AnnoucementModal.tsx b/apps/builder/src/features/dashboard/components/AnnoucementModal.tsx index 3055a218c1c..b2fecfe7af0 100644 --- a/apps/builder/src/features/dashboard/components/AnnoucementModal.tsx +++ b/apps/builder/src/features/dashboard/components/AnnoucementModal.tsx @@ -36,7 +36,7 @@ export const AnnoucementModal = ({ isOpen, onClose }: Props) => { - What's new in Typebot 2.0? + What's new in Typebot 2.0? Typebo 2.0 has been launched February the 15th 🎉. diff --git a/apps/builder/src/features/dashboard/components/OnboardingModal.tsx b/apps/builder/src/features/dashboard/components/OnboardingModal.tsx index 9a9290cbd56..5e95abd3664 100644 --- a/apps/builder/src/features/dashboard/components/OnboardingModal.tsx +++ b/apps/builder/src/features/dashboard/components/OnboardingModal.tsx @@ -8,7 +8,7 @@ import { } from '@chakra-ui/react' import { TypebotViewer } from 'bot-engine' import { useUser } from '@/features/account' -import { Answer, Typebot } from 'models' +import { AnswerInput, Typebot } from 'models' import React, { useEffect, useRef, useState } from 'react' import { getViewerUrl, sendRequest } from 'utils' import confetti from 'canvas-confetti' @@ -79,7 +79,7 @@ export const OnboardingModal = ({ totalTypebots }: Props) => { setTypebot(data as Typebot) } - const handleNewAnswer = async (answer: Answer) => { + const handleNewAnswer = async (answer: AnswerInput) => { const isName = answer.variableId === 'cl126f4hf000i2e6d8zvzc3t1' const isCompany = answer.variableId === 'cl126jqww000w2e6dq9yv4ifq' const isCategories = answer.variableId === 'cl126mo3t001b2e6dvyi16bkd' diff --git a/apps/builder/src/features/editor/hooks/useUndo.ts b/apps/builder/src/features/editor/hooks/useUndo.ts index e4964d8fa98..a649772b896 100644 --- a/apps/builder/src/features/editor/hooks/useUndo.ts +++ b/apps/builder/src/features/editor/hooks/useUndo.ts @@ -11,7 +11,7 @@ enum ActionType { Flush = 'FLUSH', } -export interface Actions { +export interface Actions { set: ( newPresent: T | ((current: T) => T), options?: { updateDate: boolean } @@ -24,13 +24,13 @@ export interface Actions { presentRef: React.MutableRefObject } -interface Action { +interface Action { type: ActionType newPresent?: T updateDate?: boolean } -export interface State { +export interface State { past: T[] present: T future: T[] @@ -42,7 +42,10 @@ const initialState = { future: [], } -const reducer = (state: State, action: Action) => { +const reducer = ( + state: State, + action: Action +) => { const { past, present, future } = state switch (action.type) { @@ -98,8 +101,6 @@ const reducer = (state: State, action: Action) => { past: [...past, present].filter(isDefined), present: { ...newPresent, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - //@ts-ignore updatedAt: updateDate ? new Date() : newPresent.updatedAt, }, future: [], @@ -111,11 +112,13 @@ const reducer = (state: State, action: Action) => { } } -const useUndo = (initialPresent: T): [State, Actions] => { +const useUndo = ( + initialPresent: T +): [State, Actions] => { const [state, dispatch] = useReducer(reducer, { ...initialState, present: initialPresent, - }) as [State, React.Dispatch>] + }) const presentRef = useRef(initialPresent) const canUndo = state.past.length !== 0 @@ -136,7 +139,7 @@ const useUndo = (initialPresent: T): [State, Actions] => { const set = useCallback( (newPresent: T | ((current: T) => T), options = { updateDate: true }) => { const updatedTypebot = - 'id' in newPresent + newPresent && 'id' in newPresent ? newPresent : (newPresent as (current: T) => T)(presentRef.current) presentRef.current = updatedTypebot @@ -153,7 +156,10 @@ const useUndo = (initialPresent: T): [State, Actions] => { dispatch({ type: ActionType.Flush }) }, []) - return [state, { set, undo, redo, flush, canUndo, canRedo, presentRef }] + return [ + state as State, + { set, undo, redo, flush, canUndo, canRedo, presentRef }, + ] } export default useUndo diff --git a/apps/builder/src/features/editor/providers/EditorProvider.tsx b/apps/builder/src/features/editor/providers/EditorProvider.tsx index af3a747ac7f..ad576626068 100644 --- a/apps/builder/src/features/editor/providers/EditorProvider.tsx +++ b/apps/builder/src/features/editor/providers/EditorProvider.tsx @@ -16,7 +16,6 @@ const editorContext = createContext<{ setRightPanel: Dispatch> startPreviewAtGroup: string | undefined setStartPreviewAtGroup: Dispatch> - // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore }>({}) diff --git a/apps/builder/src/features/editor/providers/TypebotProvider/TypebotProvider.tsx b/apps/builder/src/features/editor/providers/TypebotProvider/TypebotProvider.tsx index ec9e4e66760..b40c9fbabf6 100644 --- a/apps/builder/src/features/editor/providers/TypebotProvider/TypebotProvider.tsx +++ b/apps/builder/src/features/editor/providers/TypebotProvider/TypebotProvider.tsx @@ -88,7 +88,6 @@ const typebotContext = createContext< ItemsActions & VariablesActions & EdgesActions - // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore >({}) diff --git a/apps/builder/src/features/folders/TypebotDndProvider.tsx b/apps/builder/src/features/folders/TypebotDndProvider.tsx index 353dafe8ee0..ef83215ab46 100644 --- a/apps/builder/src/features/folders/TypebotDndProvider.tsx +++ b/apps/builder/src/features/folders/TypebotDndProvider.tsx @@ -14,7 +14,6 @@ const typebotDndContext = createContext<{ setDraggedTypebot: Dispatch> mouseOverFolderId?: string | null setMouseOverFolderId: Dispatch> - // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore }>({}) diff --git a/apps/builder/src/features/graph/components/Nodes/GroupNode/GroupNode.tsx b/apps/builder/src/features/graph/components/Nodes/GroupNode/GroupNode.tsx index a10c49591ee..341588e5a14 100644 --- a/apps/builder/src/features/graph/components/Nodes/GroupNode/GroupNode.tsx +++ b/apps/builder/src/features/graph/components/Nodes/GroupNode/GroupNode.tsx @@ -47,197 +47,196 @@ export const GroupNode = ({ group, groupIndex }: Props) => { ) } -const DraggableGroupNode = memo( - ({ - group, - groupIndex, - onGroupDrag, - }: Props & { onGroupDrag: (newCoord: Coordinates) => void }) => { - const { - connectingIds, - setConnectingIds, - previewingEdge, - isReadOnly, - focusedGroupId, - setFocusedGroupId, - graphPosition, - } = useGraph() - const { typebot, updateGroup } = useTypebot() - const { setMouseOverGroup, mouseOverGroup } = useBlockDnd() - const { setRightPanel, setStartPreviewAtGroup } = useEditor() - - const [isMouseDown, setIsMouseDown] = useState(false) - const [isConnecting, setIsConnecting] = useState(false) - const [currentCoordinates, setCurrentCoordinates] = useState( - group.graphCoordinates +const NonMemoizedDraggableGroupNode = ({ + group, + groupIndex, + onGroupDrag, +}: Props & { onGroupDrag: (newCoord: Coordinates) => void }) => { + const { + connectingIds, + setConnectingIds, + previewingEdge, + isReadOnly, + focusedGroupId, + setFocusedGroupId, + graphPosition, + } = useGraph() + const { typebot, updateGroup } = useTypebot() + const { setMouseOverGroup, mouseOverGroup } = useBlockDnd() + const { setRightPanel, setStartPreviewAtGroup } = useEditor() + + const [isMouseDown, setIsMouseDown] = useState(false) + const [isConnecting, setIsConnecting] = useState(false) + const [currentCoordinates, setCurrentCoordinates] = useState( + group.graphCoordinates + ) + const [groupTitle, setGroupTitle] = useState(group.title) + + // When the group is moved from external action (e.g. undo/redo), update the current coordinates + useEffect(() => { + setCurrentCoordinates({ + x: group.graphCoordinates.x, + y: group.graphCoordinates.y, + }) + }, [group.graphCoordinates.x, group.graphCoordinates.y]) + + // Same for group title + useEffect(() => { + setGroupTitle(group.title) + }, [group.title]) + + const isPreviewing = + previewingEdge?.from.groupId === group.id || + (previewingEdge?.to.groupId === group.id && + isNotDefined(previewingEdge.to.blockId)) + const isStartGroup = + isDefined(group.blocks[0]) && group.blocks[0].type === 'start' + + const groupRef = useRef(null) + const [debouncedGroupPosition] = useDebounce(currentCoordinates, 100) + useEffect(() => { + if (!currentCoordinates || isReadOnly) return + if ( + currentCoordinates?.x === group.graphCoordinates.x && + currentCoordinates.y === group.graphCoordinates.y ) - const [groupTitle, setGroupTitle] = useState(group.title) - - // When the group is moved from external action (e.g. undo/redo), update the current coordinates - useEffect(() => { - setCurrentCoordinates({ - x: group.graphCoordinates.x, - y: group.graphCoordinates.y, - }) - }, [group.graphCoordinates.x, group.graphCoordinates.y]) - - // Same for group title - useEffect(() => { - setGroupTitle(group.title) - }, [group.title]) - - const isPreviewing = - previewingEdge?.from.groupId === group.id || - (previewingEdge?.to.groupId === group.id && - isNotDefined(previewingEdge.to.blockId)) - const isStartGroup = - isDefined(group.blocks[0]) && group.blocks[0].type === 'start' - - const groupRef = useRef(null) - const [debouncedGroupPosition] = useDebounce(currentCoordinates, 100) - useEffect(() => { - if (!currentCoordinates || isReadOnly) return - if ( - currentCoordinates?.x === group.graphCoordinates.x && - currentCoordinates.y === group.graphCoordinates.y - ) - return - updateGroup(groupIndex, { graphCoordinates: currentCoordinates }) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [debouncedGroupPosition]) - - useEffect(() => { - setIsConnecting( - connectingIds?.target?.groupId === group.id && - isNotDefined(connectingIds.target?.blockId) - ) - }, [connectingIds, group.id]) - - const handleTitleSubmit = (title: string) => - title.length > 0 ? updateGroup(groupIndex, { title }) : undefined - - const handleMouseDown = (e: React.MouseEvent) => { - e.stopPropagation() - } + return + updateGroup(groupIndex, { graphCoordinates: currentCoordinates }) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [debouncedGroupPosition]) + + useEffect(() => { + setIsConnecting( + connectingIds?.target?.groupId === group.id && + isNotDefined(connectingIds.target?.blockId) + ) + }, [connectingIds, group.id]) - const handleMouseEnter = () => { - if (isReadOnly) return - if (mouseOverGroup?.id !== group.id && !isStartGroup) - setMouseOverGroup({ id: group.id, ref: groupRef }) - if (connectingIds) - setConnectingIds({ ...connectingIds, target: { groupId: group.id } }) - } + const handleTitleSubmit = (title: string) => + title.length > 0 ? updateGroup(groupIndex, { title }) : undefined - const handleMouseLeave = () => { - if (isReadOnly) return - setMouseOverGroup(undefined) - if (connectingIds) - setConnectingIds({ ...connectingIds, target: undefined }) - } + const handleMouseDown = (e: React.MouseEvent) => { + e.stopPropagation() + } - const startPreviewAtThisGroup = () => { - setStartPreviewAtGroup(group.id) - setRightPanel(RightPanel.PREVIEW) - } + const handleMouseEnter = () => { + if (isReadOnly) return + if (mouseOverGroup?.id !== group.id && !isStartGroup) + setMouseOverGroup({ id: group.id, ref: groupRef }) + if (connectingIds) + setConnectingIds({ ...connectingIds, target: { groupId: group.id } }) + } + + const handleMouseLeave = () => { + if (isReadOnly) return + setMouseOverGroup(undefined) + if (connectingIds) setConnectingIds({ ...connectingIds, target: undefined }) + } - useDrag( - ({ first, last, offset: [offsetX, offsetY], event, target }) => { - event.stopPropagation() - if ((target as HTMLElement).classList.contains('prevent-group-drag')) - return - if (first) { - setFocusedGroupId(group.id) - setIsMouseDown(true) - } - if (last) { - setIsMouseDown(false) - } - const newCoord = { - x: offsetX / graphPosition.scale, - y: offsetY / graphPosition.scale, - } - setCurrentCoordinates(newCoord) - onGroupDrag(newCoord) - }, - { - target: groupRef, - pointer: { keys: false }, - from: () => [ - currentCoordinates.x * graphPosition.scale, - currentCoordinates.y * graphPosition.scale, - ], + const startPreviewAtThisGroup = () => { + setStartPreviewAtGroup(group.id) + setRightPanel(RightPanel.PREVIEW) + } + + useDrag( + ({ first, last, offset: [offsetX, offsetY], event, target }) => { + event.stopPropagation() + if ((target as HTMLElement).classList.contains('prevent-group-drag')) + return + if (first) { + setFocusedGroupId(group.id) + setIsMouseDown(true) } - ) + if (last) { + setIsMouseDown(false) + } + const newCoord = { + x: offsetX / graphPosition.scale, + y: offsetY / graphPosition.scale, + } + setCurrentCoordinates(newCoord) + onGroupDrag(newCoord) + }, + { + target: groupRef, + pointer: { keys: false }, + from: () => [ + currentCoordinates.x * graphPosition.scale, + currentCoordinates.y * graphPosition.scale, + ], + } + ) - return ( - - renderMenu={() => } - isDisabled={isReadOnly || isStartGroup} - > - {(ref, isOpened) => ( - + renderMenu={() => } + isDisabled={isReadOnly || isStartGroup} + > + {(ref, isOpened) => ( + + - - - - - {typebot && ( - - )} - } - aria-label={'Preview bot from this group'} - pos="absolute" - right={2} - top={0} - size="sm" - variant="outline" - onClick={startPreviewAtThisGroup} + - - )} - - ) - } -) + + + {typebot && ( + + )} + } + aria-label={'Preview bot from this group'} + pos="absolute" + right={2} + top={0} + size="sm" + variant="outline" + onClick={startPreviewAtThisGroup} + /> + + )} + + ) +} + +export const DraggableGroupNode = memo(NonMemoizedDraggableGroupNode) diff --git a/apps/builder/src/features/graph/providers/GraphDndProvider.tsx b/apps/builder/src/features/graph/providers/GraphDndProvider.tsx index a147e0a467c..b90c1b42863 100644 --- a/apps/builder/src/features/graph/providers/GraphDndProvider.tsx +++ b/apps/builder/src/features/graph/providers/GraphDndProvider.tsx @@ -27,7 +27,6 @@ const graphDndContext = createContext<{ setMouseOverGroup: Dispatch> mouseOverBlock?: NodeInfo setMouseOverBlock: Dispatch> - // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore }>({}) diff --git a/apps/builder/src/features/graph/providers/GraphProvider.tsx b/apps/builder/src/features/graph/providers/GraphProvider.tsx index 11bda3fb84c..5c42512c36d 100644 --- a/apps/builder/src/features/graph/providers/GraphProvider.tsx +++ b/apps/builder/src/features/graph/providers/GraphProvider.tsx @@ -74,7 +74,6 @@ const graphContext = createContext<{ isReadOnly: boolean focusedGroupId?: string setFocusedGroupId: Dispatch> - // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore }>({ graphPosition: graphPositionDefaultValue, diff --git a/apps/builder/src/features/graph/providers/GroupsCoordinateProvider.tsx b/apps/builder/src/features/graph/providers/GroupsCoordinateProvider.tsx index 7fa122dab32..3d070d50846 100644 --- a/apps/builder/src/features/graph/providers/GroupsCoordinateProvider.tsx +++ b/apps/builder/src/features/graph/providers/GroupsCoordinateProvider.tsx @@ -12,7 +12,6 @@ import { GroupsCoordinates, Coordinates } from './GraphProvider' const groupsCoordinatesContext = createContext<{ groupsCoordinates: GroupsCoordinates updateGroupCoordinates: (groupId: string, newCoord: Coordinates) => void - // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore }>({}) diff --git a/apps/builder/src/features/results/ResultsProvider.tsx b/apps/builder/src/features/results/ResultsProvider.tsx index 0495e511eac..f5fe6d21c14 100644 --- a/apps/builder/src/features/results/ResultsProvider.tsx +++ b/apps/builder/src/features/results/ResultsProvider.tsx @@ -17,7 +17,6 @@ const resultsContext = createContext<{ onDeleteResults: (totalResultsDeleted: number) => void fetchNextPage: () => void refetchResults: () => void - // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore }>({}) diff --git a/apps/builder/src/features/results/components/ResultsTable/ColumnsSettingsButton.tsx b/apps/builder/src/features/results/components/ResultsTable/ColumnsSettingsButton.tsx index 8588327d51d..84e6d610261 100644 --- a/apps/builder/src/features/results/components/ResultsTable/ColumnsSettingsButton.tsx +++ b/apps/builder/src/features/results/components/ResultsTable/ColumnsSettingsButton.tsx @@ -13,7 +13,7 @@ import { } from '@chakra-ui/react' import { ToolIcon, EyeIcon, EyeOffIcon, GripIcon } from '@/components/icons' import { ResultHeaderCell } from 'models' -import React, { forwardRef, useState } from 'react' +import React, { useState } from 'react' import { isNotDefined } from 'utils' import { DndContext, @@ -128,7 +128,7 @@ export const ColumnSettingsButton = ({ - {draggingColumnId ? : null} + {draggingColumnId ? : null} @@ -210,9 +210,3 @@ const SortableColumns = ({ ) } - -const SortableColumnOverlay = forwardRef( - (_, ref: React.LegacyRef) => { - return - } -) diff --git a/apps/builder/src/features/results/components/ResultsTable/IndeterminateCheckbox.tsx b/apps/builder/src/features/results/components/ResultsTable/IndeterminateCheckbox.tsx new file mode 100644 index 00000000000..a59ad167849 --- /dev/null +++ b/apps/builder/src/features/results/components/ResultsTable/IndeterminateCheckbox.tsx @@ -0,0 +1,23 @@ +import { Checkbox, Flex } from '@chakra-ui/react' +import React from 'react' + +const TableCheckBox = ( + { indeterminate, checked, ...rest }: any, + ref: React.LegacyRef +) => { + const defaultRef = React.useRef() + const resolvedRef: any = ref || defaultRef + + return ( + + + + ) +} + +export const IndeterminateCheckbox = React.forwardRef(TableCheckBox) diff --git a/apps/builder/src/features/results/components/ResultsTable/ResultsTable.tsx b/apps/builder/src/features/results/components/ResultsTable/ResultsTable.tsx index 0af92bb0639..69e988f9c8d 100644 --- a/apps/builder/src/features/results/components/ResultsTable/ResultsTable.tsx +++ b/apps/builder/src/features/results/components/ResultsTable/ResultsTable.tsx @@ -2,7 +2,6 @@ import { Box, Button, chakra, - Checkbox, Flex, HStack, Stack, @@ -26,6 +25,7 @@ import { Row } from './Row' import { HeaderRow } from './HeaderRow' import { CellValueType, TableData } from '../../types' import { HeaderIcon } from '../../utils' +import { IndeterminateCheckbox } from './IndeterminateCheckbox' type ResultsTableProps = { resultHeader: ResultHeaderCell[] @@ -238,23 +238,3 @@ export const ResultsTable = ({ ) } - -const IndeterminateCheckbox = React.forwardRef( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ({ indeterminate, checked, ...rest }: any, ref) => { - const defaultRef = React.useRef() - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const resolvedRef: any = ref || defaultRef - - return ( - - - - ) - } -) diff --git a/apps/builder/src/features/workspace/WorkspaceProvider.tsx b/apps/builder/src/features/workspace/WorkspaceProvider.tsx index 362848f3fd9..f5d219f8c8c 100644 --- a/apps/builder/src/features/workspace/WorkspaceProvider.tsx +++ b/apps/builder/src/features/workspace/WorkspaceProvider.tsx @@ -30,7 +30,6 @@ const workspaceContext = createContext<{ ) => Promise deleteCurrentWorkspace: () => Promise refreshWorkspace: (expectedUpdates: Partial) => void - // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore }>({}) diff --git a/apps/builder/src/features/workspace/components/WorkspaceSettingsForm.tsx b/apps/builder/src/features/workspace/components/WorkspaceSettingsForm.tsx index 1559210a76f..32a6e8eb2b7 100644 --- a/apps/builder/src/features/workspace/components/WorkspaceSettingsForm.tsx +++ b/apps/builder/src/features/workspace/components/WorkspaceSettingsForm.tsx @@ -88,7 +88,7 @@ const DeleteWorkspaceButton = ({ message={ Are you sure you want to delete {workspaceName} workspace? All its - folders, typebots and results will be deleted forever.' + folders, typebots and results will be deleted forever. } confirmButtonLabel="Delete" diff --git a/apps/builder/src/hooks/useAutoSave.ts b/apps/builder/src/hooks/useAutoSave.ts index 7a3eb98f2e0..3be4b4b2bfa 100644 --- a/apps/builder/src/hooks/useAutoSave.ts +++ b/apps/builder/src/hooks/useAutoSave.ts @@ -7,8 +7,7 @@ export const useAutoSave = ( item, debounceTimeout, }: { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - handler: () => Promise + handler: () => Promise item?: T debounceTimeout: number }, diff --git a/apps/builder/src/lib/theme.ts b/apps/builder/src/lib/theme.ts index a7bfe83d3cf..e2c71c5f04f 100644 --- a/apps/builder/src/lib/theme.ts +++ b/apps/builder/src/lib/theme.ts @@ -106,5 +106,4 @@ const components = { }, } -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const customTheme: any = extendTheme({ colors, fonts, components }) diff --git a/apps/builder/src/pages/_error.tsx b/apps/builder/src/pages/_error.tsx index 2514cf6f164..3a14bde1650 100644 --- a/apps/builder/src/pages/_error.tsx +++ b/apps/builder/src/pages/_error.tsx @@ -1,4 +1,4 @@ -import NextErrorComponent from 'next/error' +import NextErrorComponent, { ErrorProps } from 'next/error' import * as Sentry from '@sentry/nextjs' import { NextPageContext } from 'next' @@ -24,14 +24,14 @@ const MyError = ({ } MyError.getInitialProps = async (context: NextPageContext) => { - const errorInitialProps = await NextErrorComponent.getInitialProps(context) + const errorInitialProps = (await NextErrorComponent.getInitialProps( + context + )) as ErrorProps & { hasGetInitialPropsRun: boolean } const { res, err, asPath } = context // Workaround for https://github.com/vercel/next.js/issues/8592, mark when // getInitialProps has run - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore errorInitialProps.hasGetInitialPropsRun = true // Returning early because we don't want to log 404 errors to Sentry. diff --git a/apps/builder/src/pages/api/integrations/google-sheets/spreadsheets.ts b/apps/builder/src/pages/api/integrations/google-sheets/spreadsheets.ts index 385e7faa144..6cd0e4d2741 100644 --- a/apps/builder/src/pages/api/integrations/google-sheets/spreadsheets.ts +++ b/apps/builder/src/pages/api/integrations/google-sheets/spreadsheets.ts @@ -18,8 +18,6 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { return res.status(404).send("Couldn't find credentials in database") const response = await drive({ version: 'v3', - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore auth: auth.client, }).files.list({ q: "mimeType='application/vnd.google-apps.spreadsheet'", diff --git a/apps/builder/src/pages/api/stripe/webhook.ts b/apps/builder/src/pages/api/stripe/webhook.ts index 836ac291947..c540531df50 100644 --- a/apps/builder/src/pages/api/stripe/webhook.ts +++ b/apps/builder/src/pages/api/stripe/webhook.ts @@ -128,5 +128,4 @@ const webhookHandler = async (req: NextApiRequest, res: NextApiResponse) => { return methodNotAllowed(res) } -// eslint-disable-next-line @typescript-eslint/no-explicit-any export default withSentry(cors(webhookHandler as any)) diff --git a/apps/builder/src/utils/helpers.ts b/apps/builder/src/utils/helpers.ts index 30089830791..ea182b8982c 100644 --- a/apps/builder/src/utils/helpers.ts +++ b/apps/builder/src/utils/helpers.ts @@ -76,9 +76,9 @@ export const readFile = (file: File): Promise => { } export const timeSince = (date: string) => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - //@ts-ignore - const seconds = Math.floor((new Date() - new Date(date)) / 1000) + const seconds = Math.floor( + (new Date().getTime() - new Date(date).getTime()) / 1000 + ) let interval = seconds / 31536000 diff --git a/apps/builder/tsconfig.json b/apps/builder/tsconfig.json index 37ab40a735d..03b552ee6d3 100644 --- a/apps/builder/tsconfig.json +++ b/apps/builder/tsconfig.json @@ -6,6 +6,5 @@ "@/*": ["src/*"] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules"] + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"] } diff --git a/apps/landing-page/.eslintrc.js b/apps/landing-page/.eslintrc.js index 96e7baf9e90..b56159ea9c2 100644 --- a/apps/landing-page/.eslintrc.js +++ b/apps/landing-page/.eslintrc.js @@ -1,29 +1,4 @@ module.exports = { - ignorePatterns: ['node_modules'], - env: { - browser: true, - es6: true, - }, - extends: [ - 'plugin:@typescript-eslint/recommended', - 'plugin:react/recommended', - 'next/core-web-vitals', - ], - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features - sourceType: 'module', // Allows for the use of imports - ecmaFeatures: { - jsx: true, // Allows for the parsing of JSX - }, - }, - settings: { - react: { - version: 'detect', // Tells eslint-plugin-react to automatically detect the version of React to use - }, - }, - plugins: ['react', '@typescript-eslint'], - rules: { - 'react/no-unescaped-entities': [0], - }, + root: true, + extends: ['custom'], } diff --git a/apps/landing-page/components/Homepage/EasyEmbed.tsx b/apps/landing-page/components/Homepage/EasyEmbed.tsx index 5087be87686..9cdea96e926 100644 --- a/apps/landing-page/components/Homepage/EasyEmbed.tsx +++ b/apps/landing-page/components/Homepage/EasyEmbed.tsx @@ -38,7 +38,7 @@ export const EasyEmbed = () => { > Embedding your typebot in your applications is a walk in the park. Typebot gives you several step-by-step platform-specific - instructions. Your typebot will always feel "native". + instructions. Your typebot will always feel "native".