8.2 KiB
Interface — 0.0.1
The interface uses the application's real API. It does not populate sample devices, simulate operation results, or present disconnected actions as working features.
Build and runtime
build.rs reads web/assets.list and combines the sources into one app.js and
one app.css. Both files and index.html are embedded in the Rust executable.
Building or running the application does not require Node, Angular, a frontend
server, nginx, an external CDN, or a font service.
| Source file | Responsibility |
|---|---|
web/js/i18n.js |
Polish, English, Spanish, and Norwegian dictionaries, including completed missing source translations |
web/js/core.js |
API access, formatting, HTML escaping, forms, and dialogs |
web/js/views.js |
Views and data presentation |
web/js/app.js |
Routing, sessions, and user actions |
web/css/app.css |
Responsive layout, themes, components, and diff styling |
Revision 4 translates project documentation into English. It does not change the interface's four supported languages or users' saved language preferences.
Views and actions
| Route | Features |
|---|---|
/login, /register |
Sign-in, registration only when enabled on the server, and validation errors |
/ |
Counts, recent backups, saved connection status, disk usage, seven-day activity, logs, and batch actions with partial results |
/devices |
Device search/filtering, creation, editing, ping, and connection tests |
/devices/:id |
Metadata, the latest test, backups, policies, and device deletion; RSC exports only for RouterOS |
/files |
Filtering, sorting, download, RSC preview, email, binary upload, ZIP, and bulk deletion |
/diff-configs |
Export selection, side-by-side and unified views, line numbers, statistics, search, changes-only mode, synchronized scrolling, and diff/HTML download |
/logs |
Actual messages and timestamps, search, pagination, and confirmed cleanup |
/settings |
Retention, automation, credentials, SMTP, Pushover, and account preferences |
/settings?tab=automation |
Flat scheduled-task controls, cron expressions, and actual next execution times |
/settings?tab=account |
Account tab with password change, matching-password confirmation, and language/font preferences |
/schedule |
Compatibility redirect to /settings?tab=automation |
/change-password |
Compatibility redirect to /settings?tab=account |
/routers and /routers/:id are device-route aliases. A Git screen and a standalone
SwOS beta module were not part of the active source API, so they are not presented
as available features. Binary upload writes a file to the device; it does not
perform a restore or restart automatically.
Behavior details
- Operations show results after receiving an API response. Deletion and upload require confirmation. Batch backup results include failures and skipped devices.
- Comparison is available only for RSC exports. The bulk compare action appears when exactly two exports are selected. Binary and SwitchOS files have no diff action. SwitchOS has no exports tab, export action, or export policy control. Diff errors use the existing toast notification without an extra error block inside the form.
- Secret fields are never prefilled. A blank field preserves the secret; a separate explicit control clears it. Revealing the global SSH key requires the account password. Closing the dialog removes the revealed text from the interface.
- The SwitchOS form has an explicit credential-source selector.
use_global_switchos_credentials=trueuses only the current global credentials;falseuses only the device's credentials. In global mode, the UI sends neitherssh_usernorssh_passwordnor their clear controls. Stored local values are retained.has_own_passwordsupplies a presence hint for the empty password field, never the password itself. A legacy record withnullpreserves its original fallback behavior on an ordinary save until the user explicitly selects a source. - The Bearer token is kept in the current tab's
sessionStorage. An existingrouteros_tokenfrom the old UI is moved into the session only after successful verification through/auth/me. Signing out clears the client session. API_PREFIXcomes from page metadata inserted by the server.- The server supplies
ALLOW_REGISTRATIONthrough<meta name="allow-registration" content="false">. If the tag is absent or its value is anything other thantrue, the registration link is hidden and/registerredirects to sign-in. The API independently enforces the same setting. - Password changes live in Settings → Account, without a separate navigation item. The previous direct route continues to work through a redirect.
- Language and font are saved through
/auth/preferences. Theme and sidebar width are browser preferences. Font stacks preserve Inter/system UI, Roboto Mono/IBM Plex Mono, Adwaita Mono, and Hack. If a font is not installed, the browser uses the configured fallback; no font is downloaded at runtime. - Names, logs, exports, and diff content are escaped as text before presentation. Server-generated diff HTML is downloaded as a file, not inserted into the app DOM.
- Weekly scheduling writes weekday names
mon–sun. Imported numbers preserve APScheduler's actual semantics: 0 = Monday, 6 = Sunday. The old interface described these numbers inconsistently; this editor shows the actual scheduled day. - Automation is part of Settings without a separate navigation item.
/settings?tab=schedulealso redirects toautomation. Schedule fields and next-run information use plain rows rather than nested cards or bordered panels. - A small API documentation footer link opens local
/docs. The backend serves this page separately from the SPA router. - If the host disallows ICMP socket creation, ping shows an unknown state with the diagnostic reason. Missing process permissions are not reported as a router outage.
Interface tests
These are development tools. Node and Playwright are not application dependencies.
node web/tests/core.test.cjs
The core suite runs without npm packages. It covers translations, HTML injection protection, secret handling in forms, UTC dates, cron semantics, and presentation of actual data structures. The browser suite requires Playwright and Chromium. It starts an isolated server with controlled API responses and exercises sign-in, device CRUD, backups, diff, settings, languages, policies, confirmation dialogs, and mobile layout. It does not connect to routers or notification services.
For an optional, repeatable browser-tool installation outside the project, run the following from the project root in one shell. Node.js and npm must be available:
MBS_UI_TEST_DIR="$(mktemp -d "${TMPDIR:-/tmp}/mbs-ui-tests.XXXXXX")"
npm install --prefix "$MBS_UI_TEST_DIR" --no-audit --no-fund --save-exact playwright@1.62.1
export NODE_PATH="$MBS_UI_TEST_DIR/node_modules${NODE_PATH:+:$NODE_PATH}"
export PLAYWRIGHT_BROWSERS_PATH="$MBS_UI_TEST_DIR/browsers"
node "$MBS_UI_TEST_DIR/node_modules/playwright/cli.js" install chromium
node web/tests/smoke.cjs
The npm package and downloaded browser remain under the temporary directory named
by MBS_UI_TEST_DIR; the project does not gain node_modules, package.json, or
an npm lockfile. Remove that temporary directory when finished. If Chromium is
already installed, skip its download and set MBS_CHROMIUM to the existing
executable path. These environment variables also apply to the live-server check
below.
To check an actual running server without changing its data:
MBS_BASE_URL=http://127.0.0.1:5581 \
MBS_TEST_USERNAME=admin \
MBS_TEST_PASSWORD='test-account-password' \
node web/tests/live.cjs
MBS_CHROMIUM optionally selects an existing Chromium executable.
MBS_SCREENSHOT_DIR saves local screenshots for inspection. The live check verifies
views against the actual backend, JavaScript/API/CSP errors, and responsive layout;
it does not create backups, upload files, or send notifications. Revision-specific
execution results are recorded in the validation report; the
presence of a test in the source tree does not imply that it has been rerun for
every revision.