fix: P1 shell tooltip fixes + Today routing + workspaces API
Shell: - WorkspaceHost: change tooltip from pluginId to human-readable title - StatusBar: replace pluginId tooltips with label or id (3 occurrences) - App: startup routing to Today view, sidebar Today nav item - Sidebar: add Today button in Overview section - TodaySurface: separate global vs workspace data (no fallthrough) Plugin API: - Add workspaces.list() method wrapping App.ListWorkspaces() (needed by browser-inbox workspace picker)
This commit is contained in:
parent
b0d80e230f
commit
9d06b164d3
|
|
@ -7,6 +7,7 @@
|
||||||
import VaultSelection from './lib/shell/VaultSelection.svelte';
|
import VaultSelection from './lib/shell/VaultSelection.svelte';
|
||||||
import WorkbenchHost from './lib/shell/WorkbenchHost.svelte';
|
import WorkbenchHost from './lib/shell/WorkbenchHost.svelte';
|
||||||
import WorkspaceHost from './lib/shell/WorkspaceHost.svelte';
|
import WorkspaceHost from './lib/shell/WorkspaceHost.svelte';
|
||||||
|
import TodaySurface from './lib/shell/TodaySurface.svelte';
|
||||||
import * as App from '../wailsjs/go/api/App';
|
import * as App from '../wailsjs/go/api/App';
|
||||||
import { debug } from './lib/log/debug.js';
|
import { debug } from './lib/log/debug.js';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
|
|
@ -74,33 +75,20 @@
|
||||||
if (err || !workspaces || workspaces.length === 0) {
|
if (err || !workspaces || workspaces.length === 0) {
|
||||||
workspaceNodes = [];
|
workspaceNodes = [];
|
||||||
selectedWorkspaceName = '';
|
selectedWorkspaceName = '';
|
||||||
currentView = 'workspace-empty';
|
currentView = 'today';
|
||||||
emitWorkspaceActive('');
|
emitWorkspaceActive('');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaceNodes = workspaces.map(workspaceAsNode);
|
workspaceNodes = workspaces.map(workspaceAsNode);
|
||||||
let currentWorkspace = null;
|
selectedWorkspaceName = '';
|
||||||
try {
|
currentView = 'today';
|
||||||
currentWorkspace = await App.GetCurrentWorkspace();
|
emitWorkspaceActive('');
|
||||||
} catch {
|
|
||||||
currentWorkspace = null;
|
|
||||||
}
|
|
||||||
const currentName = workspaceName(currentWorkspace);
|
|
||||||
const selected = workspaces.find((workspace) => workspaceName(workspace) === currentName) || workspaces[0];
|
|
||||||
selectedWorkspaceName = workspaceName(selected);
|
|
||||||
if (selectedWorkspaceName) {
|
|
||||||
try { await App.SetCurrentWorkspace(selectedWorkspaceName); } catch {}
|
|
||||||
currentView = 'workspace';
|
|
||||||
} else {
|
|
||||||
currentView = 'workspace-empty';
|
|
||||||
}
|
|
||||||
emitWorkspaceActive(selectedWorkspaceName);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debug.log('[App] openDefaultWorkspaceRoute ERROR', String(e));
|
debug.log('[App] openDefaultWorkspaceRoute ERROR', String(e));
|
||||||
workspaceNodes = [];
|
workspaceNodes = [];
|
||||||
selectedWorkspaceName = '';
|
selectedWorkspaceName = '';
|
||||||
currentView = 'workspace-empty';
|
currentView = 'today';
|
||||||
emitWorkspaceActive('');
|
emitWorkspaceActive('');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -394,6 +382,12 @@
|
||||||
<PluginManager {activeSettingsPluginId} {activeSettingsPanelId} />
|
<PluginManager {activeSettingsPluginId} {activeSettingsPanelId} />
|
||||||
{:else if currentView === 'workbench'}
|
{:else if currentView === 'workbench'}
|
||||||
<WorkbenchHost {openedResource} />
|
<WorkbenchHost {openedResource} />
|
||||||
|
{:else if currentView === 'today'}
|
||||||
|
<TodaySurface
|
||||||
|
workspaceRootPath=""
|
||||||
|
workspaceTitle=""
|
||||||
|
availableTools={[]}
|
||||||
|
/>
|
||||||
{:else if currentView === 'workspace' || currentView === 'workspace-empty'}
|
{:else if currentView === 'workspace' || currentView === 'workspace-empty'}
|
||||||
<WorkspaceHost
|
<WorkspaceHost
|
||||||
selectedWorkspaceName={selectedWorkspaceName}
|
selectedWorkspaceName={selectedWorkspaceName}
|
||||||
|
|
|
||||||
|
|
@ -502,6 +502,15 @@ export function createPluginAPI(pluginId) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
workspaces: {
|
||||||
|
list: function() {
|
||||||
|
assertActive('workspaces.list');
|
||||||
|
return callBackend(pluginId, 'workspaces.list', function() {
|
||||||
|
return App.ListWorkspaces();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
dispose: function() {
|
dispose: function() {
|
||||||
if (disposed) return;
|
if (disposed) return;
|
||||||
disposed = true;
|
disposed = true;
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,20 @@
|
||||||
<GlobalSearch />
|
<GlobalSearch />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if vaultOpen}
|
||||||
|
<div class="sidebar-section">
|
||||||
|
<span class="section-label">Overview</span>
|
||||||
|
<button
|
||||||
|
class="nav-item today-item"
|
||||||
|
on:click={() => window.dispatchEvent(new CustomEvent('verstak:nav', { detail: { viewId: 'today' } }))}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span class="nav-icon-today">★</span>
|
||||||
|
<span class="nav-label">Today</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if sidebarItems.length > 0}
|
{#if sidebarItems.length > 0}
|
||||||
<div class="sidebar-section">
|
<div class="sidebar-section">
|
||||||
<span class="section-label">Tools</span>
|
<span class="section-label">Tools</span>
|
||||||
|
|
@ -202,6 +216,21 @@
|
||||||
color: #a78bfa;
|
color: #a78bfa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.today-item {
|
||||||
|
gap: 0.55rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-icon-today {
|
||||||
|
width: 0.9rem;
|
||||||
|
height: 0.9rem;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #4ecca3;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.nav-label {
|
.nav-label {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@
|
||||||
class:status-bar-warning={item.handler}
|
class:status-bar-warning={item.handler}
|
||||||
class="status-bar-item"
|
class="status-bar-item"
|
||||||
data-status-item-id={item.id}
|
data-status-item-id={item.id}
|
||||||
title={item.handler ? `${item.pluginId}: compact status only` : item.pluginId}
|
title={item.handler ? `${item.pluginId}: click for details` : (item.label || item.id)}
|
||||||
>
|
>
|
||||||
{#if item.handler}<Icon name="warning" size={11} class="status-warning-icon" />{/if}
|
{#if item.handler}<Icon name="warning" size={11} class="status-warning-icon" />{/if}
|
||||||
{item.label || item.id}
|
{item.label || item.id}
|
||||||
|
|
@ -108,7 +108,7 @@
|
||||||
class:status-bar-warning={item.handler}
|
class:status-bar-warning={item.handler}
|
||||||
class="status-bar-item"
|
class="status-bar-item"
|
||||||
data-status-item-id={item.id}
|
data-status-item-id={item.id}
|
||||||
title={item.handler ? `${item.pluginId}: compact status only` : item.pluginId}
|
title={item.handler ? `${item.pluginId}: click for details` : (item.label || item.id)}
|
||||||
>
|
>
|
||||||
{#if item.handler}<Icon name="warning" size={11} class="status-warning-icon" />{/if}
|
{#if item.handler}<Icon name="warning" size={11} class="status-warning-icon" />{/if}
|
||||||
{item.label || item.id}
|
{item.label || item.id}
|
||||||
|
|
@ -121,7 +121,7 @@
|
||||||
class:status-bar-warning={item.handler}
|
class:status-bar-warning={item.handler}
|
||||||
class="status-bar-item"
|
class="status-bar-item"
|
||||||
data-status-item-id={item.id}
|
data-status-item-id={item.id}
|
||||||
title={item.handler ? `${item.pluginId}: compact status only` : item.pluginId}
|
title={item.handler ? `${item.pluginId}: click for details` : (item.label || item.id)}
|
||||||
>
|
>
|
||||||
{#if item.handler}<Icon name="warning" size={11} class="status-warning-icon" />{/if}
|
{#if item.handler}<Icon name="warning" size={11} class="status-warning-icon" />{/if}
|
||||||
{item.label || item.id}
|
{item.label || item.id}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
let activity = [];
|
let activity = [];
|
||||||
let worklogSuggestions = [];
|
let worklogSuggestions = [];
|
||||||
|
|
||||||
|
$: isGlobal = !workspaceRootPath || String(workspaceRootPath).trim() === '';
|
||||||
$: hasBrowserInbox = hasTool('browser inbox') || hasTool('inbox');
|
$: hasBrowserInbox = hasTool('browser inbox') || hasTool('inbox');
|
||||||
$: hasActivity = hasTool('activity');
|
$: hasActivity = hasTool('activity');
|
||||||
$: hasFiles = hasTool('files');
|
$: hasFiles = hasTool('files');
|
||||||
|
|
@ -111,24 +112,18 @@
|
||||||
readPluginSettings('verstak.journal'),
|
readPluginSettings('verstak.journal'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
captures = rowsFor(browserSettings, [
|
if (isGlobal) {
|
||||||
workspaceKey('captures:workspace:'),
|
captures = rowsFor(browserSettings, ['captures:global', 'captures']).slice(0, 4);
|
||||||
'captures:global',
|
activity = rowsFor(activitySettings, ['events:global', 'events']).slice(0, 4);
|
||||||
'captures',
|
worklogSuggestions = rowsFor(journalSettings, ['suggestions', 'worklog']).slice(0, 4);
|
||||||
]).slice(0, 4);
|
} else {
|
||||||
|
captures = rowsFor(browserSettings, [workspaceKey('captures:workspace:')]).slice(0, 4);
|
||||||
activity = rowsFor(activitySettings, [
|
activity = rowsFor(activitySettings, [workspaceKey('events:workspace:')]).slice(0, 4);
|
||||||
workspaceKey('events:workspace:'),
|
|
||||||
'events:global',
|
|
||||||
'events',
|
|
||||||
]).slice(0, 4);
|
|
||||||
|
|
||||||
worklogSuggestions = rowsFor(journalSettings, [
|
worklogSuggestions = rowsFor(journalSettings, [
|
||||||
workspaceKey('suggestions:workspace:'),
|
workspaceKey('suggestions:workspace:'),
|
||||||
workspaceKey('worklog:workspace:'),
|
workspaceKey('worklog:workspace:'),
|
||||||
'suggestions',
|
|
||||||
'worklog',
|
|
||||||
]).slice(0, 4);
|
]).slice(0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
loading = false;
|
loading = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@
|
||||||
role="tab"
|
role="tab"
|
||||||
aria-selected={toolKey(tool) === toolKey(activeTool)}
|
aria-selected={toolKey(tool) === toolKey(activeTool)}
|
||||||
type="button"
|
type="button"
|
||||||
title={tool.pluginId}
|
title={tool.title}
|
||||||
on:click={() => selectTool(tool)}
|
on:click={() => selectTool(tool)}
|
||||||
>
|
>
|
||||||
{tool.title || tool.id}
|
{tool.title || tool.id}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue