From 7fda109aba6cd077343edef086b2f2ff60124f78 Mon Sep 17 00:00:00 2001 From: silverwind Date: Thu, 28 Mar 2024 00:20:38 +0100 Subject: [PATCH] Drag-and-drop improvements for projects and issue pins (#29875) 1. Add "grabbing" cursor while dragging items: ![](https://github.com/go-gitea/gitea/assets/115237/c60845ff-7544-4215-aeaa-408e8c4ef03a) 2. Make project board only drag via their header, not via their whole body. ![](https://github.com/go-gitea/gitea/assets/115237/62c27f3d-993a-481d-9cc3-b6226b4c5d61) 3. Fix some cursor problems in projects 4. Move shared options into `createSortable`. --- templates/projects/view.tmpl | 4 ++-- web_src/css/features/projects.css | 3 +++ web_src/css/repo/issue-card.css | 4 ++++ web_src/js/features/repo-issue-list.js | 2 -- web_src/js/features/repo-projects.js | 5 +---- web_src/js/modules/sortable.js | 19 +++++++++++++++++-- 6 files changed, 27 insertions(+), 10 deletions(-) diff --git a/templates/projects/view.tmpl b/templates/projects/view.tmpl index e6c6c2049..b45174b08 100644 --- a/templates/projects/view.tmpl +++ b/templates/projects/view.tmpl @@ -67,7 +67,7 @@
{{range .Columns}}
-
+
{{.NumIssues ctx}} @@ -156,7 +156,7 @@
-
+
{{range (index $.IssuesMap .ID)}}
{{template "repo/issue/card" (dict "Issue" . "Page" $)}} diff --git a/web_src/css/features/projects.css b/web_src/css/features/projects.css index f85430a2a..30df994c3 100644 --- a/web_src/css/features/projects.css +++ b/web_src/css/features/projects.css @@ -19,6 +19,7 @@ overflow: visible; display: flex; flex-direction: column; + cursor: default; } .project-column-header { @@ -46,6 +47,7 @@ .project-column-title { background: none !important; line-height: 1.25 !important; + cursor: inherit; } .project-column > .cards { @@ -92,6 +94,7 @@ } .card-ghost { + border-color: var(--color-secondary-dark-4) !important; border-style: dashed !important; background: none !important; } diff --git a/web_src/css/repo/issue-card.css b/web_src/css/repo/issue-card.css index 5a70de47c..b9368df4f 100644 --- a/web_src/css/repo/issue-card.css +++ b/web_src/css/repo/issue-card.css @@ -19,3 +19,7 @@ font-size: 14px; margin-left: 4px; } + +.issue-card.sortable-chosen .issue-card-title { + cursor: inherit; +} diff --git a/web_src/js/features/repo-issue-list.js b/web_src/js/features/repo-issue-list.js index 9681e648d..4582f8742 100644 --- a/web_src/js/features/repo-issue-list.js +++ b/web_src/js/features/repo-issue-list.js @@ -188,8 +188,6 @@ async function initIssuePinSort() { createSortable(pinDiv, { group: 'shared', - animation: 150, - ghostClass: 'card-ghost', onEnd: pinMoveEnd, }); } diff --git a/web_src/js/features/repo-projects.js b/web_src/js/features/repo-projects.js index 1747cb2b3..d9ae85a8d 100644 --- a/web_src/js/features/repo-projects.js +++ b/web_src/js/features/repo-projects.js @@ -58,8 +58,7 @@ async function initRepoProjectSortable() { createSortable(mainBoard, { group: 'project-column', draggable: '.project-column', - animation: 150, - ghostClass: 'card-ghost', + handle: '.project-column-header', delayOnTouchOnly: true, delay: 500, onSort: async () => { @@ -86,8 +85,6 @@ async function initRepoProjectSortable() { const boardCardList = boardColumn.getElementsByClassName('cards')[0]; createSortable(boardCardList, { group: 'shared', - animation: 150, - ghostClass: 'card-ghost', onAdd: moveIssue, onUpdate: moveIssue, delayOnTouchOnly: true, diff --git a/web_src/js/modules/sortable.js b/web_src/js/modules/sortable.js index cfe7c3bf3..1c9adb6d7 100644 --- a/web_src/js/modules/sortable.js +++ b/web_src/js/modules/sortable.js @@ -1,4 +1,19 @@ -export async function createSortable(...args) { +export async function createSortable(el, opts = {}) { const {Sortable} = await import(/* webpackChunkName: "sortablejs" */'sortablejs'); - return new Sortable(...args); + + return new Sortable(el, { + animation: 150, + ghostClass: 'card-ghost', + onChoose: (e) => { + const handle = opts.handle ? e.item.querySelector(opts.handle) : e.item; + handle.classList.add('tw-cursor-grabbing'); + opts.onChoose?.(e); + }, + onUnchoose: (e) => { + const handle = opts.handle ? e.item.querySelector(opts.handle) : e.item; + handle.classList.remove('tw-cursor-grabbing'); + opts.onUnchoose?.(e); + }, + ...opts, + }); }