diff --git a/CHANGELOG.md b/CHANGELOG.md
index f49f649aca..f3da3da15b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
+- [#12117](https://github.com/inventree/InvenTree/pull/12117) adds a "preview" drawer to the InvenTree table component, allowing users to preview the details of a selected row without navigating away from the table view. This feature is optional and can be enabled or disabled via the `PREVIEW_DRAWER_ENABLED` system setting.
- [#12341](https://github.com/inventree/InvenTree/pull/12341) adds support for importing internal part prices.
- [#12295](https://github.com/inventree/InvenTree/pull/12295) adds "consumable" field to the Part model and API endpoints
- [#12250](https://github.com/inventree/InvenTree/pull/12250) adds "active" field to the ProjectCode model and API endpoints
diff --git a/docs/docs/assets/images/concepts/ui_preview_details_link.png b/docs/docs/assets/images/concepts/ui_preview_details_link.png
new file mode 100644
index 0000000000..8b375591c2
Binary files /dev/null and b/docs/docs/assets/images/concepts/ui_preview_details_link.png differ
diff --git a/docs/docs/assets/images/concepts/ui_preview_drawer.png b/docs/docs/assets/images/concepts/ui_preview_drawer.png
new file mode 100644
index 0000000000..17964acc3e
Binary files /dev/null and b/docs/docs/assets/images/concepts/ui_preview_drawer.png differ
diff --git a/docs/docs/concepts/data_import.md b/docs/docs/concepts/data_import.md
index ecee56daeb..eac5712c86 100644
--- a/docs/docs/concepts/data_import.md
+++ b/docs/docs/concepts/data_import.md
@@ -57,7 +57,7 @@ An import session can be initiated from a number of different contexts within th
Staff users can create an import session from within the [Admin Center](../settings/admin.md#admin-center). This is a general-purpose import session, and the user will be required to select the type of data to import.
-Users can quickly navigate to the data import management page from the [spotlight search](../concepts/user_interface.md#spotlight), by searching for "import" and selecting the "Import data" option.
+Users can quickly navigate to the data import management page from the [spotlight search](./ui/index.md#spotlight), by searching for "import" and selecting the "Import data" option.
### Data Tables
diff --git a/docs/docs/concepts/ui/forms.md b/docs/docs/concepts/ui/forms.md
new file mode 100644
index 0000000000..8c153eacce
--- /dev/null
+++ b/docs/docs/concepts/ui/forms.md
@@ -0,0 +1,37 @@
+---
+title: Forms
+---
+
+## Forms
+
+Data entry and editing within InvenTree is typically performed through the use of forms, which provide a structured interface for inputting and modifying data. Forms are designed to be user-friendly and efficient, allowing users to quickly enter and update information within the system.
+
+Forms are typically displayed as a modal dialog, separated into multiple sections and fields.
+
+### Data Creation
+
+Example: Creating a new part via the "Add Part" form:
+
+{{ image("concepts/ui_form_add_part.png", "Add Part Button") }}
+
+On several forms is displayed option "Keep form open" in bottom part of the form on left side of Submit button (option is visible on the screenshot above). When this switch is turned on, form window is not closed after submit and filled form data is not reset. This is useful for creating more entries at one time with similar properties (e.g. only different number in name).
+
+### Data Editing
+
+Example: Editing an existing purchase order via the "Edit Purchase Order" form:
+
+{{ image("concepts/ui_form_edit_po.png", "Edit Purchase Order") }}
+
+### Form Submission
+
+A form can be submitted by clicking the "Submit" button located at the bottom-right corner of the form.
+
+Alternatively, an open form can be submitted using the keyboard shortcut `Ctrl + Enter` (or `Cmd + Enter` on macOS). This shortcut works even while typing in a form field, providing a quick way to submit the form without needing to reach for the mouse. It is particularly useful in multi-line text fields, where pressing `Enter` inserts a new line rather than submitting the form.
+
+The keyboard shortcut is only active while a form is open, and follows the same rules as the "Submit" button - for example, it has no effect while the form is loading, or when editing an existing item without any changes.
+
+### Confirm Actions
+
+Many actions within InvenTree require user confirmation before they can be executed. This is typically implemented through the use of confirmation dialogs, which prompt the user to confirm their intention before proceeding with the action.
+
+{{ image("concepts/ui_form_hold_po.png", "Confirmation Dialog") }}
diff --git a/docs/docs/concepts/ui/global_search.md b/docs/docs/concepts/ui/global_search.md
new file mode 100644
index 0000000000..c6a81385ec
--- /dev/null
+++ b/docs/docs/concepts/ui/global_search.md
@@ -0,0 +1,31 @@
+---
+title: Global Search
+---
+
+## Global Search
+
+Accessible from the [main menu](./index.md#main-menu), the global search functionality allows users to quickly find specific items or information within the InvenTree system. The search icon is located at the top of the interface and provides a convenient way to search across all sections of the system.
+
+Clicking on the "search" icon (in the menu bar) opens the search menu, which allows users to enter search queries and view results from across the system.
+
+{{ image("concepts/ui_global_search.png", "Global Search") }}
+
+Search results are organized by category (e.g. Parts, Stock, Manufacturing, etc.) and provide quick access to the relevant pages for each search result.
+
+### Detail View
+
+To navigate to the detail page for a particular search result, simply click on the desired result from the search results list. This will take you directly to the relevant page within the InvenTree system, allowing you to view and interact with the specific item or information you were searching for.
+
+### Full Results
+
+The "global search" menu provides a limited set of search results for each category, typically showing the most relevant or recent results. To view the full set of search results for a particular category, click on the "View all results" button located at the top-left of the search results list for that category:
+
+{{ image("concepts/ui_global_search_view_all.png", "View Full Search Results") }}
+
+### Collapse Result Groups
+
+To collapse a particular category of search results in the global search menu, click on the "collapse" icon located at the top-right corner of the search results list for that category. This will hide the search results for that category, allowing you to focus on other categories or search results.
+
+### Remove Result Groups
+
+To remove a particular category of search results from the global search menu, click on the "remove" icon located at the top-right corner of the search results list for that category.
diff --git a/docs/docs/concepts/ui/index.md b/docs/docs/concepts/ui/index.md
new file mode 100644
index 0000000000..7410220a53
--- /dev/null
+++ b/docs/docs/concepts/ui/index.md
@@ -0,0 +1,182 @@
+---
+title: User Interface
+---
+
+## User Interface
+
+The InvenTree user interface is designed to be intuitive and user-friendly, providing easy access to the various features and functions of the system. The interface is organized into several key components, including navigation menus, settings, forms, tables, search functionality, and more.
+
+The interface is designed for large-format displays, and as such is explicitly *not* optimized for mobile devices. However, the interface is responsive and should work on a wide range of desktop screen sizes.
+
+## Navigation
+
+Navigation throughout the InvenTree interface is designed to be straightforward and efficient, allowing users to quickly access the various sections and features of the system. The navigation is organized into several key areas, including the main menu, navigation menu, and page panels.
+
+### Main Menu
+
+The main menu is located at the top of the interface and provides access to the primary sections of the system:
+
+{{ image("concepts/ui_main_menu.png", "Main Menu") }}
+
+From the main menu, users can access the following items:
+
+- [Navigation Menu](#navigation-menu)
+- [Dashboard](#dashboard)
+- [Global Search](./global_search.md)
+- [Spotlight](#spotlight)
+- [Barcode Scanning](#barcode-scanning)
+- [Notifications](#notifications)
+- [User Menu](#user-menu)
+
+As well as allowing navigation to the following main sections:
+
+- [Parts](../../part/index.md)
+- [Stock](../../stock/index.md)
+- [Manufacturing](../../manufacturing/index.md)
+- [Purchasing](../../purchasing/index.md)
+- [Sales](../../sales/index.md)
+
+### Navigation Menu
+
+The global navigation menu is located on the left-hand side of the interface and provides access to the various sections of the system.
+
+{{ image("concepts/ui_navigation_menu.png", "Navigation Menu") }}
+
+The navigation menu is organized into several key areas, including:
+
+- **Navigation:** Provides access to the main sections of the system, including Parts, Stock, Manufacturing, Purchasing, and Sales.
+- **Settings:** Quick access to user settings, system settings, and the admin center.
+- **Actions:** Provides quick access to commonly used actions
+- **Documentation:** Links to the online documentation.
+- **About:** InvenTree version and license information.
+
+### User Menu
+
+The user menu is located in the top-right corner of the interface and provides access to user-specific settings and actions.
+
+{{ image("concepts/ui_user_menu.png", "User Menu") }}
+
+The user menu provides access to the following items:
+
+- **User Settings:** Access to [user settings](../../settings/user.md).
+- **System Settings:** Access to [global settings](../../settings/global.md) settings. *Note: Access to system settings may be restricted based on user permissions.*
+- **Admin Center:** Access to the [admin center](../../settings/admin.md#admin-center) for operational administration
+- **Database Admin Interface:** Low level administration via the [Database Admin Interface](../../settings/db_admin.md). *Note: Access may be restricted based on user permissions.*
+- **Change Color Mode:** Toggle between light and dark color modes.
+- **About InvenTree:** View version and license information about InvenTree.
+- **Logout:** Log out of the InvenTree system.
+
+### Page Panels
+
+Most detail pages views within InvenTree are organized into panels, which provide a structured layout for displaying information and actions related to the current page.
+
+Panels are arranged in a vertical stack on the left side of the page, with the main content area on the right. Each panel contains related information and actions, allowing users to easily navigate and interact with the content.
+
+{{ image("concepts/ui_panels.png", "Page Panels") }}
+
+#### Collapse Panels
+
+The panel sidebar can be collapsed to provide more space for the main content area. To collapse or expand the panel sidebar, click the collapse icon located at the bottom of the sidebar. To expand the sidebar again, click the expand icon that appears when the sidebar is collapsed.
+
+### Breadcrumbs
+
+On some pages, a breadcrumb navigation trail is provided at the top of the page, just below the main menu. Breadcrumbs provide a visual representation of the user's current location within the system and allow for easy navigation back to previous pages.
+
+{{ image("concepts/ui_breadcrumbs.png", "Breadcrumb Navigation") }}
+
+### Navigation Tree
+
+On some pages, a navigation tree is provided on the left-hand side of the page, next to the breadcrumbs. The navigation tree provides a hierarchical view of the current section of the system, allowing users to quickly navigate to related pages and sections.
+
+Click on the navigation tree icon to expand the tree and view the available navigation options:
+
+{{ image("concepts/ui_navigation_tree.png", "Navigation Tree") }}
+
+#### Searching
+
+The navigation tree includes a search bar at the top of the panel. Typing into the search bar filters the tree to show only entries that match the search query. When a search is active, all matching results are expanded and displayed in a flat list. Clearing the search field returns the tree to its normal browsing mode.
+
+#### Highlight Selected Entry
+
+The currently selected entry in the navigation tree is highlighted with a distinct background color, making it easy to identify the active page or section within the hierarchy.
+
+#### Auto-Expand to Selected Entry
+
+When the navigation tree is opened, it automatically expands to reveal the currently selected entry. All ancestor nodes in the hierarchy are expanded so the active entry is immediately visible, without requiring manual navigation through the tree.
+
+## Dashboard
+
+The dashboard provides a customizable landing page for users when they log in to the system. The dashboard can be configured to display a variety of widgets and information panels, providing users with quick access to important data and actions.
+
+{{ image("concepts/ui_dashboard.png", "Dashboard") }}
+
+### Editing Layout
+
+To edit the layout (add, remove, or rearrange widgets) of the dashboard, open the dashboard context menu (located at the top-right corner of the dashboard) and view the available options:
+
+{{ image("concepts/ui_dashboard_edit.png", "Dashboard Context Menu") }}
+
+### Custom Widgets
+
+In addition to the set of built-in widgets provided by InvenTree, custom dashboard widgets can be implemented using [plugins](../../plugins/mixins/ui.md#dashboard-items). This allows users to create personalized dashboard experiences tailored to their specific needs and workflows.
+
+## Tables
+
+Information throughout the InvenTree interface is often presented in tabular format. Table views support a wide range of features, including pagination, sorting, filtering, and data export.
+
+Read more about working with table views on the dedicated [Tables](./tables.md) page.
+
+## Preview Panels
+
+Rather than navigating directly to an item's detail page, clicking on a table row can instead open a "preview" drawer, providing a quick summary of that item without leaving the current view.
+
+Read more about this optional feature on the dedicated [Preview Panels](./preview_panels.md) page.
+
+## Forms
+
+Data entry and editing within InvenTree is typically performed through the use of forms, which provide a structured interface for inputting and modifying data.
+
+Read more about working with forms on the dedicated [Forms](./forms.md) page.
+
+## Global Search
+
+Accessible from the [main menu](#main-menu), the global search functionality allows users to quickly find specific items or information within the InvenTree system.
+
+Read more about the global search feature on the dedicated [Global Search](./global_search.md) page.
+
+## Spotlight
+
+The user interface features a "spotlight" search functionality, which provides a quick and efficient way to access common actions or navigate to specific pages within the InvenTree system. The spotlight search is designed to enhance user productivity by allowing users to quickly find and execute actions without needing to navigate through menus or remember specific page locations.
+
+{{ image("concepts/ui_spotlight.png", "Spotlight Search") }}
+
+### Open Spotlight
+
+To open the "spotlight" search, click on the "spotlight" icon located in the main menu at the top of the interface. This will open the spotlight search menu, allowing you to enter search queries and view available actions.
+
+Alternatively, the spotlight search can be opened using the keyboard shortcut `Ctrl + K` (or `Cmd + K` on macOS), providing a quick and convenient way to access the spotlight functionality without needing to click on the menu icon.
+
+### Disable Spotlight
+
+Users may opt to disable the spotlight search functionality if they do not find it useful or prefer not to use it. To disable the spotlight search, navigate to your [user settings](../../settings/user.md) and locate the option to disable the spotlight feature. Once disabled, the spotlight search will no longer be accessible from the main menu or via keyboard shortcuts.
+
+## Copy Button
+
+Many fields within the InvenTree user interface include a "copy" button, which allows users to quickly copy the value of that field to their clipboard. This is particularly useful for fields that contain important identifiers, such as part numbers, stock item codes, or other relevant data that may need to be easily copied and pasted elsewhere.
+
+!!! important "Secure Context"
+ The "copy" button functionality relies on the browser's clipboard API, which may not be available in all contexts (e.g. if the user is accessing the InvenTree interface via a non-https connection, or through an embedded iframe or a non-standard browser). In such cases, the "copy" button may not function as intended.
+
+## User Permissions
+
+Many aspects of the user interface are controlled by user permissions, which determine what actions and features are available to each user based on their assigned roles and permissions within the system. This allows for a highly customizable user experience, where different users can have access to different features and functionality based on their specific needs and responsibilities within the organization.
+
+If a user does not have permission to access a particular feature or section of the system, that feature will be hidden from their view in the user interface. This helps to ensure that users only see the features and information that are relevant to their role, reducing clutter and improving usability.
+
+## Language Support
+
+The InvenTree user interface supports multiple languages, allowing users to interact with the system in their preferred language.
+
+The default system language can be configured by the system administrator in the [server configuration options](../../start/config.md#basic-options).
+
+Additionally, users can select their preferred language in their [user settings](../../settings/user.md), allowing them to override the system default language with their own choice. This provides a personalized experience for each user, ensuring that they can interact with the system in the language they are most comfortable with.
diff --git a/docs/docs/concepts/ui/preview_panels.md b/docs/docs/concepts/ui/preview_panels.md
new file mode 100644
index 0000000000..1f16485417
--- /dev/null
+++ b/docs/docs/concepts/ui/preview_panels.md
@@ -0,0 +1,37 @@
+---
+title: Preview Panels
+---
+
+## Preview Panels
+
+Many [table views](./tables.md) in InvenTree link each row to the detail page for the underlying item. By default, clicking on a row navigates directly to that detail page.
+
+If the preview panel feature is enabled, clicking on a row instead opens a "preview" drawer on the right-hand side of the screen. The preview drawer displays a summary of the selected item, without navigating away from the current table view.
+
+{{ image("concepts/ui_preview_drawer.png", "Preview Drawer") }}
+
+## Enabling the Preview Panel
+
+The preview panel is disabled by default. It can be enabled on a per-user basis via the **Table Preview Panel** option, found in the *Display Options* tab of the [user settings](../../settings/user.md) page.
+
+## Using the Preview Panel
+
+Once enabled, clicking on a row in a supported table opens the preview drawer for that item, rather than navigating to its detail page.
+
+### Viewing Full Details
+
+The preview drawer title includes an arrow icon, linking to the full detail page for the previewed item. Click on the title (or the arrow icon) to navigate to the detail page and close the drawer.
+
+{{ image("concepts/ui_preview_details_link.png", "View Details Link") }}
+
+### Following Links
+
+Any link within the preview drawer (for example, a link to a related part or category) can be clicked to navigate directly to that page. The preview drawer closes automatically when a link is followed.
+
+### Bypassing the Preview
+
+To navigate directly to an item's detail page without opening the preview drawer, hold `Ctrl` (or `Cmd` on macOS) while clicking the row, or middle-click the row to open the detail page in a new tab.
+
+### Closing the Preview
+
+The preview drawer can be closed by clicking the close button, clicking outside the drawer, or pressing `Escape`.
diff --git a/docs/docs/concepts/ui/tables.md b/docs/docs/concepts/ui/tables.md
new file mode 100644
index 0000000000..a1ba89e020
--- /dev/null
+++ b/docs/docs/concepts/ui/tables.md
@@ -0,0 +1,149 @@
+---
+title: Tables
+---
+
+## Table Views
+
+Information throughout the InvenTree interface is often presented in tabular format, allowing users to easily view and interact with large datasets. Tables are designed to be flexible and customizable, providing a range of features to enhance the user experience.
+
+{{ image("concepts/ui_table.png", "Table View") }}
+
+### Pagination
+
+The pagination controls are located at the bottom of the table, allowing users to navigate through large datasets by moving between pages. Users can also adjust the number of rows displayed per page using the pagination settings.
+
+### Row Selection
+
+For tables where data selection is supported, a checkbox is provided at the left-hand side of each row, allowing users to select one or more rows for further actions. A master checkbox is also provided in the table header, allowing users to quickly select or deselect all rows in the table.
+
+!!! info "Pagination and Row Selection"
+ When using the "master select" checkbox to select all rows, only the rows on the current page will be selected.
+
+{{ image("concepts/ui_table_row_selection.png", "Row Selection") }}
+
+### Table Actions
+
+A particular table view may have a set of actions associated with it, which are typically located at the top-left corner of the table. These actions may include options for adding new entries, or performing bulk actions on [selected rows](#row-selection).
+
+{{ image("concepts/ui_table_actions.png", "Table Actions") }}
+
+### Searching
+
+Some tables support searching, allowing users to quickly find specific entries within the dataset. The search bar is located at the top-right corner of the table view:
+
+{{ image("concepts/ui_table_search.png", "Table Search") }}
+
+### Column Selection
+
+Some tables allow the user to toggle the visibility of certain columns to, enabling a more customized view of the data.
+
+Column selection is accessed via the "Select Columns" menu, located to the top-right of the table view:
+
+{{ image("concepts/ui_table_column_selection.png", "Column Selection") }}
+
+### Filtering
+
+The dataset (which is fetched dynamically from the server via an API request) can be filtered by providing query parameters to the API endpoint.
+
+Select the "table filters" button to open the filter selection menu
+
+{{ image("concepts/ui_table_filter_button.png", "Table Filter Button") }}
+
+{{ image("concepts/ui_table_filter_menu.png", "Table Filter Menu") }}
+
+Table filters are saved across browser sessions, allowing users to maintain their preferred filter settings when returning to the particular table view.
+
+#### Column Filters
+
+Many table columns expose an inline filter icon directly in the column header, providing a quick way to filter by that column without opening the full filter drawer. Columns that support filtering display a small filter icon alongside the column title. The icon is highlighted when a filter for that column is currently active, giving an at-a-glance indication of which columns have active filters.
+
+Clicking the icon opens a compact popover anchored to the column header:
+
+{{ image("concepts/ui_table_column_filter_popover.png", "Column Filter Popover") }}
+
+**Single-filter columns** — for columns linked to one filter (e.g. *Active*, *Has IPN*, *Status*), selecting a value immediately applies the filter and the popover closes automatically.
+
+**Range columns** — for columns that represent a range concept (e.g. *Start Date*, *Target Date*, *Creation Date*), the popover stays open and presents multiple controls — for example *before* and *after* date pickers — so both bounds can be set in a single interaction.
+
+Once a filter is active, the popover shows a badge with the current value and a remove button (red ×) instead of the value picker. Clicking the × clears only that column's filter.
+
+!!! info "Column filters and the filter drawer share the same state"
+ Filters applied via a column popover appear immediately in the filter drawer's active-filter list, and filters added through the drawer are reflected in the column icons. Clearing all filters from the drawer also removes any filters set via column popovers.
+
+#### Saved Filter Groups
+
+Frequently used combinations of filters can be saved as a named *filter group*, allowing them to be quickly recalled later without having to re-add each filter individually.
+
+The **Saved Filter Groups** panel is displayed at the bottom of the filter drawer. When one or more filters are active, a **Save current filters** button is available. Clicking it opens an inline name input — enter a name and press Enter (or click the confirm icon) to save the group. Press Escape or click the cancel icon to discard.
+
+{{ image("concepts/ui_table_filter_group.png", "Filter Groups") }}
+
+Previously saved filter groups are listed in the panel. Each entry shows the group name alongside two actions:
+
+- **Load** (green reload icon): Replaces the current active filters with the filters stored in that group. The table immediately re-fetches data using the restored filters.
+- **Delete** (red × icon): Permanently removes the saved filter group.
+
+Saved filter groups are stored in the browser's local storage and are specific to each table or calendar view, so groups saved for one view are not available in another. They persist across local browser sessions until explicitly deleted. Filter groups are not shared to other devices.
+
+!!! info "Loading a filter group replaces active filters"
+ Loading a saved filter group replaces all currently active filters with those stored in the group. Any unsaved active filters will be overwritten.
+
+### Data Sorting
+
+Some table columns support data sorting, allowing the dataset to be sorted in ascending or descending order based on the values in that column. To sort a column, click on the column header. Clicking the column header again will toggle the sort order between ascending and descending. The current sort order is indicated by an arrow icon in the column header.
+
+{{ image("concepts/ui_table_sorting.png", "Data Sorting") }}
+
+### Data Export
+
+Some tables support downloading of the dataset in various formats (e.g. CSV, Excel, PDF). If data download is available for a given table, the "export data" button will be located at the top-right corner of the table view.
+
+This opens the "Export Data" form, which allows the user to select the desired file format for download, as well as any additional options related to the data export.
+
+{{ image("concepts/ui_table_download.png", "Data Download") }}
+
+### Row Actions
+
+In some tables, there may be specific actions associated with individual rows, allowing users to perform actions directly on a particular entry in the dataset. Row actions are typically accessed via an "actions" menu located at the right-hand side of each row.
+
+{{ image("concepts/ui_table_row_actions.png", "Row Actions") }}
+
+### Right-Click Context Menu
+
+For rows that support row actions, a right-click context menu is also available, providing quick access to the same set of actions without needing to click on the "actions" menu.
+
+{{ image("concepts/ui_table_context_menu.png", "Right-Click Context Menu") }}
+
+### Row Navigation
+
+For tables which reference other objects within the system, clicking on a row will navigate to the detail page for that particular entry. For example, clicking on a row in the "Part" table will navigate to the detail page for that specific part.
+
+If the [preview panel](./preview_panels.md) feature is enabled, clicking on a row instead opens a preview drawer for that entry, rather than navigating directly to its detail page.
+
+## Calendar Views
+
+Some [table views](#table-views) associated with various order types can be switched to a calendar view, which provides a visual representation of data based on date fields. The calendar view allows users to easily see and interact with data that is organized by date, such as scheduled tasks, events, or deadlines.
+
+To switch to the "calendar view" (for a table which supports it), click on the "calendar view" button located above and to the right of the table view:
+
+{{ image("concepts/ui_calendar_select.png", "Calendar View Button") }}
+
+This will display the data in a calendar format:
+
+{{ image("concepts/ui_calendar_view.png", "Calendar View") }}
+
+### Calendar Horizon
+
+The calendar view provides a configurable "horizon" setting, which allows users to adjust the number of months displayed in the calendar view.
+
+## Parametric Views
+
+Some [table views](#table-views) can be switched to a parametric view, which provides a visual representation of data based on specific parameters or attributes. The parametric view allows users to easily see and interact with data that is organized by certain characteristics, such as categories, types, or other relevant attributes.
+
+To switch to the "parametric view" (for a table which supports it), click on the "parametric view" button located above and to the right of the table view:
+
+{{ image("concepts/ui_parametric_select.png", "Parametric View Button") }}
+
+This will display the data in a parametric format:
+
+{{ image("concepts/ui_parametric_view.png", "Parametric View") }}
diff --git a/docs/docs/concepts/user_interface.md b/docs/docs/concepts/user_interface.md
deleted file mode 100644
index b919a8ea74..0000000000
--- a/docs/docs/concepts/user_interface.md
+++ /dev/null
@@ -1,364 +0,0 @@
----
-title: User Interface
----
-
-## User Interface
-
-The InvenTree user interface is designed to be intuitive and user-friendly, providing easy access to the various features and functions of the system. The interface is organized into several key components, including navigation menus, settings, forms, tables, search functionality, and more.
-
-The interface is designed for large-format displays, and as such is explicitly *not* optimized for mobile devices. However, the interface is responsive and should work on a wide range of desktop screen sizes.
-
-## Navigation
-
-Navigation throughout the InvenTree interface is designed to be straightforward and efficient, allowing users to quickly access the various sections and features of the system. The navigation is organized into several key areas, including the main menu, navigation menu, and page panels.
-
-### Main Menu
-
-The main menu is located at the top of the interface and provides access to the primary sections of the system:
-
-{{ image("concepts/ui_main_menu.png", "Main Menu") }}
-
-From the main menu, users can access the following items:
-
-- [Navigation Menu](#navigation-menu)
-- [Dashboard](#dashboard)
-- [Global Search](#search)
-- [Spotlight](#spotlight)
-- [Barcode Scanning](#barcode-scanning)
-- [Notifications](#notifications)
-- [User Menu](#user-menu)
-
-As well as allowing navigation to the following main sections:
-
-- [Parts](../part/index.md)
-- [Stock](../stock/index.md)
-- [Manufacturing](../manufacturing/index.md)
-- [Purchasing](../purchasing/index.md)
-- [Sales](../sales/index.md)
-
-### Navigation Menu
-
-The global navigation menu is located on the left-hand side of the interface and provides access to the various sections of the system.
-
-{{ image("concepts/ui_navigation_menu.png", "Navigation Menu") }}
-
-The navigation menu is organized into several key areas, including:
-
-- **Navigation:** Provides access to the main sections of the system, including Parts, Stock, Manufacturing, Purchasing, and Sales.
-- **Settings:** Quick access to user settings, system settings, and the admin interface.
-- **Actions:** Provides quick access to commonly used actions
-- **Documentation:** Links to the online documentation.
-- **About:** InvenTree version and license information.
-
-### User Menu
-
-The user menu is located in the top-right corner of the interface and provides access to user-specific settings and actions.
-
-{{ image("concepts/ui_user_menu.png", "User Menu") }}
-
-The user menu provides access to the following items:
-
-- **User Settings:** Access to [user settings](../settings/user.md).
-- **System Settings:** Access to [global settings](../settings/global.md) settings. *Note: Access to system settings may be restricted based on user permissions.*
-- **Admin Center:** Access to the [Admin Center](../settings/admin.md#admin-center) for operational administration.
-- **Database Admin Interface:** Low-level administration via the [Database Admin interface](../settings/db_admin.md). *Note: Access may be restricted based on user permissions and staff status.*
-- **Change Color Mode:** Toggle between light and dark color modes.
-- **About InvenTree:** View version and license information about InvenTree.
-- **Logout:** Log out of the InvenTree system.
-
-### Page Panels
-
-Most detail pages views within InvenTree are organized into panels, which provide a structured layout for displaying information and actions related to the current page.
-
-Panels are arranged in a vertical stack on the left side of the page, with the main content area on the right. Each panel contains related information and actions, allowing users to easily navigate and interact with the content.
-
-{{ image("concepts/ui_panels.png", "Page Panels") }}
-
-#### Collapse Panels
-
-The panel sidebar can be collapsed to provide more space for the main content area. To collapse or expand the panel sidebar, click the collapse icon located at the bottom of the sidebar. To expand the sidebar again, click the expand icon that appears when the sidebar is collapsed.
-
-### Breadcrumbs
-
-On some pages, a breadcrumb navigation trail is provided at the top of the page, just below the main menu. Breadcrumbs provide a visual representation of the user's current location within the system and allow for easy navigation back to previous pages.
-
-{{ image("concepts/ui_breadcrumbs.png", "Breadcrumb Navigation") }}
-
-### Navigation Tree
-
-On some pages, a navigation tree is provided on the left-hand side of the page, next to the breadcrumbs. The navigation tree provides a hierarchical view of the current section of the system, allowing users to quickly navigate to related pages and sections.
-
-Click on the navigation tree icon to expand the tree and view the available navigation options:
-
-{{ image("concepts/ui_navigation_tree.png", "Navigation Tree") }}
-
-#### Searching
-
-The navigation tree includes a search bar at the top of the panel. Typing into the search bar filters the tree to show only entries that match the search query. When a search is active, all matching results are expanded and displayed in a flat list. Clearing the search field returns the tree to its normal browsing mode.
-
-#### Highlight Selected Entry
-
-The currently selected entry in the navigation tree is highlighted with a distinct background color, making it easy to identify the active page or section within the hierarchy.
-
-#### Auto-Expand to Selected Entry
-
-When the navigation tree is opened, it automatically expands to reveal the currently selected entry. All ancestor nodes in the hierarchy are expanded so the active entry is immediately visible, without requiring manual navigation through the tree.
-
-## Dashboard
-
-The dashboard provides a customizable landing page for users when they log in to the system. The dashboard can be configured to display a variety of widgets and information panels, providing users with quick access to important data and actions.
-
-{{ image("concepts/ui_dashboard.png", "Dashboard") }}
-
-### Editing Layout
-
-To edit the layout (add, remove, or rearrange widgets) of the dashboard, open the dashboard context menu (located at the top-right corner of the dashboard) and view the available options:
-
-{{ image("concepts/ui_dashboard_edit.png", "Dashboard Context Menu") }}
-
-### Custom Widgets
-
-In addition to the set of built-in widgets provided by InvenTree, custom dashboard widgets can be implemented using [plugins](../plugins/mixins/ui.md#dashboard-items). This allows users to create personalized dashboard experiences tailored to their specific needs and workflows.
-
-## Table Views
-
-Information throughout the InvenTree interface is often presented in tabular format, allowing users to easily view and interact with large datasets. Tables are designed to be flexible and customizable, providing a range of features to enhance the user experience.
-
-{{ image("concepts/ui_table.png", "Table View") }}
-
-### Pagination
-
-The pagination controls are located at the bottom of the table, allowing users to navigate through large datasets by moving between pages. Users can also adjust the number of rows displayed per page using the pagination settings.
-
-### Row Selection
-
-For tables where data selection is supported, a checkbox is provided at the left-hand side of each row, allowing users to select one or more rows for further actions. A master checkbox is also provided in the table header, allowing users to quickly select or deselect all rows in the table.
-
-!!! info "Pagination and Row Selection"
- When using the "master select" checkbox to select all rows, only the rows on the current page will be selected.
-
-{{ image("concepts/ui_table_row_selection.png", "Row Selection") }}
-
-### Table Actions
-
-A particular table view may have a set of actions associated with it, which are typically located at the top-left corner of the table. These actions may include options for adding new entries, or performing bulk actions on [selected rows](#row-selection).
-
-{{ image("concepts/ui_table_actions.png", "Table Actions") }}
-
-### Searching
-
-Some tables support searching, allowing users to quickly find specific entries within the dataset. The search bar is located at the top-right corner of the table view:
-
-{{ image("concepts/ui_table_search.png", "Table Search") }}
-
-### Column Selection
-
-Some tables allow the user to toggle the visibility of certain columns to, enabling a more customized view of the data.
-
-Column selection is accessed via the "Select Columns" menu, located to the top-right of the table view:
-
-{{ image("concepts/ui_table_column_selection.png", "Column Selection") }}
-
-### Filtering
-
-The dataset (which is fetched dynamically from the server via an API request) can be filtered by providing query parameters to the API endpoint.
-
-Select the "table filters" button to open the filter selection menu
-
-{{ image("concepts/ui_table_filter_button.png", "Table Filter Button") }}
-
-{{ image("concepts/ui_table_filter_menu.png", "Table Filter Menu") }}
-
-Table filters are saved across browser sessions, allowing users to maintain their preferred filter settings when returning to the particular table view.
-
-#### Column Filters
-
-Many table columns expose an inline filter icon directly in the column header, providing a quick way to filter by that column without opening the full filter drawer. Columns that support filtering display a small filter icon alongside the column title. The icon is highlighted when a filter for that column is currently active, giving an at-a-glance indication of which columns have active filters.
-
-Clicking the icon opens a compact popover anchored to the column header:
-
-{{ image("concepts/ui_table_column_filter_popover.png", "Column Filter Popover") }}
-
-**Single-filter columns** — for columns linked to one filter (e.g. *Active*, *Has IPN*, *Status*), selecting a value immediately applies the filter and the popover closes automatically.
-
-**Range columns** — for columns that represent a range concept (e.g. *Start Date*, *Target Date*, *Creation Date*), the popover stays open and presents multiple controls — for example *before* and *after* date pickers — so both bounds can be set in a single interaction.
-
-Once a filter is active, the popover shows a badge with the current value and a remove button (red ×) instead of the value picker. Clicking the × clears only that column's filter.
-
-!!! info "Column filters and the filter drawer share the same state"
- Filters applied via a column popover appear immediately in the filter drawer's active-filter list, and filters added through the drawer are reflected in the column icons. Clearing all filters from the drawer also removes any filters set via column popovers.
-
-#### Saved Filter Groups
-
-Frequently used combinations of filters can be saved as a named *filter group*, allowing them to be quickly recalled later without having to re-add each filter individually.
-
-The **Saved Filter Groups** panel is displayed at the bottom of the filter drawer. When one or more filters are active, a **Save current filters** button is available. Clicking it opens an inline name input — enter a name and press Enter (or click the confirm icon) to save the group. Press Escape or click the cancel icon to discard.
-
-{{ image("concepts/ui_table_filter_group.png", "Filter Groups") }}
-
-Previously saved filter groups are listed in the panel. Each entry shows the group name alongside two actions:
-
-- **Load** (green reload icon): Replaces the current active filters with the filters stored in that group. The table immediately re-fetches data using the restored filters.
-- **Delete** (red × icon): Permanently removes the saved filter group.
-
-Saved filter groups are stored in the browser's local storage and are specific to each table or calendar view, so groups saved for one view are not available in another. They persist across local browser sessions until explicitly deleted. Filter groups are not shared to other devices.
-
-!!! info "Loading a filter group replaces active filters"
- Loading a saved filter group replaces all currently active filters with those stored in the group. Any unsaved active filters will be overwritten.
-
-### Data Sorting
-
-Some table columns support data sorting, allowing the dataset to be sorted in ascending or descending order based on the values in that column. To sort a column, click on the column header. Clicking the column header again will toggle the sort order between ascending and descending. The current sort order is indicated by an arrow icon in the column header.
-
-{{ image("concepts/ui_table_sorting.png", "Data Sorting") }}
-
-### Data Export
-
-Some tables support downloading of the dataset in various formats (e.g. CSV, Excel, PDF). If data download is available for a given table, the "export data" button will be located at the top-right corner of the table view.
-
-This opens the "Export Data" form, which allows the user to select the desired file format for download, as well as any additional options related to the data export.
-
-{{ image("concepts/ui_table_download.png", "Data Download") }}
-
-### Row Actions
-
-In some tables, there may be specific actions associated with individual rows, allowing users to perform actions directly on a particular entry in the dataset. Row actions are typically accessed via an "actions" menu located at the right-hand side of each row.
-
-{{ image("concepts/ui_table_row_actions.png", "Row Actions") }}
-
-### Right-Click Context Menu
-
-For rows that support row actions, a right-click context menu is also available, providing quick access to the same set of actions without needing to click on the "actions" menu.
-
-{{ image("concepts/ui_table_context_menu.png", "Right-Click Context Menu") }}
-
-### Row Navigation
-
-For tables which reference other objects within the system, clicking on a row will navigate to the detail page for that particular entry. For example, clicking on a row in the "Part" table will navigate to the detail page for that specific part.
-
-## Calendar Views
-
-Some [table views](#table-views) associated with various order types can be switched to a calendar view, which provides a visual representation of data based on date fields. The calendar view allows users to easily see and interact with data that is organized by date, such as scheduled tasks, events, or deadlines.
-
-To switch to the "calendar view" (for a table which supports it), click on the "calendar view" button located above and to the right of the table view:
-
-{{ image("concepts/ui_calendar_select.png", "Calendar View Button") }}
-
-This will display the data in a calendar format:
-
-{{ image("concepts/ui_calendar_view.png", "Calendar View") }}
-
-### Calendar Horizon
-
-The calendar view provides a configurable "horizon" setting, which allows users to adjust the number of months displayed in the calendar view.
-
-## Parametric Views
-
-Some [table views](#table-views) can be switched to a parametric view, which provides a visual representation of data based on specific parameters or attributes. The parametric view allows users to easily see and interact with data that is organized by certain characteristics, such as categories, types, or other relevant attributes.
-
-To switch to the "parametric view" (for a table which supports it), click on the "parametric view" button located above and to the right of the table view:
-
-{{ image("concepts/ui_parametric_select.png", "Parametric View Button") }}
-
-This will display the data in a parametric format:
-
-{{ image("concepts/ui_parametric_view.png", "Parametric View") }}
-
-## Forms
-
-Data entry and editing within InvenTree is typically performed through the use of forms, which provide a structured interface for inputting and modifying data. Forms are designed to be user-friendly and efficient, allowing users to quickly enter and update information within the system.
-
-Forms are typically displayed as a modal dialog, separated into multiple sections and fields.
-
-### Data Creation
-
-Example: Creating a new part via the "Add Part" form:
-
-{{ image("concepts/ui_form_add_part.png", "Add Part Button") }}
-
-On several forms is displayed option "Keep form open" in bottom part of the form on left side of Submit button (option is visible on the screenshot above). When this switch is turned on, form window is not closed after submit and filled form data is not reset. This is useful for creating more entries at one time with similar properties (e.g. only different number in name).
-
-### Data Editing
-
-Example: Editing an existing purchase order via the "Edit Purchase Order" form:
-
-{{ image("concepts/ui_form_edit_po.png", "Edit Purchase Order") }}
-
-### Form Submission
-
-A form can be submitted by clicking the "Submit" button located at the bottom-right corner of the form.
-
-Alternatively, an open form can be submitted using the keyboard shortcut `Ctrl + Enter` (or `Cmd + Enter` on macOS). This shortcut works even while typing in a form field, providing a quick way to submit the form without needing to reach for the mouse. It is particularly useful in multi-line text fields, where pressing `Enter` inserts a new line rather than submitting the form.
-
-The keyboard shortcut is only active while a form is open, and follows the same rules as the "Submit" button - for example, it has no effect while the form is loading, or when editing an existing item without any changes.
-
-### Confirm Actions
-
-Many actions within InvenTree require user confirmation before they can be executed. This is typically implemented through the use of confirmation dialogs, which prompt the user to confirm their intention before proceeding with the action.
-
-{{ image("concepts/ui_form_hold_po.png", "Confirmation Dialog") }}
-
-## Global Search
-
-Accessible from the [main menu](#main-menu), the global search functionality allows users to quickly find specific items or information within the InvenTree system. The search icon is located at the top of the interface and provides a convenient way to search across all sections of the system.
-
-Clicking on the "search" icon (in the menu bar) opens the search menu, which allows users to enter search queries and view results from across the system.
-
-{{ image("concepts/ui_global_search.png", "Global Search") }}
-
-Search results are organized by category (e.g. Parts, Stock, Manufacturing, etc.) and provide quick access to the relevant pages for each search result.
-
-### Detail View
-
-To navigate to the detail page for a particular search result, simply click on the desired result from the search results list. This will take you directly to the relevant page within the InvenTree system, allowing you to view and interact with the specific item or information you were searching for.
-
-### Full Results
-
-The "global search" menu provides a limited set of search results for each category, typically showing the most relevant or recent results. To view the full set of search results for a particular category, click on the "View all results" button located at the top-left of the search results list for that category:
-
-{{ image("concepts/ui_global_search_view_all.png", "View Full Search Results") }}
-
-### Collapse Result Groups
-
-To collapse a particular category of search results in the global search menu, click on the "collapse" icon located at the top-right corner of the search results list for that category. This will hide the search results for that category, allowing you to focus on other categories or search results.
-
-### Remove Result Groups
-
-To remove a particular category of search results from the global search menu, click on the "remove" icon located at the top-right corner of the search results list for that category.
-
-## Spotlight
-
-The user interface features a "spotlight" search functionality, which provides a quick and efficient way to access common actions or navigate to specific pages within the InvenTree system. The spotlight search is designed to enhance user productivity by allowing users to quickly find and execute actions without needing to navigate through menus or remember specific page locations.
-
-{{ image("concepts/ui_spotlight.png", "Spotlight Search") }}
-
-### Open Spotlight
-
-To open the "spotlight" search, click on the "spotlight" icon located in the main menu at the top of the interface. This will open the spotlight search menu, allowing you to enter search queries and view available actions.
-
-Alternatively, the spotlight search can be opened using the keyboard shortcut `Ctrl + K` (or `Cmd + K` on macOS), providing a quick and convenient way to access the spotlight functionality without needing to click on the menu icon.
-
-### Disable Spotlight
-
-Users may opt to disable the spotlight search functionality if they do not find it useful or prefer not to use it. To disable the spotlight search, navigate to your [user settings](../settings/user.md) and locate the option to disable the spotlight feature. Once disabled, the spotlight search will no longer be accessible from the main menu or via keyboard shortcuts.
-
-## Copy Button
-
-Many fields within the InvenTree user interface include a "copy" button, which allows users to quickly copy the value of that field to their clipboard. This is particularly useful for fields that contain important identifiers, such as part numbers, stock item codes, or other relevant data that may need to be easily copied and pasted elsewhere.
-
-!!! important "Secure Context"
- The "copy" button functionality relies on the browser's clipboard API, which may not be available in all contexts (e.g. if the user is accessing the InvenTree interface via a non-https connection, or through an embedded iframe or a non-standard browser). In such cases, the "copy" button may not function as intended.
-
-## User Permissions
-
-Many aspects of the user interface are controlled by user permissions, which determine what actions and features are available to each user based on their assigned roles and permissions within the system. This allows for a highly customizable user experience, where different users can have access to different features and functionality based on their specific needs and responsibilities within the organization.
-
-If a user does not have permission to access a particular feature or section of the system, that feature will be hidden from their view in the user interface. This helps to ensure that users only see the features and information that are relevant to their role, reducing clutter and improving usability.
-
-## Language Support
-
-The InvenTree user interface supports multiple languages, allowing users to interact with the system in their preferred language.
-
-The default system language can be configured by the system administrator in the [server configuration options](../start/config.md#basic-options).
-
-Additionally, users can select their preferred language in their [user settings](../settings/user.md), allowing them to override the system default language with their own choice. This provides a personalized experience for each user, ensuring that they can interact with the system in the language they are most comfortable with.
diff --git a/docs/docs/settings/user.md b/docs/docs/settings/user.md
index bc6919c780..b95abcb10a 100644
--- a/docs/docs/settings/user.md
+++ b/docs/docs/settings/user.md
@@ -25,6 +25,7 @@ The *Display Settings* screen shows general display configuration options:
{{ usersetting("BARCODE_IN_FORM_FIELDS") }}
{{ usersetting("DATE_DISPLAY_FORMAT") }}
{{ usersetting("FORMS_CLOSE_USING_ESCAPE") }}
+{{ usersetting("ENABLE_PREVIEW_PANEL") }}
{{ usersetting("DISPLAY_STOCKTAKE_TAB") }}
{{ usersetting("SHOW_FULL_CATEGORY_IN_TABLES")}}
{{ usersetting("SHOW_BOM_SUBASSEMBLY_LEVELS")}}
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
index 610a8b6a98..0eed940e1a 100644
--- a/docs/mkdocs.yml
+++ b/docs/mkdocs.yml
@@ -91,7 +91,12 @@ nav:
- Privacy: privacy.md
- Concepts:
- Terminology: concepts/terminology.md
- - User Interface: concepts/user_interface.md
+ - User Interface:
+ - Overview: concepts/ui/index.md
+ - Tables: concepts/ui/tables.md
+ - Preview Panels: concepts/ui/preview_panels.md
+ - Forms: concepts/ui/forms.md
+ - Global Search: concepts/ui/global_search.md
- Threat Model: concepts/threat_model.md
- Physical Units: concepts/units.md
- Companies: concepts/company.md
diff --git a/src/backend/InvenTree/common/setting/user.py b/src/backend/InvenTree/common/setting/user.py
index f5a2cd3f38..7d7891854d 100644
--- a/src/backend/InvenTree/common/setting/user.py
+++ b/src/backend/InvenTree/common/setting/user.py
@@ -223,6 +223,12 @@ USER_SETTINGS: dict[str, InvenTreeSettingsKeyType] = {
('MMM DD YYYY', 'Feb 22 2022'),
],
},
+ 'ENABLE_PREVIEW_PANEL': {
+ 'name': _('Table Preview Panel'),
+ 'description': _('Display a preview panel when selecting items in tables'),
+ 'default': False,
+ 'validator': bool,
+ },
'DISPLAY_STOCKTAKE_TAB': {
'name': _('Show Stock History'),
'description': _('Display stock history information in the part detail page'),
diff --git a/src/frontend/lib/components/RowActions.tsx b/src/frontend/lib/components/RowActions.tsx
index ff2ad44c40..89d57d3109 100644
--- a/src/frontend/lib/components/RowActions.tsx
+++ b/src/frontend/lib/components/RowActions.tsx
@@ -10,7 +10,7 @@ import {
} from '@tabler/icons-react';
import { type ReactNode, useMemo, useState } from 'react';
import { cancelEvent } from '../functions/Events';
-import { getDetailUrl } from '../functions/Navigation';
+import { eventModified, getDetailUrl } from '../functions/Navigation';
import { navigateToLink } from '../functions/Navigation';
import type { RowAction, RowViewProps } from '../types/Tables';
@@ -23,8 +23,18 @@ export function RowViewAction(props: RowViewProps): RowAction {
color: undefined,
icon: ,
onClick: (event: any) => {
- const url = getDetailUrl(props.modelType, props.modelId);
- navigateToLink(url, props.navigate, event);
+ const showPreviewPanel = props.isPreviewEnabled?.() ?? false;
+
+ if (
+ !showPreviewPanel ||
+ eventModified(event as any) ||
+ !props.openPreview
+ ) {
+ const url = getDetailUrl(props.modelType, props.modelId);
+ navigateToLink(url, props.navigate, event);
+ } else {
+ props.openPreview(props.modelType, props.modelId);
+ }
}
};
}
diff --git a/src/frontend/lib/enums/ModelInformation.tsx b/src/frontend/lib/enums/ModelInformation.tsx
index 5989e0acf9..39d597202b 100644
--- a/src/frontend/lib/enums/ModelInformation.tsx
+++ b/src/frontend/lib/enums/ModelInformation.tsx
@@ -1,5 +1,6 @@
import { t } from '@lingui/core/macro';
import type { InvenTreeIconType } from '../types/Icons';
+import type { InstanceRenderInterface } from '../types/Rendering';
import { ApiEndpoints } from './ApiEndpoints';
import type { ModelType } from './ModelType';
@@ -13,6 +14,9 @@ export interface ModelInformationInterface {
pk_field?: string;
supports_barcode?: boolean;
icon: keyof InvenTreeIconType;
+ preview?: (props: { instance: any; modelId: number }) => any;
+ render?: (props: Readonly) => any;
+ default_query_params?: Record;
}
export interface TranslatableModelInformationInterface
@@ -25,6 +29,33 @@ export type ModelDict = {
[key in keyof typeof ModelType]: TranslatableModelInformationInterface;
};
+type ModelPreviewKey = keyof typeof ModelType;
+type ModelPreviewProps = { instance: any; modelId: number };
+type ModelPreview = (props: ModelPreviewProps) => any;
+type ModelRender = (props: Readonly) => any;
+
+export function registerModelPreviews(
+ previews: Partial>
+) {
+ (Object.keys(previews) as ModelPreviewKey[]).forEach((model) => {
+ const preview = previews[model];
+ if (preview) {
+ ModelInformationDict[model].preview = preview;
+ }
+ });
+}
+
+export function registerModelRenderers(
+ renderers: Partial>
+) {
+ (Object.keys(renderers) as ModelPreviewKey[]).forEach((model) => {
+ const renderer = renderers[model];
+ if (renderer) {
+ ModelInformationDict[model].render = renderer;
+ }
+ });
+}
+
export const ModelInformationDict: ModelDict = {
part: {
label: () => t`Part`,
@@ -64,7 +95,12 @@ export const ModelInformationDict: ModelDict = {
api_endpoint: ApiEndpoints.supplier_part_list,
admin_url: '/company/supplierpart/',
supports_barcode: true,
- icon: 'supplier_part'
+ icon: 'supplier_part',
+ default_query_params: {
+ part_detail: true,
+ supplier_detail: true,
+ manufacturer_detail: true
+ }
},
manufacturerpart: {
label: () => t`Manufacturer Part`,
@@ -74,7 +110,8 @@ export const ModelInformationDict: ModelDict = {
api_endpoint: ApiEndpoints.manufacturer_part_list,
admin_url: '/company/manufacturerpart/',
supports_barcode: true,
- icon: 'manufacturers'
+ icon: 'manufacturers',
+ default_query_params: { part_detail: true, manufacturer_detail: true }
},
partcategory: {
label: () => t`Part Category`,
@@ -93,7 +130,8 @@ export const ModelInformationDict: ModelDict = {
api_endpoint: ApiEndpoints.stock_item_list,
admin_url: '/stock/stockitem/',
supports_barcode: true,
- icon: 'stock'
+ icon: 'stock',
+ default_query_params: { part_detail: true }
},
stocklocation: {
label: () => t`Stock Location`,
@@ -125,7 +163,8 @@ export const ModelInformationDict: ModelDict = {
api_endpoint: ApiEndpoints.build_order_list,
admin_url: '/build/build/',
supports_barcode: true,
- icon: 'build_order'
+ icon: 'build_order',
+ default_query_params: { part_detail: true }
},
buildline: {
label: () => t`Build Line`,
@@ -164,7 +203,8 @@ export const ModelInformationDict: ModelDict = {
api_endpoint: ApiEndpoints.purchase_order_list,
admin_url: '/order/purchaseorder/',
supports_barcode: true,
- icon: 'purchase_orders'
+ icon: 'purchase_orders',
+ default_query_params: { supplier_detail: true }
},
purchaseorderlineitem: {
label: () => t`Purchase Order Line`,
@@ -180,7 +220,8 @@ export const ModelInformationDict: ModelDict = {
api_endpoint: ApiEndpoints.sales_order_list,
admin_url: '/order/salesorder/',
supports_barcode: true,
- icon: 'sales_orders'
+ icon: 'sales_orders',
+ default_query_params: { customer_detail: true }
},
salesordershipment: {
label: () => t`Sales Order Shipment`,
@@ -190,7 +231,8 @@ export const ModelInformationDict: ModelDict = {
admin_url: '/order/salesordershipment/',
api_endpoint: ApiEndpoints.sales_order_shipment_list,
supports_barcode: true,
- icon: 'shipment'
+ icon: 'shipment',
+ default_query_params: { order_detail: true }
},
returnorder: {
label: () => t`Return Order`,
@@ -200,7 +242,8 @@ export const ModelInformationDict: ModelDict = {
api_endpoint: ApiEndpoints.return_order_list,
admin_url: '/order/returnorder/',
supports_barcode: true,
- icon: 'return_orders'
+ icon: 'return_orders',
+ default_query_params: { customer_detail: true }
},
returnorderlineitem: {
label: () => t`Return Order Line Item`,
diff --git a/src/frontend/lib/types/Plugins.tsx b/src/frontend/lib/types/Plugins.tsx
index 2038b1f297..d142500ae5 100644
--- a/src/frontend/lib/types/Plugins.tsx
+++ b/src/frontend/lib/types/Plugins.tsx
@@ -69,6 +69,17 @@ export type ImporterDrawerContext = {
sessionId: () => number | null;
};
+export type PreviewDrawerContext = {
+ open: (
+ modelType: ModelType,
+ id?: number,
+ instance?: any,
+ onClose?: () => void
+ ) => void;
+ close: () => void;
+ isOpen: () => boolean;
+};
+
/**
* A set of properties which are passed to a plugin,
* for rendering an element in the user interface.
@@ -90,6 +101,7 @@ export type ImporterDrawerContext = {
* @param forms - A set of functions for opening various API forms (see ../components/Forms.tsx)
* @param tables - A set of functions for rendering API tables
* @param importer - A set of functions for controlling the global importer drawer (see ../components/importer/GlobalImporterDrawer.tsx)
+ * @param preview - A set of functions for controlling the global preview drawer (see ../components/previews/GlobalPreviewDrawer.tsx)
* @param model - The model type associated with the rendered component (if applicable)
* @param id - The ID (primary key) of the model instance for the plugin (if applicable)
* @param instance - The model instance data (if available)
@@ -125,6 +137,7 @@ export type InvenTreePluginContext = {
};
tables: InvenTreeTablesContext;
importer: ImporterDrawerContext;
+ preview: PreviewDrawerContext;
model?: ModelType | string;
id?: string | number | null;
instance?: any;
diff --git a/src/frontend/lib/types/Preview.tsx b/src/frontend/lib/types/Preview.tsx
new file mode 100644
index 0000000000..963598afe3
--- /dev/null
+++ b/src/frontend/lib/types/Preview.tsx
@@ -0,0 +1,12 @@
+import type { ReactNode } from 'react';
+
+export interface PreviewType {
+ preview: ReactNode;
+ title: string;
+}
+
+export type PreviewComponentProps = {
+ instance: any;
+};
+
+export type PreviewComponent = (props: PreviewComponentProps) => PreviewType;
diff --git a/src/frontend/lib/types/Tables.tsx b/src/frontend/lib/types/Tables.tsx
index b3b4e9f0b4..44bb08cda2 100644
--- a/src/frontend/lib/types/Tables.tsx
+++ b/src/frontend/lib/types/Tables.tsx
@@ -154,7 +154,12 @@ type RowModelProps = {
navigate: NavigateFunction;
};
-export type RowViewProps = RowAction & RowModelProps;
+type RowViewBehaviorProps = {
+ isPreviewEnabled?: () => boolean;
+ openPreview?: (modelType: ModelType, modelId: number) => void;
+};
+
+export type RowViewProps = RowAction & RowModelProps & RowViewBehaviorProps;
/**
* Set of optional properties which can be passed to an InvenTreeTable component
diff --git a/src/frontend/src/components/calendar/OrderCalendar.tsx b/src/frontend/src/components/calendar/OrderCalendar.tsx
index 365d3d5ceb..247f3fe53a 100644
--- a/src/frontend/src/components/calendar/OrderCalendar.tsx
+++ b/src/frontend/src/components/calendar/OrderCalendar.tsx
@@ -7,7 +7,11 @@ import { ModelInformationDict } from '@lib/enums/ModelInformation';
import type { ModelType } from '@lib/enums/ModelType';
import type { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
-import { getDetailUrl, navigateToLink } from '@lib/functions/Navigation';
+import {
+ eventModified,
+ getDetailUrl,
+ navigateToLink
+} from '@lib/functions/Navigation';
import type { TableFilter } from '@lib/types/Filters';
import { t } from '@lingui/core/macro';
import { ActionIcon, Group, Text } from '@mantine/core';
@@ -22,6 +26,8 @@ import { useCallback, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { api } from '../../App';
import useCalendar from '../../hooks/UseCalendar';
+import { openGlobalPreview } from '../../states/PreviewDrawerState';
+import { useUserSettingsState } from '../../states/SettingsStates';
import { useUserState } from '../../states/UserState';
import { StatusRenderer, getStatusColor } from '../render/StatusRenderer';
import {
@@ -59,6 +65,9 @@ export default function OrderCalendar({
}) {
const navigate = useNavigate();
const user = useUserState();
+ const previewPanelEnabled = useUserSettingsState((state) =>
+ state.isSet('ENABLE_PREVIEW_PANEL')
+ );
// These filters apply to all order types
const orderFilters: TableFilter[] = useMemo(() => {
@@ -166,14 +175,16 @@ export default function OrderCalendar({
}
};
- // Callback when PurchaseOrder is clicked
+ // Callback when an order is clicked - open preview drawer, or navigate on modifier click
const onClickOrder = (info: EventClickArg) => {
- if (!!info.event.id) {
- navigateToLink(
- getDetailUrl(model, info.event.id),
- navigate,
- info.jsEvent
- );
+ if (!info.event.id) return;
+
+ const detailUrl = getDetailUrl(model, info.event.id);
+
+ if (eventModified(info.jsEvent as any) || !previewPanelEnabled) {
+ navigateToLink(detailUrl, navigate, info.jsEvent);
+ } else {
+ openGlobalPreview(model, Number.parseInt(info.event.id));
}
};
diff --git a/src/frontend/src/components/details/Details.tsx b/src/frontend/src/components/details/Details.tsx
index d221ea543d..5bc219285a 100644
--- a/src/frontend/src/components/details/Details.tsx
+++ b/src/frontend/src/components/details/Details.tsx
@@ -280,7 +280,7 @@ function NumberValue(props: Readonly) {
const value = props?.field_value;
// Convert to double
- const numberValue = Number.parseFloat(value.toString());
+ const numberValue = Number.parseFloat(value?.toString() ?? '');
if (value === null || value === undefined) {
return '---';
@@ -465,10 +465,12 @@ function CopyField({ value }: Readonly<{ value: string }>) {
export function DetailsTableField({
item,
- field
+ field,
+ showIcons = true
}: Readonly<{
item: any;
field: DetailsField;
+ showIcons?: boolean;
}>) {
function getFieldType(type: string) {
switch (type) {
@@ -502,10 +504,12 @@ export function DetailsTableField({
-
- {field.label}
+ {showIcons && (
+
+ )}
+ {field.label}) {
+ showIcons?: boolean;
+}
+
+export function DetailsTable({
+ item,
+ fields,
+ title,
+ showIcons = true
+}: Readonly) {
const visibleFields = useMemo(() => {
return fields.filter((field) => !field.hidden);
}, [fields]);
@@ -552,8 +560,13 @@ export function DetailsTable({
{title && {title}}