ui: add frontend diagnostics and stable test hooks

This commit is contained in:
a.tolmachev
2026-04-12 11:23:10 +03:00
parent d85f7ddf05
commit 1cb4cbc960
13 changed files with 229 additions and 51 deletions
+12 -12
View File
@@ -52,7 +52,7 @@
<div class="ws-switcher" id="ws-switcher">
<button class="ws-switcher-trigger" onclick="toggleWsSwitcher(event)">
<div class="ws-dot" id="ws-dot">A</div>
<span class="ws-current-name" id="ws-current-name">workspace</span>
<span class="ws-current-name" id="ws-current-name" data-testid="shell-workspace-name">workspace</span>
<svg width="11" height="11" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 6l4 4 4-4"/></svg>
</button>
<div class="ws-dropdown" id="ws-dropdown" style="display:none">
@@ -81,9 +81,9 @@
<button class="nav-icon-btn" data-i18n-title="nav.notifications" title="Notifications"><svg width="15" height="15"><use href="icons/general/bell.svg#icon"/></svg></button>
<div class="nav-divider"></div>
<div class="user-menu">
<div class="nav-avatar" data-i18n-title="nav.account" title="Account">AT</div>
<div class="nav-avatar" data-testid="shell-avatar" data-i18n-title="nav.account" title="Account">AT</div>
<div class="user-dropdown">
<div class="user-dropdown-header"><div class="user-dropdown-name">Crank</div><div class="user-dropdown-role"></div></div>
<div class="user-dropdown-header"><div class="user-dropdown-name" data-testid="shell-user-name">Crank</div><div class="user-dropdown-role" data-testid="shell-user-role"></div></div>
<button class="user-dropdown-item" data-action="settings-link"><svg width="13" height="13"><use href="icons/general/settings.svg#icon"/></svg><span data-i18n="nav.settings">Settings</span></button>
<div class="dropdown-divider"></div>
<button class="user-dropdown-item danger" data-action="logout"><svg width="13" height="13"><use href="icons/general/logout.svg#icon"/></svg><span data-i18n="nav.logout">Log out</span></button>
@@ -108,7 +108,7 @@
<p class="page-subtitle" data-i18n="secrets.subtitle">Encrypted upstream credentials for bearer tokens, basic auth, and API keys used by auth profiles.</p>
</div>
<div class="page-header-actions">
<button class="btn-primary" id="btn-create-secret" type="button">
<button class="btn-primary" id="btn-create-secret" data-testid="secret-create-button" type="button">
<svg width="13" height="13" viewBox="0 0 16 16" fill="currentColor"><path d="M7.75 2a.75.75 0 01.75.75V7h4.25a.75.75 0 010 1.5H8.5v4.25a.75.75 0 01-1.5 0V8.5H2.75a.75.75 0 010-1.5H7V2.75A.75.75 0 017.75 2z"/></svg>
<span data-i18n="secrets.new">Create secret</span>
</button>
@@ -168,7 +168,7 @@
</div>
</div>
<div class="modal-overlay" id="secret-modal">
<div class="modal-overlay" id="secret-modal" data-testid="secret-modal">
<div class="modal">
<div class="modal-header">
<span class="modal-title" id="secret-modal-title" data-i18n="secrets.modal.create_title">Create secret</span>
@@ -181,13 +181,13 @@
<div class="modal-body">
<div class="field-group">
<label class="field-label" data-i18n="secrets.modal.name">Secret name</label>
<input class="field-input" id="secret-name" type="text" autocomplete="off">
<input class="field-input" id="secret-name" data-testid="secret-name-input" type="text" autocomplete="off">
<div class="field-hint" data-i18n="secrets.modal.name_hint">Use a stable operator-facing label. Plaintext values are never returned after storage.</div>
</div>
<div class="field-group">
<label class="field-label" data-i18n="secrets.modal.kind">Secret kind</label>
<select class="field-select" id="secret-kind">
<select class="field-select" id="secret-kind" data-testid="secret-kind-select">
<option value="token" data-i18n="secrets.kind.token">Token</option>
<option value="username_password" data-i18n="secrets.kind.username_password">Username/password</option>
<option value="header" data-i18n="secrets.kind.header">Header value</option>
@@ -199,23 +199,23 @@
<div class="secret-value-grid" id="secret-value-fields">
<div class="field-group" data-kind-field="string">
<label class="field-label" id="secret-string-label" data-i18n="secrets.modal.value">Secret value</label>
<input class="field-input" id="secret-string-value" type="text" autocomplete="off">
<input class="field-input" id="secret-string-value" data-testid="secret-value-input" type="text" autocomplete="off">
</div>
<div class="field-row" data-kind-field="basic" style="display:none;">
<div class="field-group">
<label class="field-label" data-i18n="secrets.modal.username">Username</label>
<input class="field-input" id="secret-username" type="text" autocomplete="off">
<input class="field-input" id="secret-username" data-testid="secret-username-input" type="text" autocomplete="off">
</div>
<div class="field-group">
<label class="field-label" data-i18n="secrets.modal.password">Password</label>
<input class="field-input" id="secret-password" type="password" autocomplete="new-password">
<input class="field-input" id="secret-password" data-testid="secret-password-input" type="password" autocomplete="new-password">
</div>
</div>
<div class="field-group" data-kind-field="json" style="display:none;">
<label class="field-label" data-i18n="secrets.modal.json_payload">JSON payload</label>
<textarea class="field-textarea code-textarea" id="secret-json-value" rows="8" spellcheck="false"></textarea>
<textarea class="field-textarea code-textarea" id="secret-json-value" data-testid="secret-json-input" rows="8" spellcheck="false"></textarea>
<div class="field-hint" data-i18n="secrets.modal.json_hint">Useful for generic secret payloads. The value must be valid JSON.</div>
</div>
</div>
@@ -224,7 +224,7 @@
</div>
<div class="modal-footer">
<button class="btn-secondary" id="secret-modal-cancel-btn" type="button" data-i18n="secrets.modal.cancel">Cancel</button>
<button class="btn-primary" id="secret-modal-submit-btn" type="button" data-i18n="secrets.modal.create_action">Create secret</button>
<button class="btn-primary" id="secret-modal-submit-btn" data-testid="secret-submit-button" type="button" data-i18n="secrets.modal.create_action">Create secret</button>
</div>
</div>
</div>