diff --git a/apps/ui/html/settings.html b/apps/ui/html/settings.html
index b2f1663..62d4ea9 100644
--- a/apps/ui/html/settings.html
+++ b/apps/ui/html/settings.html
@@ -21,7 +21,7 @@
-
+
Crank
@@ -37,7 +37,7 @@
Your workspaces
@@ -84,11 +84,11 @@
diff --git a/apps/ui/html/usage.html b/apps/ui/html/usage.html
index e00ea12..6dcf31e 100644
--- a/apps/ui/html/usage.html
+++ b/apps/ui/html/usage.html
@@ -21,7 +21,7 @@
-
+
Crank
@@ -37,7 +37,7 @@
Your workspaces
@@ -84,11 +84,11 @@
diff --git a/apps/ui/html/wizard/index.html b/apps/ui/html/wizard/index.html
index a67e11f..57d02dc 100644
--- a/apps/ui/html/wizard/index.html
+++ b/apps/ui/html/wizard/index.html
@@ -22,7 +22,7 @@
-
+
Crank
@@ -38,7 +38,7 @@
Your workspaces
@@ -90,11 +90,11 @@
diff --git a/apps/ui/html/workspace-setup.html b/apps/ui/html/workspace-setup.html
index dc53806..522dad8 100644
--- a/apps/ui/html/workspace-setup.html
+++ b/apps/ui/html/workspace-setup.html
@@ -23,7 +23,7 @@
-
+
diff --git a/apps/ui/index.html b/apps/ui/index.html
index 5428888..edc156b 100644
--- a/apps/ui/index.html
+++ b/apps/ui/index.html
@@ -21,7 +21,7 @@
-
+
Crank
@@ -37,7 +37,7 @@
Your workspaces
@@ -79,7 +79,7 @@
Operator
Admin · acme-workspace
-
+
Settings
@@ -95,11 +95,11 @@
diff --git a/apps/ui/js/auth.js b/apps/ui/js/auth.js
index 5f94034..ca4bb46 100644
--- a/apps/ui/js/auth.js
+++ b/apps/ui/js/auth.js
@@ -22,11 +22,11 @@
}
function loginUrl() {
- return (window.APP_BASE || '') + 'html/login.html';
+ return (window.CrankRoutes && window.CrankRoutes.login) || '/login';
}
function homeUrl() {
- return (window.APP_BASE || '') + 'index.html';
+ return (window.CrankRoutes && window.CrankRoutes.home) || '/';
}
function clearUserMirror() {
diff --git a/apps/ui/js/catalog.js b/apps/ui/js/catalog.js
index d4c6f16..f0791f4 100644
--- a/apps/ui/js/catalog.js
+++ b/apps/ui/js/catalog.js
@@ -356,7 +356,8 @@ document.addEventListener('alpine:init', function() {
},
editOperation(operation) {
- window.location.href = (window.APP_BASE || '') + 'html/wizard/?mode=edit&operationId=' + encodeURIComponent(operation.id);
+ window.location.href = ((window.CrankRoutes && window.CrankRoutes.wizard) || '/wizard/')
+ + '?mode=edit&operationId=' + encodeURIComponent(operation.id);
},
async deleteOperation(id) {
@@ -428,7 +429,7 @@ document.addEventListener('alpine:init', function() {
},
handleNewOperation() {
- window.location.href = (window.APP_BASE || '') + 'html/wizard/';
+ window.location.href = (window.CrankRoutes && window.CrankRoutes.wizard) || '/wizard/';
},
handleLogout() {
diff --git a/apps/ui/js/config.js b/apps/ui/js/config.js
index 6021737..699747c 100644
--- a/apps/ui/js/config.js
+++ b/apps/ui/js/config.js
@@ -1,20 +1,15 @@
-/**
- * config.js — auto-detects base paths based on current page location.
- * Must be loaded before workspace.js and other navigation-using scripts.
- */
(function() {
- var p = window.location.pathname;
- // html/wizard/ is two levels deep from root
- if (/\/html\/wizard\//.test(p)) {
- window.APP_BASE = '../../';
- window.DATA_URL = '../../data/';
- // html/*.html is one level deep from root
- } else if (/\/html\//.test(p)) {
- window.APP_BASE = '../';
- window.DATA_URL = '../data/';
- // root level (index.html)
- } else {
- window.APP_BASE = '';
- window.DATA_URL = 'data/';
- }
+ window.APP_BASE = '/';
+ window.DATA_URL = '/data/';
+ window.CrankRoutes = {
+ home: '/',
+ login: '/login',
+ agents: '/agents',
+ apiKeys: '/api-keys',
+ logs: '/logs',
+ usage: '/usage',
+ settings: '/settings',
+ workspaceSetup: '/workspace-setup',
+ wizard: '/wizard/'
+ };
}());
diff --git a/apps/ui/js/nav.js b/apps/ui/js/nav.js
index 50e544a..37f0d65 100644
--- a/apps/ui/js/nav.js
+++ b/apps/ui/js/nav.js
@@ -84,7 +84,7 @@
if (dropdown) {
dropdown.style.display = 'none';
}
- window.location.href = (window.APP_BASE || '') + 'html/settings.html#profile';
+ window.location.href = ((window.CrankRoutes && window.CrankRoutes.settings) || '/settings') + '#profile';
});
});
@@ -93,7 +93,7 @@
if (dropdown) {
dropdown.style.display = 'none';
}
- window.location.href = (window.APP_BASE || '') + 'html/settings.html';
+ window.location.href = (window.CrankRoutes && window.CrankRoutes.settings) || '/settings';
});
});
}
diff --git a/apps/ui/js/wizard.js b/apps/ui/js/wizard.js
index b82ae3e..5c9cc18 100644
--- a/apps/ui/js/wizard.js
+++ b/apps/ui/js/wizard.js
@@ -189,14 +189,14 @@ document.addEventListener('DOMContentLoaded', async function() {
var backToCatalog = document.getElementById('back-to-catalog');
if (backToCatalog) {
backToCatalog.addEventListener('click', function() {
- window.location.href = (window.APP_BASE || '') + 'index.html';
+ window.location.href = (window.CrankRoutes && window.CrankRoutes.home) || '/';
});
}
var closeBtn = document.querySelector('.progress-close');
if (closeBtn) {
closeBtn.addEventListener('click', function() {
- window.location.href = (window.APP_BASE || '') + 'index.html';
+ window.location.href = (window.CrankRoutes && window.CrankRoutes.home) || '/';
});
}
diff --git a/apps/ui/js/workspace-setup.js b/apps/ui/js/workspace-setup.js
index ce1ad09..edcf822 100644
--- a/apps/ui/js/workspace-setup.js
+++ b/apps/ui/js/workspace-setup.js
@@ -330,7 +330,7 @@ async function submitForm() {
setFormDirty(false);
if (workspaceFormState.isCreateMode) {
- window.location.href = (window.APP_BASE || '') + 'html/workspace-setup.html';
+ window.location.href = (window.CrankRoutes && window.CrankRoutes.workspaceSetup) || '/workspace-setup';
return;
}
diff --git a/apps/ui/js/workspace.js b/apps/ui/js/workspace.js
index 2f726ea..1b3b90b 100644
--- a/apps/ui/js/workspace.js
+++ b/apps/ui/js/workspace.js
@@ -117,7 +117,7 @@ function renderWorkspaceList() {
' ';
}).join('') +
'
' +
- '
' +
+ ' ' +
' ' +
'Workspace settings' +
' ';
diff --git a/apps/ui/nginx.conf b/apps/ui/nginx.conf
index 14b118a..a14db78 100644
--- a/apps/ui/nginx.conf
+++ b/apps/ui/nginx.conf
@@ -1,10 +1,96 @@
server {
listen 3000;
server_name _;
+ absolute_redirect off;
root /usr/share/nginx/html;
index index.html;
+ location = / {
+ try_files /index.html =404;
+ }
+
+ location = /index.html {
+ return 302 /;
+ }
+
+ location = /login {
+ try_files /html/login.html =404;
+ }
+
+ location = /agents {
+ try_files /html/agents.html =404;
+ }
+
+ location = /api-keys {
+ try_files /html/api-keys.html =404;
+ }
+
+ location = /logs {
+ try_files /html/logs.html =404;
+ }
+
+ location = /usage {
+ try_files /html/usage.html =404;
+ }
+
+ location = /settings {
+ try_files /html/settings.html =404;
+ }
+
+ location = /workspace-setup {
+ try_files /html/workspace-setup.html =404;
+ }
+
+ location = /wizard {
+ return 302 /wizard/;
+ }
+
+ location = /wizard/ {
+ try_files /html/wizard/index.html =404;
+ }
+
+ location ~ ^/wizard/(.+)$ {
+ rewrite ^/wizard/(.+)$ /html/wizard/$1 break;
+ try_files $uri =404;
+ }
+
+ location = /html/login.html {
+ return 302 /login;
+ }
+
+ location = /html/agents.html {
+ return 302 /agents;
+ }
+
+ location = /html/api-keys.html {
+ return 302 /api-keys;
+ }
+
+ location = /html/logs.html {
+ return 302 /logs;
+ }
+
+ location = /html/usage.html {
+ return 302 /usage;
+ }
+
+ location = /html/settings.html {
+ return 302 /settings;
+ }
+
+ location = /html/workspace-setup.html {
+ return 302 /workspace-setup$is_args$args;
+ }
+
+ location = /html/wizard/ {
+ return 302 /wizard/$is_args$args;
+ }
+
+ location = /html/wizard/index.html {
+ return 302 /wizard/;
+ }
+
location / {
try_files $uri $uri/ /index.html;
}