diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/generated/app.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/generated/app.js
index 7d18b688..57d39d74 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/generated/app.js
+++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/generated/app.js
@@ -6051,9 +6051,18 @@ function initSettingsUI() {
}
async function refreshUserManagement() {
const section = document.getElementById("user-management");
- if (!section) return;
- section.style.display = authEnabled && authRole === "admin" ? "block" : "none";
- if (section.style.display === "none") return;
+ const tab = document.getElementById("settings-users-tab");
+ if (!section || !tab) return;
+ const canManageUsers = authEnabled && authRole === "admin";
+ tab.style.display = canManageUsers ? "" : "none";
+ if (!canManageUsers) {
+ const panel = document.getElementById("subtab-settings-users");
+ if (panel) panel.style.display = "none";
+ if (tab.classList.contains("active")) {
+ document.querySelector('[data-subtab="settings-scheduler"]')?.click();
+ }
+ return;
+ }
const list = requiredElement("user-list");
try {
const users = await listUsers();
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html
index a1cc9fb9..985da4ae 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html
+++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/index.html
@@ -1461,6 +1461,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
+
@@ -1750,8 +1751,8 @@ SPDX-License-Identifier: GPL-2.0-or-later
-
- User management
+
About
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/app.ts b/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/app.ts
index 1e93420e..f9ee773f 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/app.ts
+++ b/src/trx-client/trx-frontend/trx-frontend-http/frontend/src/app.ts
@@ -5055,9 +5055,18 @@ function initSettingsUI() {
async function refreshUserManagement() {
const section = document.getElementById("user-management");
- if (!section) return;
- section.style.display = authEnabled && authRole === "admin" ? "block" : "none";
- if (section.style.display === "none") return;
+ const tab = document.getElementById("settings-users-tab");
+ if (!section || !tab) return;
+ const canManageUsers = authEnabled && authRole === "admin";
+ tab.style.display = canManageUsers ? "" : "none";
+ if (!canManageUsers) {
+ const panel = document.getElementById("subtab-settings-users");
+ if (panel) panel.style.display = "none";
+ if (tab.classList.contains("active")) {
+ document.querySelector('[data-subtab="settings-scheduler"]')?.click();
+ }
+ return;
+ }
const list = requiredElement("user-list");
try {
const users = await listUsers();
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/frontend/tests/smoke.test.mjs b/src/trx-client/trx-frontend/trx-frontend-http/frontend/tests/smoke.test.mjs
index 6370d8c7..374b9ff8 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/frontend/tests/smoke.test.mjs
+++ b/src/trx-client/trx-frontend/trx-frontend-http/frontend/tests/smoke.test.mjs
@@ -9,6 +9,7 @@ import { readFile } from "node:fs/promises";
const indexPath = new URL("../../assets/web/index.html", import.meta.url);
const pluginLoaderPath = new URL("../src/plugin-loader.ts", import.meta.url);
const mapCorePath = new URL("../src/map-core.ts", import.meta.url);
+const appPath = new URL("../src/app.ts", import.meta.url);
test("index loads one first-party application bootstrap", async () => {
const html = await readFile(indexPath, "utf8");
@@ -30,6 +31,17 @@ test("startup has no remote script or stylesheet dependencies", async () => {
);
});
+test("administrator user management is a dedicated Settings sub-tab", async () => {
+ const [html, app] = await Promise.all([
+ readFile(indexPath, "utf8"),
+ readFile(appPath, "utf8"),
+ ]);
+ assert.match(html, /data-subtab="settings-users"/);
+ assert.match(html, /id="subtab-settings-users" class="sub-tab-panel"/);
+ assert.match(app, /authEnabled && authRole === "admin"/);
+ assert.match(app, /settings-users-tab/);
+});
+
test("lazy frontend features use modules and local map symbols", async () => {
const [loader, map] = await Promise.all([
readFile(pluginLoaderPath, "utf8"),