UI: Add tabs to dashboard and fix mcp capability regression
This commit is contained in:
1 parent
d71b1e6e35
commit
34cf8fc8ca
3 files changed
+106
-41
No files matched your search
+104
-35
@@ -105,8 +105,9 @@
|
|||||||
}
|
}
|
||||||
.main-container {
|
.main-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
gap: 20px;
|
gap: 10px;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
.panel {
|
.panel {
|
||||||
@@ -127,9 +128,11 @@
|
|||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
.graph-panel {
|
.graph-panel {
|
||||||
flex: 2;
|
flex: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Filter Bar */
|
/* Filter Bar */
|
||||||
@@ -225,17 +228,58 @@
|
|||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
display: flex;
|
||||||
|
gap: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
.tab-button {
|
||||||
|
padding: 8px 16px;
|
||||||
|
background: var(--panel-bg);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-bottom: none;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
color: var(--text-color);
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
.tab-button.active {
|
||||||
|
opacity: 1;
|
||||||
|
background: var(--bg-color);
|
||||||
|
font-weight: bold;
|
||||||
|
border-bottom: 1px solid var(--bg-color);
|
||||||
|
margin-bottom: -6px;
|
||||||
|
}
|
||||||
|
.tab-content {
|
||||||
|
display: none;
|
||||||
|
height: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.tab-content.active {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
.right-column {
|
.right-column {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 20px;
|
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
.right-column-panels {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
.search-panel {
|
.search-panel {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
input[type="text"] {
|
input[type="text"] {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -370,8 +414,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.activity-panel {
|
.activity-panel {
|
||||||
height: 180px;
|
flex: 1;
|
||||||
margin-top: 20px;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
#activity-feed {
|
#activity-feed {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@@ -407,42 +452,50 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<div class="panel graph-panel">
|
<div class="tabs">
|
||||||
<h2>Knowledge Graph</h2>
|
<button class="tab-button active" onclick="switchTab('graph-tab', this)">Graph Explorer</button>
|
||||||
<div class="graph-filters" id="graph-filters">
|
<button class="tab-button" onclick="switchTab('search-tab', this)">Omni-Search</button>
|
||||||
<!-- Filters injected dynamically -->
|
<button class="tab-button" onclick="switchTab('task-tab', this)">Task Board</button>
|
||||||
</div>
|
<button class="tab-button" onclick="switchTab('activity-tab', this)">Live Activity</button>
|
||||||
<div class="graph-controls">
|
</div>
|
||||||
<button onclick="zoomGraph(0.2)" title="Zoom In">+</button>
|
|
||||||
<button onclick="zoomGraph(-0.2)" title="Zoom Out">-</button>
|
<div id="graph-tab" class="tab-content active">
|
||||||
<button onclick="resetGraph()" title="Reset View">⌂</button>
|
<div class="panel graph-panel" style="flex:1;">
|
||||||
</div>
|
<div class="graph-filters" id="graph-filters">
|
||||||
<div id="network-container">
|
<!-- Filters injected dynamically -->
|
||||||
<div id="inspector-panel">
|
</div>
|
||||||
<button id="inspector-close" onclick="closeInspector()">✕</button>
|
<div class="graph-controls">
|
||||||
<h2 id="inspector-title" style="margin-top:0; color:var(--text-primary);"></h2>
|
<button onclick="zoomGraph(0.2)" title="Zoom In">+</button>
|
||||||
<div class="inspector-meta">
|
<button onclick="zoomGraph(-0.2)" title="Zoom Out">-</button>
|
||||||
<div><strong>Type:</strong> <span id="inspector-type"></span></div>
|
<button onclick="resetGraph()" title="Reset View">⌂</button>
|
||||||
<div><strong>Namespace:</strong> <span id="inspector-namespace"></span></div>
|
</div>
|
||||||
|
<div id="network-container">
|
||||||
|
<div id="inspector-panel">
|
||||||
|
<button id="inspector-close" onclick="closeInspector()">✕</button>
|
||||||
|
<h2 id="inspector-title" style="margin-top:0; color:var(--text-primary);"></h2>
|
||||||
|
<div class="inspector-meta">
|
||||||
|
<div><strong>Type:</strong> <span id="inspector-type"></span></div>
|
||||||
|
<div><strong>Namespace:</strong> <span id="inspector-namespace"></span></div>
|
||||||
|
</div>
|
||||||
|
<h4 style="margin:10px 0 5px 0;">Observations</h4>
|
||||||
|
<ul id="inspector-observations" style="padding-left:20px; font-size:0.9em; line-height:1.4;"></ul>
|
||||||
|
<h4 style="margin:15px 0 5px 0;">Relations</h4>
|
||||||
|
<ul id="inspector-relations" style="padding-left:20px; font-size:0.9em; line-height:1.4;"></ul>
|
||||||
</div>
|
</div>
|
||||||
<h4 style="margin:10px 0 5px 0;">Observations</h4>
|
|
||||||
<ul id="inspector-observations" style="padding-left:20px; font-size:0.9em; line-height:1.4;"></ul>
|
|
||||||
<h4 style="margin:15px 0 5px 0;">Relations</h4>
|
|
||||||
<ul id="inspector-relations" style="padding-left:20px; font-size:0.9em; line-height:1.4;"></ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="right-column">
|
<div id="search-tab" class="tab-content">
|
||||||
<div class="panel search-panel">
|
<div class="panel search-panel">
|
||||||
<h2>Omni-Search</h2>
|
|
||||||
<input type="text" id="search-box" placeholder="Search memory (e.g., 'database')..." onkeyup="handleSearch(event)">
|
<input type="text" id="search-box" placeholder="Search memory (e.g., 'database')..." onkeyup="handleSearch(event)">
|
||||||
<div id="search-results"></div>
|
<div id="search-results"></div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="panel kanban-panel">
|
<div id="task-tab" class="tab-content">
|
||||||
<h2>Task Board</h2>
|
<div class="panel kanban-panel" style="flex:1; display:flex; flex-direction:column;">
|
||||||
<div class="kanban-board">
|
<div class="kanban-board" style="flex:1;">
|
||||||
<div class="kanban-column">
|
<div class="kanban-column">
|
||||||
<h3>TODO / IN PROGRESS</h3>
|
<h3>TODO / IN PROGRESS</h3>
|
||||||
<div class="kanban-items" id="tasks-active"></div>
|
<div class="kanban-items" id="tasks-active"></div>
|
||||||
@@ -454,14 +507,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel activity-panel">
|
<div id="activity-tab" class="tab-content">
|
||||||
<h2>Live Activity Feed</h2>
|
<div class="panel activity-panel" style="flex:1; display:flex; flex-direction:column;">
|
||||||
<div id="activity-feed"></div>
|
<div id="activity-feed" style="flex:1;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// --- Tabs ---
|
||||||
|
function switchTab(tabId, btn) {
|
||||||
|
document.querySelectorAll('.tab-content').forEach(el => el.classList.remove('active'));
|
||||||
|
document.querySelectorAll('.tab-button').forEach(el => el.classList.remove('active'));
|
||||||
|
|
||||||
|
document.getElementById(tabId).classList.add('active');
|
||||||
|
btn.classList.add('active');
|
||||||
|
|
||||||
|
if (tabId === 'graph-tab' && network) {
|
||||||
|
// Resize graph when becoming visible again
|
||||||
|
network.redraw();
|
||||||
|
network.fit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- Theme Toggle ---
|
// --- Theme Toggle ---
|
||||||
function toggleTheme() {
|
function toggleTheme() {
|
||||||
const currentTheme = document.documentElement.getAttribute('data-theme');
|
const currentTheme = document.documentElement.getAttribute('data-theme');
|
||||||
|
|||||||
@@ -26,9 +26,7 @@ impl MemoryHandler {
|
|||||||
id,
|
id,
|
||||||
serde_json::json!({
|
serde_json::json!({
|
||||||
"protocolVersion": "2024-11-05",
|
"protocolVersion": "2024-11-05",
|
||||||
"capabilities": {
|
"capabilities": {},
|
||||||
"tools": {}
|
|
||||||
},
|
|
||||||
"serverInfo": {
|
"serverInfo": {
|
||||||
"name": "gemini-mcp-memory",
|
"name": "gemini-mcp-memory",
|
||||||
"version": "3.0.0"
|
"version": "3.0.0"
|
||||||
|
|||||||
@@ -57,9 +57,7 @@ async fn main() {
|
|||||||
id,
|
id,
|
||||||
result: Some(json!({
|
result: Some(json!({
|
||||||
"protocolVersion": "2024-11-05",
|
"protocolVersion": "2024-11-05",
|
||||||
"capabilities": {
|
"capabilities": {},
|
||||||
"tools": {}
|
|
||||||
},
|
|
||||||
"serverInfo": {
|
"serverInfo": {
|
||||||
"name": "mcp-memory-win-nvim",
|
"name": "mcp-memory-win-nvim",
|
||||||
"version": "0.1.0"
|
"version": "0.1.0"
|
||||||
|
|||||||
Reference in new issue
Block a user