2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-13 10:35:40 +00:00

PUI Plugin Panels (#7470)

* Adds basic API endpoint for requesting plugin panels

* Split PanelType out into own file

* Placeholder for a plugin panel loaded dynamically

* Add some dummy data for the plugin panels

* Example of plugin panel selection based on page

* Expose some global window attributes

* Add new setting

* Disable panel return if plugin integration is not enabled

* Update hook to auto-magically load plugin panels

* Allow custom panel integration for more panel  groups

* Remove debug call

* Tweak query return data

* async fn

* Adds <PluginPanel> component for handling panel render

* Cleanup

* Prevent API requests before instance ID is known

* Pass instance data through

* Framework for a sample plugin which implements custom panels

* offload custom panels to sample plugin

* Load raw HTML content

* Expand custom panel rendering demo

* Adjust API endpoints

* Add function to clear out static files which do not match installed plugin(s)

* Update static files when installing plugins from file

* Update static files when installing or uninstalling a plugin

* Update static files on config change

* Pass more information through to plugin panels

* Prepend hostname to plugin source

* Pass instance detail through

* Cleanup code for passing data through to plugin panels

- Define interface type
- Shorten variable names

* Update docs requirements

* Revert "Update docs requirements"

This reverts commit 63a06d97f5.

* Add placeholder for documentation

* Fix imports

* Add a broken panel which tries to load a non-existent javascript file

* Render error message if plugin does not load correctly

* Only allow superuser to perform plugin actions

* Code cleanup

* Add "dynamic" contnt - javascript file - to example plugin

* Remove default values

* Cleanup unused code

* PanelGroup updates

* Cleanup hooks for changing panel state

* More work needed...

* Code cleanup

* More updates / refactoring

- Allow dynamic hiding of a particular panel
- Pass target ref as positional argument
- Better handling of async calls

* Documentation

* Bump API version

* Provide theme object to plugin context

* Adjust sample plugin

* Docs updates

* Fix includefile call in docs

* Improve type annotation

* Cleanup

* Enable plugin panels for "purchasing index" and "sales index" pages

* Fix for plugin query check

* Improvements to panel selection

- Code refactor / cleanup
- Ensure that a valid panel is always displayed
- Allow plugin panels to persist, even after reload

* Playwright test fixes

* Update src/frontend/src/hooks/UsePluginPanels.tsx

Co-authored-by: Lukas <76838159+wolflu05@users.noreply.github.com>

* Update src/frontend/src/components/plugins/PluginPanel.tsx

Co-authored-by: Lukas <76838159+wolflu05@users.noreply.github.com>

* Update src/frontend/src/components/plugins/PluginContext.tsx

Co-authored-by: Lukas <76838159+wolflu05@users.noreply.github.com>

* Fix context

* Add more context data

* Docs updates

* Reimplement local state

* Fix mkdocs.yml

* Expose 'colorScheme' to plugin context

* Define CustomPanel type definition

* Add unit testing for user interface plugins

* Add front-end tests for plugin panels

* Add new setting to plugin_settings_keys

* Adds helper function for annotating build line allocations

* Improve query efficiency

- Especially around unit testing
- Ensure all settings are generated
- Do not auto-create settings during registry load

* Improve query efficiency for build order operations

* Reduce max query count for specific test

* Revert query count limit

* playwright test updates

---------

Co-authored-by: Lukas <76838159+wolflu05@users.noreply.github.com>
This commit is contained in:
Oliver
2024-09-16 10:36:27 +10:00
committed by GitHub
parent df8269df2a
commit 12d2865b59
56 changed files with 1446 additions and 163 deletions

View File

@ -4,6 +4,12 @@ title: Panel Mixin
## PanelMixin
!!! warning "Legacy User Interface"
This plugin mixin class is designed specifically for the the *legacy* user interface (which is rendered on the server using django templates). The new user interface (which is rendered on the client using React) does not support this mixin class. Instead, refer to the new [User Interface Mixin](./ui.md) class.
!!! warning "Deprecated Class"
This mixin class is considered deprecated, and will be removed in the 1.0.0 release.
The `PanelMixin` enables plugins to render custom content to "panels" on individual pages in the web interface.
Most pages in the web interface support multiple panels, which are selected via the sidebar menu on the left side of the screen:

View File

@ -0,0 +1,102 @@
---
title: User Interface Mixin
---
## User Interface Mixin
The *User Interface* mixin class provides a set of methods to implement custom functionality for the InvenTree web interface.
### Enable User Interface Mixin
To enable user interface plugins, the global setting `ENABLE_PLUGINS_INTERFACE` must be enabled, in the [plugin settings](../../settings/global.md#plugin-settings).
## Plugin Context
When rendering certain content in the user interface, the rendering functions are passed a `context` object which contains information about the current page being rendered. The type of the `context` object is defined in the `PluginContext` file:
{{ includefile("src/frontend/src/components/plugins/PluginContext.tsx", title="Plugin Context", fmt="javascript") }}
## Custom Panels
Many of the pages in the InvenTree web interface are built using a series of "panels" which are displayed on the page. Custom panels can be added to these pages, by implementing the `get_custom_panels` method:
::: plugin.base.integration.UserInterfaceMixin.UserInterfaceMixin.get_custom_panels
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
show_sources: True
summary: False
members: []
The custom panels can display content which is generated either on the server side, or on the client side (see below).
### Server Side Rendering
The panel content can be generated on the server side, by returning a 'content' attribute in the response. This 'content' attribute is expected to be raw HTML, and is rendered directly into the page. This is particularly useful for displaying static content.
Server-side rendering is simple to implement, and can make use of the powerful Django templating system.
Refer to the [sample plugin](#sample-plugin) for an example of how to implement server side rendering for custom panels.
**Advantages:**
- Simple to implement
- Can use Django templates to render content
- Has access to the full InvenTree database, and content not available on the client side (via the API)
**Disadvantages:**
- Content is rendered on the server side, and cannot be updated without a page refresh
- Content is not interactive
### Client Side Rendering
The panel content can also be generated on the client side, by returning a 'source' attribute in the response. This 'source' attribute is expected to be a URL which points to a JavaScript file which will be loaded by the client.
Refer to the [sample plugin](#sample-plugin) for an example of how to implement client side rendering for custom panels.
#### Panel Render Function
The JavaScript file must implement a `renderPanel` function, which is called by the client when the panel is rendered. This function is passed two parameters:
- `target`: The HTML element which the panel content should be rendered into
- `context`: A dictionary of context data which can be used to render the panel content
**Example**
```javascript
export function renderPanel(target, context) {
target.innerHTML = "<h1>Hello, world!</h1>";
}
```
#### Panel Visibility Function
The JavaScript file can also implement a `isPanelHidden` function, which is called by the client to determine if the panel is displayed. This function is passed a single parameter, *context* - which is the same as the context data passed to the `renderPanel` function.
The `isPanelHidden` function should return a boolean value, which determines if the panel is displayed or not, based on the context data.
If the `isPanelHidden` function is not implemented, the panel will be displayed by default.
**Example**
```javascript
export function isPanelHidden(context) {
// Only visible for active parts
return context.model == 'part' && context.instance?.active;
}
```
## Sample Plugin
A sample plugin which implements custom user interface functionality is provided in the InvenTree source code:
::: plugin.samples.integration.user_interface_sample.SampleUserInterfacePlugin
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
show_source: True
members: []

View File

@ -208,7 +208,6 @@ Refer to the [return order settings](../order/return_order.md#return-order-setti
### Plugin Settings
| Name | Description | Default | Units |
| ---- | ----------- | ------- | ----- |
{{ globalsetting("PLUGIN_ON_STARTUP") }}
@ -218,3 +217,4 @@ Refer to the [return order settings](../order/return_order.md#return-order-setti
{{ globalsetting("ENABLE_PLUGINS_APP") }}
{{ globalsetting("ENABLE_PLUGINS_SCHEDULE") }}
{{ globalsetting("ENABLE_PLUGINS_EVENTS") }}
{{ globalsetting("ENABLE_PLUGINS_INTERFACE") }}

View File

@ -26,7 +26,7 @@ The InvenTree server tries to locate the `config.yaml` configuration file on sta
The configuration file *template* can be found on [GitHub]({{ sourcefile("src/backend/InvenTree/config_template.yaml") }}), and is shown below:
{{ includefile("src/backend/InvenTree/config_template.yaml", "Configuration File Template", format="yaml") }}
{{ includefile("src/backend/InvenTree/config_template.yaml", "Configuration File Template", fmt="yaml") }}
!!! info "Template File"
The default configuration file (as defined by the template linked above) will be copied to the specified configuration file location on first run, if a configuration file is not found in that location.

View File

@ -213,6 +213,7 @@ nav:
- Schedule Mixin: extend/plugins/schedule.md
- Settings Mixin: extend/plugins/settings.md
- URL Mixin: extend/plugins/urls.md
- User Interface Mixin: extend/plugins/ui.md
- Validation Mixin: extend/plugins/validation.md
- Machines:
- Overview: extend/machines/overview.md