From 0ef5b127477e0758d538a08c0a3d40f2dce33d87 Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 29 Jul 2025 10:43:36 +1000 Subject: [PATCH] Sticky headers (#9022) * Add user setting * Use value of user setting * Fix user for global * Stickiness * Updated docs --- docs/docs/settings/user.md | 1 + src/backend/InvenTree/common/setting/user.py | 6 ++++++ .../src/pages/Index/Settings/UserSettings.tsx | 1 + src/frontend/src/tables/InvenTreeTable.tsx | 11 +++++++++++ 4 files changed, 19 insertions(+) diff --git a/docs/docs/settings/user.md b/docs/docs/settings/user.md index 1114e26382..5028508ead 100644 --- a/docs/docs/settings/user.md +++ b/docs/docs/settings/user.md @@ -20,6 +20,7 @@ The *Display Settings* screen shows general display configuration options: | ---- | ----------- | ------- | ----- | {{ usersetting("ICONS_IN_NAVBAR") }} {{ usersetting("STICKY_HEADER") }} +{{ usersetting("STICKY_TABLE_HEADER") }} {{ usersetting("DATE_DISPLAY_FORMAT") }} {{ usersetting("FORMS_CLOSE_USING_ESCAPE") }} {{ usersetting("DISPLAY_STOCKTAKE_TAB") }} diff --git a/src/backend/InvenTree/common/setting/user.py b/src/backend/InvenTree/common/setting/user.py index 8e5a45bbe1..2c0e3ec386 100644 --- a/src/backend/InvenTree/common/setting/user.py +++ b/src/backend/InvenTree/common/setting/user.py @@ -185,6 +185,12 @@ USER_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'default': False, 'validator': bool, }, + 'STICKY_TABLE_HEADER': { + 'name': _('Fixed Table Headers'), + 'description': _('Table headers are fixed to the top of the table'), + 'default': False, + 'validator': bool, + }, 'ICONS_IN_NAVBAR': { 'name': _('Navigation Icons'), 'description': _('Display icons in the navigation bar'), diff --git a/src/frontend/src/pages/Index/Settings/UserSettings.tsx b/src/frontend/src/pages/Index/Settings/UserSettings.tsx index cd03d70aa2..48b29748a6 100644 --- a/src/frontend/src/pages/Index/Settings/UserSettings.tsx +++ b/src/frontend/src/pages/Index/Settings/UserSettings.tsx @@ -57,6 +57,7 @@ export default function UserSettings() { keys={[ 'ICONS_IN_NAVBAR', 'STICKY_HEADER', + 'STICKY_TABLE_HEADER', 'DATE_DISPLAY_FORMAT', 'FORMS_CLOSE_USING_ESCAPE', 'DISPLAY_STOCKTAKE_TAB', diff --git a/src/frontend/src/tables/InvenTreeTable.tsx b/src/frontend/src/tables/InvenTreeTable.tsx index 3363d63033..a77b6bbb61 100644 --- a/src/frontend/src/tables/InvenTreeTable.tsx +++ b/src/frontend/src/tables/InvenTreeTable.tsx @@ -29,6 +29,7 @@ import { useApi } from '../contexts/ApiContext'; import { extractAvailableFields, mapFields } from '../functions/forms'; import { showApiErrorMessage } from '../functions/notifications'; import { useLocalState } from '../states/LocalState'; +import { useUserSettingsState } from '../states/SettingsStates'; import { useStoredTableState } from '../states/StoredTableState'; import InvenTreeTableHeader from './InvenTreeTableHeader'; @@ -91,6 +92,12 @@ export function InvenTreeTable>({ const navigate = useNavigate(); const { showContextMenu } = useContextMenu(); + const userSettings = useUserSettingsState(); + + const stickyTableHeader = useMemo(() => { + return userSettings.isSet('STICKY_TABLE_HEADER'); + }, [userSettings]); + // Key used for caching table data const cacheKey = useMemo(() => { const key: string = `table-${tableState.tableKey}`; @@ -742,6 +749,10 @@ export function InvenTreeTable>({