Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Internal server error when disabling one or both frontends #8506

Closed
thcrt opened this issue Nov 17, 2024 · 2 comments · Fixed by #8508
Closed

[BUG] Internal server error when disabling one or both frontends #8506

thcrt opened this issue Nov 17, 2024 · 2 comments · Fixed by #8508
Labels
bug Identifies a bug which needs to be addressed old user interface Issues with Old User interface Platform UI Related to the React based User Interface question This is a question setup Relates to the InvenTree setup / installation process

Comments

@thcrt
Copy link

thcrt commented Nov 17, 2024

The default config.yaml file shipped features the boolean options platform_frontend and classic_frontend, to enable or disable the PUI or CUI respectively. However, setting either of these values to false results in breakage.

Disabling PUI, enabling CUI

Reproduction

To reproduce, set the following values in config.yaml:

classic_frontend: true
platform_frontend: false

Note that setting customize.hide_pui_banner has no effect on this error.

Then restart the InvenTree server and worker to apply changes. Since I'm running under Docker Compose, I use:

docker compose restart server worker

Results

When already logged in, most of the UI remains usable. However, any areas that would normally feature links to try PUI instead return a 500 Internal Server Error when accessed, notably including the settings page and the login page for visitors not yet authenticated:

Internal Server Error

Logs are presented below, in a <details> element for convenience:

Click to toggle logs
server-1  | Internal Server Error: /accounts/login/
server-1  | Traceback (most recent call last):
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
server-1  |     response = get_response(request)
server-1  |                ^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/core/handlers/base.py", line 220, in _get_response
server-1  |     response = response.render()
server-1  |                ^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/response.py", line 114, in render
server-1  |     self.content = self.rendered_content
server-1  |                    ^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/response.py", line 92, in rendered_content
server-1  |     return template.render(context, self._request)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/backends/django.py", line 61, in render
server-1  |     return self.template.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 175, in render
server-1  |     return self._render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 167, in _render
server-1  |     return self.nodelist.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
server-1  |     return self.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/loader_tags.py", line 157, in render
server-1  |     return compiled_parent._render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 167, in _render
server-1  |     return self.nodelist.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
server-1  |     return self.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/loader_tags.py", line 63, in render
server-1  |     result = block.nodelist.render(context)
server-1  |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
server-1  |     return self.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/loader_tags.py", line 208, in render
server-1  |     return template.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 177, in render
server-1  |     return self._render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 167, in _render
server-1  |     return self.nodelist.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
server-1  |     return self.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/defaulttags.py", line 321, in render
server-1  |     return nodelist.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
server-1  |     return self.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/defaulttags.py", line 471, in render
server-1  |     url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
server-1  |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/urls/base.py", line 88, in reverse
server-1  |     return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/urls/resolvers.py", line 828, in _reverse_with_prefix
server-1  |     raise NoReverseMatch(msg)
server-1  | django.urls.exceptions.NoReverseMatch: Reverse for 'platform' not found. 'platform' is not a valid view function or pattern name.

Disabling CUI, enabling PUI

Reproduction

Make the opposite changes in config.yaml:

classic_frontend: true
platform_frontend: false

Then restart the server and worker as before.

Results

An already logged-in user will be redirected from / to /platform/ to /platform/home/, preserving functionality in the PUI. From my testing, the entire UI can be used without issue.

A user that is not yet logged in can access /platform/login/ without issue. However, accessing / does not redirect and rather presents another 500 Internal Server Error, this time without styling:

Internal Server Error

