feat: persist current workspace in user sessions

This commit is contained in:
a.tolmachev
2026-03-31 15:17:07 +03:00
parent 84f4437ce0
commit 86b61523bd
15 changed files with 331 additions and 57 deletions
+85 -20
View File
@@ -4,6 +4,7 @@ var WS_LIST = [
var workspaceLoadPromise = null;
var workspaceLoadFailed = false;
var lastWorkspaceId = null;
function workspaceColor(index) {
return ['#0d9488', '#7c3aed', '#0891b2', '#f59e0b', '#2563eb'][index % 5];
@@ -13,11 +14,14 @@ function mapWorkspace(record, index) {
var workspace = record && record.workspace ? record.workspace : record;
var displayName = workspace.display_name || workspace.slug || workspace.id;
var settings = workspace.settings || {};
var role = record && record.role
? String(record.role).replace(/^\w/, function(char) { return char.toUpperCase(); })
: 'Owner';
return {
id: workspace.id,
slug: workspace.slug,
name: displayName,
role: 'Owner',
role: role,
letter: displayName.charAt(0).toUpperCase(),
color: settings.color || workspaceColor(index),
status: workspace.status,
@@ -25,29 +29,60 @@ function mapWorkspace(record, index) {
};
}
function selectedWorkspaceId() {
return localStorage.getItem('crank_workspace_id');
function cachedWorkspaceId() {
try {
return localStorage.getItem('crank_workspace_id');
} catch (_error) {
return null;
}
}
function selectedWorkspaceSlug() {
return localStorage.getItem('crank_workspace_slug');
function cachedWorkspaceSlug() {
try {
return localStorage.getItem('crank_workspace_slug');
} catch (_error) {
return null;
}
}
function persistCurrentWorkspace(workspace) {
function sessionWorkspaceId() {
if (!window.CrankAuth || typeof window.CrankAuth.getCachedSession !== 'function') {
return null;
}
var session = window.CrankAuth.getCachedSession();
return session && session.current_workspace_id ? session.current_workspace_id : null;
}
function cacheCurrentWorkspace(workspace) {
if (!workspace) return;
localStorage.setItem('crank_workspace_id', workspace.id);
localStorage.setItem('crank_workspace_slug', workspace.slug);
try {
localStorage.setItem('crank_workspace_id', workspace.id);
localStorage.setItem('crank_workspace_slug', workspace.slug);
} catch (_error) {}
}
function resolveCurrentWorkspace() {
var workspaceId = sessionWorkspaceId() || cachedWorkspaceId();
var workspaceSlug = cachedWorkspaceSlug();
return WS_LIST.find(function(item) { return item.id === workspaceId; })
|| WS_LIST.find(function(item) { return item.slug === workspaceSlug; })
|| WS_LIST[0]
|| null;
}
function emitWorkspaceChange(workspace) {
if (!workspace) {
return;
}
lastWorkspaceId = workspace.id;
window.dispatchEvent(new CustomEvent('crank:workspacechange', { detail: workspace }));
}
function getCurrentWs() {
var workspaceId = selectedWorkspaceId();
var workspaceSlug = selectedWorkspaceSlug();
var workspace = WS_LIST.find(function(item) { return item.id === workspaceId; })
|| WS_LIST.find(function(item) { return item.slug === workspaceSlug; })
|| WS_LIST[0];
var workspace = resolveCurrentWorkspace();
if (workspace) {
persistCurrentWorkspace(workspace);
cacheCurrentWorkspace(workspace);
}
return workspace;
@@ -134,17 +169,39 @@ function toggleWsSwitcher(e) {
function switchWorkspace(workspaceId) {
var workspace = WS_LIST.find(function(item) { return item.id === workspaceId; });
if (!workspace) return;
persistCurrentWorkspace(workspace);
var dd = document.getElementById('ws-dropdown');
if (dd) dd.style.display = 'none';
renderWorkspaceList();
window.dispatchEvent(new CustomEvent('crank:workspacechange', { detail: workspace }));
if (!window.CrankApi || !window.CrankAuth || typeof window.CrankAuth.replaceSession !== 'function') {
cacheCurrentWorkspace(workspace);
renderWorkspaceList();
emitWorkspaceChange(workspace);
return;
}
return window.CrankApi
.setCurrentWorkspace(workspace.id)
.then(function(session) {
window.CrankAuth.replaceSession(session);
cacheCurrentWorkspace(workspace);
renderWorkspaceList();
emitWorkspaceChange(workspace);
return workspace;
})
.catch(function(error) {
if (window.CrankUi) {
window.CrankUi.error(error.message || 'Failed to switch workspace', 'Workspace switch failed');
}
throw error;
});
}
function setCurrentWorkspace(workspace) {
persistCurrentWorkspace(workspace);
renderWorkspaceList();
window.dispatchEvent(new CustomEvent('crank:workspacechange', { detail: workspace }));
if (!workspace) {
return Promise.resolve(null);
}
return Promise.resolve(switchWorkspace(workspace.id));
}
window.getCurrentWorkspace = getCurrentWs;
@@ -155,6 +212,14 @@ window.hasWorkspaceApiFailure = function() { return workspaceLoadFailed; };
document.addEventListener('DOMContentLoaded', initWorkspaceSwitcher);
window.addEventListener('crank:sessionchange', function() {
var workspace = getCurrentWs();
renderWorkspaceList();
if (workspace && workspace.id !== lastWorkspaceId) {
emitWorkspaceChange(workspace);
}
});
document.addEventListener('click', function(e) {
if (!e.target.closest('#ws-switcher')) {
var dd = document.getElementById('ws-dropdown');