SurfSense/surfsense_web/features/chat-artifacts/state/artifacts-panel.atom.ts

40 lines
1.7 KiB
TypeScript
Raw Normal View History

2026-06-22 22:35:50 +02:00
import { atom } from "jotai";
2026-06-22 22:36:06 +02:00
import { rightPanelCollapsedAtom, rightPanelTabAtom } from "@/atoms/layout/right-panel.atom";
2026-06-22 22:35:50 +02:00
import type { ChatArtifact } from "../model/artifact";
/** Artifacts of the active thread, synced from the message stream by `useSyncChatArtifacts`. */
export const chatArtifactsAtom = atom<ChatArtifact[]>([]);
2026-06-22 23:24:25 +02:00
/** Open === artifacts owns the tab; derived so the toggle can't drift. */
export const artifactsPanelOpenAtom = atom((get) => get(rightPanelTabAtom) === "artifacts");
2026-06-22 22:36:06 +02:00
/** Snapshot of `rightPanelCollapsedAtom` taken before the panel opens, restored on close. */
const preArtifactsCollapsedAtom = atom<boolean | null>(null);
export const openArtifactsPanelAtom = atom(null, (get, set) => {
2026-06-22 23:24:25 +02:00
if (get(rightPanelTabAtom) !== "artifacts") {
2026-06-22 22:36:06 +02:00
set(preArtifactsCollapsedAtom, get(rightPanelCollapsedAtom));
}
set(rightPanelTabAtom, "artifacts");
set(rightPanelCollapsedAtom, false);
});
export const closeArtifactsPanelAtom = atom(null, (get, set) => {
2026-06-22 23:24:25 +02:00
// Don't clobber the tab when another surface owns it.
if (get(rightPanelTabAtom) !== "artifacts") return;
// RightPanel's fallback then re-reveals any surface underneath (e.g. a report).
2026-06-22 22:36:06 +02:00
set(rightPanelTabAtom, "sources");
const prev = get(preArtifactsCollapsedAtom);
if (prev !== null) {
set(rightPanelCollapsedAtom, prev);
set(preArtifactsCollapsedAtom, null);
}
});
export const toggleArtifactsPanelAtom = atom(null, (get, set) => {
2026-06-22 23:24:25 +02:00
// Only close when artifacts is actually visible; otherwise a click always opens it.
const shown = get(rightPanelTabAtom) === "artifacts" && !get(rightPanelCollapsedAtom);
if (shown) set(closeArtifactsPanelAtom);
else set(openArtifactsPanelAtom);
});