V0.38.3 extension config sections (#236)
Co-authored-by: gobha <jasafpro@gmail.com> Co-committed-by: gobha <jasafpro@gmail.com>
This commit is contained in:
@@ -2,11 +2,12 @@
|
||||
* AdminSurface — root admin surface
|
||||
*
|
||||
* Reads globals:
|
||||
* __SECTION__ — active section name (string)
|
||||
* __BASE__ — base path
|
||||
* __SECTION__ — active section name (string)
|
||||
* __BASE__ — base path
|
||||
* __CONFIG_SECTIONS__ — v0.38.3: extension config sections (array|null)
|
||||
*
|
||||
* Layout: topbar (back + category tabs) + body (sidebar nav + content area).
|
||||
* All 24 sections are native Preact components loaded lazily.
|
||||
* All 24+ sections are native Preact components loaded lazily.
|
||||
*/
|
||||
const { html } = window;
|
||||
const { useState, useEffect, useCallback, useMemo } = hooks;
|
||||
@@ -37,6 +38,20 @@ const ADMIN_LABELS = {
|
||||
dashboard: 'Dashboard', usage: 'Usage', audit: 'Audit', stats: 'Stats',
|
||||
};
|
||||
|
||||
// ── v0.38.3: Extension config sections ──────
|
||||
// Packages declare config_section in their manifest targeting "admin".
|
||||
// We merge them into the appropriate category and section module map.
|
||||
const _configSections = window.__CONFIG_SECTIONS__ || [];
|
||||
const _base = window.__BASE__ || '';
|
||||
for (const cs of _configSections) {
|
||||
const pkgId = cs.package_id;
|
||||
const cat = cs.category || 'system';
|
||||
// Add to category (create if new — unlikely but safe)
|
||||
if (!ADMIN_SECTIONS[cat]) ADMIN_SECTIONS[cat] = [];
|
||||
if (!ADMIN_SECTIONS[cat].includes(pkgId)) ADMIN_SECTIONS[cat].push(pkgId);
|
||||
ADMIN_LABELS[pkgId] = cs.label;
|
||||
}
|
||||
|
||||
const CATEGORY_META = {
|
||||
people: { label: 'People', first: 'users', icon: 'M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2|C9 7 4' },
|
||||
ai: { label: 'AI', first: 'providers', icon: 'R4 4 16 16 2|L9 9 9.01 9|L15 9 15.01 9|M8 14s1.5 2 4 2 4-2 4-2' },
|
||||
@@ -76,6 +91,13 @@ const sectionModules = {
|
||||
stats: () => import(`./stats.js${_v}`),
|
||||
};
|
||||
|
||||
// v0.38.3: Register dynamic section loaders for extension config sections
|
||||
for (const cs of _configSections) {
|
||||
const pkgId = cs.package_id;
|
||||
const component = cs.component || 'js/config.js';
|
||||
sectionModules[pkgId] = () => import(`${_base}/surfaces/${pkgId}/${component}`);
|
||||
}
|
||||
|
||||
// ── Derive category from section ────────────
|
||||
function catForSection(section) {
|
||||
for (const [cat, sections] of Object.entries(ADMIN_SECTIONS)) {
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
* SettingsSurface — root settings surface
|
||||
*
|
||||
* Reads globals:
|
||||
* __SECTION__ — active section name (string)
|
||||
* __BASE__ — base path
|
||||
* __SECTION__ — active section name (string)
|
||||
* __BASE__ — base path
|
||||
* __CONFIG_SECTIONS__ — v0.38.3: extension config sections (array|null)
|
||||
*
|
||||
* Policy flags (BYOK, personas) come from sw.auth.policies,
|
||||
* populated at SDK boot via GET /api/v1/profile/permissions.
|
||||
@@ -75,6 +76,20 @@ const SECTION_TITLES = {
|
||||
notifications: 'Notifications',
|
||||
};
|
||||
|
||||
// ── v0.38.3: Extension config sections ──────
|
||||
// Packages declare config_section in their manifest. The backend passes
|
||||
// matching entries via __CONFIG_SECTIONS__. We merge them into the nav
|
||||
// and section module map for lazy loading.
|
||||
const _configSections = window.__CONFIG_SECTIONS__ || [];
|
||||
const EXT_NAV_ITEMS = _configSections.map(cs => ({ key: cs.package_id, label: cs.label }));
|
||||
const _base = window.__BASE__ || '';
|
||||
for (const cs of _configSections) {
|
||||
const pkgId = cs.package_id;
|
||||
const component = cs.component || 'js/config.js';
|
||||
sectionModules[pkgId] = () => import(`${_base}/surfaces/${pkgId}/${component}`);
|
||||
SECTION_TITLES[pkgId] = cs.label;
|
||||
}
|
||||
|
||||
function SettingsSurface() {
|
||||
const BASE = window.__BASE__ || '';
|
||||
const section = window.__SECTION__ || 'general';
|
||||
@@ -195,6 +210,20 @@ function SettingsSurface() {
|
||||
</p>
|
||||
</div>
|
||||
`}
|
||||
|
||||
${EXT_NAV_ITEMS.length > 0 && html`
|
||||
<div>
|
||||
<div class="settings-nav-sep"></div>
|
||||
<div class="settings-nav-label" style="font-size:10px;font-weight:600;color:var(--text-3);padding:8px 12px 4px;text-transform:uppercase;letter-spacing:0.5px;">Extensions</div>
|
||||
${EXT_NAV_ITEMS.map(item => html`
|
||||
<a href="${BASE}/settings/${item.key}"
|
||||
class="settings-nav-link ${section === item.key ? 'active' : ''}"
|
||||
onClick=${onNavClick}>
|
||||
${item.label}
|
||||
</a>
|
||||
`)}
|
||||
</div>
|
||||
`}
|
||||
</div>
|
||||
|
||||
${/* Content */''}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
* TeamAdminSurface — root team admin surface
|
||||
*
|
||||
* Reads globals:
|
||||
* __SECTION__ — active section name (string)
|
||||
* __BASE__ — base path
|
||||
* __SECTION__ — active section name (string)
|
||||
* __BASE__ — base path
|
||||
* __CONFIG_SECTIONS__ — v0.38.3: extension config sections (array|null)
|
||||
*
|
||||
* Layout: topbar (back + team name) + sidebar nav + content area.
|
||||
* All 10 sections are native Preact components loaded lazily.
|
||||
* All 10+ sections are native Preact components loaded lazily.
|
||||
*/
|
||||
const { html } = window;
|
||||
const { useState, useEffect, useCallback, useMemo } = hooks;
|
||||
@@ -45,6 +46,16 @@ const sectionModules = {
|
||||
activity: () => import('./activity.js'),
|
||||
};
|
||||
|
||||
// ── v0.38.3: Extension config sections ──────
|
||||
const _configSections = window.__CONFIG_SECTIONS__ || [];
|
||||
const _base = window.__BASE__ || '';
|
||||
for (const cs of _configSections) {
|
||||
const pkgId = cs.package_id;
|
||||
const component = cs.component || 'js/config.js';
|
||||
SECTIONS.push({ key: pkgId, label: cs.label });
|
||||
sectionModules[pkgId] = () => import(`${_base}/surfaces/${pkgId}/${component}`);
|
||||
}
|
||||
|
||||
function TeamAdminSurface() {
|
||||
const BASE = window.__BASE__ || '';
|
||||
const section = window.__SECTION__ || 'members';
|
||||
|
||||
Reference in New Issue
Block a user