229 lines
6.8 KiB
JavaScript
229 lines
6.8 KiB
JavaScript
var WS_LIST = [
|
|
{ id: 'ws_default', slug: 'default', name: 'Default workspace', role: 'Owner', letter: 'D', color: '#0d9488' }
|
|
];
|
|
|
|
var workspaceLoadPromise = null;
|
|
var workspaceLoadFailed = false;
|
|
var lastWorkspaceId = null;
|
|
|
|
function workspaceColor(index) {
|
|
return ['#0d9488', '#7c3aed', '#0891b2', '#f59e0b', '#2563eb'][index % 5];
|
|
}
|
|
|
|
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: role,
|
|
letter: displayName.charAt(0).toUpperCase(),
|
|
color: settings.color || workspaceColor(index),
|
|
status: workspace.status,
|
|
settings: settings,
|
|
};
|
|
}
|
|
|
|
function cachedWorkspaceId() {
|
|
try {
|
|
return localStorage.getItem('crank_workspace_id');
|
|
} catch (_error) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function cachedWorkspaceSlug() {
|
|
try {
|
|
return localStorage.getItem('crank_workspace_slug');
|
|
} catch (_error) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
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;
|
|
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 workspace = resolveCurrentWorkspace();
|
|
|
|
if (workspace) {
|
|
cacheCurrentWorkspace(workspace);
|
|
}
|
|
|
|
return workspace;
|
|
}
|
|
|
|
function updateWorkspaceHeader(workspace) {
|
|
var nameEl = document.getElementById('ws-current-name');
|
|
var dotEl = document.getElementById('ws-dot');
|
|
if (nameEl) nameEl.textContent = workspace ? workspace.name : 'No workspace';
|
|
if (dotEl && workspace) {
|
|
dotEl.textContent = workspace.letter;
|
|
dotEl.style.background = workspace.color;
|
|
}
|
|
}
|
|
|
|
function renderWorkspaceList() {
|
|
var current = getCurrentWs();
|
|
updateWorkspaceHeader(current);
|
|
|
|
var list = document.getElementById('ws-dropdown-list');
|
|
if (!list) return;
|
|
|
|
list.innerHTML = WS_LIST.map(function(workspace) {
|
|
var active = current && workspace.id === current.id;
|
|
return '<div class="ws-dropdown-item' + (active ? ' active' : '') + '" onclick="switchWorkspace(\'' + workspace.id + '\')">' +
|
|
'<div class="ws-item-dot" style="background:' + workspace.color + '">' + workspace.letter + '</div>' +
|
|
'<div class="ws-item-info">' +
|
|
'<div class="ws-item-name">' + workspace.name + '</div>' +
|
|
'<div class="ws-item-role">' + workspace.role + '</div>' +
|
|
'</div>' +
|
|
(active ? '<svg width="12" height="12"><use href="' + (window.APP_BASE || '') + 'icons/general/check.svg#icon"/></svg>' : '') +
|
|
'</div>';
|
|
}).join('') +
|
|
'<div class="ws-dropdown-divider"></div>' +
|
|
'<a class="ws-dropdown-mgmt-link" href="' + (window.APP_BASE || '') + 'html/workspace-setup.html" onclick="var dd=document.getElementById(\'ws-dropdown\');if(dd)dd.style.display=\'none\'">' +
|
|
'<svg width="14" height="14"><use href="' + (window.APP_BASE || '') + 'icons/general/settings.svg#icon"/></svg>' +
|
|
'Workspace settings' +
|
|
'</a>';
|
|
}
|
|
|
|
async function loadWorkspaces() {
|
|
if (workspaceLoadPromise) return workspaceLoadPromise;
|
|
|
|
workspaceLoadPromise = (async function() {
|
|
if (!window.CrankApi) {
|
|
renderWorkspaceList();
|
|
return WS_LIST;
|
|
}
|
|
|
|
try {
|
|
var response = await window.CrankApi.listWorkspaces();
|
|
var items = (response && response.items ? response.items : []).map(mapWorkspace);
|
|
if (items.length > 0) {
|
|
WS_LIST = items;
|
|
}
|
|
workspaceLoadFailed = false;
|
|
} catch (_error) {
|
|
workspaceLoadFailed = true;
|
|
}
|
|
|
|
renderWorkspaceList();
|
|
return WS_LIST;
|
|
}());
|
|
|
|
return workspaceLoadPromise;
|
|
}
|
|
|
|
async function refreshWorkspaces() {
|
|
workspaceLoadPromise = null;
|
|
return loadWorkspaces();
|
|
}
|
|
|
|
function initWorkspaceSwitcher() {
|
|
renderWorkspaceList();
|
|
loadWorkspaces();
|
|
}
|
|
|
|
function toggleWsSwitcher(e) {
|
|
e.stopPropagation();
|
|
var dd = document.getElementById('ws-dropdown');
|
|
if (dd) dd.style.display = dd.style.display === 'none' ? '' : 'none';
|
|
}
|
|
|
|
function switchWorkspace(workspaceId) {
|
|
var workspace = WS_LIST.find(function(item) { return item.id === workspaceId; });
|
|
if (!workspace) return;
|
|
|
|
var dd = document.getElementById('ws-dropdown');
|
|
if (dd) dd.style.display = 'none';
|
|
|
|
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) {
|
|
if (!workspace) {
|
|
return Promise.resolve(null);
|
|
}
|
|
return Promise.resolve(switchWorkspace(workspace.id));
|
|
}
|
|
|
|
window.getCurrentWorkspace = getCurrentWs;
|
|
window.whenWorkspacesReady = loadWorkspaces;
|
|
window.refreshWorkspaces = refreshWorkspaces;
|
|
window.setCurrentWorkspace = setCurrentWorkspace;
|
|
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');
|
|
if (dd) dd.style.display = 'none';
|
|
}
|
|
});
|