[ghai] Refactor the AI review action to be supplied by EP

(cherry picked from commit ba10b014a27b4056feba01107f8bcdfb743352c3)


(cherry picked from commit ed410ef7ca8143162e3788318666ec9e76e9df0d)

IJ-CR-148445

GitOrigin-RevId: fce66dae03512fe11333ef78b47e3f13e2762a14
This commit is contained in:
Chris Lemaire
2024-10-11 11:13:46 +02:00
committed by intellij-monorepo-bot
parent a650191208
commit 9b6b287618
4 changed files with 15 additions and 29 deletions

View File

@@ -232,6 +232,5 @@
</group> </group>
<group id="GitHub.Pull.Request.Create.Title.Actions"/> <group id="GitHub.Pull.Request.Create.Title.Actions"/>
<group id="Github.PullRequest.StatusChecks.AdditionalActions"/>
</actions> </actions>
</idea-plugin> </idea-plugin>

View File

@@ -8,6 +8,7 @@ import git4idea.changes.GitTextFilePatchWithHistory
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.ApiStatus
import org.jetbrains.plugins.github.pullrequest.data.GHPRIdentifier
import org.jetbrains.plugins.github.pullrequest.data.provider.GHPRDataProvider import org.jetbrains.plugins.github.pullrequest.data.provider.GHPRDataProvider
import org.jetbrains.plugins.github.pullrequest.ui.toolwindow.model.GHPRInfoViewModel import org.jetbrains.plugins.github.pullrequest.ui.toolwindow.model.GHPRInfoViewModel
import javax.swing.Icon import javax.swing.Icon
@@ -29,4 +30,6 @@ interface GHPRAIReviewExtension {
): Flow<List<GHPRAICommentViewModel>> ): Flow<List<GHPRAICommentViewModel>>
fun createAIThread(userIcon: Icon, vm: GHPRAICommentViewModel): JComponent fun createAIThread(userIcon: Icon, vm: GHPRAICommentViewModel): JComponent
fun createAIReviewAction(project: Project, prId: GHPRIdentifier): JComponent
} }

View File

@@ -1,26 +1,23 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. // 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.github.pullrequest.ui.details package org.jetbrains.plugins.github.pullrequest.ui.details
import com.intellij.collaboration.async.extensionListFlow
import com.intellij.collaboration.messages.CollaborationToolsBundle import com.intellij.collaboration.messages.CollaborationToolsBundle
import com.intellij.collaboration.ui.HorizontalListPanel
import com.intellij.collaboration.ui.VerticalListPanel import com.intellij.collaboration.ui.VerticalListPanel
import com.intellij.collaboration.ui.codereview.avatar.CodeReviewAvatarUtils import com.intellij.collaboration.ui.codereview.avatar.CodeReviewAvatarUtils
import com.intellij.collaboration.ui.codereview.details.CodeReviewDetailsStatusComponentFactory import com.intellij.collaboration.ui.codereview.details.CodeReviewDetailsStatusComponentFactory
import com.intellij.collaboration.ui.codereview.details.ReviewDetailsUIUtil import com.intellij.collaboration.ui.codereview.details.ReviewDetailsUIUtil
import com.intellij.collaboration.ui.util.bindChildIn
import com.intellij.collaboration.ui.util.bindContentIn import com.intellij.collaboration.ui.util.bindContentIn
import com.intellij.collaboration.ui.util.bindTextIn import com.intellij.collaboration.ui.util.bindTextIn
import com.intellij.collaboration.ui.util.toAnAction import com.intellij.collaboration.ui.util.toAnAction
import com.intellij.icons.AllIcons import com.intellij.icons.AllIcons
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.DefaultActionGroup import com.intellij.openapi.actionSystem.DefaultActionGroup
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.platform.util.coroutines.childScope import com.intellij.platform.util.coroutines.childScope
import com.intellij.ui.ExperimentalUI import com.intellij.ui.ExperimentalUI
import com.intellij.ui.ScrollPaneFactory import com.intellij.ui.ScrollPaneFactory
import com.intellij.ui.components.AnActionLink
import com.intellij.ui.components.panels.Wrapper import com.intellij.ui.components.panels.Wrapper
import com.intellij.util.ui.EmptyIcon
import com.intellij.util.ui.JBUI import com.intellij.util.ui.JBUI
import git4idea.remote.hosting.ui.ResolveConflictsLocallyDialogComponentFactory.showBranchUpdateDialog import git4idea.remote.hosting.ui.ResolveConflictsLocallyDialogComponentFactory.showBranchUpdateDialog
import git4idea.remote.hosting.ui.ResolveConflictsLocallyViewModel import git4idea.remote.hosting.ui.ResolveConflictsLocallyViewModel
@@ -28,6 +25,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.jetbrains.plugins.github.ai.GHPRAIReviewExtension
import org.jetbrains.plugins.github.api.data.GHRepositoryPermissionLevel import org.jetbrains.plugins.github.api.data.GHRepositoryPermissionLevel
import org.jetbrains.plugins.github.i18n.GithubBundle import org.jetbrains.plugins.github.i18n.GithubBundle
import org.jetbrains.plugins.github.pullrequest.data.service.GHPRSecurityService import org.jetbrains.plugins.github.pullrequest.data.service.GHPRSecurityService
@@ -38,7 +36,6 @@ import org.jetbrains.plugins.github.pullrequest.ui.details.model.GHPRStatusViewM
import org.jetbrains.plugins.github.pullrequest.ui.details.model.impl.GHPRDetailsViewModel import org.jetbrains.plugins.github.pullrequest.ui.details.model.impl.GHPRDetailsViewModel
import java.awt.event.ActionListener import java.awt.event.ActionListener
import javax.swing.JComponent import javax.swing.JComponent
import javax.swing.JLabel
import javax.swing.JScrollPane import javax.swing.JScrollPane
internal object GHPRStatusChecksComponentFactory { internal object GHPRStatusChecksComponentFactory {
@@ -56,10 +53,6 @@ internal object GHPRStatusChecksComponentFactory {
val loadingPanel = createLoadingComponent(scope, reviewStatusVm, securityService) val loadingPanel = createLoadingComponent(scope, reviewStatusVm, securityService)
val actionManager = ActionManager.getInstance()
val additionalActionsGroup = actionManager.getAction("Github.PullRequest.StatusChecks.AdditionalActions") as DefaultActionGroup
val additionalActions = additionalActionsGroup.getChildren(actionManager).toList()
val statusesPanel = VerticalListPanel().apply { val statusesPanel = VerticalListPanel().apply {
add(createAccessDeniedLabel(scope, reviewStatusVm, securityService)) add(createAccessDeniedLabel(scope, reviewStatusVm, securityService))
add(CodeReviewDetailsStatusComponentFactory.createCiComponent(scope, reviewStatusVm)) add(CodeReviewDetailsStatusComponentFactory.createCiComponent(scope, reviewStatusVm))
@@ -85,7 +78,10 @@ internal object GHPRStatusChecksComponentFactory {
) )
} }
)) ))
add(createAdditionalActionsPanel(additionalActions, detailsVm)) bindChildIn(scope, GHPRAIReviewExtension.EP.extensionListFlow()) { extensions ->
val extension = extensions.firstOrNull() ?: return@bindChildIn null
extension.createAIReviewAction(project, detailsVm.prId)
}
} }
val scrollableStatusesPanel = ScrollPaneFactory.createScrollPane(statusesPanel, true).apply { val scrollableStatusesPanel = ScrollPaneFactory.createScrollPane(statusesPanel, true).apply {
isOpaque = false isOpaque = false
@@ -178,21 +174,4 @@ internal object GHPRStatusChecksComponentFactory {
}) })
} }
} }
private fun createAdditionalActionsPanel(actions: List<AnAction>, detailsVm: GHPRDetailsViewModel): JComponent =
VerticalListPanel().apply {
for (action in actions) {
add(HorizontalListPanel(8).apply {
border = JBUI.Borders.empty(5, 0)
add(JLabel().apply {
icon = action.templatePresentation.icon ?: EmptyIcon.ICON_16
})
add(AnActionLink(action, "status").apply {
icon = null
})
})
}
}
} }

