diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 6c6a62f9f901..ade75a833aac 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -31,7 +31,8 @@ "ms-python.python", "ms-python.vscode-pylance", "batisteo.vscode-django", - "eamodio.gitlens" + "eamodio.gitlens", + "biomejs.biome" ] } }, diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 302c7d4a6913..1c5df1a003d8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -69,26 +69,12 @@ repos: pyproject.toml | src/frontend/vite.config.ts | )$ -- repo: https://github.com/pre-commit/mirrors-prettier - rev: "v4.0.0-alpha.8" - hooks: - - id: prettier - files: ^src/frontend/.*\.(js|jsx|ts|tsx)$ - additional_dependencies: - - "prettier@^2.4.1" - - "@trivago/prettier-plugin-sort-imports" -- repo: https://github.com/pre-commit/mirrors-eslint - rev: "v9.12.0" - hooks: - - id: eslint - additional_dependencies: - - eslint@^8.41.0 - - eslint-config-google@^0.14.0 - - eslint-plugin-react@6.10.3 - - babel-eslint@6.1.2 - - "@typescript-eslint/eslint-plugin@latest" - - "@typescript-eslint/parser" - files: ^src/frontend/.*\.(js|jsx|ts|tsx)$ +- repo: https://github.com/biomejs/pre-commit + rev: "v0.5.0" + hooks: + - id: biome-check + additional_dependencies: ["@biomejs/biome@1.9.4"] + files: ^src/frontend/.*\.(js|ts|tsx)$ - repo: https://github.com/gitleaks/gitleaks rev: v8.21.0 hooks: diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000000..dcc97bee6388 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "biomejs.biome" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000000..04b0a9dd9b30 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "editor.codeActionsOnSave": { + "quickfix.biome": "explicit" + } +} diff --git a/biome.json b/biome.json new file mode 100644 index 000000000000..1db36e466675 --- /dev/null +++ b/biome.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "javascript": { + "formatter": { + "quoteStyle": "single", + "jsxQuoteStyle": "single", + "trailingCommas": "none", + "indentStyle": "space" + } + }, + "linter": { + "rules": { + "suspicious" : { + "noExplicitAny": "off", + "noDoubleEquals": "off", + "noArrayIndexKey": "off", + "useDefaultSwitchClauseLast": "off" + }, + "style": { + "noUselessElse": "off", + "noNonNullAssertion": "off", + "noParameterAssign": "off" + }, "correctness":{ + "useExhaustiveDependencies": "off", + "useJsxKeyInIterable": "off", + "noUnsafeOptionalChaining": "off", + "noSwitchDeclarations": "off", + "noUnusedImports":"error" + }, "complexity": { + "noBannedTypes": "off", + "noExtraBooleanCast": "off", + "noForEach": "off", + "noUselessSwitchCase": "off", + "useLiteralKeys":"off" + }, "performance": { + "noDelete":"off" + } + } +} +} diff --git a/pyproject.toml b/pyproject.toml index 32e336ba227a..fc10ce92edc7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -106,4 +106,4 @@ known_django="django" sections=["FUTURE","STDLIB","DJANGO","THIRDPARTY","FIRSTPARTY","LOCALFOLDER"] [tool.codespell] -ignore-words-list = ["assertIn","SME","intoto"] +ignore-words-list = ["assertIn","SME","intoto","fitH"] diff --git a/src/frontend/.prettierrc b/src/frontend/.prettierrc deleted file mode 100644 index 3df4eac0cd8c..000000000000 --- a/src/frontend/.prettierrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "semi": true, - "trailingComma": "none", - "singleQuote": true, - "printWidth": 80, - "importOrder": ["", "^[./]"], - "importOrderSeparation": true, - "importOrderSortSpecifiers": true -} diff --git a/src/frontend/eslint.config.cjs b/src/frontend/eslint.config.cjs deleted file mode 100644 index b15982d7c656..000000000000 --- a/src/frontend/eslint.config.cjs +++ /dev/null @@ -1,7 +0,0 @@ -/* eslint-env node */ -module.exports = { - extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], - root: true, - }; diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 24818dccbe3e..f093dba68036 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -23,7 +23,7 @@ export function setApiDefaults() { api.defaults.xsrfHeaderName = 'X-CSRFToken'; if (token) { - api.defaults.headers['Authorization'] = `Token ${token}`; + api.defaults.headers.Authorization = `Token ${token}`; } else { delete api.defaults.headers['Authorization']; } diff --git a/src/frontend/src/components/Boundary.tsx b/src/frontend/src/components/Boundary.tsx index 126b9b76fbf9..a0d8181f9767 100644 --- a/src/frontend/src/components/Boundary.tsx +++ b/src/frontend/src/components/Boundary.tsx @@ -1,15 +1,15 @@ import { t } from '@lingui/macro'; import { Alert } from '@mantine/core'; -import { ErrorBoundary, FallbackRender } from '@sentry/react'; +import { ErrorBoundary, type FallbackRender } from '@sentry/react'; import { IconExclamationCircle } from '@tabler/icons-react'; -import { ReactNode, useCallback } from 'react'; +import { type ReactNode, useCallback } from 'react'; function DefaultFallback({ title }: Readonly<{ title: string }>): ReactNode { return ( } - title={t`Error rendering component` + `: ${title}`} + title={`${t`Error rendering component`}: ${title}`} > {t`An error occurred while rendering this component. Refer to the console for more information.`} diff --git a/src/frontend/src/components/buttons/ActionButton.tsx b/src/frontend/src/components/buttons/ActionButton.tsx index 4b8d6265b34d..57583cfb9baf 100644 --- a/src/frontend/src/components/buttons/ActionButton.tsx +++ b/src/frontend/src/components/buttons/ActionButton.tsx @@ -1,5 +1,10 @@ -import { ActionIcon, FloatingPosition, Group, Tooltip } from '@mantine/core'; -import { ReactNode } from 'react'; +import { + ActionIcon, + type FloatingPosition, + Group, + Tooltip +} from '@mantine/core'; +import type { ReactNode } from 'react'; import { identifierString } from '../../functions/conversion'; @@ -46,7 +51,7 @@ export function ActionButton(props: ActionButtonProps) { }} variant={props.variant ?? 'transparent'} > - + {props.icon} diff --git a/src/frontend/src/components/buttons/AddItemButton.tsx b/src/frontend/src/components/buttons/AddItemButton.tsx index adece8195f28..397fc2ed6e9e 100644 --- a/src/frontend/src/components/buttons/AddItemButton.tsx +++ b/src/frontend/src/components/buttons/AddItemButton.tsx @@ -1,10 +1,10 @@ import { IconPlus } from '@tabler/icons-react'; -import { ActionButton, ActionButtonProps } from './ActionButton'; +import { ActionButton, type ActionButtonProps } from './ActionButton'; /** * A generic icon button which is used to add or create a new item */ export function AddItemButton(props: Readonly) { - return } />; + return } />; } diff --git a/src/frontend/src/components/buttons/AdminButton.tsx b/src/frontend/src/components/buttons/AdminButton.tsx index 60a7107ecdb1..0bd5093077cf 100644 --- a/src/frontend/src/components/buttons/AdminButton.tsx +++ b/src/frontend/src/components/buttons/AdminButton.tsx @@ -2,7 +2,7 @@ import { t } from '@lingui/macro'; import { IconUserStar } from '@tabler/icons-react'; import { useCallback, useMemo } from 'react'; -import { ModelType } from '../../enums/ModelType'; +import type { ModelType } from '../../enums/ModelType'; import { useServerApiState } from '../../states/ApiState'; import { useLocalState } from '../../states/LocalState'; import { useUserState } from '../../states/UserState'; @@ -78,14 +78,14 @@ export default function AdminButton(props: Readonly) { return ( } - color="blue" - size="lg" - radius="sm" - variant="filled" + color='blue' + size='lg' + radius='sm' + variant='filled' tooltip={t`Open in admin interface`} hidden={!enabled} onClick={openAdmin} - tooltipAlignment="bottom" + tooltipAlignment='bottom' /> ); } diff --git a/src/frontend/src/components/buttons/ButtonMenu.tsx b/src/frontend/src/components/buttons/ButtonMenu.tsx index be9bef990430..d2b137a94b21 100644 --- a/src/frontend/src/components/buttons/ButtonMenu.tsx +++ b/src/frontend/src/components/buttons/ButtonMenu.tsx @@ -16,16 +16,16 @@ export function ButtonMenu({ tooltip?: string; }>) { return ( - + - + {icon} {label && {label}} {actions.map((action, i) => ( - {action} + {action} ))} diff --git a/src/frontend/src/components/buttons/CopyButton.tsx b/src/frontend/src/components/buttons/CopyButton.tsx index 6f2c733ec961..c42db4adbd6c 100644 --- a/src/frontend/src/components/buttons/CopyButton.tsx +++ b/src/frontend/src/components/buttons/CopyButton.tsx @@ -3,7 +3,7 @@ import { ActionIcon, Button, CopyButton as MantineCopyButton, - MantineSize, + type MantineSize, Text, Tooltip } from '@mantine/core'; @@ -30,13 +30,13 @@ export function CopyButton({ {copied ? ( - + ) : ( - + )} {content} {label && ( diff --git a/src/frontend/src/components/buttons/EditButton.tsx b/src/frontend/src/components/buttons/EditButton.tsx index 39c72114054e..7a941d3bb38f 100644 --- a/src/frontend/src/components/buttons/EditButton.tsx +++ b/src/frontend/src/components/buttons/EditButton.tsx @@ -17,7 +17,7 @@ export function EditButton({ setEditing()} disabled={disabled} - variant="default" + variant='default' > {editing ? saveIcon : } diff --git a/src/frontend/src/components/buttons/PrimaryActionButton.tsx b/src/frontend/src/components/buttons/PrimaryActionButton.tsx index 65aa4defaecf..5bd94c9adcf7 100644 --- a/src/frontend/src/components/buttons/PrimaryActionButton.tsx +++ b/src/frontend/src/components/buttons/PrimaryActionButton.tsx @@ -1,6 +1,6 @@ import { Button, Tooltip } from '@mantine/core'; -import { InvenTreeIcon, InvenTreeIconType } from '../../functions/icons'; +import { InvenTreeIcon, type InvenTreeIconType } from '../../functions/icons'; /** * A "primary action" button for display on a page detail, (for example) @@ -25,12 +25,12 @@ export default function PrimaryActionButton({ } return ( -