chore: publish clean community baseline
This commit is contained in:
@@ -0,0 +1,287 @@
|
||||
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 tKey(key) {
|
||||
return typeof t === 'function' ? t(key) : key;
|
||||
}
|
||||
function tfKey(key, vars) {
|
||||
return typeof tf === 'function' ? tf(key, vars) : key;
|
||||
}
|
||||
|
||||
function buildIconSvg(href, width, height) {
|
||||
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
svg.setAttribute('width', String(width));
|
||||
svg.setAttribute('height', String(height));
|
||||
var use = document.createElementNS('http://www.w3.org/2000/svg', 'use');
|
||||
use.setAttribute('href', href);
|
||||
svg.appendChild(use);
|
||||
return svg;
|
||||
}
|
||||
|
||||
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(); })
|
||||
: tKey('workspace_setup.role.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;
|
||||
window.CrankDom.clear(list);
|
||||
|
||||
WS_LIST.forEach(function(workspace) {
|
||||
var active = current && workspace.id === current.id;
|
||||
var item = document.createElement('div');
|
||||
item.className = 'ws-dropdown-item' + (active ? ' active' : '');
|
||||
item.addEventListener('click', function() {
|
||||
switchWorkspace(workspace.id);
|
||||
});
|
||||
|
||||
var dot = document.createElement('div');
|
||||
dot.className = 'ws-item-dot';
|
||||
dot.style.background = workspace.color;
|
||||
dot.textContent = workspace.letter;
|
||||
item.appendChild(dot);
|
||||
|
||||
var info = document.createElement('div');
|
||||
info.className = 'ws-item-info';
|
||||
var name = document.createElement('div');
|
||||
name.className = 'ws-item-name';
|
||||
name.textContent = workspace.name;
|
||||
var role = document.createElement('div');
|
||||
role.className = 'ws-item-role';
|
||||
role.textContent = workspace.role;
|
||||
info.appendChild(name);
|
||||
info.appendChild(role);
|
||||
item.appendChild(info);
|
||||
|
||||
if (active) {
|
||||
var check = buildIconSvg(
|
||||
(window.APP_BASE || '') + 'icons/general/check.svg#icon',
|
||||
12,
|
||||
12
|
||||
);
|
||||
item.appendChild(check);
|
||||
}
|
||||
|
||||
list.appendChild(item);
|
||||
});
|
||||
|
||||
var divider = document.createElement('div');
|
||||
divider.className = 'ws-dropdown-divider';
|
||||
list.appendChild(divider);
|
||||
|
||||
var manageLink = document.createElement('a');
|
||||
manageLink.className = 'ws-dropdown-mgmt-link';
|
||||
manageLink.href = (window.CrankRoutes && window.CrankRoutes.workspaceSetup) || '/workspace-setup';
|
||||
manageLink.addEventListener('click', function() {
|
||||
var dd = document.getElementById('ws-dropdown');
|
||||
if (dd) dd.hidden = true;
|
||||
});
|
||||
manageLink.appendChild(
|
||||
buildIconSvg(
|
||||
(window.APP_BASE || '') + 'icons/general/settings.svg#icon',
|
||||
14,
|
||||
14
|
||||
)
|
||||
);
|
||||
manageLink.appendChild(document.createTextNode(tKey('settings.ws.title')));
|
||||
list.appendChild(manageLink);
|
||||
}
|
||||
|
||||
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.hidden = !dd.hidden;
|
||||
}
|
||||
|
||||
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.hidden = true;
|
||||
|
||||
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 || tKey('workspace.switch_error'), tKey('workspace.switch_error_title'));
|
||||
}
|
||||
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.hidden = true;
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user