View File

@@ -16,6 +16,7 @@ import org.jetbrains.plugins.github.api.data.pullrequest.GHPullRequest
import org.jetbrains.plugins.github.api.data.pullrequest.GHPullRequestState import org.jetbrains.plugins.github.api.data.pullrequest.GHPullRequestState
import org.jetbrains.plugins.github.pullrequest.comment.convertToHtml import org.jetbrains.plugins.github.pullrequest.comment.convertToHtml
import org.jetbrains.plugins.github.pullrequest.data.GHPRDataContext import org.jetbrains.plugins.github.pullrequest.data.GHPRDataContext
import org.jetbrains.plugins.github.pullrequest.data.GHPRIdentifier
import org.jetbrains.plugins.github.pullrequest.data.provider.GHPRDataProvider import org.jetbrains.plugins.github.pullrequest.data.provider.GHPRDataProvider
import org.jetbrains.plugins.github.pullrequest.data.service.GHPRSecurityService import org.jetbrains.plugins.github.pullrequest.data.service.GHPRSecurityService
import org.jetbrains.plugins.github.pullrequest.ui.details.model.GHPRBranchesViewModel import org.jetbrains.plugins.github.pullrequest.ui.details.model.GHPRBranchesViewModel
@@ -25,6 +26,8 @@ import org.jetbrains.plugins.github.pullrequest.ui.toolwindow.model.GHPRToolWind
@ApiStatus.Experimental @ApiStatus.Experimental
interface GHPRDetailsViewModel : CodeReviewDetailsViewModel { interface GHPRDetailsViewModel : CodeReviewDetailsViewModel {
val prId: GHPRIdentifier
val securityService: GHPRSecurityService val securityService: GHPRSecurityService
val avatarIconsProvider: IconsProvider<String> val avatarIconsProvider: IconsProvider<String>
@@ -49,6 +52,8 @@ internal class GHPRDetailsViewModelImpl(
private val detailsState = MutableStateFlow(details) private val detailsState = MutableStateFlow(details)
override val prId: GHPRIdentifier = detailsState.value.prId
override val number: String = "#${detailsState.value.number}" override val number: String = "#${detailsState.value.number}"
override val url: String = detailsState.value.url override val url: String = detailsState.value.url