fix(webui): polish automation layout and session updates
This commit is contained in:
+34
-18
@@ -65,7 +65,8 @@ type BootState =
|
||||
};
|
||||
|
||||
const SIDEBAR_STORAGE_KEY = "nanobot-webui.sidebar";
|
||||
const COMPLETED_RUNS_STORAGE_KEY = "nanobot-webui.sidebar.completed-runs.v1";
|
||||
const SESSION_UPDATES_STORAGE_KEY = "nanobot-webui.sidebar.session-updates.v1";
|
||||
const LEGACY_COMPLETED_RUNS_STORAGE_KEY = "nanobot-webui.sidebar.completed-runs.v1";
|
||||
const RESTART_STARTED_KEY = "nanobot-webui.restartStartedAt";
|
||||
const SIDEBAR_WIDTH = 272;
|
||||
const SIDEBAR_RAIL_WIDTH = 56;
|
||||
@@ -258,10 +259,12 @@ function readSidebarOpen(): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
function readCompletedRunChatIds(): Set<string> {
|
||||
function readSessionUpdateChatIds(): Set<string> {
|
||||
if (typeof window === "undefined") return new Set();
|
||||
try {
|
||||
const raw = window.localStorage.getItem(COMPLETED_RUNS_STORAGE_KEY);
|
||||
const raw =
|
||||
window.localStorage.getItem(SESSION_UPDATES_STORAGE_KEY)
|
||||
?? window.localStorage.getItem(LEGACY_COMPLETED_RUNS_STORAGE_KEY);
|
||||
const parsed = raw ? JSON.parse(raw) : [];
|
||||
if (!Array.isArray(parsed)) return new Set();
|
||||
return new Set(parsed.filter((item): item is string => typeof item === "string"));
|
||||
@@ -270,10 +273,10 @@ function readCompletedRunChatIds(): Set<string> {
|
||||
}
|
||||
}
|
||||
|
||||
function writeCompletedRunChatIds(chatIds: Set<string>): void {
|
||||
function writeSessionUpdateChatIds(chatIds: Set<string>): void {
|
||||
try {
|
||||
window.localStorage.setItem(
|
||||
COMPLETED_RUNS_STORAGE_KEY,
|
||||
SESSION_UPDATES_STORAGE_KEY,
|
||||
JSON.stringify(Array.from(chatIds)),
|
||||
);
|
||||
} catch {
|
||||
@@ -573,7 +576,7 @@ function Shell({
|
||||
const [restartToast, setRestartToast] = useState<string | null>(null);
|
||||
const [isRestarting, setIsRestarting] = useState(false);
|
||||
const [runningChatIds, setRunningChatIds] = useState<Set<string>>(() => new Set());
|
||||
const [completedChatIds, setCompletedChatIds] = useState<Set<string>>(readCompletedRunChatIds);
|
||||
const [updatedChatIds, setUpdatedChatIds] = useState<Set<string>>(readSessionUpdateChatIds);
|
||||
const [workspaces, setWorkspaces] = useState<WorkspacesPayload | null>(null);
|
||||
const skills = useSkills(token);
|
||||
const [settingsSnapshot, setSettingsSnapshot] = useState<SettingsPayload | null>(null);
|
||||
@@ -641,20 +644,20 @@ function Shell({
|
||||
}, [hostSidebarOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
writeCompletedRunChatIds(completedChatIds);
|
||||
}, [completedChatIds]);
|
||||
writeSessionUpdateChatIds(updatedChatIds);
|
||||
}, [updatedChatIds]);
|
||||
|
||||
const activeSession = useMemo<ChatSummary | null>(() => {
|
||||
if (!activeKey) return null;
|
||||
return sessions.find((s) => s.key === activeKey) ?? null;
|
||||
}, [sessions, activeKey]);
|
||||
const runningChatIdList = useMemo(() => Array.from(runningChatIds), [runningChatIds]);
|
||||
const completedChatIdList = useMemo(() => Array.from(completedChatIds), [completedChatIds]);
|
||||
const updatedChatIdList = useMemo(() => Array.from(updatedChatIds), [updatedChatIds]);
|
||||
const activeChatId = activeSession?.chatId ?? null;
|
||||
useEffect(() => {
|
||||
activeChatIdRef.current = activeChatId;
|
||||
if (!activeChatId) return;
|
||||
setCompletedChatIds((current) => {
|
||||
setUpdatedChatIds((current) => {
|
||||
if (!current.has(activeChatId)) return current;
|
||||
const next = new Set(current);
|
||||
next.delete(activeChatId);
|
||||
@@ -694,7 +697,7 @@ function Shell({
|
||||
useEffect(() => {
|
||||
if (loading) return;
|
||||
const knownChatIds = new Set(sessions.map((session) => session.chatId));
|
||||
setCompletedChatIds((current) => {
|
||||
setUpdatedChatIds((current) => {
|
||||
const next = new Set(
|
||||
Array.from(current).filter((chatId) => knownChatIds.has(chatId)),
|
||||
);
|
||||
@@ -722,12 +725,25 @@ function Shell({
|
||||
}, [activeKey, loading, navigate, sessions]);
|
||||
|
||||
useEffect(() => {
|
||||
return client.onSessionUpdate((_chatId, _scope, workspaceScope) => {
|
||||
return client.onSessionUpdate((chatId, scope, workspaceScope) => {
|
||||
if (scope === "thread") {
|
||||
setUpdatedChatIds((current) => {
|
||||
const next = new Set(current);
|
||||
if (activeChatIdRef.current === chatId) {
|
||||
next.delete(chatId);
|
||||
} else {
|
||||
next.add(chatId);
|
||||
}
|
||||
return next.size === current.size && next.has(chatId) === current.has(chatId)
|
||||
? current
|
||||
: next;
|
||||
});
|
||||
}
|
||||
if (!workspaceScope) return;
|
||||
const next = normalizeWorkspaceScope(workspaceScope);
|
||||
setWorkspaceOverrides((current) => ({
|
||||
...current,
|
||||
[_chatId]: next,
|
||||
[chatId]: next,
|
||||
}));
|
||||
setDraftWorkspaceScope(next);
|
||||
setWorkspaceError(null);
|
||||
@@ -764,7 +780,7 @@ function Shell({
|
||||
runningChatIdsRef.current = next;
|
||||
return next;
|
||||
});
|
||||
setCompletedChatIds((current) => {
|
||||
setUpdatedChatIds((current) => {
|
||||
let changed = false;
|
||||
const next = new Set(current);
|
||||
for (const chatId of activeRunIds) {
|
||||
@@ -961,7 +977,7 @@ function Shell({
|
||||
const selected = sessions.find((session) => session.key === key);
|
||||
const selectedChatId = selected?.chatId;
|
||||
if (selectedChatId) {
|
||||
setCompletedChatIds((current) => {
|
||||
setUpdatedChatIds((current) => {
|
||||
if (!current.has(selectedChatId)) return current;
|
||||
const next = new Set(current);
|
||||
next.delete(selectedChatId);
|
||||
@@ -1232,7 +1248,7 @@ function Shell({
|
||||
nextRunning.add(chatId);
|
||||
runningChatIdsRef.current = nextRunning;
|
||||
setRunningChatIds(nextRunning);
|
||||
setCompletedChatIds((current) => {
|
||||
setUpdatedChatIds((current) => {
|
||||
if (!current.has(chatId)) return current;
|
||||
const next = new Set(current);
|
||||
next.delete(chatId);
|
||||
@@ -1246,7 +1262,7 @@ function Shell({
|
||||
nextRunning.delete(chatId);
|
||||
runningChatIdsRef.current = nextRunning;
|
||||
setRunningChatIds(nextRunning);
|
||||
setCompletedChatIds((current) => {
|
||||
setUpdatedChatIds((current) => {
|
||||
const next = new Set(current);
|
||||
if (activeChatIdRef.current === chatId) {
|
||||
next.delete(chatId);
|
||||
@@ -1393,7 +1409,7 @@ function Shell({
|
||||
projectNameOverrides: sidebarState.project_name_overrides,
|
||||
collapsedGroups: sidebarState.collapsed_groups,
|
||||
runningChatIds: runningChatIdList,
|
||||
completedChatIds: completedChatIdList,
|
||||
updatedChatIds: updatedChatIdList,
|
||||
viewState: sidebarState.view,
|
||||
showArchived: sidebarState.view.show_archived,
|
||||
archivedCount: sidebarState.archived_keys.length,
|
||||
|
||||
Reference in New Issue
Block a user