Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drag-and-drop improvements for projects and issue pins #29875

Merged
merged 11 commits into from
Mar 27, 2024
4 changes: 2 additions & 2 deletions templates/projects/view.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
<div class="board {{if .CanWriteProjects}}sortable{{end}}">
{{range .Columns}}
<div class="ui segment project-column" style="background: {{.Color}} !important;" data-id="{{.ID}}" data-sorting="{{.Sorting}}" data-url="{{$.Link}}/{{.ID}}">
<div class="project-column-header">
<div class="project-column-header{{if and $canWriteProject (ne .ID 0)}}{{/* ID 0 is default column which cannot be moved */}} tw-cursor-grab{{end}}">
silverwind marked this conversation as resolved.
Show resolved Hide resolved
<div class="ui large label project-column-title gt-py-2">
<div class="ui small circular grey label project-column-issue-count">
{{.NumIssues ctx}}
Expand Down Expand Up @@ -165,7 +165,7 @@

<div class="divider"></div>

<div class="ui cards {{if and $canWriteProject (ne .ID 0)}}{{/* ID 0 is default column which cannot be moved */}}tw-cursor-grab{{end}}" data-url="{{$.Link}}/{{.ID}}" data-project="{{$.Project.ID}}" data-board="{{.ID}}" id="board_{{.ID}}">
<div class="ui cards" data-url="{{$.Link}}/{{.ID}}" data-project="{{$.Project.ID}}" data-board="{{.ID}}" id="board_{{.ID}}">
{{range (index $.IssuesMap .ID)}}
<div class="issue-card gt-word-break {{if $canWriteProject}}tw-cursor-grab{{end}}" data-issue="{{.ID}}">
{{template "repo/issue/card" (dict "Issue" . "Page" $)}}
Expand Down
2 changes: 2 additions & 0 deletions web_src/css/features/projects.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
overflow: visible;
display: flex;
flex-direction: column;
cursor: default;
}

.project-column-header {
Expand Down Expand Up @@ -46,6 +47,7 @@
.project-column-title {
background: none !important;
line-height: 1.25 !important;
cursor: inherit;
}

.project-column > .cards {
Expand Down
4 changes: 4 additions & 0 deletions web_src/css/repo/issue-card.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@
font-size: 14px;
margin-left: 4px;
}

.issue-card.sortable-chosen .issue-card-title {
cursor: inherit;
}
2 changes: 0 additions & 2 deletions web_src/js/features/repo-issue-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,6 @@ async function initIssuePinSort() {

createSortable(pinDiv, {
group: 'shared',
animation: 150,
ghostClass: 'card-ghost',
onEnd: pinMoveEnd,
});
}
Expand Down
5 changes: 1 addition & 4 deletions web_src/js/features/repo-projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@ async function initRepoProjectSortable() {
createSortable(mainBoard, {
group: 'project-column',
draggable: '.project-column',
handle: '.project-column-header',
filter: '[data-id="0"]',
silverwind marked this conversation as resolved.
Show resolved Hide resolved
animation: 150,
ghostClass: 'card-ghost',
delayOnTouchOnly: true,
delay: 500,
onSort: async () => {
Expand All @@ -87,8 +86,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,
Expand Down
19 changes: 17 additions & 2 deletions web_src/js/modules/sortable.js
Original file line number Diff line number Diff line change
@@ -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;
silverwind marked this conversation as resolved.
Show resolved Hide resolved
handle.classList.add('tw-cursor-grabbing');
opts.onStart?.(e);
silverwind marked this conversation as resolved.
Show resolved Hide resolved
},
onUnchoose: (e) => {
const handle = opts?.handle ? e.item.querySelector(opts.handle) : e.item;
silverwind marked this conversation as resolved.
Show resolved Hide resolved
handle.classList.remove('tw-cursor-grabbing');
opts.onUnchoose?.(e);
},
...opts,
});
}