diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py index 183e491580..629ee1f31a 100644 --- a/InvenTree/InvenTree/views.py +++ b/InvenTree/InvenTree/views.py @@ -38,6 +38,8 @@ from part.models import PartCategory from common.models import InvenTreeSetting, ColorTheme from users.models import check_user_role, RuleSet +from plugin.registry import registry + from .forms import DeleteForm, EditUserForm, SetPasswordForm from .forms import SettingCategorySelectForm from .helpers import str2bool @@ -56,6 +58,38 @@ def auth_request(request): return HttpResponse(status=403) +class InvenTreePluginMixin: + """ + Custom view mixin which adds context data to the view, + based on loaded plugins. + + This allows rendered pages to be augmented by loaded plugins. + + """ + + def get_plugin_panels(self): + """ + Return a list of extra 'plugin panels' associated with this view + """ + + panels = [] + + for plug in registry.with_mixin('panel'): + + panels += plug.render_panels(self, self.request) + + return panels + + def get_context_data(self, **kwargs): + + ctx = super().get_context_data(**kwargs) + + if settings.PLUGINS_ENABLED: + ctx['plugin_panels'] = self.get_plugin_panels() + + return ctx + + class InvenTreeRoleMixin(PermissionRequiredMixin): """ Permission class based on user roles, not user 'permissions'. diff --git a/InvenTree/part/templates/part/detail.html b/InvenTree/part/templates/part/detail.html index aa3ad4963a..cd8404be5b 100644 --- a/InvenTree/part/templates/part/detail.html +++ b/InvenTree/part/templates/part/detail.html @@ -397,9 +397,11 @@
- + +{% include "panel/plugin_panels.html" %} + {% endblock %} {% block js_load %} @@ -1083,4 +1085,6 @@ } }); + {% include "panel/plugin_javascript.html" %} + {% endblock %} diff --git a/InvenTree/part/templates/part/part_sidebar.html b/InvenTree/part/templates/part/part_sidebar.html index e8763fb973..18890b82af 100644 --- a/InvenTree/part/templates/part/part_sidebar.html +++ b/InvenTree/part/templates/part/part_sidebar.html @@ -58,3 +58,5 @@ {% include "sidebar_item.html" with label="part-attachments" text=text icon="fa-paperclip" %} {% trans "Notes" as text %} {% include "sidebar_item.html" with label="part-notes" text=text icon="fa-clipboard" %} + +{% include "panel/plugin_menu_items.html" %} \ No newline at end of file diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index efaf83ae95..cb9725f94e 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -49,7 +49,7 @@ from order.models import PurchaseOrderLineItem from InvenTree.views import AjaxView, AjaxCreateView, AjaxUpdateView, AjaxDeleteView from InvenTree.views import QRCodeView -from InvenTree.views import InvenTreeRoleMixin +from InvenTree.views import InvenTreeRoleMixin, InvenTreePluginMixin from InvenTree.helpers import str2bool @@ -365,7 +365,7 @@ class PartImportAjax(FileManagementAjaxView, PartImport): return PartImport.validate(self, self.steps.current, form, **kwargs) -class PartDetail(InvenTreeRoleMixin, DetailView): +class PartDetail(InvenTreeRoleMixin, InvenTreePluginMixin, DetailView): """ Detail view for Part object """ diff --git a/InvenTree/plugin/samples/integration/custom_panel_sample.py b/InvenTree/plugin/samples/integration/custom_panel_sample.py index 5cca44f524..3b999cce27 100644 --- a/InvenTree/plugin/samples/integration/custom_panel_sample.py +++ b/InvenTree/plugin/samples/integration/custom_panel_sample.py @@ -46,9 +46,6 @@ class CustomPanelSample(PanelMixin, IntegrationPluginBase): # This panel will *only* display on the StockLocation view, # and *only* if the StockLocation has *no* child locations if isinstance(view, StockLocationDetail): - - print("yep, stocklocation view!") - try: loc = view.get_object() @@ -58,11 +55,7 @@ class CustomPanelSample(PanelMixin, IntegrationPluginBase): 'icon': 'fa-user', 'content': '

I have no children!

' }) - else: - print("abcdefgh") - except: - print("error could not get object!") pass return panels diff --git a/InvenTree/templates/panel/plugin_javascript.html b/InvenTree/templates/panel/plugin_javascript.html new file mode 100644 index 0000000000..bf8b7fea34 --- /dev/null +++ b/InvenTree/templates/panel/plugin_javascript.html @@ -0,0 +1,10 @@ +{% if plugin_panels %} +// Run custom javascript when plugin panels are loaded +{% for panel in plugin_panels %} +{% if panel.javascript %} +onPanelLoad('{{ panel.key }}', function() { +{{ panel.javascript | safe }} +}); +{% endif %} +{% endfor %} +{% endif %} \ No newline at end of file diff --git a/InvenTree/templates/panel/plugin_menu_items.html b/InvenTree/templates/panel/plugin_menu_items.html new file mode 100644 index 0000000000..2c084a021e --- /dev/null +++ b/InvenTree/templates/panel/plugin_menu_items.html @@ -0,0 +1,3 @@ +{% for panel in plugin_panels %} +{% include "sidebar_item.html" with label=panel.key text=panel.title icon=panel.icon %} +{% endfor %} \ No newline at end of file diff --git a/InvenTree/templates/panel/plugin_panels.html b/InvenTree/templates/panel/plugin_panels.html new file mode 100644 index 0000000000..ddbdbeee45 --- /dev/null +++ b/InvenTree/templates/panel/plugin_panels.html @@ -0,0 +1,18 @@ +{% for panel in plugin_panels %} + +
+
+
+

{{ panel.title }}

+ {% include "spacer.html" %} +
+ +
+
+
+
+ {{ panel.content | safe }} +
+
+ +{% endfor %} \ No newline at end of file