mirror of
https://github.com/go-gitea/gitea.git
synced 2026-04-04 23:10:38 +02:00
97 lines
3.3 KiB
TypeScript
97 lines
3.3 KiB
TypeScript
import {createSortable} from '../modules/sortable.ts';
|
|
import Sortable, {type SortableEvent, type SortableOptions} from 'sortablejs';
|
|
import {POST} from '../modules/fetch.ts';
|
|
import {toggleElem} from '../utils/dom.ts';
|
|
export function initCommonGroup() {
|
|
if (!document.querySelectorAll('.group').length) {
|
|
return;
|
|
}
|
|
|
|
document.querySelector('.group.settings.options #group_name')?.addEventListener('input', function (this: HTMLInputElement) {
|
|
const nameChanged = this.value.toLowerCase() !== this.getAttribute('data-group-name').toLowerCase();
|
|
toggleElem('#group-name-change-prompt', nameChanged);
|
|
});
|
|
}
|
|
|
|
async function moveItem({item, from, to, oldIndex}: SortableEvent): Promise<void> {
|
|
const closestUl = to.nodeName.toLowerCase() === 'ul' ? to : to.closest('ul');
|
|
const sortable = Sortable.get(closestUl);
|
|
const isGroup = Boolean(item.getAttribute('data-is-group'));
|
|
const strs = sortable.toArray();
|
|
const newIndex = Math.max(1, strs.filter((a) => isGroup ?
|
|
a.toLocaleLowerCase().startsWith('group') :
|
|
a.toLocaleLowerCase().startsWith('repo')).indexOf(item.getAttribute('data-sort-id')) + 1);
|
|
const data = {
|
|
newParent: parseInt(to.closest('ul').closest('li')?.getAttribute('data-id') || '0'),
|
|
id: parseInt(item.getAttribute('data-id')),
|
|
newPos: newIndex,
|
|
isGroup,
|
|
};
|
|
try {
|
|
await POST(`${to.getAttribute('data-url')}/items/move`, {
|
|
data,
|
|
});
|
|
} catch (error) {
|
|
console.error(error);
|
|
from.insertBefore(item, from.children[oldIndex]);
|
|
}
|
|
}
|
|
|
|
function idSortFn(a: string, b: string): number {
|
|
return parseInt(a.split('-')[2]) - parseInt(b.split('-')[2]);
|
|
}
|
|
|
|
function onEnd(ev: SortableEvent) {
|
|
const {to} = ev;
|
|
const closestUl = to.nodeName.toLowerCase() === 'ul' ? to : (to.closest('li')?.closest('ul') ?? to.closest('ul'));
|
|
const sortable = Sortable.get(closestUl);
|
|
const strs = sortable.toArray();
|
|
const groups = strs.filter((a) => a.toLocaleLowerCase().startsWith('group'));
|
|
const repos = strs.filter((a) => a.toLocaleLowerCase().startsWith('repo'));
|
|
const newArr = [...groups.toSorted(idSortFn), ...repos.toSorted(idSortFn)];
|
|
sortable.sort(newArr, true);
|
|
moveItem(ev);
|
|
}
|
|
|
|
const baseSortableOptions: SortableOptions = {
|
|
group: {
|
|
name: 'group',
|
|
put(to, from, drag, ev) {
|
|
console.debug('to', to);
|
|
console.debug('from', from);
|
|
console.debug('drag', drag);
|
|
console.debug('ev', ev);
|
|
const closestUl = to.el.nodeName.toLowerCase() === 'ul' ? to.el : to.el.closest('ul');
|
|
console.debug('put this');
|
|
return Boolean(closestUl?.getAttribute('data-is-group') ?? true);
|
|
},
|
|
pull: true,
|
|
},
|
|
dataIdAttr: 'data-sort-id',
|
|
draggable: '.expandable-menu-item',
|
|
delayOnTouchOnly: true,
|
|
delay: 500,
|
|
// onMove: beforeMove,
|
|
onEnd,
|
|
emptyInsertThreshold: 25,
|
|
};
|
|
|
|
function initSubgroupSortable(list: Element) {
|
|
createSortable(list, {...baseSortableOptions});
|
|
for (const el of list.querySelectorAll('.expandable-menu-item')) {
|
|
if (!el.getAttribute('data-is-group')) continue;
|
|
const sublist = el.querySelector('ul');
|
|
initSubgroupSortable(sublist);
|
|
}
|
|
}
|
|
|
|
async function initGroupSortable(parentEl: Element): Promise<void> {
|
|
initSubgroupSortable(parentEl);
|
|
}
|
|
|
|
export function initGroup(): void {
|
|
const mainContainer = document.querySelector('#group-navigation-menu > .sortable');
|
|
if (!mainContainer) return;
|
|
initGroupSortable(mainContainer);
|
|
}
|