Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
77f7807
Replace Fomantic search module with first-party autocomplete
silverwind Apr 26, 2026
cfe9e70
Trim e2e to a single minimal collaborator-search test
silverwind Apr 26, 2026
2ecee0b
Refactor search-box module to await-style chooseFromApi
silverwind Apr 26, 2026
fae5d79
Rename test var target to userName for clarity
silverwind Apr 26, 2026
4fd1ade
Expand rc- prefix to repo-collab- for clarity
silverwind Apr 26, 2026
26cdb90
Tighten search-box types, expand test prefix, drop stale CSS comment
silverwind Apr 26, 2026
5859380
Convert search box to imperative attach API
silverwind Apr 26, 2026
dbe3328
Extend e2e test to verify selected user lands in collaborator list
silverwind Apr 26, 2026
a9a2e60
Apply suggestion from @silverwind
silverwind Apr 26, 2026
6b7c386
Simplify attachSearchBox and restore the CSS comment
silverwind Apr 26, 2026
73d7f68
Address Copilot review on attachSearchBox
silverwind Apr 27, 2026
4e1c658
Merge branch 'main' into search
silverwind Apr 28, 2026
cd59e7e
Merge branch 'main' into search
silverwind May 4, 2026
92158b1
Tweak attachSearchBox: rename `all`→`resultEls`, clarify stale-respon…
silverwind May 4, 2026
3adfa3f
Add errorName helper, use it instead of (err as Error).name
silverwind May 4, 2026
1c44b48
Add TSDoc to errorMessage and errorName helpers
silverwind May 4, 2026
200633a
Merge branch 'main' into search
silverwind May 7, 2026
bcc1f0a
Merge branch 'main' into search
silverwind May 10, 2026
7388128
Add e2e regression test for add-team-member search box
silverwind May 10, 2026
8e3ff0e
Make apiCreateTeam permission and units optional with read/code defaults
silverwind May 10, 2026
50a4c2a
Address Copilot reviews on attachSearchBox
silverwind May 10, 2026
577d9cf
Merge branch 'main' into search
GiteaBot May 11, 2026
b04fdd6
Merge branch 'main' into search
GiteaBot May 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions templates/admin/badge/users.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
{{.Title}}
</h4>
<div class="ui attached segment">
<form class="ui form" action="{{.Link}}" method="post">
<div id="search-user-box" class="ui search input tw-align-middle">
<form class="ui form flex-text-block" action="{{.Link}}" method="post">
<div id="search-user-box" class="ui search input">
<input class="prompt" name="user" placeholder="{{ctx.Locale.Tr "search.user_kind"}}" autocomplete="off" autofocus required>
</div>
<button class="ui primary button">{{ctx.Locale.Tr "admin.badges.add_user"}}</button>
Expand Down
4 changes: 2 additions & 2 deletions templates/repo/settings/actions_general.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@
</div>
{{end}}
<div class="ui bottom attached segment">
<form class="ui form form-fetch-action" action="{{.Link}}/collaborative_owner/add" method="post">
<div id="search-user-box" class="ui search input tw-align-middle" data-include-orgs="true">
<form class="ui form form-fetch-action flex-text-block" action="{{.Link}}/collaborative_owner/add" method="post">
<div id="search-user-box" class="ui search input" data-include-orgs="true">
<input class="prompt" name="collaborative_owner" placeholder="{{ctx.Locale.Tr "search.user_kind"}}" autocomplete="off" autofocus required>
</div>
<button class="ui primary button">{{ctx.Locale.Tr "actions.general.add_collaborative_owner"}}</button>
Expand Down
8 changes: 4 additions & 4 deletions templates/repo/settings/collaboration.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
</div>
{{end}}
<div class="ui bottom attached segment">
<form class="ui form" id="repo-collab-form" action="{{.Link}}" method="post">
<div id="search-user-box" class="ui search input tw-align-middle">
<form class="ui form flex-text-block" id="repo-collab-form" action="{{.Link}}" method="post">
<div id="search-user-box" class="ui search input">
<input class="prompt" name="collaborator" placeholder="{{ctx.Locale.Tr "search.user_kind"}}" autocomplete="off" autofocus required>
</div>
<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.add_collaborator"}}</button>
Expand Down Expand Up @@ -106,8 +106,8 @@
{{end}}
<div class="ui bottom attached segment">
{{if $allowedToChangeTeams}}
<form class="ui form" id="repo-collab-team-form" action="{{.Link}}/team" method="post">
<div id="search-team-box" class="ui search input tw-align-middle" data-org-name="{{.OrgName}}">
<form class="ui form flex-text-block" id="repo-collab-team-form" action="{{.Link}}/team" method="post">
<div id="search-team-box" class="ui search input" data-org-name="{{.OrgName}}">
<input class="prompt" name="team" placeholder="{{ctx.Locale.Tr "search.team_kind"}}" autocomplete="off" required>
</div>
<button class="ui primary button">{{ctx.Locale.Tr "repo.settings.add_team"}}</button>
Expand Down
23 changes: 22 additions & 1 deletion tests/e2e/org.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {test, expect} from '@playwright/test';
import {login, apiDeleteOrg, randomString} from './utils.ts';
import {login, apiCreateOrg, apiCreateTeam, apiCreateUser, apiDeleteOrg, randomString} from './utils.ts';

