Adding Support for Resolving/Unresolving Discussions (#39)

This MR adds the ability to mark discussions as resolved or unresolved. This is important to the review process.
This commit is contained in:
Harrison (Harry) Cramer
2023-08-17 12:42:36 -04:00
committed by GitHub
parent 1676992266
commit d25c62ae9f
7 changed files with 130 additions and 35 deletions

View File

@@ -143,11 +143,28 @@ M.send_edits = function(discussion_id, note_id)
local json = vim.json.encode(json_table)
job.run_job("comment", "PATCH", json, function(data)
vim.notify(data.message, vim.log.levels.INFO)
M.redraw_node(text)
M.redraw_text(text)
end)
end
end
M.toggle_resolved = function()
local note = state.tree:get_node()
if not note.resolvable then return end
local json_table = {
discussion_id = note.id,
note_id = note.root_note_id,
resolved = not note.resolved,
}
local json = vim.json.encode(json_table)
job.run_job("comment", "PATCH", json, function(data)
vim.notify(data.message, vim.log.levels.INFO)
M.update_resolved_status(note, not note.resolved)
end)
end
-- Helpers
M.find_deletion_commit = function(file)
local current_line = vim.api.nvim_get_current_line()
@@ -167,7 +184,35 @@ M.find_deletion_commit = function(file)
return words[2]
end
M.redraw_node = function(text)
M.update_resolved_status = function(note, mark_resolved)
local current_text = state.tree.nodes.by_id["-" .. note.id].text
local target = mark_resolved and 'resolved' or 'unresolved'
local current = mark_resolved and 'unresolved' or 'resolved'
local function set_property(key, val)
state.tree.nodes.by_id["-" .. note.id][key] = val
end
local has_symbol = function(s)
return state.SYMBOLS[s] ~= nil and state.SYMBOLS[s] ~= ''
end
set_property('resolved', mark_resolved)
if not has_symbol(current) and not has_symbol(target) then return end
if not has_symbol(current) and has_symbol(target) then
set_property('text', (current_text .. " " .. state.SYMBOLS[target]))
elseif has_symbol(current) and not has_symbol(target) then
set_property('text', u.remove_last_chunk(current_text))
else
set_property('text', (u.remove_last_chunk(current_text) .. " " .. state.SYMBOLS[target]))
end
state.tree:render()
end
M.redraw_text = function(text)
local current_node = state.tree:get_node()
local note_node = discussions.get_note_node(current_node)

View File

@@ -35,7 +35,7 @@ M.list_discussions = function()
return
end
local splitState = state.DISCUSSION_SPLIT
local splitState = state.DISCUSSION.SPLIT
splitState.buf_options = { modifiable = false }
local split = NuiSplit(splitState)
split:mount()
@@ -84,6 +84,10 @@ M.set_tree_keymaps = function(buf)
require("gitlab.comment").delete_comment()
end, { buffer = true })
vim.keymap.set('n', state.keymaps.discussion_tree.toggle_resolved, function()
require("gitlab.comment").toggle_resolved()
end, { buffer = true })
-- Expand/collapse the current node
vim.keymap.set('n', state.keymaps.discussion_tree.toggle_node, function()
local node = state.tree:get_node()
@@ -134,7 +138,7 @@ M.get_note_node = function(node)
end
end
M.build_note_body = function(note)
M.build_note_body = function(note, resolve_info)
local text_nodes = {}
for bodyLine in note.body:gmatch("[^\n]+") do
local line = u.attach_uuid(bodyLine)
@@ -145,23 +149,26 @@ M.build_note_body = function(note)
}, {}))
end
local noteHeader = "@" ..
note.author.username .. " " .. u.format_date(note.created_at)
local resolve_symbol = ''
if resolve_info ~= nil and resolve_info.resolvable then
resolve_symbol = resolve_info.resolved and state.SYMBOLS.resolved or state.SYMBOLS.unresolved
end
local noteHeader = "@" .. note.author.username .. " " .. u.format_date(note.created_at) .. " " .. resolve_symbol
return noteHeader, text_nodes
end
M.build_note = function(note)
local text, text_nodes = M.build_note_body(note)
M.build_note = function(note, resolve_info)
local text, text_nodes = M.build_note_body(note, resolve_info)
local line_number = note.position.new_line or note.position.old_line
local note_node = NuiTree.Node(
{
text = text,
id = note.id,
file_name = note.position.new_path,
line_number = line_number,
is_note = true
}, text_nodes)
local note_node = NuiTree.Node({
text = text,
id = note.id,
file_name = note.position.new_path,
line_number = line_number,
is_note = true,
}, text_nodes)
return note_node, text, text_nodes
end
@@ -212,14 +219,18 @@ M.add_discussions_to_table = function(discussions)
local root_file_name = ''
local root_id = 0
local root_text_nodes = {}
local resolvable = false
local resolved = false
for j, note in ipairs(discussion.notes) do
if j == 1 then
__, root_text, root_text_nodes = M.build_note(note)
__, root_text, root_text_nodes = M.build_note(note, { resolved = note.resolved, resolvable = note.resolvable })
root_file_name = note.position.new_path
root_line_number = note.position.new_line or note.position.old_line
root_id = discussion.id
root_note_id = note.id
resolvable = note.resolvable
resolved = note.resolved
else -- Otherwise insert it as a child node...
local note_node = M.build_note(note)
table.insert(discussion_children, note_node)
@@ -236,6 +247,8 @@ M.add_discussions_to_table = function(discussions)
root_note_id = root_note_id,
file_name = root_file_name,
line_number = root_line_number,
resolvable = resolvable,
resolved = resolved
}, body)
table.insert(t, root_node)

