ui: unify shell identity rendering

This commit is contained in:
a.tolmachev
2026-04-12 02:06:20 +03:00
parent c69c327123
commit 22227ba523
3 changed files with 13 additions and 53 deletions
+7 -6
View File
@@ -2,19 +2,20 @@
## Current
### `feat/frontend-shell-unification`
### `feat/frontend-wizard-modularization`
Status: in_progress
DoD:
- duplicated shell identity logic is removed from `auth.js` and `nav.js`
- one shared source of truth renders avatar, name, role, and menu state
- pages keep the current shell behavior after the consolidation
- no page depends on divergent copies of `crank_user` handling
- `wizard.js` is split into smaller modules by responsibility
- global mutable wizard state is reduced to one explicit shared state object
- protocol-specific logic is separated from navigation/rendering plumbing
- the existing wizard flow keeps working after the split
- targeted wizard e2e coverage stays green
## Next
- `feat/frontend-wizard-modularization`
- `feat/frontend-build-pipeline`
## Backlog
+3
View File
@@ -226,6 +226,9 @@
fetchSession: fetchSession,
replaceSession: replaceSession,
getCachedSession: function() { return sessionCache; },
renderShellIdentity: function() {
renderShellIdentity(sessionCache);
},
guardProtectedPage: guardProtectedPage,
guardLoginPage: guardLoginPage,
login: login,
+3 -47
View File
@@ -1,52 +1,8 @@
(function () {
var STORAGE_KEY = 'crank_user';
function tKey(key) {
return typeof t === 'function' ? t(key) : key;
}
function roleLabel(role) {
var normalized = String(role || 'viewer').toLowerCase();
if (normalized === 'operator' || normalized === 'developer') return tKey('workspace_setup.role.operator');
if (normalized === 'owner') return tKey('workspace_setup.role.owner');
if (normalized === 'admin') return tKey('workspace_setup.role.admin');
if (normalized === 'viewer') return tKey('workspace_setup.role.viewer');
return normalized.replace(/^\w/, function (character) {
return character.toUpperCase();
});
}
function currentUser() {
try {
return JSON.parse(localStorage.getItem(STORAGE_KEY));
} catch (_error) {
return null;
}
}
function fillUserInfo() {
var user = currentUser();
if (!user) {
return;
}
document.querySelectorAll('.nav-avatar').forEach(function (element) {
element.textContent = user.initials || 'CR';
});
var nameElement = document.querySelector('.user-dropdown-name');
var roleElement = document.querySelector('.user-dropdown-role');
if (nameElement) {
nameElement.textContent = user.name || tKey('nav.user_fallback');
}
if (roleElement) {
roleElement.textContent = roleLabel(user.role) + ' · ' + (user.workspace || tKey('nav.workspace_fallback'));
}
}
function initNav() {
fillUserInfo();
if (window.CrankAuth && typeof window.CrankAuth.renderShellIdentity === 'function') {
window.CrankAuth.renderShellIdentity();
}
var dropdown = document.querySelector('.user-dropdown');
var avatar = document.querySelector('.nav-avatar');