diff --git a/cmd/description.go b/cmd/description.go index 4f63f36..0fb3073 100644 --- a/cmd/description.go +++ b/cmd/description.go @@ -9,16 +9,17 @@ import ( "github.com/xanzy/go-gitlab" ) -type DescriptionUpdateRequest struct { +type SummaryUpdateRequest struct { Description string `json:"description"` + Title string `json:"title"` } -type DescriptionUpdateResponse struct { +type SummaryUpdateResponse struct { SuccessResponse MergeRequest *gitlab.MergeRequest `json:"mr"` } -func DescriptionHandler(w http.ResponseWriter, r *http.Request) { +func SummaryHandler(w http.ResponseWriter, r *http.Request) { c := r.Context().Value("client").(Client) w.Header().Set("Content-Type", "application/json") if r.Method != http.MethodPut { @@ -34,31 +35,34 @@ func DescriptionHandler(w http.ResponseWriter, r *http.Request) { } defer r.Body.Close() - var DescriptionUpdateRequest DescriptionUpdateRequest - err = json.Unmarshal(body, &DescriptionUpdateRequest) + var SummaryUpdateRequest SummaryUpdateRequest + err = json.Unmarshal(body, &SummaryUpdateRequest) if err != nil { c.handleError(w, err, "Could not read JSON from request", http.StatusBadRequest) return } - mr, res, err := c.git.MergeRequests.UpdateMergeRequest(c.projectId, c.mergeId, &gitlab.UpdateMergeRequestOptions{Description: &DescriptionUpdateRequest.Description}) + mr, res, err := c.git.MergeRequests.UpdateMergeRequest(c.projectId, c.mergeId, &gitlab.UpdateMergeRequestOptions{ + Description: &SummaryUpdateRequest.Description, + Title: &SummaryUpdateRequest.Title, + }) if err != nil { - c.handleError(w, err, "Could not edit merge request description", http.StatusBadRequest) + c.handleError(w, err, "Could not edit merge request summary", http.StatusBadRequest) return } if res.StatusCode != http.StatusOK { - c.handleError(w, err, "Could not edit merge request description", http.StatusBadRequest) + c.handleError(w, err, "Could not edit merge request summary", http.StatusBadRequest) return } w.WriteHeader(http.StatusOK) - response := DescriptionUpdateResponse{ + response := SummaryUpdateResponse{ SuccessResponse: SuccessResponse{ - Message: "Description updated", + Message: "Summary updated", Status: http.StatusOK, }, MergeRequest: mr, diff --git a/cmd/main.go b/cmd/main.go index f4c67dc..041bce3 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -29,7 +29,7 @@ func main() { } m := http.NewServeMux() - m.Handle("/mr/description", withGitlabContext(http.HandlerFunc(DescriptionHandler), c)) + m.Handle("/mr/summary", withGitlabContext(http.HandlerFunc(SummaryHandler), c)) m.Handle("/mr/attachment", withGitlabContext(http.HandlerFunc(AttachmentHandler), c)) m.Handle("/mr/reviewer", withGitlabContext(http.HandlerFunc(ReviewersHandler), c)) m.Handle("/mr/revisions", withGitlabContext(http.HandlerFunc(RevisionsHandler), c)) diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index 2727e20..86dd124 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -1,40 +1,120 @@ -- This module is responsible for the MR description -- This lets the user open the description in a popup and -- send edits to the description back to Gitlab -local Popup = require("nui.popup") -local job = require("gitlab.job") -local state = require("gitlab.state") -local miscellaneous = require("gitlab.actions.miscellaneous") -local u = require("gitlab.utils") -local M = {} +local Layout = require("nui.layout") +local Popup = require("nui.popup") +local job = require("gitlab.job") +local u = require("gitlab.utils") +local state = require("gitlab.state") +local miscellaneous = require("gitlab.actions.miscellaneous") +local M = { + layout_visible = false, + layout = nil, + layout_buf = nil, + title_bufnr = nil, + description_bufnr = nil +} -local descriptionPopup = Popup(u.create_popup_state("Loading Description...", "80%", "80%")) -- The function will render the MR description in a popup -M.summary = function() - descriptionPopup:mount() +M.summary = function() + if M.layout_visible then + M.layout:unmount() + M.layout_visible = false + return + end + + local layout, title_popup, description_popup = M.create_layout() + + M.layout = layout + M.layout_buf = layout.bufnr + M.layout_visible = true + + local function exit() + layout:unmount() + M.layout_visible = false + end + local currentBuffer = vim.api.nvim_get_current_buf() local title = state.INFO.title local description = state.INFO.description local lines = {} + for line in description:gmatch("[^\n]+") do table.insert(lines, line) table.insert(lines, "") end + vim.schedule(function() vim.api.nvim_buf_set_lines(currentBuffer, 0, -1, false, lines) - descriptionPopup.border:set_text("top", title, "center") - state.set_popup_keymaps(descriptionPopup, M.edit_description, miscellaneous.attach_file) + vim.api.nvim_buf_set_lines(title_popup.bufnr, 0, -1, false, { title }) + state.set_popup_keymaps(description_popup, M.edit_summary, miscellaneous.attach_file, exit) + state.set_popup_keymaps(title_popup, M.edit_summary, nil, exit) end) end -- This function will PUT the new description to the Go server -M.edit_description = function(text) - local body = { description = text } - job.run_job("/mr/description", "PUT", body, function(data) +M.edit_summary = function() + local description = u.get_buffer_text(M.description_bufnr) + local title = u.get_buffer_text(M.title_bufnr):gsub("\n", " ") + local body = { title = title, description = description } + job.run_job("/mr/summary", "PUT", body, function(data) vim.notify(data.message, vim.log.levels.INFO) state.INFO.description = data.mr.description + state.INFO.title = data.mr.title + M.layout:unmount() + M.layout_visible = false end) end +local top_popup = { + buf_options = { + filetype = 'markdown' + }, + focusable = true, + border = { + style = "rounded", + text = { + top = "Merge Request" + }, + }, +} + +local bottom_popup = { + buf_options = { + filetype = 'markdown' + }, + enter = true, + focusable = true, + border = { + style = "rounded", + }, +} + +M.create_layout = function() + local title_popup = Popup(top_popup) + M.title_bufnr = title_popup.bufnr + local description_popup = Popup(bottom_popup) + M.description_bufnr = description_popup.bufnr + + local layout = Layout( + { + position = "50%", + relative = "editor", + size = { + width = 100, + height = 80, + }, + }, + Layout.Box({ + Layout.Box(title_popup, { size = { height = 3 } }), + Layout.Box(description_popup, { size = "50%" }), + }, { dir = "col" }) + ) + + layout:mount() + + return layout, title_popup, description_popup +end + return M diff --git a/lua/gitlab/state.lua b/lua/gitlab/state.lua index 2fb7391..0b11553 100644 --- a/lua/gitlab/state.lua +++ b/lua/gitlab/state.lua @@ -107,19 +107,20 @@ M.setPluginConfiguration = function() return true end -local function exit(popup) +local function exit(popup, cb) popup:unmount() + if cb ~= nil then cb() end end -- These keymaps are buffer specific and are set dynamically when popups mount -M.set_popup_keymaps = function(popup, action, linewise_action) - vim.keymap.set('n', M.settings.popup.exit, function() exit(popup) end, { buffer = true }) +M.set_popup_keymaps = function(popup, action, linewise_action, cb) + vim.keymap.set('n', M.settings.popup.exit, function() exit(popup, cb) end, { buffer = popup.bufnr }) if action ~= nil then vim.keymap.set('n', M.settings.popup.perform_action, function() local text = u.get_buffer_text(popup.bufnr) - exit(popup) action(text) - end, { buffer = true }) + exit(popup) + end, { buffer = popup.bufnr }) end if linewise_action ~= nil then @@ -128,7 +129,7 @@ M.set_popup_keymaps = function(popup, action, linewise_action) local linnr = vim.api.nvim_win_get_cursor(0)[1] local text = u.get_line_content(bufnr, linnr) linewise_action(text) - end, { buffer = true }) + end, { buffer = popup.bufnr }) end end