From 50f55f11c4f785b72a39e59b0fc12ae70ab8d8b5 Mon Sep 17 00:00:00 2001
From: Bram Hagens <bram@bramh.me>
Date: Sun, 4 Feb 2024 23:37:45 +0100
Subject: [PATCH] Show whether a PR is WIP inside popups  (#28975)

Fixes https://codeberg.org/forgejo/forgejo/issues/2257

Draft status of a PR is currently not exposed by the API. This PR adds a
'draft' field to pull requests in the API, which is used to correctly
set the PR color/icon in a ContextPopup.

---

Before:

![image](https://github.com/go-gitea/gitea/assets/5541521/72cbd30e-1175-4338-aa97-ac99c46c5118)

After:

![image](https://github.com/go-gitea/gitea/assets/5541521/111c9eba-460e-4d57-bcca-23a151c3a4f1)
---
 modules/structs/issue.go               |  5 +++--
 services/convert/issue.go              |  3 ++-
 templates/swagger/v1_json.tmpl         |  4 ++++
 web_src/js/components/ContextPopup.vue | 18 +++++++++++++-----
 web_src/js/svg.js                      |  2 ++
 5 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/modules/structs/issue.go b/modules/structs/issue.go
index 1aec5cc6b8..34eae69329 100644
--- a/modules/structs/issue.go
+++ b/modules/structs/issue.go
@@ -26,8 +26,9 @@ const (
 
 // PullRequestMeta PR info if an issue is a PR
 type PullRequestMeta struct {
-	HasMerged bool       `json:"merged"`
-	Merged    *time.Time `json:"merged_at"`
+	HasMerged        bool       `json:"merged"`
+	Merged           *time.Time `json:"merged_at"`
+	IsWorkInProgress bool       `json:"draft"`
 }
 
 // RepositoryMeta basic repository information
diff --git a/services/convert/issue.go b/services/convert/issue.go
index 39d785e108..c6e06180c8 100644
--- a/services/convert/issue.go
+++ b/services/convert/issue.go
@@ -98,7 +98,8 @@ func toIssue(ctx context.Context, issue *issues_model.Issue, getDownloadURL func
 		}
 		if issue.PullRequest != nil {
 			apiIssue.PullRequest = &api.PullRequestMeta{
-				HasMerged: issue.PullRequest.HasMerged,
+				HasMerged:        issue.PullRequest.HasMerged,
+				IsWorkInProgress: issue.PullRequest.IsWorkInProgress(ctx),
 			}
 			if issue.PullRequest.HasMerged {
 				apiIssue.PullRequest.Merged = issue.PullRequest.MergedUnix.AsTimePtr()
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl
index dc04a97b83..403f241d72 100644
--- a/templates/swagger/v1_json.tmpl
+++ b/templates/swagger/v1_json.tmpl
@@ -21610,6 +21610,10 @@
       "description": "PullRequestMeta PR info if an issue is a PR",
       "type": "object",
       "properties": {
+        "draft": {
+          "type": "boolean",
+          "x-go-name": "IsWorkInProgress"
+        },
         "merged": {
           "type": "boolean",
           "x-go-name": "HasMerged"
diff --git a/web_src/js/components/ContextPopup.vue b/web_src/js/components/ContextPopup.vue
index 303e6d0c89..d9e6da316c 100644
--- a/web_src/js/components/ContextPopup.vue
+++ b/web_src/js/components/ContextPopup.vue
@@ -30,6 +30,9 @@ export default {
     icon() {
       if (this.issue.pull_request !== null) {
         if (this.issue.state === 'open') {
+          if (this.issue.pull_request.draft === true) {
+            return 'octicon-git-pull-request-draft'; // WIP PR
+          }
           return 'octicon-git-pull-request'; // Open PR
         } else if (this.issue.pull_request.merged === true) {
           return 'octicon-git-merge'; // Merged PR
@@ -42,12 +45,17 @@ export default {
     },
 
     color() {
-      if (this.issue.state === 'open') {
-        return 'green';
-      } else if (this.issue.pull_request !== null && this.issue.pull_request.merged === true) {
-        return 'purple';
+      if (this.issue.pull_request !== null) {
+        if (this.issue.pull_request.draft === true) {
+          return 'grey'; // WIP PR
+        } else if (this.issue.pull_request.merged === true) {
+          return 'purple'; // Merged PR
+        }
       }
-      return 'red';
+      if (this.issue.state === 'open') {
+        return 'green'; // Open Issue
+      }
+      return 'red'; // Closed Issue
     },
 
     labels() {
diff --git a/web_src/js/svg.js b/web_src/js/svg.js
index c2a96fba3f..084256587c 100644
--- a/web_src/js/svg.js
+++ b/web_src/js/svg.js
@@ -33,6 +33,7 @@ import octiconGitBranch from '../../public/assets/img/svg/octicon-git-branch.svg
 import octiconGitCommit from '../../public/assets/img/svg/octicon-git-commit.svg';
 import octiconGitMerge from '../../public/assets/img/svg/octicon-git-merge.svg';
 import octiconGitPullRequest from '../../public/assets/img/svg/octicon-git-pull-request.svg';
+import octiconGitPullRequestDraft from '../../public/assets/img/svg/octicon-git-pull-request-draft.svg';
 import octiconHeading from '../../public/assets/img/svg/octicon-heading.svg';
 import octiconHorizontalRule from '../../public/assets/img/svg/octicon-horizontal-rule.svg';
 import octiconImage from '../../public/assets/img/svg/octicon-image.svg';
@@ -104,6 +105,7 @@ const svgs = {
   'octicon-git-commit': octiconGitCommit,
   'octicon-git-merge': octiconGitMerge,
   'octicon-git-pull-request': octiconGitPullRequest,
+  'octicon-git-pull-request-draft': octiconGitPullRequestDraft,
   'octicon-heading': octiconHeading,
   'octicon-horizontal-rule': octiconHorizontalRule,
   'octicon-image': octiconImage,