From a3aa79a98dabaa83ea3c0fe883cde2344a9c5698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20F=2E=20Bortl=C3=ADk?= Date: Sun, 8 Dec 2024 20:02:41 +0100 Subject: [PATCH] Feat: Automatically update MR summary details (#427) --- lua/gitlab/actions/approvals.lua | 17 ++++- .../actions/assignees_and_reviewers.lua | 11 +++- lua/gitlab/actions/labels.lua | 11 ++-- lua/gitlab/actions/summary.lua | 66 +++++++++++++++---- 4 files changed, 82 insertions(+), 23 deletions(-) diff --git a/lua/gitlab/actions/approvals.lua b/lua/gitlab/actions/approvals.lua index 8ca7669c..12b3e09d 100644 --- a/lua/gitlab/actions/approvals.lua +++ b/lua/gitlab/actions/approvals.lua @@ -1,13 +1,26 @@ local job = require("gitlab.job") +local state = require("gitlab.state") +local u = require("gitlab.utils") local M = {} +local refresh_status_state = function(data) + u.notify(data.message, vim.log.levels.INFO) + state.load_new_state("info", function() + require("gitlab.actions.summary").update_summary_details() + end) +end + M.approve = function() - job.run_job("/mr/approve", "POST") + job.run_job("/mr/approve", "POST", nil, function(data) + refresh_status_state(data) + end) end M.revoke = function() - job.run_job("/mr/revoke", "POST") + job.run_job("/mr/revoke", "POST", nil, function(data) + refresh_status_state(data) + end) end return M diff --git a/lua/gitlab/actions/assignees_and_reviewers.lua b/lua/gitlab/actions/assignees_and_reviewers.lua index 329f3825..77716d1e 100644 --- a/lua/gitlab/actions/assignees_and_reviewers.lua +++ b/lua/gitlab/actions/assignees_and_reviewers.lua @@ -22,6 +22,12 @@ M.delete_reviewer = function() M.delete_popup("reviewer") end +local refresh_user_state = function(type, data, message) + u.notify(message, vim.log.levels.INFO) + state.INFO[type] = data + require("gitlab.actions.summary").update_summary_details() +end + M.add_popup = function(type) local plural = type .. "s" local current = state.INFO[plural] @@ -39,8 +45,7 @@ M.add_popup = function(type) table.insert(current_ids, choice.id) local body = { ids = current_ids } job.run_job("/mr/" .. type, "PUT", body, function(data) - u.notify(data.message, vim.log.levels.INFO) - state.INFO[plural] = data[plural] + refresh_user_state(plural, data[plural], data.message) end) end) end @@ -61,7 +66,7 @@ M.delete_popup = function(type) local body = { ids = ids } job.run_job("/mr/" .. type, "PUT", body, function(data) u.notify(data.message, vim.log.levels.INFO) - state.INFO[plural] = data[plural] + refresh_user_state(plural, data[plural], data.message) end) end) end diff --git a/lua/gitlab/actions/labels.lua b/lua/gitlab/actions/labels.lua index da9447f6..e182df73 100644 --- a/lua/gitlab/actions/labels.lua +++ b/lua/gitlab/actions/labels.lua @@ -14,8 +14,10 @@ M.delete_label = function() M.delete_popup("label") end -local refresh_label_state = function(labels) +local refresh_label_state = function(labels, message) + u.notify(message, vim.log.levels.INFO) state.INFO.labels = labels + require("gitlab.actions.summary").update_summary_details() end local get_current_labels = function() @@ -41,9 +43,7 @@ M.add_popup = function(type) table.insert(current_labels, choice) local body = { labels = current_labels } job.run_job("/mr/" .. type, "PUT", body, function(data) - u.notify(data.message, vim.log.levels.INFO) - - refresh_label_state(data.labels) + refresh_label_state(data.labels, data.message) end) end) end @@ -59,8 +59,7 @@ M.delete_popup = function(type) local filtered_labels = u.filter(current_labels, choice) local body = { labels = filtered_labels } job.run_job("/mr/" .. type, "PUT", body, function(data) - u.notify(data.message, vim.log.levels.INFO) - refresh_label_state(data.labels) + refresh_label_state(data.labels, data.message) end) end) end diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index 9f75ca7d..f23d0d8d 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -35,6 +35,9 @@ M.summary = function() local info_lines = state.settings.info.enabled and M.build_info_lines() or { "" } local layout, title_popup, description_popup, info_popup = M.create_layout(info_lines) + + layout:mount() + local popups = { title_popup, description_popup, @@ -42,6 +45,9 @@ M.summary = function() } M.layout = layout + M.info_popup = info_popup + M.title_popup = title_popup + M.description_popup = description_popup M.layout_buf = layout.bufnr M.layout_visible = true @@ -55,9 +61,7 @@ M.summary = function() vim.api.nvim_buf_set_lines(title_popup.bufnr, 0, -1, false, { title }) if info_popup then - vim.api.nvim_buf_set_lines(info_popup.bufnr, 0, -1, false, info_lines) - u.switch_can_edit_buf(info_popup.bufnr, false) - M.color_details(info_popup.bufnr) -- Color values in details popup + M.update_details_popup(info_popup.bufnr, info_lines) end popup.set_popup_keymaps( @@ -87,6 +91,23 @@ M.summary = function() git.check_mr_in_good_condition() end +M.update_summary_details = function() + if not M.info_popup or not M.info_popup.bufnr then + return + end + local details_lines = state.settings.info.enabled and M.build_info_lines() or { "" } + local internal_layout = M.create_internal_layout(details_lines, M.title_popup, M.description_popup, M.info_popup) + M.layout:update(M.get_outer_layout_config(), internal_layout) + M.update_details_popup(M.info_popup.bufnr, details_lines) +end + +M.update_details_popup = function(bufnr, info_lines) + u.switch_can_edit_buf(bufnr, true) + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, info_lines) + u.switch_can_edit_buf(bufnr, false) + M.color_details(bufnr) -- Color values in details popup +end + -- Builds a lua list of strings that contain metadata about the current MR. Only builds the -- lines that users include in their state.settings.info.fields list. M.build_info_lines = function() @@ -166,6 +187,8 @@ M.edit_summary = function() end) end +---Create the Summary layout and individual popups that make up the Layout. +---@return NuiLayout, NuiPopup, NuiPopup, NuiPopup M.create_layout = function(info_lines) local settings = u.merge(state.settings.popup, state.settings.popup.summary or {}) local title_popup = Popup(popup.create_box_popup_state(nil, false, settings)) @@ -173,10 +196,28 @@ M.create_layout = function(info_lines) local description_popup = Popup(popup.create_popup_state("Description", settings)) M.description_bufnr = description_popup.bufnr local details_popup + if state.settings.info.enabled then + details_popup = Popup(popup.create_box_popup_state("Details", false, settings)) + end + + local internal_layout = M.create_internal_layout(info_lines, title_popup, description_popup, details_popup) + + local layout = Layout(M.get_outer_layout_config(), internal_layout) + popup.set_up_autocommands(description_popup, layout, vim.api.nvim_get_current_win()) + + return layout, title_popup, description_popup, details_popup +end + +---Create the internal layout of the Summary and individual popups that make up the Layout. +---@param info_lines string[] Table of strings that make up the details content +---@param title_popup NuiPopup +---@param description_popup NuiPopup +---@param details_popup NuiPopup +---@return NuiLayout.Box +M.create_internal_layout = function(info_lines, title_popup, description_popup, details_popup) local internal_layout if state.settings.info.enabled then - details_popup = Popup(popup.create_box_popup_state("Details", false, settings)) if state.settings.info.horizontal then local longest_line = u.get_longest_string(info_lines) internal_layout = Layout.Box({ @@ -184,7 +225,7 @@ M.create_layout = function(info_lines) Layout.Box({ Layout.Box(details_popup, { size = longest_line + 3 }), Layout.Box(description_popup, { grow = 1 }), - }, { dir = "row", size = "100%" }), + }, { dir = "row", size = "95%" }), }, { dir = "col" }) else internal_layout = Layout.Box({ @@ -199,20 +240,21 @@ M.create_layout = function(info_lines) Layout.Box(description_popup, { grow = 1 }), }, { dir = "col" }) end + return internal_layout +end - local layout = Layout({ +---Create the config for the outer Layout of the Summary +---@return nui_layout_options +M.get_outer_layout_config = function() + local settings = u.merge(state.settings.popup, state.settings.popup.summary or {}) + return { position = settings.position, relative = "editor", size = { width = settings.width, height = settings.height, }, - }, internal_layout) - - popup.set_up_autocommands(description_popup, layout, vim.api.nvim_get_current_win()) - - layout:mount() - return layout, title_popup, description_popup, details_popup + } end M.color_details = function(bufnr)