View File

@@ -43,10 +43,11 @@ local M = {}
M.summary = ensureState(summary.summary)
M.approve = ensureState(job.approve)
M.revoke = ensureState(job.revoke)
M.create_comment = ensureState(comment.create_comment)
M.list_discussions = ensureState(discussions.list_discussions)
M.create_comment = ensureState(comment.create_comment)
M.edit_comment = ensureState(comment.edit_comment)
M.delete_comment = ensureState(comment.delete_comment)
M.toggle_resolved = ensureState(comment.toggle_resolved)
M.add_reviewer = ensureProjectMembers(ensureState(assignees_and_reviewers.add_reviewer))
M.delete_reviewer = ensureProjectMembers(ensureState(assignees_and_reviewers.delete_reviewer))
M.add_assignee = ensureProjectMembers(ensureState(assignees_and_reviewers.add_assignee))
@@ -160,10 +161,17 @@ M.setPluginConfiguration = function(args)
-- Configuration for the plugin, such as port of server, layout, etc
state.PORT = args.port or 21036
state.LOG_PATH = args.log_path or (vim.fn.stdpath("cache") .. "/gitlab.nvim.log")
state.DISCUSSION_SPLIT = {
relative = args.keymaps and args.keymaps.discussion_tree and args.keymaps.discussion_tree.relative or "editor",
position = args.keymaps and args.keymaps.discussion_tree and args.keymaps.discussion_tree.position or "left",
size = args.keymaps and args.keymaps.discussion_tree and args.keymaps.discussion_tree.size or "20%",
state.DISCUSSION = {
SPLIT = {
relative = args.keymaps and args.keymaps.discussion_tree and args.keymaps.discussion_tree.relative or "editor",
position = args.keymaps and args.keymaps.discussion_tree and args.keymaps.discussion_tree.position or "left",
size = args.keymaps and args.keymaps.discussion_tree and args.keymaps.discussion_tree.size or "20%",
}
}
state.SYMBOLS = {
resolved = (args.symbols and args.symbols.resolved or ''),
unresolved = (args.symbols and args.symbols.unresolved or '')
}
return true

View File

@@ -17,6 +17,7 @@ M.keymaps = {
delete_comment = "dd",
reply_to_comment = "r",
toggle_node = "t",
toggle_resolved = "p"
},
dialogue = {
focus_next = { "j", "<Down>", "<Tab>" },

View File

@@ -284,7 +284,17 @@ local extract = function(t, property)
return resultTable
end
local remove_last_chunk = function(sentence)
local words = {}
for word in sentence:gmatch("%S+") do
table.insert(words, word)
end
table.remove(words, #words)
local sentence_without_last = table.concat(words, " ")
return sentence_without_last
end
M.remove_last_chunk = remove_last_chunk
M.extract = extract
M.contains = contains
M.attach_uuid = attach_uuid