diff --git a/ui/README.md b/ui/README.md
index ff253e6ddc..2df3760f84 100644
--- a/ui/README.md
+++ b/ui/README.md
@@ -24,6 +24,14 @@ Your hosting environment should make the Conductor Server API available on the s
See `docker/serverAndUI` for an `nginx` based example.
+#### Different host path
+The static UI would work when rendered from any host route.
+The default is '/'. You can customize this by setting the 'homepage' field in package.json
+Refer
+- https://docs.npmjs.com/cli/v9/configuring-npm/package-json#homepage
+- https://create-react-app.dev/docs/deployment/#building-for-relative-paths
+
+
### Customization Hooks
For ease of maintenance, a number of touch points for customization have been removed to `/plugins`.
diff --git a/ui/package.json b/ui/package.json
index 33b909bb13..623a5c6dc1 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -1,6 +1,6 @@
{
"name": "client",
- "version": "3.7.2",
+ "version": "3.8.0",
"dependencies": {
"@material-ui/core": "^4.12.3",
"@material-ui/icons": "^4.11.2",
diff --git a/ui/src/components/NavLink.jsx b/ui/src/components/NavLink.jsx
index ae47b24f4e..9ccb93364f 100644
--- a/ui/src/components/NavLink.jsx
+++ b/ui/src/components/NavLink.jsx
@@ -4,12 +4,14 @@ import { Link } from "@material-ui/core";
import LaunchIcon from "@material-ui/icons/Launch";
import Url from "url-parse";
import { useEnv } from "../plugins/env";
+import { getBasename } from "../utils/helpers";
+import { cleanDuplicateSlash } from "../plugins/fetch";
// 1. Strip `navigate` from props to prevent error
// 2. Preserve stack param
export default React.forwardRef((props, ref) => {
- const { navigate, path, newTab, ...rest } = props;
+ const { navigate, path, newTab, absolutePath = false, ...rest } = props;
const { stack, defaultStack } = useEnv();
const url = new Url(path, {}, true);
@@ -24,8 +26,9 @@ export default React.forwardRef((props, ref) => {
);
} else {
+ const href = absolutePath ? url.toString() : cleanDuplicateSlash(getBasename() + "/" + url.toString());
return (
-
+
{rest.children}
diff --git a/ui/src/index.js b/ui/src/index.js
index 52201aeaae..eb1b10ecf1 100644
--- a/ui/src/index.js
+++ b/ui/src/index.js
@@ -8,6 +8,7 @@ import { BrowserRouter } from "react-router-dom";
import CssBaseline from "@material-ui/core/CssBaseline";
import { QueryClient, QueryClientProvider } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";
+import { getBasename } from "./utils/helpers";
const queryClient = new QueryClient({
defaultOptions: {
@@ -22,7 +23,7 @@ ReactDOM.render(
//
-
+
diff --git a/ui/src/plugins/AppLogo.jsx b/ui/src/plugins/AppLogo.jsx
index 2650542836..ad825e5bcd 100644
--- a/ui/src/plugins/AppLogo.jsx
+++ b/ui/src/plugins/AppLogo.jsx
@@ -1,5 +1,7 @@
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
+import { getBasename } from "../utils/helpers";
+import { cleanDuplicateSlash } from "./fetch";
const useStyles = makeStyles((theme) => ({
logo: {
@@ -11,5 +13,6 @@ const useStyles = makeStyles((theme) => ({
export default function AppLogo() {
const classes = useStyles();
- return
;
+ const logoPath = getBasename() + '/logo.svg';
+ return
;
}
diff --git a/ui/src/plugins/fetch.js b/ui/src/plugins/fetch.js
index bf4ba2fe8b..aabb5b1bdd 100644
--- a/ui/src/plugins/fetch.js
+++ b/ui/src/plugins/fetch.js
@@ -1,3 +1,4 @@
+import { getBasename } from "../utils/helpers";
import { useEnv } from "./env";
export function useFetchContext() {
@@ -15,8 +16,9 @@ export function fetchWithContext(
) {
const newParams = { ...fetchParams };
- const newPath = `/api/${path}`;
- const cleanPath = newPath.replace(/([^:]\/)\/+/g, "$1"); // Cleanup duplicated slashes
+ const basename = getBasename();
+ const newPath = basename + `/api/${path}`;
+ const cleanPath = cleanDuplicateSlash(newPath); // Cleanup duplicated slashes
return fetch(cleanPath, newParams)
.then((res) => Promise.all([res, res.text()]))
@@ -38,3 +40,7 @@ export function fetchWithContext(
}
});
}
+
+export function cleanDuplicateSlash(path) {
+ return path.replace(/([^:]\/)\/+/g, "$1");
+}
diff --git a/ui/src/utils/helpers.js b/ui/src/utils/helpers.js
index a514ce606a..11bf45e943 100644
--- a/ui/src/utils/helpers.js
+++ b/ui/src/utils/helpers.js
@@ -1,5 +1,6 @@
import { format, formatDuration, intervalToDuration } from "date-fns";
import _ from "lodash";
+import packageJson from '../../package.json';
export function timestampRenderer(date) {
if (_.isNil(date)) return null;
@@ -88,3 +89,11 @@ export function isEmptyIterable(iterable) {
}
return true;
}
+
+export function getBasename() {
+ let basename = '/';
+ try{
+ basename = new URL(packageJson.homepage).pathname;
+ } catch(e) {}
+ return _.isEmpty(basename) ? '/' : basename;
+}