diff options
Diffstat (limited to 'web_src')
-rw-r--r-- | web_src/js/features/repo-issue-list.ts | 6 | ||||
-rw-r--r-- | web_src/js/features/repo-settings-branches.test.ts | 71 | ||||
-rw-r--r-- | web_src/js/features/repo-settings-branches.ts | 32 | ||||
-rw-r--r-- | web_src/js/features/repo-settings.ts | 2 | ||||
-rw-r--r-- | web_src/js/svg.ts | 2 |
5 files changed, 112 insertions, 1 deletions
diff --git a/web_src/js/features/repo-issue-list.ts b/web_src/js/features/repo-issue-list.ts index 931122db3c..a7185e5f99 100644 --- a/web_src/js/features/repo-issue-list.ts +++ b/web_src/js/features/repo-issue-list.ts @@ -196,7 +196,11 @@ async function initIssuePinSort() { createSortable(pinDiv, { group: 'shared', - onEnd: pinMoveEnd, // eslint-disable-line @typescript-eslint/no-misused-promises + onEnd: (e) => { + (async () => { + await pinMoveEnd(e); + })(); + }, }); } diff --git a/web_src/js/features/repo-settings-branches.test.ts b/web_src/js/features/repo-settings-branches.test.ts new file mode 100644 index 0000000000..023039334f --- /dev/null +++ b/web_src/js/features/repo-settings-branches.test.ts @@ -0,0 +1,71 @@ +import {beforeEach, describe, expect, test, vi} from 'vitest'; +import {initRepoBranchesSettings} from './repo-settings-branches.ts'; +import {POST} from '../modules/fetch.ts'; +import {createSortable} from '../modules/sortable.ts'; + +vi.mock('../modules/fetch.ts', () => ({ + POST: vi.fn(), +})); + +vi.mock('../modules/sortable.ts', () => ({ + createSortable: vi.fn(), +})); + +describe('Repository Branch Settings', () => { + beforeEach(() => { + document.body.innerHTML = ` + <div id="protected-branches-list" data-update-priority-url="some/repo/branches/priority"> + <div class="flex-item tw-items-center item" data-id="1" > + <div class="drag-handle"></div> + </div> + <div class="flex-item tw-items-center item" data-id="2" > + <div class="drag-handle"></div> + </div> + <div class="flex-item tw-items-center item" data-id="3" > + <div class="drag-handle"></div> + </div> + </div> + `; + + vi.clearAllMocks(); + }); + + test('should initialize sortable for protected branches list', () => { + initRepoBranchesSettings(); + + expect(createSortable).toHaveBeenCalledWith( + document.querySelector('#protected-branches-list'), + expect.objectContaining({ + handle: '.drag-handle', + animation: 150, + }), + ); + }); + + test('should not initialize if protected branches list is not present', () => { + document.body.innerHTML = ''; + + initRepoBranchesSettings(); + + expect(createSortable).not.toHaveBeenCalled(); + }); + + test('should post new order after sorting', async () => { + vi.mocked(POST).mockResolvedValue({ok: true} as Response); + + // Mock createSortable to capture and execute the onEnd callback + vi.mocked(createSortable).mockImplementation((_el, options) => { + options.onEnd(); + return {destroy: vi.fn()}; + }); + + initRepoBranchesSettings(); + + expect(POST).toHaveBeenCalledWith( + 'some/repo/branches/priority', + expect.objectContaining({ + data: {ids: [1, 2, 3]}, + }), + ); + }); +}); diff --git a/web_src/js/features/repo-settings-branches.ts b/web_src/js/features/repo-settings-branches.ts new file mode 100644 index 0000000000..43b98f79b3 --- /dev/null +++ b/web_src/js/features/repo-settings-branches.ts @@ -0,0 +1,32 @@ +import {createSortable} from '../modules/sortable.ts'; +import {POST} from '../modules/fetch.ts'; +import {showErrorToast} from '../modules/toast.ts'; +import {queryElemChildren} from '../utils/dom.ts'; + +export function initRepoBranchesSettings() { + const protectedBranchesList = document.querySelector('#protected-branches-list'); + if (!protectedBranchesList) return; + + createSortable(protectedBranchesList, { + handle: '.drag-handle', + animation: 150, + + onEnd: () => { + (async () => { + const itemElems = queryElemChildren(protectedBranchesList, '.item[data-id]'); + const itemIds = Array.from(itemElems, (el) => parseInt(el.getAttribute('data-id'))); + + try { + await POST(protectedBranchesList.getAttribute('data-update-priority-url'), { + data: { + ids: itemIds, + }, + }); + } catch (err) { + const errorMessage = String(err); + showErrorToast(`Failed to update branch protection rule priority:, error: ${errorMessage}`); + } + })(); + }, + }); +} diff --git a/web_src/js/features/repo-settings.ts b/web_src/js/features/repo-settings.ts index 72213f794a..5a009cfea4 100644 --- a/web_src/js/features/repo-settings.ts +++ b/web_src/js/features/repo-settings.ts @@ -3,6 +3,7 @@ import {minimatch} from 'minimatch'; import {createMonaco} from './codeeditor.ts'; import {onInputDebounce, queryElems, toggleElem} from '../utils/dom.ts'; import {POST} from '../modules/fetch.ts'; +import {initRepoBranchesSettings} from './repo-settings-branches.ts'; const {appSubUrl, csrfToken} = window.config; @@ -154,4 +155,5 @@ export function initRepoSettings() { initRepoSettingsCollaboration(); initRepoSettingsSearchTeamBox(); initRepoSettingsGitHook(); + initRepoBranchesSettings(); } diff --git a/web_src/js/svg.ts b/web_src/js/svg.ts index d04f63793f..cbb1af4ba1 100644 --- a/web_src/js/svg.ts +++ b/web_src/js/svg.ts @@ -34,6 +34,7 @@ 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 octiconGrabber from '../../public/assets/img/svg/octicon-grabber.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'; @@ -107,6 +108,7 @@ const svgs = { 'octicon-git-merge': octiconGitMerge, 'octicon-git-pull-request': octiconGitPullRequest, 'octicon-git-pull-request-draft': octiconGitPullRequestDraft, + 'octicon-grabber': octiconGrabber, 'octicon-heading': octiconHeading, 'octicon-horizontal-rule': octiconHorizontalRule, 'octicon-image': octiconImage, |