2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-09-13 14:11:37 +00:00

[UI] Search shortcut (#10181)

* Add search shortcut

- Use '/' to open search drawer

* Add user setting for spotlight

* Hide spotlight if disabled

* Updated playwright tests
This commit is contained in:
Oliver
2025-08-15 20:41:03 +10:00
committed by GitHub
parent 4cadc433bb
commit 0f04c31ffb
6 changed files with 52 additions and 15 deletions

View File

@@ -21,6 +21,7 @@ The *Display Settings* screen shows general display configuration options:
{{ usersetting("ICONS_IN_NAVBAR") }}
{{ usersetting("STICKY_HEADER") }}
{{ usersetting("STICKY_TABLE_HEADER") }}
{{ usersetting("SHOW_SPOTLIGHT") }}
{{ usersetting("DATE_DISPLAY_FORMAT") }}
{{ usersetting("FORMS_CLOSE_USING_ESCAPE") }}
{{ usersetting("DISPLAY_STOCKTAKE_TAB") }}

View File

@@ -191,6 +191,12 @@ USER_SETTINGS: dict[str, InvenTreeSettingsKeyType] = {
'default': False,
'validator': bool,
},
'SHOW_SPOTLIGHT': {
'name': _('Show Spotlight'),
'description': _('Enable spotlight navigation functionality'),
'default': True,
'validator': bool,
},
'ICONS_IN_NAVBAR': {
'name': _('Navigation Icons'),
'description': _('Display icons in the navigation bar'),

View File

@@ -8,7 +8,11 @@ import {
Tooltip,
UnstyledButton
} from '@mantine/core';
import { useDisclosure, useDocumentVisibility } from '@mantine/hooks';
import {
useDisclosure,
useDocumentVisibility,
useHotkeys
} from '@mantine/hooks';
import { IconBell, IconSearch } from '@tabler/icons-react';
import { useQuery } from '@tanstack/react-query';
import { type ReactNode, useEffect, useMemo, useState } from 'react';
@@ -49,11 +53,27 @@ export function Header() {
const [server] = useServerApiState(useShallow((state) => [state.server]));
const [navDrawerOpened, { open: openNavDrawer, close: closeNavDrawer }] =
useDisclosure(navigationOpen);
const [
searchDrawerOpened,
{ open: openSearchDrawer, close: closeSearchDrawer }
] = useDisclosure(false);
useHotkeys([
[
'/',
() => {
openSearchDrawer();
}
],
[
'mod+/',
() => {
openSearchDrawer();
}
]
]);
const [
notificationDrawerOpened,
{ open: openNotificationDrawer, close: closeNotificationDrawer }
@@ -154,7 +174,7 @@ export function Header() {
<IconSearch />
</ActionIcon>
</Tooltip>
<SpotlightButton />
{userSettings.isSet('SHOW_SPOTLIGHT') && <SpotlightButton />}
{globalSettings.isSet('BARCODE_ENABLE') && <ScanButton />}
<Indicator
radius='lg'

View File

@@ -7,6 +7,7 @@ import { Navigate, Outlet, useLocation, useNavigate } from 'react-router-dom';
import { getActions } from '../../defaults/actions';
import * as classes from '../../main.css';
import { useUserSettingsState } from '../../states/SettingsStates';
import { useUserState } from '../../states/UserState';
import { Boundary } from '../Boundary';
import { Footer } from './Footer';
@@ -37,6 +38,7 @@ export const [firstStore, firstSpotlight] = createSpotlight();
export default function LayoutComponent() {
const navigate = useNavigate();
const location = useLocation();
const userSettings = useUserSettingsState();
const defaultActions = getActions(navigate);
const [actions, setActions] = useState(defaultActions);
@@ -68,6 +70,7 @@ export default function LayoutComponent() {
</Container>
<Space h='xl' />
<Footer />
{userSettings.isSet('SHOW_SPOTLIGHT') && (
<Spotlight
actions={actions}
store={firstStore}
@@ -76,9 +79,10 @@ export default function LayoutComponent() {
leftSection: <IconSearch size='1.2rem' />,
placeholder: t`Search...`
}}
shortcut={['mod + K', '/']}
shortcut={['mod + K']}
nothingFound={t`Nothing found...`}
/>
)}
</Flex>
</ProtectedRoute>
);

View File

@@ -58,6 +58,7 @@ export default function UserSettings() {
'ICONS_IN_NAVBAR',
'STICKY_HEADER',
'STICKY_TABLE_HEADER',
'SHOW_SPOTLIGHT',
'DATE_DISPLAY_FORMAT',
'FORMS_CLOSE_USING_ESCAPE',
'DISPLAY_STOCKTAKE_TAB',

View File

@@ -5,7 +5,7 @@ import { doCachedLogin } from './login.js';
/**
* Test for integration of django admin button
*/
test('Admin Button', async ({ browser }) => {
test('General - Admin Button', async ({ browser }) => {
const page = await doCachedLogin(browser, {
username: 'admin',
password: 'inventree',
@@ -21,12 +21,17 @@ test('Admin Button', async ({ browser }) => {
});
// Tests for the global search functionality
test('Search', async ({ browser }) => {
test('General - Search', async ({ browser }) => {
const page = await doCachedLogin(browser, {
username: 'steven',
password: 'wizardstaff'
});
// Open the search drawer with a shortcut
await page.keyboard.press('Control+/');
await page.getByRole('textbox', { name: 'global-search-input' }).waitFor();
await page.keyboard.press('Escape');
await globalSearch(page, 'another customer');
// Check for expected results