feat: connect alpine operations and wizard to admin api
This commit is contained in:
+114
-30
@@ -1,44 +1,121 @@
|
||||
/* ═══════════════════════════════════════════════════
|
||||
Crank — workspace switcher
|
||||
═══════════════════════════════════════════════════ */
|
||||
|
||||
var WS_LIST = [
|
||||
{ slug: 'acme-workspace', name: 'acme-workspace', role: 'Owner', letter: 'A', color: '#0d9488' },
|
||||
{ slug: 'startup-demo', name: 'startup-demo', role: 'Developer', letter: 'S', color: '#7c3aed' },
|
||||
{ slug: 'personal', name: 'personal', role: 'Owner', letter: 'P', color: '#0891b2' },
|
||||
{ id: 'ws_default', slug: 'default', name: 'Default workspace', role: 'Owner', letter: 'D', color: '#0d9488' }
|
||||
];
|
||||
|
||||
function getCurrentWs() {
|
||||
var slug = localStorage.getItem('crank_workspace') || 'acme-workspace';
|
||||
return WS_LIST.find(function(w) { return w.slug === slug; }) || WS_LIST[0];
|
||||
var workspaceLoadPromise = null;
|
||||
var workspaceLoadFailed = false;
|
||||
|
||||
function workspaceColor(index) {
|
||||
return ['#0d9488', '#7c3aed', '#0891b2', '#f59e0b', '#2563eb'][index % 5];
|
||||
}
|
||||
|
||||
function initWorkspaceSwitcher() {
|
||||
var ws = getCurrentWs();
|
||||
function mapWorkspace(record, index) {
|
||||
var workspace = record && record.workspace ? record.workspace : record;
|
||||
var displayName = workspace.display_name || workspace.slug || workspace.id;
|
||||
return {
|
||||
id: workspace.id,
|
||||
slug: workspace.slug,
|
||||
name: displayName,
|
||||
role: 'Owner',
|
||||
letter: displayName.charAt(0).toUpperCase(),
|
||||
color: workspaceColor(index),
|
||||
status: workspace.status,
|
||||
};
|
||||
}
|
||||
|
||||
function selectedWorkspaceId() {
|
||||
return localStorage.getItem('crank_workspace_id');
|
||||
}
|
||||
|
||||
function selectedWorkspaceSlug() {
|
||||
return localStorage.getItem('crank_workspace_slug');
|
||||
}
|
||||
|
||||
function persistCurrentWorkspace(workspace) {
|
||||
if (!workspace) return;
|
||||
localStorage.setItem('crank_workspace_id', workspace.id);
|
||||
localStorage.setItem('crank_workspace_slug', workspace.slug);
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
if (workspace) {
|
||||
persistCurrentWorkspace(workspace);
|
||||
}
|
||||
|
||||
return workspace;
|
||||
}
|
||||
|
||||
function updateWorkspaceHeader(workspace) {
|
||||
var nameEl = document.getElementById('ws-current-name');
|
||||
var dotEl = document.getElementById('ws-dot');
|
||||
if (nameEl) nameEl.textContent = ws.name;
|
||||
if (dotEl) { dotEl.textContent = ws.letter; dotEl.style.background = ws.color; }
|
||||
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(w) {
|
||||
var active = w.slug === ws.slug;
|
||||
return '<div class="ws-dropdown-item' + (active ? ' active' : '') + '" onclick="switchWorkspace(\'' + w.slug + '\')">' +
|
||||
'<div class="ws-item-dot" style="background:' + w.color + '">' + w.letter + '</div>' +
|
||||
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">' + w.name + '</div>' +
|
||||
'<div class="ws-item-role">' + w.role + '</div>' +
|
||||
'<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>' : '') +
|
||||
(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>';
|
||||
'<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;
|
||||
}
|
||||
|
||||
function initWorkspaceSwitcher() {
|
||||
renderWorkspaceList();
|
||||
loadWorkspaces();
|
||||
}
|
||||
|
||||
function toggleWsSwitcher(e) {
|
||||
@@ -47,13 +124,20 @@ function toggleWsSwitcher(e) {
|
||||
if (dd) dd.style.display = dd.style.display === 'none' ? '' : 'none';
|
||||
}
|
||||
|
||||
function switchWorkspace(slug) {
|
||||
localStorage.setItem('crank_workspace', slug);
|
||||
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';
|
||||
initWorkspaceSwitcher();
|
||||
renderWorkspaceList();
|
||||
window.dispatchEvent(new CustomEvent('crank:workspacechange', { detail: workspace }));
|
||||
}
|
||||
|
||||
window.getCurrentWorkspace = getCurrentWs;
|
||||
window.whenWorkspacesReady = loadWorkspaces;
|
||||
window.hasWorkspaceApiFailure = function() { return workspaceLoadFailed; };
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initWorkspaceSwitcher);
|
||||
|
||||
document.addEventListener('click', function(e) {
|
||||
|
||||
Reference in New Issue
Block a user