Move global plugin navigation into shell
This commit is contained in:
parent
0c788bed80
commit
6d30015a1d
|
|
@ -28,10 +28,22 @@ test.describe('B: Sidebar opens plugin view by item.view', () => {
|
|||
});
|
||||
|
||||
test('Sidebar item exists with correct label', async ({ page }) => {
|
||||
await expect(page.locator('.sidebar .nav-item').filter({ hasText: 'Plugin Manager' })).not.toBeVisible();
|
||||
await expect(page.locator('.sidebar .plugin-item').filter({ hasText: 'Activity' })).toBeVisible();
|
||||
await expect(page.locator('.sidebar .plugin-item').filter({ hasText: 'Browser Inbox' })).toBeVisible();
|
||||
|
||||
const sidebarItem = page.locator('.sidebar .plugin-item').filter({ hasText: 'Platform Test' });
|
||||
await expect(sidebarItem).toBeVisible();
|
||||
});
|
||||
|
||||
test('Global Activity and Browser Inbox sidebar items open plugin views', async ({ page }) => {
|
||||
await page.locator('.sidebar .plugin-item').filter({ hasText: 'Activity' }).click();
|
||||
await expect(page.locator('.view-container .view-header h2')).toHaveText('Activity', { timeout: 10000 });
|
||||
|
||||
await page.locator('.sidebar .plugin-item').filter({ hasText: 'Browser Inbox' }).click();
|
||||
await expect(page.locator('.view-container .view-header h2')).toHaveText('Browser Inbox', { timeout: 10000 });
|
||||
});
|
||||
|
||||
test('Click sidebar item opens diagnostics view by view ID, not sidebar ID', async ({ page }) => {
|
||||
const sidebarItem = page.locator('.sidebar .plugin-item').filter({ hasText: 'Platform Test' });
|
||||
await expect(sidebarItem).toBeVisible();
|
||||
|
|
|
|||
|
|
@ -18,9 +18,24 @@ test.describe('Status Bar host', () => {
|
|||
test('renders enabled plugin statusBarItems', async ({ page }) => {
|
||||
const statusBar = page.locator('.status-bar');
|
||||
await expect(statusBar).toBeVisible();
|
||||
await expect(statusBar.locator('.vault-status')).toContainText('Vault: open');
|
||||
await expect(statusBar.locator('[data-status-item-id="verstak.platform-test.status"]')).toContainText('All Tests Pass');
|
||||
});
|
||||
|
||||
test('opens settings menu with plugin manager and plugin settings', async ({ page }) => {
|
||||
await page.locator('[data-settings-menu-button]').click();
|
||||
|
||||
await expect(page.locator('[data-settings-action="plugin-manager"]')).toBeVisible();
|
||||
await expect(page.locator('[data-settings-panel-id="verstak.sync.settings"]')).toBeVisible();
|
||||
|
||||
await page.locator('.sidebar .plugin-item').filter({ hasText: 'Platform Test' }).click();
|
||||
await expect(page.locator('.view-container .view-header h2')).toHaveText('Platform Diagnostics');
|
||||
|
||||
await page.locator('[data-settings-menu-button]').click();
|
||||
await page.locator('[data-settings-action="plugin-manager"]').click();
|
||||
await expect(page.locator('.plugin-manager')).toBeVisible();
|
||||
});
|
||||
|
||||
test('refreshes statusBarItems after disabling plugin', async ({ page }) => {
|
||||
const pluginCard = page.locator('.plugin-card').filter({ hasText: 'verstak.platform-test' });
|
||||
await expect(page.locator('[data-status-item-id="verstak.platform-test.status"]')).toBeVisible();
|
||||
|
|
|
|||
|
|
@ -14,10 +14,6 @@
|
|||
let sidebarItems = [];
|
||||
let errorMessage = '';
|
||||
|
||||
let navItems = [
|
||||
{ id: 'plugin-manager', label: 'Plugin Manager', icon: 'puzzle' },
|
||||
];
|
||||
|
||||
$: vaultOpen = vaultStatus.status === 'open';
|
||||
|
||||
async function loadSidebar() {
|
||||
|
|
@ -66,11 +62,6 @@
|
|||
window.removeEventListener('verstak:plugins-changed', loadSidebar);
|
||||
});
|
||||
|
||||
function handleNav(id) {
|
||||
debug.log('[Sidebar] handleNav:', id);
|
||||
window.dispatchEvent(new CustomEvent('verstak:nav', { detail: { viewId: id } }));
|
||||
}
|
||||
|
||||
function handleSidebarItem(item) {
|
||||
debug.log('[Sidebar] handleSidebarItem:', item.id, '-> view:', item.view);
|
||||
// Use item.view (the view contribution ID) if available, fall back to item.id
|
||||
|
|
@ -85,22 +76,9 @@
|
|||
<span class="sidebar-title">Verstak</span>
|
||||
</div>
|
||||
|
||||
<nav class="sidebar-nav">
|
||||
{#each navItems as item}
|
||||
<button
|
||||
class="nav-item"
|
||||
on:click={() => handleNav(item.id)}
|
||||
type="button"
|
||||
>
|
||||
<Icon name={item.icon} size={16} class="nav-icon" />
|
||||
<span class="nav-label">{item.label}</span>
|
||||
</button>
|
||||
{/each}
|
||||
</nav>
|
||||
|
||||
{#if sidebarItems.length > 0}
|
||||
<div class="sidebar-section">
|
||||
<span class="section-label">Plugins</span>
|
||||
<span class="section-label">Tools</span>
|
||||
{#each sidebarItems as item}
|
||||
<button
|
||||
class="nav-item plugin-item"
|
||||
|
|
@ -125,11 +103,6 @@
|
|||
Plugin UI error
|
||||
</span>
|
||||
{/if}
|
||||
{#if vaultStatus.status !== 'unknown'}
|
||||
<span class="vault-indicator" class:vault-open={vaultStatus.status === 'open'} class:vault-closed={vaultStatus.status !== 'open'}>
|
||||
● Vault: {vaultStatus.status}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
|
|
@ -165,20 +138,12 @@
|
|||
font-weight: 600;
|
||||
}
|
||||
|
||||
.sidebar-nav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0.5rem 0.75rem;
|
||||
gap: 0.15rem;
|
||||
}
|
||||
|
||||
.sidebar-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0.5rem 0.75rem;
|
||||
gap: 0.15rem;
|
||||
border-top: 1px solid #0f3460;
|
||||
margin-top: 0.25rem;
|
||||
border-bottom: 1px solid #0f3460;
|
||||
}
|
||||
|
||||
:global(workspace-tree) {
|
||||
|
|
@ -240,19 +205,6 @@
|
|||
border-top: 1px solid #0f3460;
|
||||
}
|
||||
|
||||
.vault-indicator {
|
||||
font-size: 0.7rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.vault-indicator.vault-open {
|
||||
color: #4ecca3;
|
||||
}
|
||||
|
||||
.vault-indicator.vault-closed {
|
||||
color: #a0a0b8;
|
||||
}
|
||||
|
||||
.sidebar-error {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
|||
|
|
@ -1,20 +1,29 @@
|
|||
<script>
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import * as App from '../../../wailsjs/go/api/App';
|
||||
import Icon from '../ui/Icon.svelte';
|
||||
|
||||
let items = [];
|
||||
let settingsPanels = [];
|
||||
let vaultStatus = { status: 'unknown', path: '', vaultId: '' };
|
||||
let settingsOpen = false;
|
||||
|
||||
$: leftItems = items.filter((item) => item.position === 'left');
|
||||
$: centerItems = items.filter((item) => item.position === 'center');
|
||||
$: rightItems = items.filter((item) => item.position === 'right');
|
||||
$: vaultOpen = vaultStatus.status === 'open';
|
||||
$: vaultLabel = vaultStatus.status && vaultStatus.status !== 'unknown' ? 'Vault: ' + vaultStatus.status : 'Vault: unknown';
|
||||
|
||||
const inactiveStatuses = new Set(['disabled', 'failed', 'incompatible', 'missing-required-capability']);
|
||||
|
||||
async function loadStatusBar() {
|
||||
const [plugins, contributions] = await Promise.all([
|
||||
const [plugins, contributions, vault] = await Promise.all([
|
||||
App.GetPlugins().catch(() => []),
|
||||
App.GetContributions().catch(() => ({})),
|
||||
App.GetVaultStatus().catch(() => ({ status: 'unknown', path: '', vaultId: '' })),
|
||||
]);
|
||||
const pluginById = new Map((plugins || []).map((plugin) => [plugin.manifest?.id, plugin]));
|
||||
vaultStatus = vault || { status: 'unknown', path: '', vaultId: '' };
|
||||
items = (contributions.statusBarItems || [])
|
||||
.filter((item) => {
|
||||
const plugin = pluginById.get(item.pluginId);
|
||||
|
|
@ -25,20 +34,62 @@
|
|||
...item,
|
||||
position: item.position || 'left',
|
||||
}));
|
||||
settingsPanels = (contributions.settingsPanels || [])
|
||||
.filter((panel) => {
|
||||
const plugin = pluginById.get(panel.pluginId);
|
||||
if (!plugin) return false;
|
||||
return !inactiveStatuses.has(plugin.status);
|
||||
})
|
||||
.sort((a, b) => String(a.title || a.id).localeCompare(String(b.title || b.id)));
|
||||
}
|
||||
|
||||
function openPluginManager() {
|
||||
settingsOpen = false;
|
||||
window.dispatchEvent(new CustomEvent('verstak:close-settings'));
|
||||
window.dispatchEvent(new CustomEvent('verstak:nav', { detail: { viewId: 'plugin-manager' } }));
|
||||
}
|
||||
|
||||
function openSettingsPanel(panel) {
|
||||
settingsOpen = false;
|
||||
window.dispatchEvent(new CustomEvent('verstak:open-settings', {
|
||||
detail: { pluginId: panel.pluginId, panelId: panel.id }
|
||||
}));
|
||||
}
|
||||
|
||||
function toggleSettings(event) {
|
||||
event.stopPropagation();
|
||||
settingsOpen = !settingsOpen;
|
||||
}
|
||||
|
||||
function closeSettings() {
|
||||
settingsOpen = false;
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
loadStatusBar();
|
||||
window.addEventListener('verstak:plugins-changed', loadStatusBar);
|
||||
window.addEventListener('verstak:vault-opened', loadStatusBar);
|
||||
window.addEventListener('click', closeSettings);
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
window.removeEventListener('verstak:plugins-changed', loadStatusBar);
|
||||
window.removeEventListener('verstak:vault-opened', loadStatusBar);
|
||||
window.removeEventListener('click', closeSettings);
|
||||
});
|
||||
</script>
|
||||
|
||||
<footer class="status-bar" aria-label="Status bar">
|
||||
<div class="status-bar-group status-left">
|
||||
<span
|
||||
class="vault-status"
|
||||
class:vault-open={vaultOpen}
|
||||
class:vault-closed={!vaultOpen}
|
||||
title={vaultStatus.path || vaultStatus.vaultId || vaultLabel}
|
||||
>
|
||||
<Icon name="vault" size={13} class="status-icon" />
|
||||
{vaultLabel}
|
||||
</span>
|
||||
{#each leftItems as item}
|
||||
<span class="status-bar-item" data-status-item-id={item.id} title={item.pluginId}>
|
||||
{item.label || item.id}
|
||||
|
|
@ -58,11 +109,58 @@
|
|||
{item.label || item.id}
|
||||
</span>
|
||||
{/each}
|
||||
<div class="settings-menu-wrap">
|
||||
<button
|
||||
class="settings-button"
|
||||
class:active={settingsOpen}
|
||||
type="button"
|
||||
title="Settings"
|
||||
aria-haspopup="menu"
|
||||
aria-expanded={settingsOpen}
|
||||
data-settings-menu-button
|
||||
on:click={toggleSettings}
|
||||
>
|
||||
<Icon name="settings" size={14} class="settings-icon" />
|
||||
<Icon name="chevronDown" size={12} class="settings-chevron" />
|
||||
</button>
|
||||
{#if settingsOpen}
|
||||
<div class="settings-menu" role="menu">
|
||||
<button
|
||||
class="settings-menu-item"
|
||||
type="button"
|
||||
role="menuitem"
|
||||
data-settings-action="plugin-manager"
|
||||
on:click={openPluginManager}
|
||||
>
|
||||
<Icon name="puzzle" size={14} class="settings-menu-icon" />
|
||||
<span>Plugin Manager</span>
|
||||
</button>
|
||||
{#if settingsPanels.length > 0}
|
||||
<div class="settings-menu-separator"></div>
|
||||
{#each settingsPanels as panel}
|
||||
<button
|
||||
class="settings-menu-item"
|
||||
type="button"
|
||||
role="menuitem"
|
||||
data-settings-panel-id={panel.id}
|
||||
title={panel.pluginId}
|
||||
on:click={() => openSettingsPanel(panel)}
|
||||
>
|
||||
<Icon name={panel.icon || 'settings'} size={14} class="settings-menu-icon" />
|
||||
<span>{panel.title || panel.id}</span>
|
||||
</button>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<style>
|
||||
.status-bar {
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
min-height: 1.7rem;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
||||
|
|
@ -99,4 +197,102 @@
|
|||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.vault-status {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
max-width: 24rem;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
padding: 0.12rem 0.35rem;
|
||||
border-radius: 4px;
|
||||
color: #a0a0b8;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.vault-status.vault-open {
|
||||
color: #4ecca3;
|
||||
}
|
||||
|
||||
.vault-status.vault-closed {
|
||||
color: #9fb2ca;
|
||||
}
|
||||
|
||||
:global(.status-icon) {
|
||||
flex-shrink: 0;
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.settings-menu-wrap {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.settings-button {
|
||||
min-height: 1.35rem;
|
||||
height: 1.35rem;
|
||||
padding: 0 0.35rem;
|
||||
gap: 0.15rem;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
color: #9fb2ca;
|
||||
}
|
||||
|
||||
.settings-button:hover,
|
||||
.settings-button.active {
|
||||
border-color: #1a3a5c;
|
||||
background: #16213e;
|
||||
color: #e0e0f0;
|
||||
}
|
||||
|
||||
:global(.settings-icon),
|
||||
:global(.settings-chevron),
|
||||
:global(.settings-menu-icon) {
|
||||
flex-shrink: 0;
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.settings-menu {
|
||||
position: fixed;
|
||||
right: 0.65rem;
|
||||
bottom: 2rem;
|
||||
z-index: 10000;
|
||||
min-width: 13rem;
|
||||
padding: 0.3rem;
|
||||
border: 1px solid #1a3a5c;
|
||||
border-radius: 6px;
|
||||
background: #12122a;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.settings-menu-item {
|
||||
width: 100%;
|
||||
min-height: 1.8rem;
|
||||
justify-content: flex-start;
|
||||
gap: 0.45rem;
|
||||
padding: 0.3rem 0.45rem;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
color: #cfd8e3;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.settings-menu-item:hover {
|
||||
background: #0f3460;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.settings-menu-separator {
|
||||
height: 1px;
|
||||
margin: 0.25rem 0.2rem;
|
||||
background: #1a3a5c;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -157,11 +157,59 @@
|
|||
},
|
||||
rootPath: '/tmp/verstak-test/plugins/sync',
|
||||
error: ''
|
||||
},
|
||||
'verstak.activity': {
|
||||
status: 'loaded',
|
||||
enabled: true,
|
||||
manifest: {
|
||||
schemaVersion: 1,
|
||||
id: 'verstak.activity',
|
||||
name: 'Activity',
|
||||
version: '0.1.0',
|
||||
apiVersion: '0.1.0',
|
||||
description: 'Workspace-scoped activity log for public plugin events.',
|
||||
source: 'official',
|
||||
icon: 'activity',
|
||||
provides: ['activity.log', 'activity.provider', 'activity.reconstruction'],
|
||||
permissions: ['events.subscribe', 'storage.namespace', 'ui.register'],
|
||||
frontend: { entry: 'frontend/dist/index.js' },
|
||||
contributes: {
|
||||
views: [{ id: 'verstak.activity.view', title: 'Activity', icon: 'activity', component: 'ActivityView' }],
|
||||
sidebarItems: [{ id: 'verstak.activity.sidebar', title: 'Activity', icon: 'activity', view: 'verstak.activity.view', position: 20 }],
|
||||
workspaceItems: [{ id: 'verstak.activity.workspace', title: 'Activity', icon: 'activity', component: 'ActivityView' }]
|
||||
}
|
||||
},
|
||||
rootPath: '/tmp/verstak-test/plugins/activity',
|
||||
error: ''
|
||||
},
|
||||
'verstak.browser-inbox': {
|
||||
status: 'loaded',
|
||||
enabled: true,
|
||||
manifest: {
|
||||
schemaVersion: 1,
|
||||
id: 'verstak.browser-inbox',
|
||||
name: 'Browser Inbox',
|
||||
version: '0.1.0',
|
||||
apiVersion: '0.1.0',
|
||||
description: 'Workspace-scoped inbox for browser captures.',
|
||||
source: 'official',
|
||||
icon: 'inbox',
|
||||
provides: ['browser.inbox'],
|
||||
permissions: ['events.subscribe', 'storage.namespace', 'ui.register'],
|
||||
frontend: { entry: 'frontend/dist/index.js' },
|
||||
contributes: {
|
||||
views: [{ id: 'verstak.browser-inbox.view', title: 'Browser Inbox', icon: 'inbox', component: 'BrowserInboxView' }],
|
||||
sidebarItems: [{ id: 'verstak.browser-inbox.sidebar', title: 'Browser Inbox', icon: 'inbox', view: 'verstak.browser-inbox.view', position: 30 }],
|
||||
workspaceItems: [{ id: 'verstak.browser-inbox.workspace', title: 'Browser Inbox', icon: 'inbox', component: 'BrowserInboxView' }]
|
||||
}
|
||||
},
|
||||
rootPath: '/tmp/verstak-test/plugins/browser-inbox',
|
||||
error: ''
|
||||
}
|
||||
};
|
||||
|
||||
var vaultStatus = { status: 'open', path: '/tmp/verstak-test/vault', vaultId: 'test-vault-001' };
|
||||
var vaultPluginState = { enabledPlugins: ['verstak.platform-test', 'verstak.default-editor', 'verstak.files', 'verstak.sync'], disabledPlugins: [], desiredPlugins: [{ id: 'verstak.platform-test', version: '0.1.0', source: 'official' }, { id: 'verstak.default-editor', version: '0.1.0', source: 'official' }, { id: 'verstak.files', version: '0.1.0', source: 'official' }, { id: 'verstak.sync', version: '0.1.0', source: 'official' }] };
|
||||
var vaultPluginState = { enabledPlugins: ['verstak.platform-test', 'verstak.default-editor', 'verstak.files', 'verstak.sync', 'verstak.activity', 'verstak.browser-inbox'], disabledPlugins: [], desiredPlugins: [{ id: 'verstak.platform-test', version: '0.1.0', source: 'official' }, { id: 'verstak.default-editor', version: '0.1.0', source: 'official' }, { id: 'verstak.files', version: '0.1.0', source: 'official' }, { id: 'verstak.sync', version: '0.1.0', source: 'official' }, { id: 'verstak.activity', version: '0.1.0', source: 'official' }, { id: 'verstak.browser-inbox', version: '0.1.0', source: 'official' }] };
|
||||
var appSettings = { currentVaultPath: '/tmp/verstak-test/vault', recentVaults: [] };
|
||||
var workbenchPreferences = {};
|
||||
var openedResources = [];
|
||||
|
|
@ -922,6 +970,24 @@
|
|||
}.toString() + ')();';
|
||||
}
|
||||
|
||||
function activityBundle() {
|
||||
return [
|
||||
"(function(){",
|
||||
"var ActivityView={mount:function(containerEl){containerEl.innerHTML='';var root=document.createElement('div');root.className='activity-root';root.setAttribute('data-plugin-id','verstak.activity');var title=document.createElement('h2');title.textContent='Activity';var body=document.createElement('div');body.textContent='Global activity feed';root.appendChild(title);root.appendChild(body);containerEl.appendChild(root);},unmount:function(containerEl){containerEl.innerHTML='';}};",
|
||||
"window.VerstakPluginRegister('verstak.activity',{components:{ActivityView:ActivityView}});",
|
||||
"})();"
|
||||
].join('');
|
||||
}
|
||||
|
||||
function browserInboxBundle() {
|
||||
return [
|
||||
"(function(){",
|
||||
"var BrowserInboxView={mount:function(containerEl){containerEl.innerHTML='';var root=document.createElement('div');root.className='browser-inbox-root';root.setAttribute('data-plugin-id','verstak.browser-inbox');var title=document.createElement('h2');title.textContent='Browser Inbox';var body=document.createElement('div');body.textContent='Global browser inbox';root.appendChild(title);root.appendChild(body);containerEl.appendChild(root);},unmount:function(containerEl){containerEl.innerHTML='';}};",
|
||||
"window.VerstakPluginRegister('verstak.browser-inbox',{components:{BrowserInboxView:BrowserInboxView}});",
|
||||
"})();"
|
||||
].join('');
|
||||
}
|
||||
|
||||
function platformTestBundle() {
|
||||
return [
|
||||
"(function(){",
|
||||
|
|
@ -1152,6 +1218,12 @@
|
|||
if (pluginId === 'verstak.files' && assetPath === 'frontend/dist/index.js') {
|
||||
return Promise.resolve(filesPluginBundle());
|
||||
}
|
||||
if (pluginId === 'verstak.activity' && assetPath === 'frontend/dist/index.js') {
|
||||
return Promise.resolve(activityBundle());
|
||||
}
|
||||
if (pluginId === 'verstak.browser-inbox' && assetPath === 'frontend/dist/index.js') {
|
||||
return Promise.resolve(browserInboxBundle());
|
||||
}
|
||||
return Promise.resolve('');
|
||||
},
|
||||
GetPluginCapability: function (pluginId, capId) {
|
||||
|
|
@ -1583,10 +1655,58 @@
|
|||
},
|
||||
rootPath: '/tmp/verstak-test/plugins/sync',
|
||||
error: ''
|
||||
},
|
||||
'verstak.activity': {
|
||||
status: 'loaded',
|
||||
enabled: true,
|
||||
manifest: {
|
||||
schemaVersion: 1,
|
||||
id: 'verstak.activity',
|
||||
name: 'Activity',
|
||||
version: '0.1.0',
|
||||
apiVersion: '0.1.0',
|
||||
description: 'Workspace-scoped activity log for public plugin events.',
|
||||
source: 'official',
|
||||
icon: 'activity',
|
||||
provides: ['activity.log', 'activity.provider', 'activity.reconstruction'],
|
||||
permissions: ['events.subscribe', 'storage.namespace', 'ui.register'],
|
||||
frontend: { entry: 'frontend/dist/index.js' },
|
||||
contributes: {
|
||||
views: [{ id: 'verstak.activity.view', title: 'Activity', icon: 'activity', component: 'ActivityView' }],
|
||||
sidebarItems: [{ id: 'verstak.activity.sidebar', title: 'Activity', icon: 'activity', view: 'verstak.activity.view', position: 20 }],
|
||||
workspaceItems: [{ id: 'verstak.activity.workspace', title: 'Activity', icon: 'activity', component: 'ActivityView' }]
|
||||
}
|
||||
},
|
||||
rootPath: '/tmp/verstak-test/plugins/activity',
|
||||
error: ''
|
||||
},
|
||||
'verstak.browser-inbox': {
|
||||
status: 'loaded',
|
||||
enabled: true,
|
||||
manifest: {
|
||||
schemaVersion: 1,
|
||||
id: 'verstak.browser-inbox',
|
||||
name: 'Browser Inbox',
|
||||
version: '0.1.0',
|
||||
apiVersion: '0.1.0',
|
||||
description: 'Workspace-scoped inbox for browser captures.',
|
||||
source: 'official',
|
||||
icon: 'inbox',
|
||||
provides: ['browser.inbox'],
|
||||
permissions: ['events.subscribe', 'storage.namespace', 'ui.register'],
|
||||
frontend: { entry: 'frontend/dist/index.js' },
|
||||
contributes: {
|
||||
views: [{ id: 'verstak.browser-inbox.view', title: 'Browser Inbox', icon: 'inbox', component: 'BrowserInboxView' }],
|
||||
sidebarItems: [{ id: 'verstak.browser-inbox.sidebar', title: 'Browser Inbox', icon: 'inbox', view: 'verstak.browser-inbox.view', position: 30 }],
|
||||
workspaceItems: [{ id: 'verstak.browser-inbox.workspace', title: 'Browser Inbox', icon: 'inbox', component: 'BrowserInboxView' }]
|
||||
}
|
||||
},
|
||||
rootPath: '/tmp/verstak-test/plugins/browser-inbox',
|
||||
error: ''
|
||||
}
|
||||
};
|
||||
vaultStatus = { status: 'open', path: '/tmp/verstak-test/vault', vaultId: 'test-vault-001' };
|
||||
vaultPluginState = { enabledPlugins: ['verstak.platform-test', 'verstak.default-editor', 'verstak.files', 'verstak.sync'], disabledPlugins: [], desiredPlugins: [{ id: 'verstak.platform-test', version: '0.1.0', source: 'official' }, { id: 'verstak.default-editor', version: '0.1.0', source: 'official' }, { id: 'verstak.files', version: '0.1.0', source: 'official' }, { id: 'verstak.sync', version: '0.1.0', source: 'official' }] };
|
||||
vaultPluginState = { enabledPlugins: ['verstak.platform-test', 'verstak.default-editor', 'verstak.files', 'verstak.sync', 'verstak.activity', 'verstak.browser-inbox'], disabledPlugins: [], desiredPlugins: [{ id: 'verstak.platform-test', version: '0.1.0', source: 'official' }, { id: 'verstak.default-editor', version: '0.1.0', source: 'official' }, { id: 'verstak.files', version: '0.1.0', source: 'official' }, { id: 'verstak.sync', version: '0.1.0', source: 'official' }, { id: 'verstak.activity', version: '0.1.0', source: 'official' }, { id: 'verstak.browser-inbox', version: '0.1.0', source: 'official' }] };
|
||||
appSettings = { currentVaultPath: '/tmp/verstak-test/vault', recentVaults: [] };
|
||||
workbenchPreferences = {};
|
||||
openedResources = [];
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
* - NO dependency on system icon fonts
|
||||
* - If name is not found, renders a default circle icon
|
||||
*/
|
||||
import Activity from 'lucide-svelte/icons/activity';
|
||||
import Briefcase from 'lucide-svelte/icons/briefcase';
|
||||
import ChevronDown from 'lucide-svelte/icons/chevron-down';
|
||||
import ChevronLeft from 'lucide-svelte/icons/chevron-left';
|
||||
|
|
@ -18,6 +19,7 @@
|
|||
import Circle from 'lucide-svelte/icons/circle';
|
||||
import FlaskConical from 'lucide-svelte/icons/flask-conical';
|
||||
import Folder from 'lucide-svelte/icons/folder';
|
||||
import Inbox from 'lucide-svelte/icons/inbox';
|
||||
import LayoutGrid from 'lucide-svelte/icons/layout-grid';
|
||||
import PanelsTopLeft from 'lucide-svelte/icons/panels-top-left';
|
||||
import Pencil from 'lucide-svelte/icons/pencil';
|
||||
|
|
@ -34,6 +36,7 @@
|
|||
export let className = '';
|
||||
|
||||
const icons = {
|
||||
activity: Activity,
|
||||
case: Briefcase,
|
||||
chevronDown: ChevronDown,
|
||||
chevronLeft: ChevronLeft,
|
||||
|
|
@ -43,6 +46,7 @@
|
|||
flask: FlaskConical,
|
||||
folder: Folder,
|
||||
gear: Settings,
|
||||
inbox: Inbox,
|
||||
logo: PanelsTopLeft,
|
||||
plugin: Plug,
|
||||
puzzle: Puzzle,
|
||||
|
|
|
|||
Loading…
Reference in New Issue