From 89795f632cb8ae7dd67fea20abbfc8929a45291c Mon Sep 17 00:00:00 2001 From: Lukas <76838159+wolflu05@users.noreply.github.com> Date: Thu, 10 Aug 2023 12:57:33 +0200 Subject: [PATCH] [P_UI] Added django settings for p_ui (#5343) * Added django settings for pui * Fix: server version is not loaded on initial load * Moved server version out of server selector icon * Use polling only for WSL * Added comment and extracted to constant instead of function * Default show server selector to false if not in dev mode * Refactored hostList settings * Move json serialization into global scope * Show server selector in netlify builds * Use demo server for netlify * Renamed netilfy mode to dev or demo mode * Translate for netlify * Dont use translation in main as the are not working there --- InvenTree/InvenTree/settings.py | 4 ++ InvenTree/config_template.yaml | 9 +++++ InvenTree/web/templates/web/index.html | 1 + InvenTree/web/templatetags/spa_helper.py | 10 ++++- src/frontend/netlify.toml | 5 ++- .../src/components/forms/AuthFormOptions.tsx | 8 ++-- src/frontend/src/defaults/defaultHostList.tsx | 17 +-------- src/frontend/src/main.tsx | 38 +++++++++++++++++++ src/frontend/src/pages/Auth/Login.tsx | 2 + src/frontend/src/vite-env.d.ts | 8 ++++ src/frontend/vite.config.ts | 14 ++++++- 11 files changed, 95 insertions(+), 21 deletions(-) diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 2c67860e97..390cbc0404 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -979,6 +979,10 @@ CUSTOM_LOGO = get_custom_file('INVENTREE_CUSTOM_LOGO', 'customize.logo', 'custom CUSTOM_SPLASH = get_custom_file('INVENTREE_CUSTOM_SPLASH', 'customize.splash', 'custom splash') CUSTOMIZE = get_setting('INVENTREE_CUSTOMIZE', 'customize', {}) + +# Frontend settings +PUI_SETTINGS = get_setting("INVENTREE_PUI_SETTINGS", "pui_settings", {}) + if DEBUG: logger.info("InvenTree running with DEBUG enabled") diff --git a/InvenTree/config_template.yaml b/InvenTree/config_template.yaml index 6f6d6aab33..62a190963e 100644 --- a/InvenTree/config_template.yaml +++ b/InvenTree/config_template.yaml @@ -240,6 +240,15 @@ remote_login_header: HTTP_REMOTE_USER # hide_admin_link: true # hide_password_reset: true +# Platform UI options +# pui_settings: +# server_list: +# my_server1: +# host: https://demo.inventree.org/api/ +# name: InvenTree Demo +# default_server: my_server1 +# show_server_selector: false + # Custom flags # InvenTree uses django-flags; read more in their docs at https://cfpb.github.io/django-flags/conditions/ # Use environment variable INVENTREE_FLAGS or the settings below diff --git a/InvenTree/web/templates/web/index.html b/InvenTree/web/templates/web/index.html index bb007ee6dd..7d4d33c4a4 100644 --- a/InvenTree/web/templates/web/index.html +++ b/InvenTree/web/templates/web/index.html @@ -12,6 +12,7 @@
+ {% spa_settings %} {% spa_bundle %} diff --git a/InvenTree/web/templatetags/spa_helper.py b/InvenTree/web/templatetags/spa_helper.py index a94c8a1288..3087e7c34e 100644 --- a/InvenTree/web/templatetags/spa_helper.py +++ b/InvenTree/web/templatetags/spa_helper.py @@ -7,9 +7,11 @@ from django import template from django.conf import settings from django.utils.safestring import mark_safe -logger = getLogger("gwaesser_backend") +logger = getLogger("InvenTree") register = template.Library() +PUI_SETTINGS = json.dumps(settings.PUI_SETTINGS) + @register.simple_tag def spa_bundle(): @@ -36,3 +38,9 @@ def spa_bundle(): f""" {imports_files}""" ) + + +@register.simple_tag +def spa_settings(): + """Render settings for spa.""" + return mark_safe(f"""""") diff --git a/src/frontend/netlify.toml b/src/frontend/netlify.toml index 0f7783e4d0..9dbf89b30c 100644 --- a/src/frontend/netlify.toml +++ b/src/frontend/netlify.toml @@ -2,9 +2,12 @@ # https://www.netlify.com/docs/netlify-toml-reference/ [build] - command = "yarn run build --outDir dist" + command = "yarn run extract && yarn run compile && yarn run build --outDir dist" publish = "dist" +[build.environment] + VITE_DEMO = "true" + # Send requests to subpath [[redirects]] diff --git a/src/frontend/src/components/forms/AuthFormOptions.tsx b/src/frontend/src/components/forms/AuthFormOptions.tsx index bdf91ccaaf..002005224e 100644 --- a/src/frontend/src/components/forms/AuthFormOptions.tsx +++ b/src/frontend/src/components/forms/AuthFormOptions.tsx @@ -19,9 +19,11 @@ export function AuthFormOptions({ - - - + {window.INVENTREE_SETTINGS.show_server_selector && ( + + + + )} {server.version} | {server.apiVersion} diff --git a/src/frontend/src/defaults/defaultHostList.tsx b/src/frontend/src/defaults/defaultHostList.tsx index 111f380674..38cec156c3 100644 --- a/src/frontend/src/defaults/defaultHostList.tsx +++ b/src/frontend/src/defaults/defaultHostList.tsx @@ -2,18 +2,5 @@ import { t } from '@lingui/macro'; import { HostList } from '../states/states'; -export const defaultHostList: HostList = { - 'mantine-u56l5jt85': { - host: 'https://demo.inventree.org/api/', - name: t`InvenTree Demo` - }, - 'mantine-g8t1zrj50': { - host: 'https://sample.app.invenhost.com/api/', - name: 'InvenHost: Sample' - }, - 'mantine-cqj63coxn': { - host: 'http://localhost:8000/api/', - name: t`Local Server` - } -}; -export const defaultHostKey = 'mantine-cqj63coxn'; +export const defaultHostList: HostList = window.INVENTREE_SETTINGS.server_list; +export const defaultHostKey = window.INVENTREE_SETTINGS.default_server; diff --git a/src/frontend/src/main.tsx b/src/frontend/src/main.tsx index 000a15c091..d6a6e65512 100644 --- a/src/frontend/src/main.tsx +++ b/src/frontend/src/main.tsx @@ -4,6 +4,44 @@ import 'react-grid-layout/css/styles.css'; import 'react-resizable/css/styles.css'; import App from './App'; +import { HostList } from './states/states'; + +// define settings +declare global { + interface Window { + INVENTREE_SETTINGS: { + server_list: HostList; + default_server: string; + show_server_selector: boolean; + }; + } +} + +export const IS_DEV = import.meta.env.DEV; +export const IS_DEMO = import.meta.env.VITE_DEMO === 'true'; +export const IS_DEV_OR_DEMO = IS_DEV || IS_DEMO; + +window.INVENTREE_SETTINGS = { + server_list: { + 'mantine-cqj63coxn': { + host: `${window.location.origin}/api/`, + name: 'Current Server' + }, + ...(IS_DEV_OR_DEMO + ? { + 'mantine-u56l5jt85': { + host: 'https://demo.inventree.org/api/', + name: 'InvenTree Demo' + } + } + : {}) + }, + default_server: IS_DEMO ? 'mantine-u56l5jt85' : 'mantine-cqj63coxn', // use demo server for demo mode + show_server_selector: IS_DEV_OR_DEMO, + + // merge in settings that are already set via django's spa_view or for development + ...((window.INVENTREE_SETTINGS || {}) as any) +}; ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( diff --git a/src/frontend/src/pages/Auth/Login.tsx b/src/frontend/src/pages/Auth/Login.tsx index 2cd11b7005..0452669083 100644 --- a/src/frontend/src/pages/Auth/Login.tsx +++ b/src/frontend/src/pages/Auth/Login.tsx @@ -3,6 +3,7 @@ import { Center, Container } from '@mantine/core'; import { useToggle } from '@mantine/hooks'; import { useEffect } from 'react'; +import { setApiDefaults } from '../../App'; import { AuthFormOptions } from '../../components/forms/AuthFormOptions'; import { AuthenticationForm } from '../../components/forms/AuthenticationForm'; import { InstanceOptions } from '../../components/forms/InstanceOptions'; @@ -27,6 +28,7 @@ export default function Login() { // Data manipulation functions function ChangeHost(newHost: string): void { setHost(hostList[newHost].host, newHost); + setApiDefaults(); fetchServerApiState(); } diff --git a/src/frontend/src/vite-env.d.ts b/src/frontend/src/vite-env.d.ts index 11f02fe2a0..f915651859 100644 --- a/src/frontend/src/vite-env.d.ts +++ b/src/frontend/src/vite-env.d.ts @@ -1 +1,9 @@ /// + +interface ImportMetaEnv { + readonly VITE_DEMO: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/src/frontend/vite.config.ts b/src/frontend/vite.config.ts index 092b5d90a3..fbc74ca6fc 100644 --- a/src/frontend/vite.config.ts +++ b/src/frontend/vite.config.ts @@ -1,6 +1,9 @@ import react from '@vitejs/plugin-react'; +import { platform } from 'node:os'; import { defineConfig, splitVendorChunkPlugin } from 'vite'; +const IS_IN_WSL = platform().includes('WSL'); + // https://vitejs.dev/config/ export default defineConfig({ plugins: [ @@ -16,8 +19,17 @@ export default defineConfig({ outDir: '../../InvenTree/web/static/web' }, server: { + proxy: { + '/api': { + target: 'http://localhost:8000', + changeOrigin: true, + secure: true + } + }, watch: { - usePolling: true + // use polling only for WSL as the file system doesn't trigger notifications for Linux apps + // ref: https://github.com/vitejs/vite/issues/1153#issuecomment-785467271 + usePolling: IS_IN_WSL } } });