From 7f02f4722cf85f9b3db7b81935e4520b28a1f8d6 Mon Sep 17 00:00:00 2001
From: Sai Nane <esainane+git@gmail.com>
Date: Fri, 30 Aug 2024 12:53:40 +0000
Subject: [PATCH 1/3] Test: Milestone assignment in new issue

This test currently fails, as expected, given this functionality is currently
broken.
---
 tests/e2e/issue-sidebar.test.e2e.js | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/tests/e2e/issue-sidebar.test.e2e.js b/tests/e2e/issue-sidebar.test.e2e.js
index 3bda7bdd17..0311910a34 100644
--- a/tests/e2e/issue-sidebar.test.e2e.js
+++ b/tests/e2e/issue-sidebar.test.e2e.js
@@ -119,3 +119,25 @@ test('Issue: Milestone', async ({browser}, workerInfo) => {
   await expect(selectedMilestone).toContainText('No milestone');
   await expect(page.locator('.timeline-item.event').last()).toContainText('user2 removed this from the milestone1 milestone');
 });
+
+test('New Issue: Milestone', async ({browser}, workerInfo) => {
+  test.skip(workerInfo.project.name === 'Mobile Safari', 'Unable to get tests working on Safari Mobile, see https://codeberg.org/forgejo/forgejo/pulls/3445#issuecomment-1789636');
+  const page = await login({browser}, workerInfo);
+
+  const response = await page.goto('/user2/repo1/issues/new');
+  await expect(response?.status()).toBe(200);
+
+  const selectedMilestone = page.locator('.issue-content-right .select-milestone.list');
+  const milestoneDropdown = page.locator('.issue-content-right .select-milestone.dropdown');
+  await expect(selectedMilestone).toContainText('No milestone');
+
+  // Add milestone.
+  await milestoneDropdown.click();
+  await page.getByRole('option', {name: 'milestone1'}).click();
+  await expect(selectedMilestone).toContainText('milestone1');
+
+  // Clear milestone.
+  await milestoneDropdown.click();
+  await page.getByText('Clear milestone', {exact: true}).click();
+  await expect(selectedMilestone).toContainText('No milestone');
+});

From b42ca2ed0c3482529728712e19434a5ad902037b Mon Sep 17 00:00:00 2001
From: Sai Nane <esainane+git@gmail.com>
Date: Wed, 4 Sep 2024 03:07:15 +0000
Subject: [PATCH 2/3] Revert repo-legacy.js to pre-#4542

The New Issue form should not use the new HTMX system. This first requires
we restore the ability to locally assign the milestone ID.
---
 web_src/js/features/repo-legacy.js | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/web_src/js/features/repo-legacy.js b/web_src/js/features/repo-legacy.js
index d9aa881127..b25fc28dea 100644
--- a/web_src/js/features/repo-legacy.js
+++ b/web_src/js/features/repo-legacy.js
@@ -270,7 +270,9 @@ export function initRepoCommentForm() {
       }
 
       let icon = '';
