2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-27 19:16:44 +00:00

[UI] Add CUI compatibility URLs (#9541)

* Add CUI compatibility URLs

* Add config option to enable URL compatibility

* Add unit tests

* Simplify tests
This commit is contained in:
Oliver 2025-04-21 08:27:41 +10:00 committed by GitHub
parent 1dae1bc906
commit 7d87b8b896
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 155 additions and 1 deletions

View File

@ -484,4 +484,13 @@ def get_frontend_settings(debug=True):
# If no servers are specified, show server selector
frontend_settings['show_server_selector'] = True
# Support compatibility with "legacy" URLs?
try:
frontend_settings['url_compatibility'] = bool(
frontend_settings.get('url_compatibility', True)
)
except Exception:
# If the value is not a boolean, set it to True
frontend_settings['url_compatibility'] = True
return frontend_settings

View File

@ -1704,3 +1704,22 @@ class SchemaPostprocessingTest(TestCase):
self.assertNotIn('customer_detail', schemas_out.get('SalesOrder')['required'])
# required key removed when empty
self.assertNotIn('required', schemas_out.get('SalesOrderShipment'))
class URLCompatibilityTest(InvenTreeTestCase):
"""Unit test for legacy URL compatibility."""
URL_MAPPINGS = [
('/index/', '/web'),
('/part/1/', '/web/part/1/'),
('/company/customers/', '/web/sales/index/customers'),
('/build/3/', '/web/manufacturing/build-order/3'),
('/stock/item/1/', '/web/stock/item/1/'),
]
def test_legacy_urls(self):
"""Test legacy URLs."""
for old_url, new_url in self.URL_MAPPINGS:
response = self.client.get(old_url)
self.assertEqual(response.status_code, 302)
self.assertEqual(response['Location'], new_url)

View File

@ -28,6 +28,7 @@ import report.api
import stock.api
import users.api
from plugin.urls import get_plugin_urls
from web.urls import cui_compatibility_urls
from web.urls import urlpatterns as platform_urls
from .api import (
@ -172,6 +173,10 @@ urlpatterns.append(
)
)
# Compatibility layer for old (CUI) URLs
if settings.FRONTEND_SETTINGS.get('url_compatibility'):
urlpatterns += cui_compatibility_urls(settings.FRONTEND_URL_BASE)
# Send any unknown URLs to the index page
urlpatterns += [
re_path(

View File

@ -3,10 +3,131 @@
from django.conf import settings
from django.urls import include, path, re_path
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.generic import TemplateView
from django.views.generic import RedirectView, TemplateView
spa_view = ensure_csrf_cookie(TemplateView.as_view(template_name='web/index.html'))
def cui_compatibility_urls(base: str) -> list:
"""Generate a list of URL patterns for compatibility with old (CUI) URLs.
These URLs are provided for backwards compatibility with older versions of InvenTree,
before we moved to a SPA (Single Page Application) architecture in the 1.0.0 release.
At some future point these may be removed?
Args:
base (str): The base URL to use for generating the patterns.
Returns:
list: A list of URL patterns.
"""
return [
# Old 'index' view - reroute to the dashboard
path('index/', RedirectView.as_view(url=f'/{base}')),
path('settings/', RedirectView.as_view(url=f'/{base}/settings')),
# Company patterns
path(
'company/',
include([
path(
'customers/',
RedirectView.as_view(url=f'/{base}/sales/index/customers'),
),
path(
'manufacturers/',
RedirectView.as_view(url=f'/{base}/purchasing/index/manufacturers'),
),
path(
'suppliers/',
RedirectView.as_view(url=f'/{base}/purchasing/index/suppliers'),
),
re_path(
r'(?P<pk>\d+)/', RedirectView.as_view(url=f'/{base}/company/%(pk)s')
),
]),
),
# "Part" app views
re_path(
r'^part/(?P<path>.*)$', RedirectView.as_view(url=f'/{base}/part/%(path)s')
),
# "Stock" app views
re_path(
r'^stock/(?P<path>.*)$', RedirectView.as_view(url=f'/{base}/stock/%(path)s')
),
# "Build" app views (requires some custom handling)
path(
'build/',
include([
re_path(
r'^(?P<pk>\d+)/',
RedirectView.as_view(
url=f'/{base}/manufacturing/build-order/%(pk)s'
),
),
re_path('.*', RedirectView.as_view(url=f'/{base}/manufacturing/')),
]),
),
# "Order" app views
path(
'order/',
include([
path(
'purchase-order/',
include([
re_path(
r'^(?P<pk>\d+)/',
RedirectView.as_view(
url=f'/{base}/purchasing/purchase-order/%(pk)s'
),
),
re_path(
'.*',
RedirectView.as_view(
url=f'/{base}/purchasing/index/purchaseorders/'
),
),
]),
),
path(
'sales-order/',
include([
re_path(
r'^(?P<pk>\d+)/',
RedirectView.as_view(
url=f'/{base}/sales/sales-order/%(pk)s'
),
),
re_path(
'.*',
RedirectView.as_view(
url=f'/{base}/sales/index/salesorders/'
),
),
]),
),
path(
'return-order/',
include([
re_path(
r'^(?P<pk>\d+)/',
RedirectView.as_view(
url=f'/{base}/sales/return-order/%(pk)s'
),
),
re_path(
'.*',
RedirectView.as_view(
url=f'/{base}/sales/index/returnorders/'
),
),
]),
),
]),
),
]
urlpatterns = [
path(
f'{settings.FRONTEND_URL_BASE}/',