@parhelia/core 0.1.12308 → 0.1.12325
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents-view/AgentsView.js +113 -23
- package/dist/agents-view/AgentsView.js.map +1 -1
- package/dist/components/MarkdownDisplay.d.ts +6 -1
- package/dist/components/MarkdownDisplay.js +3 -0
- package/dist/components/MarkdownDisplay.js.map +1 -1
- package/dist/editor/ai/AgentTerminal.js +28 -4
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/dialogs/AgentDialogHandler.js +32 -8
- package/dist/editor/ai/dialogs/AgentDialogHandler.js.map +1 -1
- package/dist/editor/ai/dialogs/QuestionnaireInline.d.ts +2 -1
- package/dist/editor/ai/dialogs/QuestionnaireInline.js +44 -23
- package/dist/editor/ai/dialogs/QuestionnaireInline.js.map +1 -1
- package/dist/editor/ai/dialogs/agentDialogTypes.d.ts +3 -1
- package/dist/editor/ai/dialogs/agentDialogTypes.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/task-board/TaskBoardWorkspace.js +46 -42
- package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
- package/dist/task-board/assigneeDisplay.d.ts +9 -0
- package/dist/task-board/assigneeDisplay.js +22 -0
- package/dist/task-board/assigneeDisplay.js.map +1 -0
- package/dist/task-board/components/ProjectAgentsPanel.js +1 -28
- package/dist/task-board/components/ProjectAgentsPanel.js.map +1 -1
- package/dist/task-board/components/TaskAssigneePicker.d.ts +5 -1
- package/dist/task-board/components/TaskAssigneePicker.js +5 -3
- package/dist/task-board/components/TaskAssigneePicker.js.map +1 -1
- package/dist/task-board/components/TaskCard.d.ts +5 -2
- package/dist/task-board/components/TaskCard.js +12 -5
- package/dist/task-board/components/TaskCard.js.map +1 -1
- package/dist/task-board/components/TaskRow.d.ts +4 -1
- package/dist/task-board/components/TaskRow.js +7 -6
- package/dist/task-board/components/TaskRow.js.map +1 -1
- package/dist/task-board/components/WizardAgentTerminalPanel.d.ts +16 -0
- package/dist/task-board/components/WizardAgentTerminalPanel.js +7 -0
- package/dist/task-board/components/WizardAgentTerminalPanel.js.map +1 -0
- package/dist/task-board/components/WizardCommunicationCards.d.ts +18 -0
- package/dist/task-board/components/WizardCommunicationCards.js +22 -0
- package/dist/task-board/components/WizardCommunicationCards.js.map +1 -0
- package/dist/task-board/components/WizardCommunicationCenter.d.ts +1 -12
- package/dist/task-board/components/WizardCommunicationCenter.js +14 -129
- package/dist/task-board/components/WizardCommunicationCenter.js.map +1 -1
- package/dist/task-board/components/WizardCommunicationShared.d.ts +22 -0
- package/dist/task-board/components/WizardCommunicationShared.js +84 -0
- package/dist/task-board/components/WizardCommunicationShared.js.map +1 -0
- package/dist/task-board/components/WizardTask.d.ts +50 -0
- package/dist/task-board/components/WizardTask.js +36 -0
- package/dist/task-board/components/WizardTask.js.map +1 -0
- package/dist/task-board/components/WizardTaskDetailsPanel.d.ts +29 -0
- package/dist/task-board/components/WizardTaskDetailsPanel.js +22 -0
- package/dist/task-board/components/WizardTaskDetailsPanel.js.map +1 -0
- package/dist/task-board/taskExecutionRecords.js +2 -1
- package/dist/task-board/taskExecutionRecords.js.map +1 -1
- package/dist/task-board/views/KanbanView.d.ts +1 -1
- package/dist/task-board/views/KanbanView.js +27 -1
- package/dist/task-board/views/KanbanView.js.map +1 -1
- package/dist/task-board/views/ListView.d.ts +1 -1
- package/dist/task-board/views/ListView.js +29 -3
- package/dist/task-board/views/ListView.js.map +1 -1
- package/dist/task-board/views/WizardView.d.ts +2 -0
- package/dist/task-board/views/WizardView.js +19 -8
- package/dist/task-board/views/WizardView.js.map +1 -1
- package/package.json +1 -1
- package/dist/editor/ai/HelpTerminal.d.ts +0 -5
- package/dist/editor/ai/HelpTerminal.js +0 -166
- package/dist/editor/ai/HelpTerminal.js.map +0 -1
- package/dist/editor/settings/AllAgentsPanel.d.ts +0 -5
- package/dist/editor/settings/AllAgentsPanel.js +0 -139
- package/dist/editor/settings/AllAgentsPanel.js.map +0 -1
- package/dist/editor/settings/LatestFeedback.d.ts +0 -1
- package/dist/editor/settings/LatestFeedback.js +0 -136
- package/dist/editor/settings/LatestFeedback.js.map +0 -1
- package/dist/editor/sidebar/LeftToolbar.d.ts +0 -1
- package/dist/editor/sidebar/LeftToolbar.js +0 -12
- package/dist/editor/sidebar/LeftToolbar.js.map +0 -1
- package/dist/editor/sidebar/NavigationSidebar.d.ts +0 -4
- package/dist/editor/sidebar/NavigationSidebar.js +0 -254
- package/dist/editor/sidebar/NavigationSidebar.js.map +0 -1
- package/dist/images/bg-shape-black.webp +0 -0
- package/dist/images/parhelia-logo-1.jpg +0 -0
- package/dist/images/phlogo.png +0 -0
- package/dist/images/wizard-bg.png +0 -0
- package/dist/styles.css +0 -8962
- package/dist/task-board/components/ProjectList.d.ts +0 -7
- package/dist/task-board/components/ProjectList.js +0 -74
- package/dist/task-board/components/ProjectList.js.map +0 -1
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState, useEffect } from "react";
|
|
3
|
-
import { getAllAgents, closeAgent, deleteAgent, } from "../services/agentService";
|
|
4
|
-
import { getAgentStatusConfig } from "../ai/AgentStatusBadge";
|
|
5
|
-
import { cn } from "../../lib/utils";
|
|
6
|
-
import { Trash, X, RefreshCw } from "lucide-react";
|
|
7
|
-
import { SimpleIconButton } from "../ui/SimpleIconButton";
|
|
8
|
-
import { useEditContext } from "../client/editContext";
|
|
9
|
-
import { Spinner } from "../ui/Spinner";
|
|
10
|
-
/**
|
|
11
|
-
* Settings panel that displays all non-closed agents across all users
|
|
12
|
-
* Admin-only feature for monitoring and managing agents
|
|
13
|
-
*/
|
|
14
|
-
export function AllAgentsPanel() {
|
|
15
|
-
const [agents, setAgents] = useState([]);
|
|
16
|
-
const [loading, setLoading] = useState(true);
|
|
17
|
-
const [error, setError] = useState(null);
|
|
18
|
-
const [refreshing, setRefreshing] = useState(false);
|
|
19
|
-
const [searchTerm, setSearchTerm] = useState("");
|
|
20
|
-
const editContext = useEditContext();
|
|
21
|
-
const loadAgents = async () => {
|
|
22
|
-
try {
|
|
23
|
-
setError(null);
|
|
24
|
-
const result = await getAllAgents(1000);
|
|
25
|
-
setAgents(result);
|
|
26
|
-
}
|
|
27
|
-
catch (err) {
|
|
28
|
-
console.error("Failed to load agents:", err);
|
|
29
|
-
setError(err?.message ||
|
|
30
|
-
"Failed to load agents. Check if you have admin permissions.");
|
|
31
|
-
}
|
|
32
|
-
finally {
|
|
33
|
-
setLoading(false);
|
|
34
|
-
setRefreshing(false);
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
loadAgents();
|
|
39
|
-
}, []);
|
|
40
|
-
const handleRefresh = async () => {
|
|
41
|
-
setRefreshing(true);
|
|
42
|
-
await loadAgents();
|
|
43
|
-
};
|
|
44
|
-
const handleCloseAgent = async (agentId, agentName) => {
|
|
45
|
-
editContext?.confirm({
|
|
46
|
-
header: "Close Agent",
|
|
47
|
-
message: `Are you sure you want to close agent "${agentName}"? This will stop its execution if running.`,
|
|
48
|
-
acceptLabel: "Close Agent",
|
|
49
|
-
accept: async () => {
|
|
50
|
-
try {
|
|
51
|
-
await closeAgent(agentId);
|
|
52
|
-
// Remove from list or reload
|
|
53
|
-
setAgents((prev) => prev.filter((a) => a.id !== agentId));
|
|
54
|
-
}
|
|
55
|
-
catch (err) {
|
|
56
|
-
console.error("Failed to close agent:", err);
|
|
57
|
-
alert(`Failed to close agent: ${err?.message || "Unknown error"}`);
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
showCancel: true,
|
|
61
|
-
});
|
|
62
|
-
};
|
|
63
|
-
const handleDeleteAgent = async (agentId, agentName, event) => {
|
|
64
|
-
event.stopPropagation();
|
|
65
|
-
editContext?.confirm({
|
|
66
|
-
header: "Delete Agent",
|
|
67
|
-
message: `Are you sure you want to permanently delete agent "${agentName}"?`,
|
|
68
|
-
acceptLabel: "Delete",
|
|
69
|
-
accept: async () => {
|
|
70
|
-
try {
|
|
71
|
-
await deleteAgent(agentId);
|
|
72
|
-
setAgents((prev) => prev.filter((a) => a.id !== agentId));
|
|
73
|
-
}
|
|
74
|
-
catch (err) {
|
|
75
|
-
console.error("Failed to delete agent:", err);
|
|
76
|
-
alert(`Failed to delete agent: ${err?.message || "Unknown error"}`);
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
showCancel: true,
|
|
80
|
-
});
|
|
81
|
-
};
|
|
82
|
-
const formatDateTime = (dateString) => {
|
|
83
|
-
try {
|
|
84
|
-
const date = new Date(dateString);
|
|
85
|
-
return date.toLocaleString();
|
|
86
|
-
}
|
|
87
|
-
catch {
|
|
88
|
-
return dateString;
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
const filteredAgents = agents.filter((agent) => {
|
|
92
|
-
if (!searchTerm.trim())
|
|
93
|
-
return true;
|
|
94
|
-
const search = searchTerm.toLowerCase();
|
|
95
|
-
return (agent.name.toLowerCase().includes(search) ||
|
|
96
|
-
agent.userId?.toLowerCase().includes(search) ||
|
|
97
|
-
agent.id.toLowerCase().includes(search));
|
|
98
|
-
});
|
|
99
|
-
// Group agents by status
|
|
100
|
-
const groupedAgents = filteredAgents.reduce((acc, agent) => {
|
|
101
|
-
const statusConfig = getAgentStatusConfig(agent);
|
|
102
|
-
const statusLabel = statusConfig.label.replace("Status: ", "");
|
|
103
|
-
if (!acc[statusLabel]) {
|
|
104
|
-
acc[statusLabel] = [];
|
|
105
|
-
}
|
|
106
|
-
acc[statusLabel].push(agent);
|
|
107
|
-
return acc;
|
|
108
|
-
}, {});
|
|
109
|
-
// Sort groups by priority
|
|
110
|
-
const statusOrder = [
|
|
111
|
-
"Waiting for Approval",
|
|
112
|
-
"Running",
|
|
113
|
-
"Error",
|
|
114
|
-
"New",
|
|
115
|
-
"Completed",
|
|
116
|
-
];
|
|
117
|
-
const sortedGroups = Object.entries(groupedAgents).sort(([a], [b]) => {
|
|
118
|
-
const indexA = statusOrder.indexOf(a);
|
|
119
|
-
const indexB = statusOrder.indexOf(b);
|
|
120
|
-
if (indexA === -1)
|
|
121
|
-
return 1;
|
|
122
|
-
if (indexB === -1)
|
|
123
|
-
return -1;
|
|
124
|
-
return indexA - indexB;
|
|
125
|
-
});
|
|
126
|
-
if (loading) {
|
|
127
|
-
return (_jsxs("div", { className: "flex h-full items-center justify-center gap-2", children: [_jsx(Spinner, { size: "sm" }), _jsx("div", { className: "text-sm text-gray-500", children: "Loading agents..." })] }));
|
|
128
|
-
}
|
|
129
|
-
if (error) {
|
|
130
|
-
return (_jsx("div", { className: "flex h-full items-center justify-center", children: _jsxs("div", { className: "max-w-md text-center", children: [_jsx("div", { className: "mb-4 text-sm text-red-600", children: error }), _jsx("button", { onClick: handleRefresh, className: "rounded bg-blue-500 px-4 py-2 text-xs text-white hover:bg-blue-600", children: "Retry" })] }) }));
|
|
131
|
-
}
|
|
132
|
-
return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "border-b border-gray-200 bg-white p-4", children: [_jsxs("div", { className: "mb-3 flex items-center justify-between", children: [_jsx("div", { children: _jsxs("p", { className: "text-xs text-gray-500", children: ["Showing ", filteredAgents.length, " non-closed agent", filteredAgents.length !== 1 ? "s" : "", " across all users"] }) }), _jsx(SimpleIconButton, { onClick: handleRefresh, icon: _jsx(RefreshCw, { className: cn("size-4", refreshing && "animate-spin"), strokeWidth: 1.5 }), label: "Refresh", disabled: refreshing, className: "text-gray-600 hover:text-gray-800" })] }), _jsx("input", { type: "text", placeholder: "Search by name, user, or agent ID...", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), className: "w-full rounded border border-gray-200 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none" })] }), _jsx("div", { className: "flex-1 overflow-auto", children: filteredAgents.length === 0 ? (_jsx("div", { className: "flex h-full items-center justify-center text-sm text-gray-500", children: searchTerm.trim()
|
|
133
|
-
? "No agents match your search"
|
|
134
|
-
: "No non-closed agents found" })) : (_jsx("div", { className: "space-y-6 p-4", children: sortedGroups.map(([statusLabel, groupAgents]) => (_jsxs("div", { children: [_jsxs("h3", { className: "mb-2 text-xs font-semibold tracking-wide text-gray-500 uppercase", children: [statusLabel, " (", groupAgents.length, ")"] }), _jsx("div", { className: "space-y-2", children: groupAgents.map((agent) => {
|
|
135
|
-
const statusConfig = getAgentStatusConfig(agent);
|
|
136
|
-
return (_jsx("div", { className: "rounded-lg border border-gray-200 bg-white p-3 shadow-sm transition-shadow hover:shadow-md", children: _jsxs("div", { className: "flex items-start justify-between", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "mb-1 flex items-center gap-2", children: [_jsx("div", { className: cn("h-2 w-2 flex-shrink-0 rounded-full", statusConfig.color, statusConfig.shouldPulse && "animate-pulse"), title: statusConfig.label }), _jsx("h4", { className: "truncate font-medium text-gray-900", children: agent.name })] }), _jsxs("div", { className: "space-y-1 text-xs text-gray-600", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-medium", children: "User:" }), _jsx("span", { children: agent.userId || "Unknown" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-medium", children: "ID:" }), _jsx("span", { className: "font-mono text-xs", children: agent.id })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-medium", children: "Updated:" }), _jsx("span", { children: formatDateTime(agent.updatedDate) })] }), agent.totalCost > 0 && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-medium", children: "Cost:" }), _jsxs("span", { children: ["$", agent.totalCost.toFixed(4)] })] }))] })] }), _jsxs("div", { className: "ml-3 flex gap-1", children: [_jsx(SimpleIconButton, { onClick: () => handleCloseAgent(agent.id, agent.name), icon: _jsx(X, { className: "size-3", strokeWidth: 1.5 }), label: "Close Agent", className: "text-gray-600 opacity-60 hover:text-gray-800 hover:opacity-100" }), _jsx(SimpleIconButton, { onClick: (e) => handleDeleteAgent(agent.id, agent.name, e), icon: _jsx(Trash, { className: "size-3", strokeWidth: 1.5 }), label: "Delete Agent", className: "text-red-600 opacity-60 hover:text-red-700 hover:opacity-100" })] })] }) }, agent.id));
|
|
137
|
-
}) })] }, statusLabel))) })) })] }));
|
|
138
|
-
}
|
|
139
|
-
//# sourceMappingURL=AllAgentsPanel.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AllAgentsPanel.js","sourceRoot":"","sources":["../../../src/editor/settings/AllAgentsPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function LatestFeedback(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useCallback, useEffect, useState } from "react";
|
|
3
|
-
import { useEditContext } from "../client/editContext";
|
|
4
|
-
import { getLatestComments } from "../services/reviewsService";
|
|
5
|
-
import { getLatestSuggestedEdits } from "../services/suggestedEditsService";
|
|
6
|
-
import { Lightbulb, MessageSquare } from "lucide-react";
|
|
7
|
-
import { LanguageSelector } from "../../components/ui/LanguageSelector";
|
|
8
|
-
export function LatestFeedback() {
|
|
9
|
-
const editContext = useEditContext();
|
|
10
|
-
const [items, setItems] = useState([]);
|
|
11
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
12
|
-
const [error, setError] = useState(null);
|
|
13
|
-
const [selectedLanguage, setSelectedLanguage] = useState(undefined);
|
|
14
|
-
// Cutoff is now computed server-side. Keep memo in case we later want client hints.
|
|
15
|
-
const sinceIso = null;
|
|
16
|
-
const load = useCallback(async () => {
|
|
17
|
-
let cancelled = false;
|
|
18
|
-
setIsLoading(true);
|
|
19
|
-
setError(null);
|
|
20
|
-
try {
|
|
21
|
-
const take = 50;
|
|
22
|
-
const [cRes, sRes] = await Promise.all([
|
|
23
|
-
getLatestComments(take, selectedLanguage),
|
|
24
|
-
getLatestSuggestedEdits(take, selectedLanguage),
|
|
25
|
-
]);
|
|
26
|
-
const comments = (cRes.data || []).map((c) => ({
|
|
27
|
-
...c,
|
|
28
|
-
kind: "comment",
|
|
29
|
-
}));
|
|
30
|
-
const suggestions = (sRes.data || []).map((s) => ({
|
|
31
|
-
...s,
|
|
32
|
-
kind: "suggestion",
|
|
33
|
-
}));
|
|
34
|
-
const merged = [...comments, ...suggestions].sort((a, b) => {
|
|
35
|
-
const ad = new Date(a.created || 0).getTime();
|
|
36
|
-
const bd = new Date(b.created || 0).getTime();
|
|
37
|
-
return bd - ad;
|
|
38
|
-
});
|
|
39
|
-
const latest = merged.slice(0, 50);
|
|
40
|
-
if (!cancelled)
|
|
41
|
-
setItems(latest);
|
|
42
|
-
}
|
|
43
|
-
catch (e) {
|
|
44
|
-
if (!cancelled)
|
|
45
|
-
setError(e?.message || "Failed to load latest items");
|
|
46
|
-
}
|
|
47
|
-
finally {
|
|
48
|
-
if (!cancelled)
|
|
49
|
-
setIsLoading(false);
|
|
50
|
-
}
|
|
51
|
-
return () => {
|
|
52
|
-
cancelled = true;
|
|
53
|
-
};
|
|
54
|
-
}, [sinceIso, selectedLanguage]);
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
let disposed;
|
|
57
|
-
(async () => {
|
|
58
|
-
disposed = await load();
|
|
59
|
-
})();
|
|
60
|
-
return () => {
|
|
61
|
-
try {
|
|
62
|
-
disposed?.();
|
|
63
|
-
}
|
|
64
|
-
catch { }
|
|
65
|
-
};
|
|
66
|
-
}, [load]);
|
|
67
|
-
useEffect(() => {
|
|
68
|
-
const typesToRefresh = new Set([
|
|
69
|
-
"comment-updated",
|
|
70
|
-
"comment-deleted",
|
|
71
|
-
"suggested-edit-updated",
|
|
72
|
-
"suggested-edit-deleted",
|
|
73
|
-
]);
|
|
74
|
-
const dispose = editContext?.addSocketMessageListener?.((message) => {
|
|
75
|
-
try {
|
|
76
|
-
if (typesToRefresh.has(message?.type)) {
|
|
77
|
-
void load();
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
catch { }
|
|
81
|
-
});
|
|
82
|
-
return () => {
|
|
83
|
-
try {
|
|
84
|
-
dispose?.();
|
|
85
|
-
}
|
|
86
|
-
catch { }
|
|
87
|
-
};
|
|
88
|
-
}, [editContext?.addSocketMessageListener, load]);
|
|
89
|
-
// Items are server-side filtered by language when selected
|
|
90
|
-
const onOpenItem = async (item) => {
|
|
91
|
-
try {
|
|
92
|
-
const mainId = item.kind === "comment" ? item.mainItemId : item.mainItemId;
|
|
93
|
-
const lang = item.kind === "comment" ? item.language : item.mainItemLanguage;
|
|
94
|
-
const ver = item.kind === "comment" ? item.version : item.mainItemVersion;
|
|
95
|
-
await editContext?.loadItem({ id: mainId, language: lang, version: ver });
|
|
96
|
-
editContext?.setSelectedComment(item.kind === "comment" ? item : undefined);
|
|
97
|
-
if (item.kind === "comment") {
|
|
98
|
-
editContext?.setScrollIntoView(item.itemId);
|
|
99
|
-
}
|
|
100
|
-
editContext?.openSidebar("feedback");
|
|
101
|
-
}
|
|
102
|
-
catch { }
|
|
103
|
-
};
|
|
104
|
-
const Row = ({ item }) => {
|
|
105
|
-
const isComment = item.kind === "comment";
|
|
106
|
-
const created = item.created
|
|
107
|
-
? new Date(item.created)
|
|
108
|
-
: undefined;
|
|
109
|
-
const dateText = created
|
|
110
|
-
? `${created.toLocaleDateString()} ${created.toLocaleTimeString()}`
|
|
111
|
-
: "";
|
|
112
|
-
const comment = isComment ? item : undefined;
|
|
113
|
-
const pageName = isComment
|
|
114
|
-
? comment?.mainItemName ||
|
|
115
|
-
(comment?.relatedItems || []).find((ri) => ri.itemId === comment?.mainItemId)?.itemName
|
|
116
|
-
: item.mainItemName;
|
|
117
|
-
const componentName = isComment
|
|
118
|
-
? comment?.itemName
|
|
119
|
-
: item.itemName;
|
|
120
|
-
const fieldName = isComment ? comment?.fieldName : undefined;
|
|
121
|
-
const user = item.authorDisplayName || item.author || "";
|
|
122
|
-
const label = isComment ? "Comment" : "Suggestion";
|
|
123
|
-
return (_jsx("button", { className: "w-full cursor-pointer rounded p-1 text-left hover:bg-gray-100", onClick: () => onOpenItem(item), children: _jsxs("div", { className: "flex items-center justify-between gap-2 text-xs", children: [_jsxs("div", { className: "flex items-center gap-2 truncate", children: [_jsx("span", { className: "inline-flex items-center justify-center rounded py-0.5 text-gray-700", "aria-label": label, title: label, children: isComment ? (_jsx(MessageSquare, { className: "h-3.5 w-3.5", strokeWidth: 1 })) : (_jsx(Lightbulb, { className: "h-3.5 w-3.5", strokeWidth: 1 })) }), _jsx("div", { className: "flex items-center", children: [
|
|
124
|
-
pageName,
|
|
125
|
-
componentName,
|
|
126
|
-
fieldName ||
|
|
127
|
-
(item.kind === "suggestion" ? item.fieldId : undefined),
|
|
128
|
-
]
|
|
129
|
-
.filter((x) => !!x && x.length > 0)
|
|
130
|
-
.map((seg, idx, arr) => (_jsxs("span", { className: "truncate", children: [idx > 0 && (_jsx("span", { className: "mx-1 text-gray-400", children: ">" })), _jsx("span", { className: idx === 0
|
|
131
|
-
? "font-medium text-gray-900"
|
|
132
|
-
: "text-gray-500", children: seg })] }, idx))) }), user && _jsxs("span", { className: "text-gray-500", children: [" \u00B7 ", user] })] }), _jsx("div", { className: "shrink-0 text-[10px] text-gray-500", children: dateText })] }) }));
|
|
133
|
-
};
|
|
134
|
-
return (_jsxs("div", { className: "h-full overflow-auto p-2", children: [_jsxs("div", { className: "mb-2 flex items-center gap-2", children: [_jsx(LanguageSelector, { selectedLanguage: selectedLanguage, onLanguageSelected: (language) => setSelectedLanguage(language.languageCode), showAllLanguages: true }), selectedLanguage && (_jsx("button", { className: "text-xs text-gray-600 hover:underline", onClick: () => setSelectedLanguage(undefined), children: "Clear" }))] }), isLoading && _jsx("div", { className: "p-2 text-xs text-gray-500", children: "Loading\u2026" }), error && _jsx("div", { className: "p-2 text-xs text-red-600", children: error }), !isLoading && !error && items.length === 0 && (_jsx("div", { className: "p-2 text-xs text-gray-500", children: "No recent activity" })), _jsx("div", { className: "divide-y", children: items.map((it) => (_jsx(Row, { item: it }, `${it.kind}-${it.id}`))) })] }));
|
|
135
|
-
}
|
|
136
|
-
//# sourceMappingURL=LatestFeedback.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LatestFeedback.js","sourceRoot":"","sources":["../../../src/editor/settings/LatestFeedback.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function LeftToolbar(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { cn } from "../../lib/utils";
|
|
3
|
-
import { useEditContext } from "../client/editContext";
|
|
4
|
-
import { NavigationSidebar } from "./NavigationSidebar";
|
|
5
|
-
export function LeftToolbar() {
|
|
6
|
-
const editContext = useEditContext();
|
|
7
|
-
const showLabels = editContext?.userInfo.preferences?.showLabels ?? editContext?.userInfo.preferences?.showViewNames ?? false;
|
|
8
|
-
return (_jsx("div", { className: cn("border-gray-200 bg-gray-50/50 flex items-center gap-1.5 border-r p-1.5", editContext?.isMobile
|
|
9
|
-
? "scrollbar-hide flex-row overflow-x-auto"
|
|
10
|
-
: `flex-col ${showLabels ? "w-16" : "w-9"}`), children: _jsx(NavigationSidebar, {}) }));
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=LeftToolbar.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LeftToolbar.js","sourceRoot":"","sources":["../../../src/editor/sidebar/LeftToolbar.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,UAAU,WAAW;IACzB,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,MAAM,UAAU,GACd,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,UAAU,IAAI,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,aAAa,IAAI,KAAK,CAAC;IAC7G,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,wEAAwE,EACxE,WAAW,EAAE,QAAQ;YACnB,CAAC,CAAC,yCAAyC;YAC3C,CAAC,CAAC,YAAY,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAC9C,YAED,KAAC,iBAAiB,KAAG,GACjB,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import React, { useState, useMemo, useCallback, useRef, useEffect, } from "react";
|
|
3
|
-
import { cn } from "../../lib/utils";
|
|
4
|
-
import { useEditContext } from "../client/editContext";
|
|
5
|
-
import { VerticalDotsIcon, ViewToggleIcon } from "../ui/Icons";
|
|
6
|
-
import { Popover, PopoverContent, PopoverTrigger, } from "../../components/ui/popover";
|
|
7
|
-
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "../../components/ui/tooltip";
|
|
8
|
-
import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, } from "../../components/ui/context-menu";
|
|
9
|
-
import { DrawingPinFilledIcon, DrawingPinIcon } from "@radix-ui/react-icons";
|
|
10
|
-
import { Pin, PinOff, X } from "lucide-react";
|
|
11
|
-
function NavigationSidebarComponent() {
|
|
12
|
-
const editContext = useEditContext();
|
|
13
|
-
// Extract sidebar values
|
|
14
|
-
const contextValues = useMemo(() => ({
|
|
15
|
-
// Workspace state (for checking if we're in Editor workspace)
|
|
16
|
-
workspaceId: editContext?.workspaceId ?? "home",
|
|
17
|
-
// Sidebar state (for Editor workspace)
|
|
18
|
-
sidebars: editContext?.availableSidebars ?? [],
|
|
19
|
-
openSidebars: editContext?.openSidebars ?? [],
|
|
20
|
-
pinnedSidebars: editContext?.pinnedSidebars ?? [],
|
|
21
|
-
lockedSidebars: editContext?.lockedSidebars ?? [],
|
|
22
|
-
sidebarStacks: editContext?.sidebarStacks ?? [],
|
|
23
|
-
toggleSidebar: editContext?.toggleSidebar,
|
|
24
|
-
openSidebar: editContext?.openSidebar,
|
|
25
|
-
toggleSidebarPin: editContext?.toggleSidebarPin,
|
|
26
|
-
toggleSidebarLock: editContext?.toggleSidebarLock,
|
|
27
|
-
stackSidebar: editContext?.stackSidebar,
|
|
28
|
-
unstackSidebar: editContext?.unstackSidebar,
|
|
29
|
-
// Display preferences
|
|
30
|
-
showLabels: editContext?.userInfo.preferences?.showLabels ??
|
|
31
|
-
editContext?.userInfo.preferences?.showViewNames ??
|
|
32
|
-
false,
|
|
33
|
-
isMobile: editContext?.isMobile ?? false,
|
|
34
|
-
setUserPreferences: editContext?.setUserPreferences,
|
|
35
|
-
// Workspace state
|
|
36
|
-
visibleWorkspaces: editContext?.visibleWorkspaces ?? [],
|
|
37
|
-
switchWorkspace: editContext?.switchWorkspace,
|
|
38
|
-
}), [
|
|
39
|
-
editContext?.workspaceId,
|
|
40
|
-
editContext?.availableSidebars,
|
|
41
|
-
editContext?.openSidebars,
|
|
42
|
-
editContext?.pinnedSidebars,
|
|
43
|
-
editContext?.lockedSidebars,
|
|
44
|
-
editContext?.toggleSidebar,
|
|
45
|
-
editContext?.openSidebar,
|
|
46
|
-
editContext?.toggleSidebarPin,
|
|
47
|
-
editContext?.toggleSidebarLock,
|
|
48
|
-
editContext?.sidebarStacks,
|
|
49
|
-
editContext?.stackSidebar,
|
|
50
|
-
editContext?.unstackSidebar,
|
|
51
|
-
editContext?.userInfo.preferences?.showLabels,
|
|
52
|
-
editContext?.userInfo.preferences?.showViewNames,
|
|
53
|
-
editContext?.isMobile,
|
|
54
|
-
editContext?.setUserPreferences,
|
|
55
|
-
editContext?.visibleWorkspaces,
|
|
56
|
-
editContext?.switchWorkspace,
|
|
57
|
-
]);
|
|
58
|
-
const [isSidebarPopoverOpen, setIsSidebarPopoverOpen] = useState(false);
|
|
59
|
-
const [disableTooltip, setDisableTooltip] = useState(false);
|
|
60
|
-
const tooltipReenableTimer = useRef(null);
|
|
61
|
-
useEffect(() => {
|
|
62
|
-
return () => {
|
|
63
|
-
if (tooltipReenableTimer.current) {
|
|
64
|
-
window.clearTimeout(tooltipReenableTimer.current);
|
|
65
|
-
tooltipReenableTimer.current = null;
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
}, []);
|
|
69
|
-
// Check if we're in the Editor workspace (which supports sidebars)
|
|
70
|
-
const isEditorWorkspace = contextValues.workspaceId === "editor";
|
|
71
|
-
// Get visible sidebars for the current position
|
|
72
|
-
const leftSidebars = useMemo(() => {
|
|
73
|
-
return contextValues.sidebars
|
|
74
|
-
.filter((s) => s.position === "left" && !s.hidden)
|
|
75
|
-
.sort((a, b) => (a.sortOrder ?? 100) - (b.sortOrder ?? 100));
|
|
76
|
-
}, [contextValues.sidebars]);
|
|
77
|
-
const toggleShowLabels = useCallback(() => {
|
|
78
|
-
const newShowLabels = !contextValues.showLabels;
|
|
79
|
-
contextValues.setUserPreferences?.({ showLabels: newShowLabels });
|
|
80
|
-
}, [contextValues.showLabels, contextValues.setUserPreferences]);
|
|
81
|
-
const mobileWorkspaces = useMemo(() => {
|
|
82
|
-
const base = (contextValues.visibleWorkspaces ?? [])
|
|
83
|
-
.filter((w) => !w.hidden)
|
|
84
|
-
.filter((w) => w.id !== "home")
|
|
85
|
-
.slice()
|
|
86
|
-
.sort((a, b) => (a.sortOrder ?? 100) - (b.sortOrder ?? 100));
|
|
87
|
-
const settingsIndex = base.findIndex((w) => w.id === "settings");
|
|
88
|
-
if (settingsIndex >= 0) {
|
|
89
|
-
const [settings] = base.splice(settingsIndex, 1);
|
|
90
|
-
if (settings)
|
|
91
|
-
base.push(settings);
|
|
92
|
-
}
|
|
93
|
-
return base;
|
|
94
|
-
}, [contextValues.visibleWorkspaces]);
|
|
95
|
-
const handleWorkspaceClick = useCallback((targetWorkspaceId) => {
|
|
96
|
-
if (targetWorkspaceId !== contextValues.workspaceId) {
|
|
97
|
-
contextValues.switchWorkspace?.(targetWorkspaceId);
|
|
98
|
-
}
|
|
99
|
-
}, [contextValues.workspaceId, contextValues.switchWorkspace]);
|
|
100
|
-
const renderIcon = useCallback((icon, additionalClassName) => {
|
|
101
|
-
if (icon && React.isValidElement(icon)) {
|
|
102
|
-
return React.cloneElement(icon, {
|
|
103
|
-
className: cn("w-4 h-4", additionalClassName),
|
|
104
|
-
strokeWidth: 1.5,
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
return null;
|
|
108
|
-
}, []);
|
|
109
|
-
const handleSidebarClick = useCallback((sidebarId) => {
|
|
110
|
-
contextValues.toggleSidebar?.(sidebarId);
|
|
111
|
-
}, [contextValues.toggleSidebar]);
|
|
112
|
-
const handleSidebarClickAndClosePopover = useCallback((sidebarId) => {
|
|
113
|
-
contextValues.openSidebar?.(sidebarId);
|
|
114
|
-
if (tooltipReenableTimer.current) {
|
|
115
|
-
window.clearTimeout(tooltipReenableTimer.current);
|
|
116
|
-
}
|
|
117
|
-
setDisableTooltip(true);
|
|
118
|
-
tooltipReenableTimer.current = window.setTimeout(() => {
|
|
119
|
-
setDisableTooltip(false);
|
|
120
|
-
tooltipReenableTimer.current = null;
|
|
121
|
-
}, 800);
|
|
122
|
-
setIsSidebarPopoverOpen(false);
|
|
123
|
-
}, [contextValues.openSidebar]);
|
|
124
|
-
const handlePinClick = useCallback((e, sidebarId) => {
|
|
125
|
-
e.stopPropagation();
|
|
126
|
-
contextValues.toggleSidebarPin?.(sidebarId);
|
|
127
|
-
}, [contextValues.toggleSidebarPin]);
|
|
128
|
-
// Drag state for reordering pinned sidebar icons
|
|
129
|
-
const [dragOverId, setDragOverId] = useState(null);
|
|
130
|
-
const handleIconDragStart = useCallback((e, sidebarId) => {
|
|
131
|
-
e.dataTransfer.setData("text/alpaca-sidebar-icon", sidebarId);
|
|
132
|
-
e.dataTransfer.effectAllowed = "move";
|
|
133
|
-
}, []);
|
|
134
|
-
const handleIconDragOver = useCallback((e, sidebarId) => {
|
|
135
|
-
e.preventDefault();
|
|
136
|
-
e.dataTransfer.dropEffect = "move";
|
|
137
|
-
setDragOverId(sidebarId);
|
|
138
|
-
}, []);
|
|
139
|
-
const handleIconDragLeave = useCallback(() => {
|
|
140
|
-
setDragOverId(null);
|
|
141
|
-
}, []);
|
|
142
|
-
const handleIconDrop = useCallback((e, targetSidebarId) => {
|
|
143
|
-
e.preventDefault();
|
|
144
|
-
setDragOverId(null);
|
|
145
|
-
const sourceSidebarId = e.dataTransfer.getData("text/alpaca-sidebar-icon");
|
|
146
|
-
if (!sourceSidebarId || sourceSidebarId === targetSidebarId) {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
// Reorder pinned sidebars
|
|
150
|
-
const currentPinned = [...contextValues.pinnedSidebars];
|
|
151
|
-
const sourceIndex = currentPinned.indexOf(sourceSidebarId);
|
|
152
|
-
const targetIndex = currentPinned.indexOf(targetSidebarId);
|
|
153
|
-
if (sourceIndex === -1 || targetIndex === -1) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
// Remove source and insert at target position
|
|
157
|
-
currentPinned.splice(sourceIndex, 1);
|
|
158
|
-
const newTargetIndex = currentPinned.indexOf(targetSidebarId);
|
|
159
|
-
const insertIndex = sourceIndex < targetIndex ? newTargetIndex + 1 : newTargetIndex;
|
|
160
|
-
currentPinned.splice(insertIndex, 0, sourceSidebarId);
|
|
161
|
-
editContext?.reorderPinnedSidebars?.(currentPinned);
|
|
162
|
-
}, [contextValues.pinnedSidebars, editContext]);
|
|
163
|
-
// Get the currently visible sidebars in the selector (pinned + open)
|
|
164
|
-
// Order: pinned sidebars first (in their saved order), then open-but-not-pinned
|
|
165
|
-
const visibleSidebarItems = useMemo(() => {
|
|
166
|
-
const pinnedSet = new Set(contextValues.pinnedSidebars);
|
|
167
|
-
const openSet = new Set(contextValues.openSidebars);
|
|
168
|
-
const sidebarMap = new Map(leftSidebars.map((s) => [s.id, s]));
|
|
169
|
-
// Start with pinned sidebars in their saved order
|
|
170
|
-
const result = [];
|
|
171
|
-
for (const id of contextValues.pinnedSidebars) {
|
|
172
|
-
const sidebar = sidebarMap.get(id);
|
|
173
|
-
if (sidebar) {
|
|
174
|
-
result.push(sidebar);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
// Add open-but-not-pinned sidebars (in their sortOrder)
|
|
178
|
-
for (const sidebar of leftSidebars) {
|
|
179
|
-
if (openSet.has(sidebar.id) && !pinnedSet.has(sidebar.id)) {
|
|
180
|
-
result.push(sidebar);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return result;
|
|
184
|
-
}, [leftSidebars, contextValues.pinnedSidebars, contextValues.openSidebars]);
|
|
185
|
-
return (_jsxs(TooltipProvider, { delayDuration: 500, skipDelayDuration: 0, children: [isEditorWorkspace &&
|
|
186
|
-
visibleSidebarItems.map((sidebar) => {
|
|
187
|
-
const isOpen = contextValues.openSidebars.includes(sidebar.id);
|
|
188
|
-
const isPinned = contextValues.pinnedSidebars.includes(sidebar.id);
|
|
189
|
-
const currentStack = contextValues.sidebarStacks?.find((s) => s.includes(sidebar.id)) ??
|
|
190
|
-
null;
|
|
191
|
-
const isStacked = !!(currentStack && currentStack.length > 1);
|
|
192
|
-
// Check if any sidebar in the stack is locked (stack-level lock)
|
|
193
|
-
const isLocked = currentStack
|
|
194
|
-
? currentStack.some((id) => contextValues.lockedSidebars?.includes(id))
|
|
195
|
-
: (contextValues.lockedSidebars?.includes(sidebar.id) ?? false);
|
|
196
|
-
const stackCandidates = leftSidebars.filter((s) => s.id !== sidebar.id && contextValues.openSidebars.includes(s.id));
|
|
197
|
-
return (_jsxs(ContextMenu, { children: [_jsx(ContextMenuTrigger, { asChild: true, children: _jsxs(Tooltip, { delayDuration: 500, children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("div", { className: cn(
|
|
198
|
-
// Sidebar icons: smaller, subtler appearance
|
|
199
|
-
isOpen
|
|
200
|
-
? "border-gray-300 bg-gray-100 text-gray-900"
|
|
201
|
-
: "border-transparent text-gray-500 hover:bg-gray-50 hover:text-gray-700", "relative flex cursor-pointer flex-col items-center justify-center rounded border select-none", contextValues.showLabels ? "p-1" : "p-1", contextValues.isMobile ? "shrink-0" : "",
|
|
202
|
-
// Drag-over visual feedback
|
|
203
|
-
dragOverId === sidebar.id && "ring-2 ring-blue-400"), "data-sidebar-id": sidebar.id, "data-testid": `sidebar-icon-${sidebar.id}`, onClick: () => {
|
|
204
|
-
handleSidebarClick(sidebar.id);
|
|
205
|
-
},
|
|
206
|
-
// Drag-and-drop for reordering pinned icons
|
|
207
|
-
draggable: isPinned, onDragStart: (e) => isPinned && handleIconDragStart(e, sidebar.id), onDragOver: (e) => isPinned && handleIconDragOver(e, sidebar.id), onDragLeave: handleIconDragLeave, onDrop: (e) => isPinned && handleIconDrop(e, sidebar.id), children: [_jsxs("div", { className: cn("relative", contextValues.showLabels ? "p-0.5" : ""), children: [renderIcon(sidebar.icon), isStacked && (_jsx("div", { className: "bg-theme-secondary absolute right-0 bottom-0 size-1.5 rounded-full" }))] }), contextValues.showLabels && (_jsx("span", { className: "mt-0.5 max-w-[50px] text-center text-[10px] leading-tight wrap-break-word", children: sidebar.title }))] }) }), _jsx(TooltipContent, { side: "right", children: sidebar.title })] }) }), _jsxs(ContextMenuContent, { children: [isOpen && (_jsx(ContextMenuItem, { onSelect: () => {
|
|
208
|
-
contextValues.toggleSidebarLock?.(sidebar.id);
|
|
209
|
-
}, children: isLocked ? (_jsxs(_Fragment, { children: [_jsx(PinOff, { className: "size-4", strokeWidth: 1 }), isStacked ? "Unpin stack" : "Unpin"] })) : (_jsxs(_Fragment, { children: [_jsx(Pin, { className: "size-4", strokeWidth: 1 }), isStacked ? "Pin stack open" : "Pin open"] })) })), isOpen && stackCandidates.length > 0 && (_jsxs(ContextMenuSub, { children: [_jsx(ContextMenuSubTrigger, { children: "Stack with..." }), _jsx(ContextMenuSubContent, { children: stackCandidates.map((target) => (_jsx(ContextMenuItem, { onSelect: () => {
|
|
210
|
-
contextValues.stackSidebar?.(sidebar.id, target.id, "after");
|
|
211
|
-
}, children: target.title }, `stack-with-${sidebar.id}-${target.id}`))) })] })), isOpen && isStacked && (_jsx(ContextMenuItem, { onSelect: () => {
|
|
212
|
-
contextValues.unstackSidebar?.(sidebar.id);
|
|
213
|
-
}, children: "Unstack" })), _jsx(ContextMenuItem, { onSelect: () => {
|
|
214
|
-
contextValues.toggleSidebarPin?.(sidebar.id);
|
|
215
|
-
}, children: isPinned ? (_jsxs(_Fragment, { children: [_jsx(PinOff, { className: "size-4", strokeWidth: 1 }), "Unpin from toolbar"] })) : (_jsxs(_Fragment, { children: [_jsx(Pin, { className: "size-4", strokeWidth: 1 }), "Pin to toolbar"] })) }), isOpen && (_jsxs(ContextMenuItem, { onSelect: () => {
|
|
216
|
-
contextValues.toggleSidebar?.(sidebar.id, {
|
|
217
|
-
forceClose: true,
|
|
218
|
-
});
|
|
219
|
-
}, children: [_jsx(X, { className: "size-4", strokeWidth: 1 }), "Close"] }))] })] }, `sidebar-${sidebar.id}`));
|
|
220
|
-
}), isEditorWorkspace && leftSidebars.length > 0 && (_jsxs(Popover, { open: isSidebarPopoverOpen, onOpenChange: (open) => {
|
|
221
|
-
setIsSidebarPopoverOpen(open);
|
|
222
|
-
}, children: [_jsxs(Tooltip, { delayDuration: disableTooltip ? 100000 : 500, open: isSidebarPopoverOpen || disableTooltip ? false : undefined, children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { "data-testid": "more-sidebars-button", className: cn("flex items-center justify-center rounded border border-transparent p-1", "text-gray-400 hover:border-gray-200 hover:bg-gray-50 hover:text-gray-600", contextValues.isMobile ? "shrink-0" : ""), children: _jsx(VerticalDotsIcon, { className: "h-4 w-4" }) }) }) }), _jsx(TooltipContent, { side: "right", children: "More panels" })] }), _jsx(PopoverContent, { className: "w-56 p-2", side: contextValues.isMobile ? "bottom" : "right", align: "start", onInteractOutside: (e) => {
|
|
223
|
-
const target = e.target;
|
|
224
|
-
if (target && target.closest('[data-slot="tooltip-content"]')) {
|
|
225
|
-
e.preventDefault();
|
|
226
|
-
}
|
|
227
|
-
}, onPointerDownOutside: (e) => {
|
|
228
|
-
const target = e.target;
|
|
229
|
-
if (target && target.closest('[data-slot="tooltip-content"]')) {
|
|
230
|
-
e.preventDefault();
|
|
231
|
-
}
|
|
232
|
-
}, onFocusOutside: (e) => {
|
|
233
|
-
const target = e.target;
|
|
234
|
-
if (target && target.closest('[data-slot="tooltip-content"]')) {
|
|
235
|
-
e.preventDefault();
|
|
236
|
-
}
|
|
237
|
-
}, children: _jsxs("div", { className: "space-y-1", children: [_jsx("div", { className: "px-2 py-1 text-[9px] font-medium tracking-wider text-gray-600 uppercase", children: "Sidebars" }), leftSidebars.map((sidebar) => {
|
|
238
|
-
const isOpen = contextValues.openSidebars.includes(sidebar.id);
|
|
239
|
-
const isPinned = contextValues.pinnedSidebars.includes(sidebar.id);
|
|
240
|
-
return (_jsxs("div", { className: cn("group flex cursor-pointer items-center justify-between rounded p-2 hover:bg-gray-100", isOpen && "bg-gray-50"), onClick: () => handleSidebarClickAndClosePopover(sidebar.id), "data-testid": `sidebar-${sidebar.id}`, children: [_jsxs("div", { className: "flex flex-1 items-center gap-1.5", children: [renderIcon(sidebar.icon, "w-4 h-4"), _jsx("span", { className: "text-xs", children: sidebar.title })] }), _jsxs(Tooltip, { delayDuration: 500, children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "flex h-6 w-6 shrink-0 items-center justify-center rounded hover:bg-gray-200", onClick: (e) => {
|
|
241
|
-
e.stopPropagation();
|
|
242
|
-
e.preventDefault();
|
|
243
|
-
handlePinClick(e, sidebar.id);
|
|
244
|
-
}, onMouseDown: (e) => {
|
|
245
|
-
e.stopPropagation();
|
|
246
|
-
}, children: isPinned ? (_jsx(DrawingPinFilledIcon, { className: "text-theme-secondary h-4 w-4" })) : (_jsx(DrawingPinIcon, { className: "h-4 w-4 text-gray-400" })) }) }), _jsx(TooltipContent, { side: "right", children: isPinned ? "Unpin from toolbar" : "Pin to toolbar" })] })] }, `menu-sidebar-${sidebar.id}`));
|
|
247
|
-
})] }) })] })), _jsx("div", { className: "flex-1" }), contextValues.isMobile && mobileWorkspaces.length > 0 && (_jsxs(_Fragment, { children: [_jsx("div", { className: "mx-1 h-px w-full bg-gray-200" }), mobileWorkspaces.map((workspace) => {
|
|
248
|
-
const active = workspace.id === contextValues.workspaceId;
|
|
249
|
-
return (_jsx("button", { type: "button", "aria-label": workspace.title, "aria-current": active ? "page" : undefined, "data-testid": `workspace-mobile-${workspace.id}`, className: cn("flex items-center justify-center rounded border border-transparent p-1", "text-gray-500 hover:border-gray-200 hover:bg-gray-50 hover:text-gray-800", active && "border-gray-300 bg-gray-100 text-gray-900"), onClick: () => handleWorkspaceClick(workspace.id), children: renderIcon(workspace.icon) }, `workspace-${workspace.id}`));
|
|
250
|
-
})] })), _jsxs(Tooltip, { delayDuration: 500, children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { className: cn("flex items-center justify-center rounded border border-transparent p-0.5", "text-gray-400 hover:border-gray-200 hover:bg-gray-50 hover:text-gray-600", contextValues.isMobile ? "shrink-0" : ""), onClick: toggleShowLabels, children: _jsx(ViewToggleIcon, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { side: "right", children: contextValues.showLabels ? "Hide labels" : "Show labels" })] })] }));
|
|
251
|
-
}
|
|
252
|
-
// Export memoized component to prevent unnecessary re-renders
|
|
253
|
-
export const NavigationSidebar = React.memo(NavigationSidebarComponent);
|
|
254
|
-
//# sourceMappingURL=NavigationSidebar.js.map
|