summaryrefslogtreecommitdiff
path: root/frontend/src/store/flowStore.ts
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/store/flowStore.ts')
-rw-r--r--frontend/src/store/flowStore.ts55
1 files changed, 55 insertions, 0 deletions
diff --git a/frontend/src/store/flowStore.ts b/frontend/src/store/flowStore.ts
index 56ade75..a049a8a 100644
--- a/frontend/src/store/flowStore.ts
+++ b/frontend/src/store/flowStore.ts
@@ -121,11 +121,22 @@ export interface ArchivedNode {
mergeStrategy?: 'raw' | 'smart';
}
+export interface FileMeta {
+ id: string;
+ name: string;
+ size: number;
+ mime: string;
+ created_at: number;
+ provider?: string;
+ provider_file_id?: string;
+}
+
interface FlowState {
nodes: LLMNode[];
edges: Edge[];
selectedNodeId: string | null;
archivedNodes: ArchivedNode[]; // Stored node templates
+ files: FileMeta[];
theme: 'light' | 'dark';
projectTree: FSItem[];
currentBlueprintPath?: string;
@@ -188,6 +199,10 @@ interface FlowState {
clearBlueprint: () => void;
loadArchivedNodes: () => Promise<void>;
saveArchivedNodes: () => Promise<void>;
+ refreshFiles: () => Promise<void>;
+ uploadFile: (file: File) => Promise<FileMeta>;
+ deleteFile: (fileId: string) => Promise<void>;
+ setFiles: (files: FileMeta[]) => void;
// Merge trace functions
createMergedTrace: (
@@ -247,6 +262,7 @@ const useFlowStore = create<FlowState>((set, get) => {
edges: [],
selectedNodeId: null,
archivedNodes: [],
+ files: [],
theme: 'light' as const,
projectTree: [],
currentBlueprintPath: undefined,
@@ -268,6 +284,9 @@ const useFlowStore = create<FlowState>((set, get) => {
set({ lastViewport: viewport });
},
+ setFiles: (files: FileMeta[]) => {
+ set({ files });
+ },
findNonOverlappingPosition: (baseX: number, baseY: number) => {
const { nodes } = get();
// Estimate larger dimensions to be safe, considering dynamic handles
@@ -1529,6 +1548,42 @@ const useFlowStore = create<FlowState>((set, get) => {
});
},
+ // Files management
+ refreshFiles: async () => {
+ const res = await jsonFetch<{ files: FileMeta[] }>(
+ `${API_BASE}/api/files?user=${encodeURIComponent(DEFAULT_USER)}`
+ );
+ set({ files: res.files || [] });
+ },
+
+ uploadFile: async (file: File) => {
+ const form = new FormData();
+ form.append('file', file);
+ const res = await fetch(`${API_BASE}/api/files/upload?user=${encodeURIComponent(DEFAULT_USER)}`, {
+ method: 'POST',
+ body: form,
+ });
+ if (!res.ok) {
+ throw new Error(await res.text());
+ }
+ const data = await res.json();
+ if (!data.file) {
+ throw new Error('Upload succeeded but no file info returned');
+ }
+ await get().refreshFiles();
+ return data.file as FileMeta;
+ },
+
+ deleteFile: async (fileId: string) => {
+ const res = await fetch(`${API_BASE}/api/files/delete?user=${encodeURIComponent(DEFAULT_USER)}&file_id=${encodeURIComponent(fileId)}`, {
+ method: 'POST',
+ });
+ if (!res.ok) {
+ throw new Error(await res.text());
+ }
+ await get().refreshFiles();
+ },
+
// --------------------------------------------------------
// Compute merged messages based on strategy