Changeset 0.37.6 (#218)

Co-authored-by: gobha <jasafpro@gmail.com>
Co-committed-by: gobha <jasafpro@gmail.com>
This commit is contained in:
2026-03-21 16:21:59 +00:00
committed by xcaliber
parent 74f3cb84e9
commit 5f1c733002
30 changed files with 2959 additions and 131 deletions

View File

@@ -0,0 +1,69 @@
/**
* Admin > System > Packages (Extensions)
*/
const { html } = window;
const { useState, useEffect, useCallback } = hooks;
export default function PackagesSection() {
const [extensions, setExtensions] = useState([]);
const [loading, setLoading] = useState(true);
const load = useCallback(async () => {
try {
const data = await sw.api.admin.extensions.list();
setExtensions(Array.isArray(data) ? data : data.data || []);
} catch (e) { sw.toast(e.message, 'error'); }
finally { setLoading(false); }
}, []);
useEffect(() => { load(); }, []);
async function toggleEnabled(ext) {
try {
await sw.api.admin.extensions.update(ext.id, { is_enabled: !ext.is_enabled });
sw.toast(`Extension ${ext.is_enabled ? 'disabled' : 'enabled'}`, 'success');
load();
} catch (e) { sw.toast(e.message, 'error'); }
}
async function deleteExt(id) {
const ok = await sw.confirm('Delete this extension?', true);
if (!ok) return;
try {
await sw.api.admin.extensions.del(id);
sw.toast('Extension deleted', 'success');
load();
} catch (e) { sw.toast(e.message, 'error'); }
}
function tierBadge(tier) {
const cls = tier === 'browser' ? 'badge-active' : tier === 'starlark' ? 'badge-pending' : '';
return html`<span class="badge ${cls}">${tier || 'unknown'}</span>`;
}
if (loading) return html`<div class="settings-placeholder">Loading\u2026</div>`;
return html`
<div>
<div class="admin-list">
${extensions.length === 0 && html`<div class="empty-hint">No extensions installed</div>`}
${extensions.map(ext => html`
<div class="admin-surface-row" key=${ext.id}>
<div style="flex:1;min-width:0;">
<strong>${ext.name}</strong>
<span class="text-muted" style="margin-left:6px;font-size:11px;">v${ext.version || '?'}</span>
${' '}${tierBadge(ext.tier)}
${ext.is_system && html`<span class="badge" style="margin-left:4px;">system</span>`}
</div>
<div class="admin-actions-cell">
<button class="btn-small" onClick=${() => toggleEnabled(ext)}>
${ext.is_enabled ? 'Disable' : 'Enable'}
</button>
${!ext.is_system && html`<button class="btn-small btn-danger" onClick=${() => deleteExt(ext.id)}>Delete</button>`}
</div>
</div>
`)}
</div>
</div>
`;
}