-      if (input_id === '#project_id') {
+      if (input_id === '#milestone_id') {
+        icon = svg('octicon-milestone', 18, 'tw-mr-2');
+      } else if (input_id === '#project_id') {
         icon = svg('octicon-project', 18, 'tw-mr-2');
       } else if (input_id === '#assignee_id') {
         icon = `<img class="ui avatar image tw-mr-2" alt="avatar" src=${$(this).data('avatar')}>`;
@@ -311,6 +313,7 @@ export function initRepoCommentForm() {
 
   // Milestone, Assignee, Project
   selectItem('.select-project', '#project_id');
+  selectItem('.select-milestone', '#milestone_id');
   selectItem('.select-assignee', '#assignee_id');
 }
 

From 1e54e211ca25eee308f0773213d26855330f2e94 Mon Sep 17 00:00:00 2001
From: Sai Nane <esainane+git@gmail.com>
Date: Wed, 4 Sep 2024 03:07:23 +0000
Subject: [PATCH 3/3] Fix milestone assignment in New Issue

Avoids the use of HTMX on milestone assignment within a New Issue form.

The New Issue form doesn't have an issue ID to send to a milestone change URL,
which the backend expects in order to construct a proper reply. The frontend
template was also not built to use the new HTMX response. This resulted in a
backend error and a large warning whenever anyone tried to set a milestone
from within the New Issue form (new pull requests were also affected), rather
than from a View Issue page.

This introduces a new parameter into the `issue/milestone/select_menu`
template, "NewIssuePage".

When unset, the template produces the same results as before. Selection uses
`hx-post` to notify the server immediately, using the updated htmx fragment
from the reply.

When set to a truthy value, the old style of form is used. Selection uses
`data-id` and `data-href` to update the selected milestone locally, via
`selectItem` in `repo-legacy.js`, recreating the selected element and updating
the hidden form value.

Fixes #5176.
---
 templates/repo/issue/milestone/select_menu.tmpl | 7 ++++---
 templates/repo/issue/new_form.tmpl              | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/templates/repo/issue/milestone/select_menu.tmpl b/templates/repo/issue/milestone/select_menu.tmpl
index eae2f3baa9..570acc2eee 100644
--- a/templates/repo/issue/milestone/select_menu.tmpl
+++ b/templates/repo/issue/milestone/select_menu.tmpl
@@ -1,3 +1,4 @@
+{{$useHTMX := not .NewIssuePage}}
 {{if or .OpenMilestones .ClosedMilestones}}
 	<div class="ui icon search input">
 		<i class="icon">{{svg "octicon-search" 16}}</i>
@@ -5,7 +6,7 @@
 	</div>
 	<div class="divider"></div>
 {{end}}
-<div class="no-select item" hx-post="{{$.RepoLink}}/issues/milestone?issue_ids={{$.Issue.ID}}&htmx=true">{{ctx.Locale.Tr "repo.issues.new.clear_milestone"}}</div>
+<div class="no-select item"{{if $useHTMX}} hx-post="{{$.RepoLink}}/issues/milestone?issue_ids={{$.Issue.ID}}&htmx=true"{{end}}>{{ctx.Locale.Tr "repo.issues.new.clear_milestone"}}</div>
 {{if and (not .OpenMilestones) (not .ClosedMilestones)}}
 	<div class="disabled item">
 		{{ctx.Locale.Tr "repo.issues.new.no_items"}}
@@ -17,7 +18,7 @@
 			{{ctx.Locale.Tr "repo.issues.new.open_milestone"}}
 		</div>
 		{{range .OpenMilestones}}
-			<a class="item" hx-post="{{$.RepoLink}}/issues/milestone?id={{.ID}}&issue_ids={{$.Issue.ID}}&htmx=true">
+			<a class="item"{{if $useHTMX}} hx-post="{{$.RepoLink}}/issues/milestone?id={{.ID}}&issue_ids={{$.Issue.ID}}&htmx=true"{{else}} data-id="{{.ID}}" data-href="{{$.RepoLink}}/issues?milestone={{.ID}}"{{end}}>
 				{{svg "octicon-milestone" 16 "tw-mr-1"}}
 				{{.Name}}
 			</a>
@@ -29,7 +30,7 @@
 			{{ctx.Locale.Tr "repo.issues.new.closed_milestone"}}
 		</div>
 		{{range .ClosedMilestones}}
-			<a class="item" hx-post="{{$.RepoLink}}/issues/milestone?id={{.ID}}&issue_ids={{$.Issue.ID}}&htmx=true">
+			<a class="item"{{if $useHTMX}} hx-post="{{$.RepoLink}}/issues/milestone?id={{.ID}}&issue_ids={{$.Issue.ID}}&htmx=true"{{else}} data-id="{{.ID}}" data-href="{{$.RepoLink}}/issues?milestone={{.ID}}"{{end}}>
 				{{svg "octicon-milestone" 16 "tw-mr-1"}}
 				{{.Name}}
 			</a>
diff --git a/templates/repo/issue/new_form.tmpl b/templates/repo/issue/new_form.tmpl
index 465cb44f6f..fe10c1f9b9 100644
--- a/templates/repo/issue/new_form.tmpl
+++ b/templates/repo/issue/new_form.tmpl
@@ -64,7 +64,7 @@
 				{{end}}
 			</span>
 			<div class="menu">
-				{{template "repo/issue/milestone/select_menu" .}}
+				{{template "repo/issue/milestone/select_menu" dict "." . "NewIssuePage" 1}}
 			</div>
 		</div>
 		<div class="ui select-milestone list">