Click to toggle logs
server-1  | Traceback (most recent call last):
server-1  |   File "/root/.local/lib/python3.11/site-packages/gunicorn/workers/gthread.py", line 282, in handle
server-1  |     keepalive = self.handle_request(req, conn)
server-1  |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/gunicorn/workers/gthread.py", line 334, in handle_request
server-1  |     respiter = self.wsgi(environ, resp.start_response)
server-1  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/core/handlers/wsgi.py", line 124, in __call__
server-1  |     response = self.get_response(request)
server-1  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/core/handlers/base.py", line 140, in get_response
server-1  |     response = self._middleware_chain(request)
server-1  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/core/handlers/exception.py", line 57, in inner
server-1  |     response = response_for_exception(request, exc)
server-1  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/core/handlers/exception.py", line 140, in response_for_exception
server-1  |     response = handle_uncaught_exception(
server-1  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/core/handlers/exception.py", line 185, in handle_uncaught_exception
server-1  |     return callback(request)
server-1  |            ^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/utils/decorators.py", line 134, in _wrapper_view
server-1  |     response = view_func(request, *args, **kwargs)
server-1  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/views/defaults.py", line 99, in server_error
server-1  |     return HttpResponseServerError(template.render())
server-1  |                                    ^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/backends/django.py", line 61, in render
server-1  |     return self.template.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 175, in render
server-1  |     return self._render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 167, in _render
server-1  |     return self.nodelist.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
server-1  |     return self.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/loader_tags.py", line 157, in render
server-1  |     return compiled_parent._render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 167, in _render
server-1  |     return self.nodelist.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
server-1  |     return self.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/loader_tags.py", line 208, in render
server-1  |     return template.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 177, in render
server-1  |     return self._render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 167, in _render
server-1  |     return self.nodelist.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
server-1  |     return SafeString("".join([node.render_annotated(context) for node in self]))
server-1  |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
server-1  |     return self.render(context)
server-1  |            ^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/template/defaulttags.py", line 471, in render
server-1  |     url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
server-1  |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/urls/base.py", line 88, in reverse
server-1  |     return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
server-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
server-1  |   File "/root/.local/lib/python3.11/site-packages/django/urls/resolvers.py", line 828, in _reverse_with_prefix
server-1  |     raise NoReverseMatch(msg)
server-1  | django.urls.exceptions.NoReverseMatch: Reverse for 'notifications' not found. 'notifications' is not a valid view function or pattern name.

Disabling both, for fun (?) and profit (??)

Yes, this is obviously a silly thing to do, but let's try it anyway:

classic_frontend: true
platform_frontend: false

Loading / gives us the Internal Server Error we've already seen:
Internal Server Error

Loading /platform (no trailing slash) makes Firefox complain:
The page isn't redirecting properly

Loading /platform/ (with a trailing slash) redirects us to /platform/platform. Adding a trailing slash again and loading /platform/platform/ redirects us to /platform/platform/platform. All steps along the way involve the same redirect error shown above.

Further information

stack.env
INVENTREE_TAG=0.16.8

INVENTREE_DB_NAME=inventree
INVENTREE_DB_HOST=db
INVENTREE_DB_PORT=5432
INVENTREE_DB_USER=### REDACTED ###
INVENTREE_DB_PASSWORD=### REDACTED ###

INVENTREE_GUNICORN_TIMEOUT=90
config.yaml
debug: false
log_level: WARNING
db_logging: false
language: en-us
timezone: Europe/Amsterdam
site_url: '### REDACTED ###'
sentry_enabled: False
tracing:
  enabled: false
plugins_enabled: True
auto_update: True
allowed_hosts:
  - '*'
trusted_origins:
- '### REDACTED ###'
use_x_forwarded_host: false
use_x_forwarded_port: false
cookie:
  secure: true
  samesite: false
cors:
  allow_all: false
  allow_credentials: true
  whitelist:
  - '### REDACTED ###'
background:
  workers: 4
  timeout: 90
  max_attempts: 5
cache:
  enabled: true
  host: 'cache'
  port: 6379
login_confirm_days: 3
login_attempts: 5
login_default_protocol: https
logout_redirect_url: '### REDACTED ###'
social_backends:
  - 'allauth.socialaccount.providers.openid_connect'
ldap:
  enabled: false

classic_frontend: false  # <-- Issue
platform_frontend: true # <-- Issue
compose.yaml
services:
  db:
    image: postgres:13
    restart: unless-stopped

    volumes:
      - data:/var/lib/postgresql/data/
    environment:
      PGDATA: /var/lib/postgresql/data/pgdb
      POSTGRES_USER: ${INVENTREE_DB_USER:?You must provide the 'INVENTREE_DB_USER' variable in the .env file}
      POSTGRES_PASSWORD: ${INVENTREE_DB_PASSWORD:?You must provide the 'INVENTREE_DB_PASSWORD' variable in the .env file}
      POSTGRES_DB: ${INVENTREE_DB_NAME:?You must provide the 'INVENTREE_DB_NAME' variable in the .env file}

  cache:
    image: redis:7.0
    restart: unless-stopped

    env_file:
      - stack.env

  server:
    image: inventree/inventree:${INVENTREE_TAG:-stable}
    restart: unless-stopped
    depends_on:
      - db
      - cache

    networks:
      - default
      - exposed
    volumes:
      - data:/home/inventree/data
      - ./config.yaml:/home/inventree/data/config.yaml:z
    env_file:
      - stack.env

  worker:
    image: inventree/inventree:${INVENTREE_TAG:-stable}
    restart: unless-stopped
    depends_on:
      - server
    command: invoke worker

    volumes:
      - data:/home/inventree/data
      - ./config.yaml:/home/inventree/data/config.yaml:z
    env_file:
      - stack.env

  proxy:
    image: caddy:alpine
    restart: unless-stopped
    hostname: pottery-proxy
    depends_on:
      - server

    networks:
      - default
      - exposed
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro,z
      - data:/var/log
      - data:/data
      - data:/config
      - type: volume
        source: data
        target: /var/www/static
        volume:
          subpath: static
      - type: volume
        source: data
        target: /var/www/media
        volume:
          subpath: media
    env_file:
      - stack.env

networks:
  exposed:
    external: true

volumes:
  data:
Version information
InvenTree-Version: 0.16.8
Django Version: 4.2.15
Commit Hash: f23d405
Commit Date: 2024-11-07

Database: postgresql
Debug-Mode: False
Deployed using Docker: True
Platform: Linux-6.1.0-21-arm64-aarch64-with
Installer: DOC

Active plugins: [{'name': 'InvenTreeBarcode', 'slug': 'inventreebarcode', 'version': '2.1.0'}, {'name': 'InvenTreeCoreNotificationsPlugin', 'slug': 'inventreecorenotificationsplugin', 'version': '1.0.0'}, {'name': 'InvenTreeCurrencyExchange', 'slug': 'inventreecurrencyexchange', 'version': '1.0.0'}, {'name': 'InvenTreeLabel', 'slug': 'inventreelabel', 'version': '1.1.0'}, {'name': 'InvenTreeLabelMachine', 'slug': 'inventreelabelmachine', 'version': '1.0.0'}, {'name': 'InvenTreeLabelSheet', 'slug': 'inventreelabelsheet', 'version': '1.0.0'}, {'name': 'DigiKeyPlugin', 'slug': 'digikeyplugin', 'version': '1.0.0'}, {'name': 'LCSCPlugin', 'slug': 'lcscplugin', 'version': '1.0.0'}, {'name': 'MouserPlugin', 'slug': 'mouserplugin', 'version': '1.0.0'}, {'name': 'TMEPlugin', 'slug': 'tmeplugin', 'version': '1.0.0'}]

I checked and didn't find a similar issue.

@thcrt thcrt added bug Identifies a bug which needs to be addressed question This is a question triage:not-checked Item was not checked by the core team labels Nov 17, 2024
@thcrt thcrt changed the title [BUG] Internal server error when disabling Platform frontend [BUG] Internal server error when disabling either Platform or Classic frontend Nov 17, 2024
@thcrt thcrt changed the title [BUG] Internal server error when disabling either Platform or Classic frontend [BUG] Internal server error when disabling one or both frontends Nov 17, 2024
@SchrodingersGat SchrodingersGat added setup Relates to the InvenTree setup / installation process old user interface Issues with Old User interface Platform UI Related to the React based User Interface and removed triage:not-checked Item was not checked by the core team labels Nov 17, 2024
@SchrodingersGat
Copy link
Member

@thcrt thanks for reporting this! Fix incoming in #8508

@matmair
Copy link
Member

matmair commented Nov 18, 2024

Just as a note - we are removing CUI after the soon-ish release of 0.17.0 - see #8384 . Please report issues with PUI as it will be the only interface available

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Identifies a bug which needs to be addressed old user interface Issues with Old User interface Platform UI Related to the React based User Interface question This is a question setup Relates to the InvenTree setup / installation process
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants