diff --git a/.github/workflows/ci-front.yaml b/.github/workflows/ci-front.yaml
index 496b8e434..56c8517f3 100644
--- a/.github/workflows/ci-front.yaml
+++ b/.github/workflows/ci-front.yaml
@@ -145,7 +145,7 @@ jobs:
- name: Front / Install Dependencies
run: cd front && yarn
- name: Front / Run linter
- run: cd front && yarn lint --config .eslintrc-ci.js
+ run: cd front && yarn lint --config .eslintrc-ci.cjs
front-jest:
needs: front-yarn-install
runs-on: ubuntu-latest
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 3f4b28eeb..c33ef9aea 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -38,5 +38,11 @@
"cSpell.words": [
"twentyhq"
],
- "typescript.preferences.importModuleSpecifier": "non-relative"
+ "typescript.preferences.importModuleSpecifier": "non-relative",
+ "[javascript][typescript][typescriptreact]": {
+ "editor.codeActionsOnSave": {
+ "source.fixAll.eslint": "explicit",
+ "source.addMissingImports": "always"
+ }
+ }
}
\ No newline at end of file
diff --git a/front/.eslintrc-ci.js b/front/.eslintrc-ci.cjs
similarity index 84%
rename from front/.eslintrc-ci.js
rename to front/.eslintrc-ci.cjs
index 53a455b90..9d6e8e979 100644
--- a/front/.eslintrc-ci.js
+++ b/front/.eslintrc-ci.cjs
@@ -8,7 +8,7 @@ module.exports = {
},
],
extends: [
- './.eslintrc.js'
+ './.eslintrc.cjs'
],
rules: {
'no-console': 'error',
diff --git a/front/.eslintrc.js b/front/.eslintrc.cjs
similarity index 57%
rename from front/.eslintrc.js
rename to front/.eslintrc.cjs
index d431859be..b9f9d2051 100644
--- a/front/.eslintrc.js
+++ b/front/.eslintrc.cjs
@@ -1,37 +1,118 @@
module.exports = {
parser: '@typescript-eslint/parser',
- parserOptions: {
- project: 'tsconfig.json',
- tsconfigRootDir: __dirname,
- sourceType: 'module',
- ecmaVersion: "2023"
- },
- plugins: [
- '@typescript-eslint/eslint-plugin',
- 'unused-imports',
- 'simple-import-sort',
- 'prefer-arrow',
- 'import',
- 'twenty',
- ],
- extends: [
- 'plugin:@typescript-eslint/recommended',
- 'plugin:prettier/recommended',
- 'plugin:storybook/recommended',
- 'plugin:react/recommended',
- 'plugin:react-hooks/recommended',
- ],
root: true,
env: {
+ browser: true,
node: true,
jest: true,
},
+ parserOptions: {
+ ecmaVersion: 'latest',
+ sourceType: 'module',
+ project: ['./tsconfig.json', './tsconfig.node.json'],
+ tsconfigRootDir: __dirname,
+ },
+ rules: {
+ '@typescript-eslint/interface-name-prefix': 'off',
+ '@typescript-eslint/explicit-function-return-type': 'off',
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
+ '@typescript-eslint/no-explicit-any': 'off',
+ '@typescript-eslint/no-unused-vars': 'off',
+ 'simple-import-sort/imports': 'error',
+ 'simple-import-sort/exports': 'error',
+ 'twenty/effect-components': 'error',
+ 'twenty/no-hardcoded-colors': 'error',
+ 'twenty/matching-state-variable': 'error',
+ 'twenty/component-props-naming': 'error',
+ 'twenty/sort-css-properties-alphabetically': 'error',
+ 'twenty/styled-components-prefixed-with-styled': 'error',
+ 'twenty/no-state-useref': 'error',
+ 'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
+ 'no-unused-vars': 'off',
+ 'react/jsx-props-no-spreading': [
+ 'error',
+ {
+ explicitSpread: 'ignore',
+ },
+ ],
+ 'react-hooks/exhaustive-deps': [
+ 'warn',
+ {
+ additionalHooks: 'useRecoilCallback',
+ },
+ ],
+ 'unused-imports/no-unused-imports': 'warn',
+ 'unused-imports/no-unused-vars': [
+ 'warn',
+ {
+ vars: 'all',
+ varsIgnorePattern: '^_',
+ args: 'after-used',
+ argsIgnorePattern: '^_',
+ },
+ ],
+ 'no-restricted-imports': [
+ 'error',
+ {
+ patterns: [
+ {
+ group: ['@tabler/icons-react'],
+ message: 'Icon imports are only allowed for `@/ui/icon`',
+ },
+ {
+ group: ['react-hotkeys-web-hook'],
+ importNames: ['useHotkeys'],
+ message: 'Please use the custom wrapper: `useScopedHotkeys`',
+ },
+ ],
+ },
+ ],
+ '@typescript-eslint/consistent-type-imports': [
+ 'error',
+ { prefer: 'no-type-imports' },
+ ],
+ 'no-console': ['warn', { allow: ['group', 'groupCollapsed', 'groupEnd'] }],
+ // 'react-refresh/only-export-components': [
+ // 'warn',
+ // { allowConstantExport: true },
+ // ],
+ },
+ settings: {
+ react: {
+ version: 'detect',
+ },
+ },
+ extends: [
+ 'plugin:@typescript-eslint/recommended',
+ 'eslint:recommended',
+ 'plugin:react/recommended',
+ 'plugin:react-hooks/recommended',
+ 'plugin:prettier/recommended',
+ 'plugin:storybook/recommended',
+ ],
+ plugins: [
+ '@typescript-eslint/eslint-plugin',
+ 'simple-import-sort',
+ 'unused-imports',
+ 'prefer-arrow',
+ 'twenty',
+ 'react-refresh',
+ ],
+ ignorePatterns: [
+ 'mockServiceWorker.js',
+ '**/generated*/*',
+ '.eslintrc.cjs',
+ '*.config.cjs',
+ '*.config.ts',
+ '*config.js',
+ 'codegen*',
+ ],
overrides: [
{
files: ['*.stories.tsx', '*.test.ts'],
rules: {
'no-console': 'off',
- }
+ },
},
{
files: ['*.js', '*.jsx', '*.ts', '*.tsx'],
@@ -43,7 +124,7 @@ module.exports = {
'react/jsx-uses-react': 'off',
'react/react-in-jsx-scope': 'off',
'no-control-regex': 0,
- 'import/no-duplicates': ["error", {"considerQueryString": true}],
+ 'no-undef': 'off',
'simple-import-sort/imports': [
'error',
{
@@ -53,76 +134,19 @@ module.exports = {
['^\\u0000'],
['^\\.\\.(?!/?$)', '^\\.\\./?$'],
['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'],
- ['^.+\\.?(css)$']
- ]
- }
+ ['^.+\\.?(css)$'],
+ ],
+ },
],
'prefer-arrow/prefer-arrow-functions': [
'error',
{
- "disallowPrototype": true,
- "singleReturnOnly": false,
- "classPropertiesAllowed": false
- }
- ]
- }
- },
- ],
- ignorePatterns: ['.eslintrc.js', 'codegen*.js', '**/generated*/*', '*.config.js'],
- rules: {
- '@typescript-eslint/interface-name-prefix': 'off',
- '@typescript-eslint/explicit-function-return-type': 'off',
- '@typescript-eslint/explicit-module-boundary-types': 'off',
- '@typescript-eslint/no-explicit-any': 'off',
- 'simple-import-sort/imports': 'error',
- 'simple-import-sort/exports': 'error',
- 'twenty/effect-components': 'error',
- 'twenty/no-hardcoded-colors': 'error',
- 'twenty/matching-state-variable': 'error',
- 'twenty/component-props-naming': 'error',
- 'twenty/sort-css-properties-alphabetically': 'error',
- 'twenty/styled-components-prefixed-with-styled': 'error',
- 'twenty/no-state-useref': 'error',
- 'func-style':['error', 'declaration', { 'allowArrowFunctions': true }],
- "@typescript-eslint/no-unused-vars": "off",
- "no-unused-vars": "off",
- "react/jsx-props-no-spreading": [
- "error", {
- "explicitSpread": "ignore",
- }
- ],
- "react-hooks/exhaustive-deps": [
- "warn", {
- "additionalHooks": "useRecoilCallback"
- }
- ],
- "unused-imports/no-unused-imports": "warn",
- "unused-imports/no-unused-vars": [
- "warn",
- { "vars": "all", "varsIgnorePattern": "^_", "args": "after-used", "argsIgnorePattern": "^_" }
- ],
- 'no-restricted-imports': [
- 'error',
- {
- 'patterns': [
- {
- 'group': ['@tabler/icons-react'],
- 'message': 'Icon imports are only allowed for `@/ui/icon`',
- },
- {
- 'group': ['react-hotkeys-web-hook'],
- "importNames": ["useHotkeys"],
- 'message': 'Please use the custom wrapper: `useScopedHotkeys`',
+ disallowPrototype: true,
+ singleReturnOnly: false,
+ classPropertiesAllowed: false,
},
],
},
- ],
- "@typescript-eslint/consistent-type-imports": ["error", { "prefer": "no-type-imports" }],
- 'no-console': ['warn', { allow: ['group', 'groupCollapsed', 'groupEnd'] }],
- },
- settings: {
- "react": {
- "version": "detect"
- }
- }
+ },
+ ],
};
diff --git a/front/.gitignore b/front/.gitignore
index ea617b5d6..00cb9385c 100644
--- a/front/.gitignore
+++ b/front/.gitignore
@@ -1,7 +1,15 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
# dependencies
/node_modules
+/coverage*
/.pnp
.pnp.js
@@ -12,16 +20,22 @@ build-storybook.log
# production
/build
+dist
+dist-ssr
-# misc
-.DS_Store
+# env
.env.local
.env.development.local
.env.test.local
.env.production.local
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-
-.nyc_output
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/front/.prettierignore b/front/.prettierignore
new file mode 100644
index 000000000..48f48cec2
--- /dev/null
+++ b/front/.prettierignore
@@ -0,0 +1,3 @@
+**/generated*/
+*.lock
+*.yaml
\ No newline at end of file
diff --git a/front/.prettierrc b/front/.prettierrc
index 9d36f26d8..4510dc5c8 100644
--- a/front/.prettierrc
+++ b/front/.prettierrc
@@ -2,4 +2,4 @@
"singleQuote": true,
"trailingComma": "all",
"endOfLine": "auto"
-}
\ No newline at end of file
+}
diff --git a/front/.storybook/main.js b/front/.storybook/main.js
deleted file mode 100644
index 699315238..000000000
--- a/front/.storybook/main.js
+++ /dev/null
@@ -1,94 +0,0 @@
-const path = require('path');
-
-computeStoriesGlob = () => {
- if (process.env.STORYBOOK_SCOPE === 'pages') {
- return [
- '../src/pages/**/*.stories.@(js|jsx|ts|tsx)',
- '../src/__stories__/*.stories.@(js|jsx|ts|tsx)',
- '../src/pages/**/*.docs.mdx',
- '../src/__stories__/*.docs.mdx'
- ]
- }
-
- if (process.env.STORYBOOK_SCOPE === 'modules') {
- return ['../src/modules/**/*.stories.@(js|jsx|ts|tsx)', '../src/modules/**/*.docs.mdx']
- }
-
- if (process.env.STORYBOOK_SCOPE === 'ui-docs') {
- return ['../src/modules/ui/**/*.docs.mdx'];
- }
-
- return ['../src/**/*.stories.@(js|jsx|ts|tsx)', '../src/**/*.docs.mdx']
-};
-
-module.exports = {
- webpackFinal: (config) => {
- config.module.rules.push({
- test: /\.tsx?$/,
- exclude: /node_modules/,
- use: [
- {
- loader: require.resolve('babel-loader'),
- options: {
- presets: [
- require('@babel/preset-typescript').default,
- [
- require('@babel/preset-react').default,
- {
- runtime: 'automatic',
- },
- ],
- require('@babel/preset-env').default,
- ],
- },
- },
- ],
- });
- config.resolve.extensions.push('.ts', '.tsx');
- config.module.rules.push({
- test: /\.mjs$/,
- include: /node_modules/,
- type: 'javascript/auto',
- });
- config.module.rules.push({
- test: /\.svg$/,
- use: [
- {
- loader: '@svgr/webpack',
- },
- {
- loader: 'file-loader',
- options: {
- name: 'static/media/[path][name].[ext]',
- },
- },
- ],
- type: 'javascript/auto',
- issuer: {
- and: [/\.(ts|tsx|js|jsx|md|mdx)$/],
- },
- });
- config.resolve.extensions.push('.mjs');
- config.resolve.alias = {
- ...config.resolve.alias,
- '~': path.resolve(__dirname, '../src'),
- '@': path.resolve(__dirname, '../src/modules'),
- };
- return config;
- },
- stories: computeStoriesGlob(),
- addons: [
- '@storybook/addon-links',
- '@storybook/addon-essentials',
- '@storybook/addon-interactions',
- '@storybook/addon-coverage',
- '@storybook/addon-styling',
- 'storybook-addon-pseudo-states',
- 'storybook-addon-cookie',
- ],
- docs: { autodocs: false },
- framework: {
- name: '@storybook/react-webpack5',
- options: {},
- },
-};
diff --git a/front/.storybook/main.ts b/front/.storybook/main.ts
new file mode 100644
index 000000000..ccc903898
--- /dev/null
+++ b/front/.storybook/main.ts
@@ -0,0 +1,45 @@
+import type { StorybookConfig } from '@storybook/react-vite';
+
+const computeStoriesGlob = () => {
+ if (process.env.STORYBOOK_SCOPE === 'pages') {
+ return [
+ '../src/pages/**/*.stories.@(js|jsx|ts|tsx)',
+ '../src/__stories__/*.stories.@(js|jsx|ts|tsx)',
+ '../src/pages/**/*.docs.mdx',
+ '../src/__stories__/*.docs.mdx'
+ ]
+ }
+
+ if (process.env.STORYBOOK_SCOPE === 'modules') {
+ return ['../src/modules/**/*.stories.@(js|jsx|ts|tsx)', '../src/modules/**/*.docs.mdx']
+ }
+
+ if (process.env.STORYBOOK_SCOPE === 'ui-docs') {
+ return ['../src/modules/ui/**/*.docs.mdx'];
+ }
+
+ return ['../src/**/*.docs.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)']
+};
+
+const config: StorybookConfig = {
+ stories: computeStoriesGlob(),
+ staticDirs: ['../public'],
+ addons: [
+ '@storybook/addon-links',
+ '@storybook/addon-essentials',
+ '@storybook/addon-onboarding',
+ '@storybook/addon-interactions',
+ '@storybook/addon-coverage',
+ '@storybook/addon-themes',
+ 'storybook-addon-cookie',
+ 'storybook-addon-pseudo-states',
+ ],
+ framework: {
+ name: '@storybook/react-vite',
+ options: {},
+ },
+ docs: {
+ autodocs: false,
+ },
+};
+export default config;
diff --git a/front/.storybook/preview-head.html b/front/.storybook/preview-head.html
index b846fe879..06bfbae2f 100644
--- a/front/.storybook/preview-head.html
+++ b/front/.storybook/preview-head.html
@@ -2,7 +2,12 @@
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"
rel="stylesheet"
/>
+
+
+