diff --git a/docs/docs/settings/user.md b/docs/docs/settings/user.md index bd862cd695..fc8a1664cb 100644 --- a/docs/docs/settings/user.md +++ b/docs/docs/settings/user.md @@ -30,6 +30,7 @@ The *Display Settings* screen shows general display configuration options: {{ usersetting("SHOW_BOM_SUBASSEMBLY_LEVELS")}} {{ usersetting("ENABLE_LAST_BREADCRUMB") }} {{ usersetting("SHOW_FULL_LOCATION_IN_TABLES") }} +{{ usersetting("DISPLAY_ITEMS_FINAL_LEVEL") }} ### Search Settings diff --git a/src/backend/InvenTree/common/setting/user.py b/src/backend/InvenTree/common/setting/user.py index 57a117e20e..c9cae610ba 100644 --- a/src/backend/InvenTree/common/setting/user.py +++ b/src/backend/InvenTree/common/setting/user.py @@ -268,4 +268,12 @@ USER_SETTINGS: dict[str, InvenTreeSettingsKeyType] = { 'description': _('Save the last used printing machines for a user'), 'default': '', }, + 'DISPLAY_ITEMS_FINAL_LEVEL': { + 'name': _('Display Items at Final Level'), + 'description': _( + 'Automatically default to showing items/parts instead of sub-levels for locations or categories with no children' + ), + 'default': False, + 'validator': bool, + }, } diff --git a/src/frontend/src/components/panels/PanelGroup.tsx b/src/frontend/src/components/panels/PanelGroup.tsx index 2288205206..a5dcf701e5 100644 --- a/src/frontend/src/components/panels/PanelGroup.tsx +++ b/src/frontend/src/components/panels/PanelGroup.tsx @@ -79,6 +79,7 @@ export type PanelProps = { model?: ModelType; id?: number | null; selectedPanel?: string; + defaultPanel?: string; onPanelChange?: (panel: string) => void; collapsible?: boolean; pluginPanelWithoutId?: boolean; @@ -483,12 +484,16 @@ function getPanelContent( function IndexPanelComponent({ pageKey, selectedPanel, + defaultPanel, panels }: Readonly) { const lastUsedPanel = useLocalState( useShallow((state) => { const panelName = - selectedPanel || state.lastUsedPanels[pageKey] || panels[0]?.name; + selectedPanel || + defaultPanel || + state.lastUsedPanels[pageKey] || + panels[0]?.name; const panel = panels.findIndex( (p) => p.name === panelName && !p.disabled && !p.hidden diff --git a/src/frontend/src/pages/part/CategoryDetail.tsx b/src/frontend/src/pages/part/CategoryDetail.tsx index d6fd2958d1..2f4dcc6e53 100644 --- a/src/frontend/src/pages/part/CategoryDetail.tsx +++ b/src/frontend/src/pages/part/CategoryDetail.tsx @@ -42,6 +42,7 @@ import { useEditApiFormModal } from '../../hooks/UseForm'; import { useInstance } from '../../hooks/UseInstance'; +import { useUserSettingsState } from '../../states/SettingsStates'; import { useUserState } from '../../states/UserState'; import ParametricPartTable from '../../tables/part/ParametricPartTable'; import { PartCategoryTable } from '../../tables/part/PartCategoryTable'; @@ -63,6 +64,7 @@ export default function CategoryDetail() { const navigate = useNavigate(); const user = useUserState(); + const settings = useUserSettingsState(); const [treeOpen, setTreeOpen] = useState(false); @@ -344,6 +346,17 @@ export default function CategoryDetail() { [category] ); + const defaultPanel = useMemo(() => { + if ( + settings.isSet('DISPLAY_ITEMS_FINAL_LEVEL', true) && + category.pk && + category.subcategories === 0 + ) { + return 'parts'; + } + return undefined; + }, [settings, category]); + return ( <> {editCategory.modal} @@ -385,6 +398,7 @@ export default function CategoryDetail() { instance={category} reloadInstance={refreshInstance} id={category.pk ?? null} + defaultPanel={defaultPanel} /> diff --git a/src/frontend/src/pages/stock/LocationDetail.tsx b/src/frontend/src/pages/stock/LocationDetail.tsx index ea004bf523..629f95d83d 100644 --- a/src/frontend/src/pages/stock/LocationDetail.tsx +++ b/src/frontend/src/pages/stock/LocationDetail.tsx @@ -47,6 +47,7 @@ import { } from '../../hooks/UseForm'; import { useInstance } from '../../hooks/UseInstance'; import { useStockAdjustActions } from '../../hooks/UseStockAdjustActions'; +import { useUserSettingsState } from '../../states/SettingsStates'; import { useUserState } from '../../states/UserState'; import { PartListTable } from '../../tables/part/PartTable'; import { StockItemTable } from '../../tables/stock/StockItemTable'; @@ -63,6 +64,7 @@ export default function Stock() { const navigate = useNavigate(); const user = useUserState(); + const settings = useUserSettingsState(); const [treeOpen, setTreeOpen] = useState(false); @@ -431,6 +433,17 @@ export default function Stock() { [location] ); + const defaultPanel = useMemo(() => { + if ( + settings.isSet('DISPLAY_ITEMS_FINAL_LEVEL', true) && + location.pk && + location.sublocations === 0 + ) { + return 'stock-items'; + } + return undefined; + }, [settings, location]); + return ( <> {editLocation.modal} @@ -479,6 +492,7 @@ export default function Stock() { id={location?.pk} instance={location} pluginPanelWithoutId + defaultPanel={defaultPanel} /> {stockAdjustActions.modals.map((modal) => modal.modal)}