diff --git a/TASKS.md b/TASKS.md index 6c3df06..ebb98c0 100644 --- a/TASKS.md +++ b/TASKS.md @@ -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 diff --git a/apps/ui/js/auth.js b/apps/ui/js/auth.js index 489f112..01a8027 100644 --- a/apps/ui/js/auth.js +++ b/apps/ui/js/auth.js @@ -226,6 +226,9 @@ fetchSession: fetchSession, replaceSession: replaceSession, getCachedSession: function() { return sessionCache; }, + renderShellIdentity: function() { + renderShellIdentity(sessionCache); + }, guardProtectedPage: guardProtectedPage, guardLoginPage: guardLoginPage, login: login, diff --git a/apps/ui/js/nav.js b/apps/ui/js/nav.js index 704d06d..bf5da50 100644 --- a/apps/ui/js/nav.js +++ b/apps/ui/js/nav.js @@ -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');