From 8f86e85ce5a4301318f58c5f8e9b682d10fbe0d7 Mon Sep 17 00:00:00 2001 From: Ivan Semenov Date: Fri, 13 Jan 2023 18:32:42 +0100 Subject: [PATCH] [gitlab] better presentation for system MR events GitOrigin-RevId: 1ac931318698a5832664397dcbf5574289e9f2e5 --- .../messages/GitLabBundle.properties | 10 ++- .../gitlab/api/dto/GitLabLabelRestDTO.kt | 4 +- .../gitlab/api/dto/GitLabMilestoneDTO.kt | 3 +- .../api/dto/GitLabResourceStateEventDTO.kt | 22 +++++- ...LabMergeRequestTimelineComponentFactory.kt | 78 +++++++++++++++++-- 5 files changed, 105 insertions(+), 12 deletions(-) diff --git a/plugins/gitlab/resources/messages/GitLabBundle.properties b/plugins/gitlab/resources/messages/GitLabBundle.properties index 2f56aeda495a..2cc0157ae365 100644 --- a/plugins/gitlab/resources/messages/GitLabBundle.properties +++ b/plugins/gitlab/resources/messages/GitLabBundle.properties @@ -36,4 +36,12 @@ merge.request.list.renderer.user.reviewers={0, choice, 1#Reviewer|2#Reviewers} merge.request.show.action=Show Merge Request merge.request.show.action.description=Show merge request details merge.request.open.in.browser.action=Open Merge Request On GitLab -merge.request.open.in.browser.action.description=Open merge request in a web browser \ No newline at end of file +merge.request.open.in.browser.action.description=Open merge request in a web browser + +merge.request.event.closed=closed this merge request +merge.request.event.reopened=reopened this merge request +merge.request.event.merged=merged this merge request +merge.request.event.milestone.removed=removed milestone {0} +merge.request.event.milestone.changed=changed milestone to {0} +merge.request.event.label.added=added {0} label +merge.request.event.label.removed=removed {0} label \ No newline at end of file diff --git a/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabLabelRestDTO.kt b/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabLabelRestDTO.kt index 20d125ced998..3c81af801a92 100644 --- a/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabLabelRestDTO.kt +++ b/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabLabelRestDTO.kt @@ -1,11 +1,13 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.plugins.gitlab.api.dto +import org.jetbrains.annotations.Nls + data class GitLabLabelRestDTO( val color: String, val description: String?, val descriptionHtml: String?, val id: Int, - val name: String, + val name: @Nls String, val textColor: String ) \ No newline at end of file diff --git a/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabMilestoneDTO.kt b/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabMilestoneDTO.kt index 415327ade787..3406016cfaf4 100644 --- a/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabMilestoneDTO.kt +++ b/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabMilestoneDTO.kt @@ -1,6 +1,7 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.plugins.gitlab.api.dto +import org.jetbrains.annotations.Nls import java.util.* data class GitLabMilestoneDTO( @@ -12,7 +13,7 @@ data class GitLabMilestoneDTO( val projectId: Int, val startDate: Date?, val state: String, - val title: String, + val title: @Nls String, val updatedAt: String, val webUrl: String ) \ No newline at end of file diff --git a/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabResourceStateEventDTO.kt b/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabResourceStateEventDTO.kt index f4dfd8b709a1..f7cd272b522f 100644 --- a/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabResourceStateEventDTO.kt +++ b/plugins/gitlab/src/org/jetbrains/plugins/gitlab/api/dto/GitLabResourceStateEventDTO.kt @@ -1,6 +1,8 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.plugins.gitlab.api.dto +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.diagnostic.logger import java.util.* data class GitLabResourceStateEventDTO( @@ -10,4 +12,22 @@ data class GitLabResourceStateEventDTO( val resourceType: String, val state: String, val user: GitLabUserDTO -) \ No newline at end of file +) { + val stateEnum: State = parseState(state) + + enum class State { + CLOSED, REOPENED, MERGED + } + + companion object { + private val logger: Logger = logger() + + private fun parseState(value: String): State = try { + State.valueOf(value.uppercase(Locale.getDefault())) + } + catch (_: IllegalArgumentException) { + logger.warn("Unable to parse merge label event action: $value") + State.CLOSED + } + } +} \ No newline at end of file diff --git a/plugins/gitlab/src/org/jetbrains/plugins/gitlab/mergerequest/ui/timeline/GitLabMergeRequestTimelineComponentFactory.kt b/plugins/gitlab/src/org/jetbrains/plugins/gitlab/mergerequest/ui/timeline/GitLabMergeRequestTimelineComponentFactory.kt index 2cac496c4033..61a1e70722ac 100644 --- a/plugins/gitlab/src/org/jetbrains/plugins/gitlab/mergerequest/ui/timeline/GitLabMergeRequestTimelineComponentFactory.kt +++ b/plugins/gitlab/src/org/jetbrains/plugins/gitlab/mergerequest/ui/timeline/GitLabMergeRequestTimelineComponentFactory.kt @@ -6,6 +6,8 @@ import com.intellij.collaboration.ui.SimpleHtmlPane import com.intellij.collaboration.ui.TransparentScrollPane import com.intellij.collaboration.ui.VerticalListPanel import com.intellij.collaboration.ui.codereview.CodeReviewChatItemUIUtil +import com.intellij.collaboration.ui.codereview.timeline.StatusMessageComponentFactory +import com.intellij.collaboration.ui.codereview.timeline.StatusMessageType import com.intellij.collaboration.ui.icon.IconsProvider import com.intellij.openapi.editor.colors.EditorColorsManager import com.intellij.openapi.util.text.HtmlBuilder @@ -19,9 +21,11 @@ import com.intellij.util.ui.update.UiNotifyConnector import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch -import org.jetbrains.plugins.gitlab.api.dto.GitLabUserDTO +import org.jetbrains.annotations.Nls +import org.jetbrains.plugins.gitlab.api.dto.* import org.jetbrains.plugins.gitlab.mergerequest.data.GitLabMergeRequestTimelineItem import org.jetbrains.plugins.gitlab.mergerequest.ui.timeline.GitLabMergeRequestTimelineViewModel.LoadingState +import org.jetbrains.plugins.gitlab.util.GitLabBundle import java.util.* import javax.swing.JComponent import javax.swing.JLabel @@ -81,15 +85,60 @@ object GitLabMergeRequestTimelineComponentFactory { } private fun createContent(item: GitLabMergeRequestTimelineItem): JComponent { - val text = when (item) { - is GitLabMergeRequestTimelineItem.Discussion -> item.discussion.notes.first().body - is GitLabMergeRequestTimelineItem.LabelEvent -> "${item.event.action} label ${item.event.label.name}" - is GitLabMergeRequestTimelineItem.MilestoneEvent -> "${item.event.action} milestone ${item.event.milestone.title}" - is GitLabMergeRequestTimelineItem.StateEvent -> "changed state to ${item.event.state}" + return when (item) { + is GitLabMergeRequestTimelineItem.Discussion -> createDiscussionContent(item) + is GitLabMergeRequestTimelineItem.LabelEvent -> createLabeledEventContent(item) + is GitLabMergeRequestTimelineItem.MilestoneEvent -> createMilestonedEventContent(item) + is GitLabMergeRequestTimelineItem.StateEvent -> createStateChangeContent(item) } - return SimpleHtmlPane(text) } + private fun createDiscussionContent(item: GitLabMergeRequestTimelineItem.Discussion): JComponent { + val firstNote = item.discussion.notes.first() + return if (firstNote.system) { + StatusMessageComponentFactory.create(SimpleHtmlPane(firstNote.body)) + } + else { + SimpleHtmlPane(firstNote.body) + } + } + + private fun createLabeledEventContent(item: GitLabMergeRequestTimelineItem.LabelEvent): JComponent { + val text = when (item.event.actionEnum) { + GitLabResourceLabelEventDTO.Action.ADD -> GitLabBundle.message("merge.request.event.label.added", item.event.label.toHtml()) + GitLabResourceLabelEventDTO.Action.REMOVE -> GitLabBundle.message("merge.request.event.label.removed", item.event.label.toHtml()) + } + val textPane = SimpleHtmlPane(text) + return StatusMessageComponentFactory.create(textPane) + } + + private fun createMilestonedEventContent(item: GitLabMergeRequestTimelineItem.MilestoneEvent): JComponent { + val text = when (item.event.actionEnum) { + GitLabResourceMilestoneEventDTO.Action.ADD -> + GitLabBundle.message("merge.request.event.milestone.changed", item.event.milestone.toHtml()) + GitLabResourceMilestoneEventDTO.Action.REMOVE -> + GitLabBundle.message("merge.request.event.milestone.removed", item.event.milestone.toHtml()) + } + val textPane = SimpleHtmlPane(text) + return StatusMessageComponentFactory.create(textPane) + } + + private fun createStateChangeContent(item: GitLabMergeRequestTimelineItem.StateEvent): JComponent { + val text = when (item.event.stateEnum) { + GitLabResourceStateEventDTO.State.CLOSED -> GitLabBundle.message("merge.request.event.closed") + GitLabResourceStateEventDTO.State.REOPENED -> GitLabBundle.message("merge.request.event.reopened") + GitLabResourceStateEventDTO.State.MERGED -> GitLabBundle.message("merge.request.event.merged") + } + val type: StatusMessageType = when (item.event.stateEnum) { + GitLabResourceStateEventDTO.State.CLOSED -> StatusMessageType.SECONDARY_INFO + GitLabResourceStateEventDTO.State.REOPENED -> StatusMessageType.INFO + GitLabResourceStateEventDTO.State.MERGED -> StatusMessageType.SUCCESS + } + val textPane = SimpleHtmlPane(text) + return StatusMessageComponentFactory.create(textPane, type) + } + + private fun createTitleTextPane(actor: GitLabUserDTO, date: Date?): JComponent { val userNameLink = HtmlChunk.link(actor.webUrl, actor.name) .wrapWith(HtmlChunk.font(ColorUtil.toHtmlColor(UIUtil.getLabelForeground()))) @@ -107,4 +156,17 @@ object GitLabMergeRequestTimelineComponentFactory { } return titleTextPane } -} \ No newline at end of file +} + +private fun GitLabLabelRestDTO.toHtml(): @Nls String { + val bg = CollaborationToolsUIUtil.getLabelBackground(color) + val fg = CollaborationToolsUIUtil.getLabelForeground(bg) + + return HtmlChunk.span("color: #${ColorUtil.toHex(fg)}; background: #${ColorUtil.toHex(bg)}") + .child(HtmlChunk.nbsp()) + .addText(name) + .child(HtmlChunk.nbsp()) + .toString() +} + +private fun GitLabMilestoneDTO.toHtml(): @Nls String = HtmlChunk.link(webUrl, title).toString()