新的樹狀管理器
This commit is contained in:
@@ -340,6 +340,24 @@
|
||||
const tree = await res.json();
|
||||
const container = document.getElementById('pagesTree');
|
||||
container.innerHTML = '';
|
||||
container.addEventListener('dragover', e => {
|
||||
e.preventDefault();
|
||||
e.dataTransfer.dropEffect = 'move';
|
||||
});
|
||||
container.addEventListener('drop', e => {
|
||||
e.preventDefault();
|
||||
const nameEnc = e.dataTransfer.getData('text/name');
|
||||
if (!nameEnc) return;
|
||||
const name = decodeURIComponent(nameEnc);
|
||||
const src = container.querySelector(`[data-name='${CSS.escape(name)}']`);
|
||||
if (!src) return;
|
||||
let rootUl = container.querySelector(':scope > ul');
|
||||
if (!rootUl) {
|
||||
rootUl = document.createElement('ul');
|
||||
container.appendChild(rootUl);
|
||||
}
|
||||
rootUl.appendChild(src);
|
||||
});
|
||||
|
||||
function createLi(item) {
|
||||
const li = document.createElement('li');
|
||||
@@ -347,6 +365,9 @@
|
||||
li.draggable = true;
|
||||
li.dataset.type = item.type || 'file';
|
||||
li.dataset.name = item.name || item.title || '';
|
||||
li.dataset.showInNav = item.show_in_nav !== false ? 'true' : 'false';
|
||||
li.dataset.isHomepage = item.is_homepage ? 'true' : 'false';
|
||||
li.dataset.requiresPassword = item.requires_password ? 'true' : 'false';
|
||||
|
||||
const titleWrap = document.createElement('span');
|
||||
titleWrap.className = 'tree-title';
|
||||
@@ -356,7 +377,56 @@
|
||||
btns.className = 'tree-item-actions';
|
||||
btns.innerHTML = "<button class='btn btn-ghost btn-sm btn-toggle' title='展開/收合'>▼</button>";
|
||||
|
||||
const meta = document.createElement('span');
|
||||
meta.className = 'tree-item-meta';
|
||||
meta.innerHTML = `
|
||||
<button class='btn btn-ghost btn-sm btn-nav' title='顯示於導覽列'>☰</button>
|
||||
<button class='btn btn-ghost btn-sm btn-homepage' title='設為首頁'>⭐</button>
|
||||
<button class='btn btn-ghost btn-sm btn-password' title='需要密碼'>🔒</button>
|
||||
`;
|
||||
|
||||
const btnNav = meta.querySelector('.btn-nav');
|
||||
const btnHome = meta.querySelector('.btn-homepage');
|
||||
const btnPassword = meta.querySelector('.btn-password');
|
||||
|
||||
const updateMetaState = () => {
|
||||
const showNav = li.dataset.showInNav === 'true';
|
||||
const isHomepage = li.dataset.isHomepage === 'true';
|
||||
const requiresPassword = li.dataset.requiresPassword === 'true';
|
||||
btnNav.classList.toggle('active', showNav);
|
||||
btnNav.title = showNav ? '顯示於導覽列' : '從導覽列隱藏';
|
||||
btnHome.classList.toggle('active', isHomepage);
|
||||
btnHome.title = isHomepage ? '首頁' : '設為首頁';
|
||||
btnPassword.classList.toggle('active', requiresPassword);
|
||||
btnPassword.title = requiresPassword ? '需要密碼' : '不需要密碼';
|
||||
if (li.dataset.type !== 'file') {
|
||||
btnHome.disabled = true;
|
||||
btnHome.title = '僅限單一頁面';
|
||||
}
|
||||
};
|
||||
|
||||
updateMetaState();
|
||||
|
||||
btnNav.addEventListener('click', () => {
|
||||
li.dataset.showInNav = li.dataset.showInNav === 'true' ? 'false' : 'true';
|
||||
updateMetaState();
|
||||
});
|
||||
btnPassword.addEventListener('click', () => {
|
||||
li.dataset.requiresPassword = li.dataset.requiresPassword === 'true' ? 'false' : 'true';
|
||||
updateMetaState();
|
||||
});
|
||||
btnHome.addEventListener('click', () => {
|
||||
if (li.dataset.type !== 'file') return;
|
||||
container.querySelectorAll('.tree-item').forEach(other => {
|
||||
other.dataset.isHomepage = 'false';
|
||||
});
|
||||
container.querySelectorAll('.btn-homepage').forEach(button => button.classList.remove('active'));
|
||||
li.dataset.isHomepage = 'true';
|
||||
updateMetaState();
|
||||
});
|
||||
|
||||
li.appendChild(titleWrap);
|
||||
li.appendChild(meta);
|
||||
li.appendChild(btns);
|
||||
|
||||
if (item.children && item.children.length) {
|
||||
@@ -374,6 +444,7 @@
|
||||
li.addEventListener('dragleave', () => { li.classList.remove('tree-drop-hover'); });
|
||||
li.addEventListener('drop', e => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
li.classList.remove('tree-drop-hover');
|
||||
const nameEnc = e.dataTransfer.getData('text/name');
|
||||
if (!nameEnc) return;
|
||||
@@ -422,7 +493,14 @@
|
||||
const title = li.querySelector('.tree-title')?.textContent || '';
|
||||
const name = li.dataset.name || '';
|
||||
const type = li.dataset.type || 'file';
|
||||
const obj = { name, title, type };
|
||||
const obj = {
|
||||
name,
|
||||
title,
|
||||
type,
|
||||
show_in_nav: li.dataset.showInNav === 'true',
|
||||
is_homepage: li.dataset.isHomepage === 'true',
|
||||
requires_password: li.dataset.requiresPassword === 'true',
|
||||
};
|
||||
const childUl = li.querySelector(':scope > ul');
|
||||
if (childUl) obj.children = walk(childUl);
|
||||
arr.push(obj);
|
||||
|
||||
Reference in New Issue
Block a user