This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/src/js/sw/sdk/storage.js
Jeffrey Smith 22c70034c6 Feat v0.2.4: SDK Topbar, Schedules surface, manifest icons, UserMenu cleanup
Shell navigation:
- sw.shell.Topbar — composable nav bar (title + slot + bell + user menu)
- Topbar CSS in sw-shell.css, wired into SDK via dynamic import

Schedules surface (packages/schedules/):
- Wraps kernel /api/v1/schedules CRUD + run + logs
- Table view with cron badge, human-readable preview, enable toggle
- Create/edit dialog with live cron-to-english preview

Manifest icons:
- icon field in manifest.json (emoji string)
- Surfaces API returns icon from package manifest
- UserMenu renders per-surface icons

UserMenu cleanup:
- Removed dead Chat/Notes/Projects hardcoded links
- Menu now driven by /api/v1/surfaces API (installed surfaces only)
- Core surfaces filtered via CORE_IDS set

Bug fixes:
- isAdmin() in can.js now checks surface.admin.access RBAC grant
  instead of deprecated user.role column (v0.2.0 regression)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 10:16:37 +00:00

61 lines
1.9 KiB
JavaScript

// ==========================================
// Switchboard Core — SDK: Storage Module
// ==========================================
// Namespaced localStorage wrapper.
//
// Factory: createStorage()
// ==========================================
/**
* Create the storage module.
*
* @returns {object} storage — { local(namespace) }
*/
export function createStorage() {
return {
/**
* Scoped localStorage wrapper.
* @param {string} ns — namespace (e.g. package id)
* @returns {object} — { get, set, remove, keys, clear }
*/
local(ns) {
const prefix = 'sw::' + ns + '::';
return {
get(key) {
const raw = localStorage.getItem(prefix + key);
if (raw === null) return null;
try { return JSON.parse(raw); }
catch { return raw; }
},
set(key, val) {
localStorage.setItem(prefix + key, JSON.stringify(val));
},
remove(key) {
localStorage.removeItem(prefix + key);
},
keys() {
const out = [];
for (let i = 0; i < localStorage.length; i++) {
const k = localStorage.key(i);
if (k.startsWith(prefix)) out.push(k.slice(prefix.length));
}
return out;
},
clear() {
const toRemove = [];
for (let i = 0; i < localStorage.length; i++) {
const k = localStorage.key(i);
if (k.startsWith(prefix)) toRemove.push(k);
}
toRemove.forEach(k => localStorage.removeItem(k));
},
};
},
};
}