diff --git a/pyproject.toml b/pyproject.toml index 69176dbccf..04f341b519 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,6 +58,7 @@ ignore = [ "N812", # - RUF032 - decimal-from-float-literal "RUF032", + # - RUF045 - implicit-class-var-in-dataclass "RUF045", # - UP045 - Use `X | None` instead of `Optional[X]` "UP045", diff --git a/src/backend/InvenTree/web/templates/web/index.html b/src/backend/InvenTree/web/templates/web/index.html index 300368d9b4..879f7daf2a 100644 --- a/src/backend/InvenTree/web/templates/web/index.html +++ b/src/backend/InvenTree/web/templates/web/index.html @@ -9,6 +9,7 @@ {% inventree_instance_name %} + {% include "favicon.html" %} diff --git a/src/frontend/index.html b/src/frontend/index.html index 3e7fd76816..36deaa0c1a 100644 --- a/src/frontend/index.html +++ b/src/frontend/index.html @@ -5,6 +5,7 @@ InvenTree + diff --git a/src/frontend/lib/types/Forms.tsx b/src/frontend/lib/types/Forms.tsx index 9425f43774..8e3a574f01 100644 --- a/src/frontend/lib/types/Forms.tsx +++ b/src/frontend/lib/types/Forms.tsx @@ -1,6 +1,6 @@ import type { DefaultMantineColor, MantineStyleProp } from '@mantine/core'; import type { UseFormReturnType } from '@mantine/form'; -import type { ReactNode } from 'react'; +import type { JSX, ReactNode } from 'react'; import type { FieldValues, UseFormReturn } from 'react-hook-form'; import type { ApiEndpoints } from '../enums/ApiEndpoints'; import type { ModelType } from '../enums/ModelType'; diff --git a/src/frontend/src/components/Boundary.tsx b/src/frontend/src/components/Boundary.tsx index ec557f7b66..119b8fc9eb 100644 --- a/src/frontend/src/components/Boundary.tsx +++ b/src/frontend/src/components/Boundary.tsx @@ -23,7 +23,7 @@ export function Boundary({ }: Readonly<{ children: ReactNode; label: string; - fallback?: React.ReactElement | FallbackRender; + fallback?: React.ReactElement | FallbackRender; }>): ReactNode { const onError = useCallback( (error: unknown, componentStack: string | undefined, eventId: string) => { diff --git a/src/frontend/src/components/buttons/CopyButton.tsx b/src/frontend/src/components/buttons/CopyButton.tsx index a31338bde6..79edcc174c 100644 --- a/src/frontend/src/components/buttons/CopyButton.tsx +++ b/src/frontend/src/components/buttons/CopyButton.tsx @@ -10,6 +10,8 @@ import { import { InvenTreeIcon } from '../../functions/icons'; +import type { JSX } from 'react'; + export function CopyButton({ value, label, diff --git a/src/frontend/src/components/buttons/SSOButton.tsx b/src/frontend/src/components/buttons/SSOButton.tsx index 4a418b1816..892c4c8057 100644 --- a/src/frontend/src/components/buttons/SSOButton.tsx +++ b/src/frontend/src/components/buttons/SSOButton.tsx @@ -18,6 +18,8 @@ import type { AuthProvider } from '@lib/types/Auth'; import { t } from '@lingui/core/macro'; import { ProviderLogin } from '../../functions/auth'; +import type { JSX } from 'react'; + const brandIcons: { [key: string]: JSX.Element } = { google: , github: , diff --git a/src/frontend/src/components/buttons/StarredToggleButton.tsx b/src/frontend/src/components/buttons/StarredToggleButton.tsx index 7fd9bbbb7c..73d241d92c 100644 --- a/src/frontend/src/components/buttons/StarredToggleButton.tsx +++ b/src/frontend/src/components/buttons/StarredToggleButton.tsx @@ -4,6 +4,7 @@ import { apiUrl } from '@lib/functions/Api'; import { t } from '@lingui/core/macro'; import { showNotification } from '@mantine/notifications'; import { IconBell } from '@tabler/icons-react'; +import type { JSX } from 'react'; import { useApi } from '../../contexts/ApiContext'; import { ActionButton } from './ActionButton'; diff --git a/src/frontend/src/components/dashboard/DashboardWidget.tsx b/src/frontend/src/components/dashboard/DashboardWidget.tsx index d2f4840470..3054963285 100644 --- a/src/frontend/src/components/dashboard/DashboardWidget.tsx +++ b/src/frontend/src/components/dashboard/DashboardWidget.tsx @@ -4,6 +4,8 @@ import { IconX } from '@tabler/icons-react'; import { Boundary } from '../Boundary'; +import type { JSX } from 'react'; + /** * Dashboard widget properties. * diff --git a/src/frontend/src/components/editors/TemplateEditor/TemplateEditor.tsx b/src/frontend/src/components/editors/TemplateEditor/TemplateEditor.tsx index 9398eec487..f712cc6de8 100644 --- a/src/frontend/src/components/editors/TemplateEditor/TemplateEditor.tsx +++ b/src/frontend/src/components/editors/TemplateEditor/TemplateEditor.tsx @@ -99,7 +99,7 @@ export function TemplateEditor(props: Readonly) { previewAreas[0].key ); - const codeRef = useRef(); + const codeRef = useRef(undefined); const loadCodeToEditor = useCallback(async (code: string) => { try { diff --git a/src/frontend/src/components/items/DocTooltip.tsx b/src/frontend/src/components/items/DocTooltip.tsx index ce4b6b1528..f2566edb81 100644 --- a/src/frontend/src/components/items/DocTooltip.tsx +++ b/src/frontend/src/components/items/DocTooltip.tsx @@ -1,6 +1,6 @@ import { Trans } from '@lingui/react/macro'; import { Anchor, Container, HoverCard, ScrollArea, Text } from '@mantine/core'; -import { useEffect, useRef, useState } from 'react'; +import { type JSX, useEffect, useRef, useState } from 'react'; import * as classes from '../../main.css'; diff --git a/src/frontend/src/components/items/LanguageToggle.tsx b/src/frontend/src/components/items/LanguageToggle.tsx index 63acbad93f..046c2d644a 100644 --- a/src/frontend/src/components/items/LanguageToggle.tsx +++ b/src/frontend/src/components/items/LanguageToggle.tsx @@ -16,6 +16,7 @@ export function LanguageToggle() { margin: open === true ? 2 : 12, padding: open === true ? 8 : 0 }} + aria-label='Open language options' > { diff --git a/src/frontend/src/components/modals/AboutInvenTreeModal.tsx b/src/frontend/src/components/modals/AboutInvenTreeModal.tsx index a8c7e6aeed..cf916327d3 100644 --- a/src/frontend/src/components/modals/AboutInvenTreeModal.tsx +++ b/src/frontend/src/components/modals/AboutInvenTreeModal.tsx @@ -24,6 +24,8 @@ import { useUserState } from '../../states/UserState'; import { CopyButton } from '../buttons/CopyButton'; import { StylishText } from '../items/StylishText'; +import type { JSX } from 'react'; + type AboutLookupRef = { ref: string; title: JSX.Element; diff --git a/src/frontend/src/components/nav/Header.tsx b/src/frontend/src/components/nav/Header.tsx index 524ac8a144..d6e2b12eb8 100644 --- a/src/frontend/src/components/nav/Header.tsx +++ b/src/frontend/src/components/nav/Header.tsx @@ -56,7 +56,7 @@ export function Header() { { open: openNotificationDrawer, close: closeNotificationDrawer } ] = useDisclosure(false); - const { isLoggedIn } = useUserState(); + const { isLoggedIn, isStaff } = useUserState(); const [notificationCount, setNotificationCount] = useState(0); const globalSettings = useGlobalSettingsState(); diff --git a/src/frontend/src/components/nav/Layout.tsx b/src/frontend/src/components/nav/Layout.tsx index e25712e618..f34187ebbd 100644 --- a/src/frontend/src/components/nav/Layout.tsx +++ b/src/frontend/src/components/nav/Layout.tsx @@ -2,7 +2,7 @@ import { t } from '@lingui/core/macro'; import { Container, Flex, Space } from '@mantine/core'; import { Spotlight, createSpotlight } from '@mantine/spotlight'; import { IconSearch } from '@tabler/icons-react'; -import { useEffect, useState } from 'react'; +import { type JSX, useEffect, useState } from 'react'; import { Navigate, Outlet, useLocation, useNavigate } from 'react-router-dom'; import { getActions } from '../../defaults/actions'; diff --git a/src/frontend/src/contexts/LanguageContext.tsx b/src/frontend/src/contexts/LanguageContext.tsx index 9923c12093..8332baf961 100644 --- a/src/frontend/src/contexts/LanguageContext.tsx +++ b/src/frontend/src/contexts/LanguageContext.tsx @@ -2,7 +2,7 @@ import { i18n } from '@lingui/core'; import { t } from '@lingui/core/macro'; import { I18nProvider } from '@lingui/react'; import { LoadingOverlay, Text } from '@mantine/core'; -import { useEffect, useRef, useState } from 'react'; +import { type JSX, useEffect, useRef, useState } from 'react'; import { useShallow } from 'zustand/react/shallow'; import { api } from '../App'; diff --git a/src/frontend/src/contexts/ThemeContext.tsx b/src/frontend/src/contexts/ThemeContext.tsx index 7fa0f7fb3e..a0fb46842e 100644 --- a/src/frontend/src/contexts/ThemeContext.tsx +++ b/src/frontend/src/contexts/ThemeContext.tsx @@ -13,6 +13,8 @@ import { useLocalState } from '../states/LocalState'; import { LanguageContext } from './LanguageContext'; import { colorSchema } from './colorSchema'; +import type { JSX } from 'react'; + export function ThemeContext({ children }: Readonly<{ children: JSX.Element }>) { diff --git a/src/frontend/src/forms/StockForms.tsx b/src/frontend/src/forms/StockForms.tsx index 16d64aa528..a0449c4168 100644 --- a/src/frontend/src/forms/StockForms.tsx +++ b/src/frontend/src/forms/StockForms.tsx @@ -20,7 +20,7 @@ import { IconUsersGroup } from '@tabler/icons-react'; import { useQuery, useSuspenseQuery } from '@tanstack/react-query'; -import { Suspense, useEffect, useMemo, useState } from 'react'; +import { type JSX, Suspense, useEffect, useMemo, useState } from 'react'; import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; import { ModelType } from '@lib/enums/ModelType'; diff --git a/src/frontend/src/functions/icons.tsx b/src/frontend/src/functions/icons.tsx index 35d45c934b..bd9a3b0337 100644 --- a/src/frontend/src/functions/icons.tsx +++ b/src/frontend/src/functions/icons.tsx @@ -1,6 +1,5 @@ import type { InvenTreeIconType, TablerIconType } from '@lib/types/Icons'; import { - Icon123, IconArrowBigDownLineFilled, IconArrowMerge, IconBell, @@ -61,6 +60,7 @@ import { IconMapPinHeart, IconMinusVertical, IconNotes, + IconNumber123, IconNumbers, IconPackage, IconPackageImport, @@ -122,7 +122,7 @@ const icons: InvenTreeIconType = { ordering: IconShoppingCart, building: IconTool, category: IconBinaryTree2, - IPN: Icon123, + IPN: IconNumber123, revision: IconGitBranch, units: IconRulerMeasure, keywords: IconTag, diff --git a/src/frontend/src/functions/loading.tsx b/src/frontend/src/functions/loading.tsx index 87c3f249c6..73c56d04a7 100644 --- a/src/frontend/src/functions/loading.tsx +++ b/src/frontend/src/functions/loading.tsx @@ -1,5 +1,5 @@ import { Center, Loader, MantineProvider, Stack } from '@mantine/core'; -import { Suspense } from 'react'; +import { type JSX, Suspense } from 'react'; import { colorSchema } from '../contexts/colorSchema'; import { theme } from '../theme'; diff --git a/src/frontend/src/hooks/UseCalendar.tsx b/src/frontend/src/hooks/UseCalendar.tsx index e728e399b4..7335ea28cc 100644 --- a/src/frontend/src/hooks/UseCalendar.tsx +++ b/src/frontend/src/hooks/UseCalendar.tsx @@ -60,7 +60,7 @@ export default function useCalendar({ endpoint: ApiEndpoints; queryParams?: any; }): CalendarState { - const ref = useRef(null); + const ref = useRef(null as any); const filterSet = useFilterSet(`calendar-${name}`); diff --git a/src/frontend/src/pages/Index/Settings/AccountSettings/useConfirm.tsx b/src/frontend/src/pages/Index/Settings/AccountSettings/useConfirm.tsx index decfe20249..e66a8d4cd4 100644 --- a/src/frontend/src/pages/Index/Settings/AccountSettings/useConfirm.tsx +++ b/src/frontend/src/pages/Index/Settings/AccountSettings/useConfirm.tsx @@ -1,7 +1,7 @@ import { t } from '@lingui/core/macro'; import { Trans } from '@lingui/react/macro'; import { Button, Group, Modal, Stack, TextInput } from '@mantine/core'; -import { useState } from 'react'; +import { type JSX, useState } from 'react'; /* Adapted from https://daveteu.medium.com/react-custom-confirmation-box-458cceba3f7b */ const createPromise = () => { diff --git a/src/frontend/tests/pui_printing.spec.ts b/src/frontend/tests/pui_printing.spec.ts index a2f5a546d6..3bc8130167 100644 --- a/src/frontend/tests/pui_printing.spec.ts +++ b/src/frontend/tests/pui_printing.spec.ts @@ -28,7 +28,7 @@ test('Label Printing', async ({ browser }) => { // Select plugin await page.getByLabel('related-field-plugin').click(); - await page.getByText('InvenTreeLabelSheet').click(); + await page.getByText('InvenTreeLabelSheet').last().click(); // Select label template await page.getByLabel('related-field-template').click(); @@ -36,6 +36,9 @@ test('Label Printing', async ({ browser }) => { await page.waitForTimeout(100); + await page.getByLabel('related-field-plugin').click(); + await page.getByText('InvenTreeLabelSheet').last().click(); + // Submit the print form (second time should result in success) await page.getByRole('button', { name: 'Print', exact: true }).isEnabled(); await page.getByRole('button', { name: 'Print', exact: true }).click(); diff --git a/src/frontend/tests/settings/selectionList.spec.ts b/src/frontend/tests/settings/selectionList.spec.ts index 1f899ce78e..21507a9d9b 100644 --- a/src/frontend/tests/settings/selectionList.spec.ts +++ b/src/frontend/tests/settings/selectionList.spec.ts @@ -89,7 +89,7 @@ test('PUI - Admin - Parameter', async ({ browser }) => { .getByText('Template *Parameter') .locator('div') .filter({ hasText: /^Search\.\.\.$/ }) - .nth(2) + .first() .click(); await page .getByText('Template *Parameter')