diff --git a/docs/PLAN.md b/docs/PLAN.md index 32515b9..7dcaf24 100644 --- a/docs/PLAN.md +++ b/docs/PLAN.md @@ -20,7 +20,7 @@ | 7 | Actions: Run URL/File/Command + GUI Tab | ✅ выполнен | | 8 | Worklog: Entries + Report + GUI Tab | ✅ выполнен | | 9 | FTS5 Search: Rebuild Index + GUI Search Bar | ✅ выполнен | -| 10 | Plugins System (Lua + Templates) | ⬜ не начат | +| 10 | Plugins System (Lua + Templates) | ✅ выполнен | | 11 | Sync Server Skeleton | ⬜ не начат | | 12 | Sync Client MVP | ⬜ не начат | | 13 | Activity + File Scanner/Watcher | ⬜ не начат | diff --git a/internal/gui/index.html.go b/internal/gui/index.html.go index 3ca0fd2..34965ea 100644 --- a/internal/gui/index.html.go +++ b/internal/gui/index.html.go @@ -217,9 +217,11 @@ input[type=checkbox]{width:auto!important;margin-right:6px;display:inline}
-

Файл

-

MVP: добавление файлов через интерфейс пока недоступно.

-
+

Добавить файл

+

Файл будет скопирован в vault и привязан к выбранному делу.

+ + +

Действие

@@ -792,6 +794,17 @@ async function submitWorklog(){ }catch(e){alert('Ошибка: '+e.message)} } +async function submitFile(){ + const path=G('mf-path').value.trim(); + if(!path)return; + if(!sel.nodeId){E('Выберите дело слева');return} + try{ + const rec=await api('/api/files/upload',{method:'PUT',body:JSON.stringify({node_id:sel.nodeId,file_path:path,node_slug:''})}); + closeM('m-file'); + selectNode({dataset:{id:sel.nodeId}}); + }catch(e){alert('Ошибка: '+e.message)} +} + /* ════════════════════════════════════════════ SEARCH ════════════════════════════════════════════ */ diff --git a/internal/gui/server.go b/internal/gui/server.go index cebe7bd..53865d0 100644 --- a/internal/gui/server.go +++ b/internal/gui/server.go @@ -59,6 +59,7 @@ func (s *Server) Start() (string, error) { mux.HandleFunc("/api/nodes/from-template", s.handleNodeFromTemplate) mux.HandleFunc("/api/nodes/", s.handleNodeDetail) mux.HandleFunc("/api/notes/", s.handleNotes) + mux.HandleFunc("/api/files/upload", s.handleFileUpload) mux.HandleFunc("/api/files/", s.handleFiles) mux.HandleFunc("/api/actions/", s.handleActions) mux.HandleFunc("/api/worklog/", s.handleWorklog) @@ -291,6 +292,30 @@ func (s *Server) handleNotes(w http.ResponseWriter, r *http.Request) { } } +// PUT /api/files/upload — register an external file into the vault. +func (s *Server) handleFileUpload(w http.ResponseWriter, r *http.Request) { + if r.Method != "PUT" { + jsonErr(w, 405, "method not allowed") + return + } + var req struct { + NodeID string `json:"node_id"` + FilePath string `json:"file_path"` + NodeSlug string `json:"node_slug"` + } + json.NewDecoder(r.Body).Decode(&req) + if req.NodeID == "" || req.FilePath == "" { + jsonErr(w, 400, "node_id and file_path required") + return + } + rec, err := s.files.CopyIntoVault(req.NodeID, req.FilePath, req.NodeSlug) + if err != nil { + jsonErr(w, 500, err.Error()) + return + } + jsonOK(w, rec) +} + // GET/DELETE /api/files/{id} func (s *Server) handleFiles(w http.ResponseWriter, r *http.Request) { id := strings.TrimPrefix(r.URL.Path, "/api/files/") diff --git a/verstak-gui b/verstak-gui new file mode 100755 index 0000000..a4562d8 Binary files /dev/null and b/verstak-gui differ