test('create an organization', async ({page}) => {
const orgName = `e2e-org-${randomString(8)}`;
Expand All @@ -11,3 +11,24 @@ test('create an organization', async ({page}) => {
// delete via API because of issues related to form-fetch-action
await apiDeleteOrg(page.request, orgName);
});

test('add team member search', async ({page, request}) => {
const orgName = `team-add-${randomString(8)}`;
const teamName = `team-add-${randomString(8)}`;
const userName = `team-add-${randomString(8)}`;

await Promise.all([
(async () => {
await apiCreateOrg(request, orgName);
await apiCreateTeam(request, orgName, teamName);
})(),
apiCreateUser(request, userName),
login(page),
]);

await page.goto(`/org/${orgName}/teams/${teamName}`);
const input = page.locator('#search-user-box input.prompt');
await input.fill(userName.slice(-6));
const result = page.locator('#search-user-box .results .result').first();
await expect(result).toContainText(userName);
});
24 changes: 24 additions & 0 deletions tests/e2e/repo-collab.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {env} from 'node:process';
import {test, expect} from '@playwright/test';
import {apiCreateRepo, apiCreateUser, login, randomString} from './utils.ts';

test('add collaborator search', async ({page, request}) => {
const userName = `repo-collab-${randomString(8)}`;
const repoName = `repo-collab-${randomString(8)}`;

await Promise.all([
apiCreateUser(request, userName),
apiCreateRepo(request, {name: repoName, autoInit: false}),
login(page),
]);

await page.goto(`/${env.GITEA_TEST_E2E_USER}/${repoName}/settings/collaboration`);
const input = page.locator('#search-user-box input.prompt');
await input.fill(userName.slice(-6));
const result = page.locator('#search-user-box .results .result').first();
await expect(result).toContainText(userName);
await result.click();
await expect(input).toHaveValue(userName);
await page.getByRole('button', {name: 'Add Collaborator'}).click();
await expect(page.locator('body')).toContainText(userName);
});
14 changes: 14 additions & 0 deletions tests/e2e/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,20 @@ export async function apiCreateRepo(requestContext: APIRequestContext, {name, au
}), 'apiCreateRepo');
}

export async function apiCreateOrg(requestContext: APIRequestContext, name: string, {headers}: {headers?: Record<string, string>} = {}) {
await apiRetry(() => requestContext.post(`${baseUrl()}/api/v1/orgs`, {
headers: headers || apiHeaders(),
data: {username: name},
}), 'apiCreateOrg');
}

export async function apiCreateTeam(requestContext: APIRequestContext, org: string, name: string, {permission = 'read', units = ['repo.code'], headers}: {permission?: string; units?: Array<string>; headers?: Record<string, string>} = {}) {
await apiRetry(() => requestContext.post(`${baseUrl()}/api/v1/orgs/${org}/teams`, {
headers: headers || apiHeaders(),
data: {name, permission, units},
}), 'apiCreateTeam');
}

export async function apiStartStopwatch(requestContext: APIRequestContext, owner: string, repo: string, issueIndex: number, {headers}: {headers?: Record<string, string>} = {}) {
await apiRetry(() => requestContext.post(`${baseUrl()}/api/v1/repos/${owner}/${repo}/issues/${issueIndex}/stopwatch/start`, {
headers: headers || apiHeaders(),
Expand Down
Loading
Loading