fix: replace access list ID field with EntityPicker, add deploy toggle, improve UX
- Replace raw NPM access list ID input with EntityPicker on project edit form - Resolve access list name from NPM API when editing project - Add "Deploy immediately" toggle to Quick Deploy (off by default) - Fix stage form layout: all fields on same row with toggles - Fix empty port default on project creation (placeholder instead of pre-filled) - Improve inspect error message when Docker is unavailable - Trigger proxy resync when NPM access list changes - Resolve access list name on NPM settings page load
This commit is contained in:
+28
-9
@@ -81,7 +81,13 @@ func (s *Server) inspectImage(w http.ResponseWriter, r *http.Request) {
|
||||
info, err := s.docker.InspectImage(ctx, req.Image)
|
||||
if err != nil {
|
||||
slog.Error("failed to inspect image", "image", req.Image, "error", err)
|
||||
respondError(w, http.StatusInternalServerError, "internal server error")
|
||||
errMsg := "Failed to inspect image. "
|
||||
if strings.Contains(err.Error(), "docker_engine") || strings.Contains(err.Error(), "docker.sock") {
|
||||
errMsg += "Docker is not available on this machine. Enter port and project name manually."
|
||||
} else {
|
||||
errMsg += "Image may not exist or registry requires authentication."
|
||||
}
|
||||
respondError(w, http.StatusBadGateway, errMsg)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -103,6 +109,7 @@ type quickDeployRequest struct {
|
||||
Port int `json:"port"`
|
||||
Force bool `json:"force"` // skip duplicate check
|
||||
EnableProxy *bool `json:"enable_proxy"` // nil defaults to true
|
||||
AutoDeploy *bool `json:"auto_deploy"` // nil defaults to true (deploy immediately)
|
||||
}
|
||||
|
||||
// quickDeploy handles POST /api/deploy/quick.
|
||||
@@ -172,11 +179,15 @@ func (s *Server) quickDeploy(w http.ResponseWriter, r *http.Request) {
|
||||
if req.EnableProxy != nil {
|
||||
enableProxy = *req.EnableProxy
|
||||
}
|
||||
shouldDeploy := true
|
||||
if req.AutoDeploy != nil {
|
||||
shouldDeploy = *req.AutoDeploy
|
||||
}
|
||||
stage, err := s.store.CreateStage(store.Stage{
|
||||
ProjectID: project.ID,
|
||||
Name: "dev",
|
||||
TagPattern: "*",
|
||||
AutoDeploy: true,
|
||||
AutoDeploy: shouldDeploy,
|
||||
MaxInstances: 1,
|
||||
EnableProxy: enableProxy,
|
||||
})
|
||||
@@ -186,12 +197,20 @@ func (s *Server) quickDeploy(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Trigger deploy asynchronously.
|
||||
deployID, err := s.deployer.AsyncTriggerDeploy(r.Context(), project.ID, stage.ID, req.Tag)
|
||||
if err != nil {
|
||||
slog.Error("failed to trigger deploy", "error", err)
|
||||
respondError(w, http.StatusInternalServerError, "internal server error")
|
||||
return
|
||||
// Only trigger deploy if auto_deploy is enabled.
|
||||
var deployID string
|
||||
if shouldDeploy {
|
||||
deployID, err = s.deployer.AsyncTriggerDeploy(r.Context(), project.ID, stage.ID, req.Tag)
|
||||
if err != nil {
|
||||
slog.Error("failed to trigger deploy", "error", err)
|
||||
respondError(w, http.StatusInternalServerError, "internal server error")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
status := "created"
|
||||
if shouldDeploy {
|
||||
status = "deploying"
|
||||
}
|
||||
|
||||
respondJSON(w, http.StatusAccepted, map[string]any{
|
||||
@@ -199,7 +218,7 @@ func (s *Server) quickDeploy(w http.ResponseWriter, r *http.Request) {
|
||||
"stage": stage,
|
||||
"tag": req.Tag,
|
||||
"deploy_id": deployID,
|
||||
"status": "deploying",
|
||||
"status": status,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -239,6 +239,7 @@ func (s *Server) updateSettings(w http.ResponseWriter, r *http.Request) {
|
||||
proxyChanged := existing.Domain != updated.Domain ||
|
||||
existing.ProxyProvider != updated.ProxyProvider ||
|
||||
existing.NpmRemote != updated.NpmRemote ||
|
||||
existing.NpmAccessListID != updated.NpmAccessListID ||
|
||||
sslChanged
|
||||
if proxyChanged {
|
||||
go s.resyncAllProxies(existing, updated)
|
||||
|
||||
Reference in New Issue
Block a user