diff --git a/internal/server/frag.go b/internal/server/frag.go index d5160f8..27658f5 100644 --- a/internal/server/frag.go +++ b/internal/server/frag.go @@ -5,6 +5,8 @@ import ( "html/template" "log" "net/http" + + "github.com/x-grk/longpolling-remote-access/internal/proto" ) // A panel page is either a fragment - its content alone, for the shell to put @@ -49,6 +51,7 @@ func (s *Server) renderPage(w http.ResponseWriter, r *http.Request, name string, // shell writes the shell page with data (View, Body, Open, Dialog). func (s *Server) shell(w http.ResponseWriter, r *http.Request, data map[string]any) { data["IsAdmin"] = s.currentAdmin(r).IsAdmin() + data["EditLimit"] = proto.FSReadCap if data["View"] == "dashboard" && data["Body"] == nil { // The machines list under a dialog: draw it too. var body bytes.Buffer diff --git a/internal/server/handlers_panel_fs.go b/internal/server/handlers_panel_fs.go index f3975da..e9f60ef 100644 --- a/internal/server/handlers_panel_fs.go +++ b/internal/server/handlers_panel_fs.go @@ -34,16 +34,6 @@ var fsOps = map[string]string{ // fsTaskTimeout bounds how long we wait for an agent to answer a file op. const fsTaskTimeout = 60 * time.Second -func (s *Server) handleFilesPage(w http.ResponseWriter, r *http.Request) { - id := r.PathValue("id") - a, err := s.db.GetAgent(id) - if err != nil || a == nil { - http.NotFound(w, r) - return - } - s.render(w, "files.html", map[string]any{"Agent": a, "EditLimit": proto.FSReadCap}) -} - // POST /api/panel/agents/{id}/fs/{op} - run a file-manager operation on the // agent and return its result. The request body is the op's JSON args and is // forwarded verbatim to the agent. diff --git a/internal/server/web/static/app.css b/internal/server/web/static/app.css index 0e0024d..8e19d0f 100644 --- a/internal/server/web/static/app.css +++ b/internal/server/web/static/app.css @@ -422,3 +422,340 @@ body.touch .keys { touch-action:manipulation; -webkit-tap-highlight-color:transparent; } body.touch .area { -webkit-user-select:none; user-select:none; -webkit-touch-callout:none; } #status:empty { display:none; } + +/* ---- File panes and their dialogs ---- */ +.fm-bar { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:12px; } +/* Normalize buttons and the file