diff --git a/collections/documents/images/new-file.md b/collections/documents/images/new-file.md new file mode 100644 index 0000000..09f37b3 --- /dev/null +++ b/collections/documents/images/new-file.md @@ -0,0 +1,2 @@ +# New File + diff --git a/static/js/file-tree-actions.js b/static/js/file-tree-actions.js index 018c6d7..ab21030 100644 --- a/static/js/file-tree-actions.js +++ b/static/js/file-tree-actions.js @@ -33,42 +33,45 @@ class FileTreeActions { } }, - newFile: async function(path, isDir) { + 'new-file': async function(path, isDir) { if (!isDir) return; - const filename = await this.showInputDialog('Enter filename:', 'new-file.md'); - if (filename) { - const fullPath = `${path}/${filename}`.replace(/\/+/g, '/'); - await this.webdavClient.put(fullPath, '# New File\n\n'); - await this.fileTree.load(); - showNotification(`Created ${filename}`, 'success'); - } + await this.showInputDialog('Enter filename:', 'new-file.md', async (filename) => { + if (filename) { + const fullPath = `${path}/${filename}`.replace(/\/+/g, '/'); + await this.webdavClient.put(fullPath, '# New File\n\n'); + await this.fileTree.load(); + showNotification(`Created ${filename}`, 'success'); + await this.editor.loadFile(fullPath); + } + }); }, - newFolder: async function(path, isDir) { + 'new-folder': async function(path, isDir) { if (!isDir) return; - const foldername = await this.showInputDialog('Enter folder name:', 'new-folder'); - if (foldername) { - const fullPath = `${path}/${foldername}`.replace(/\/+/g, '/'); - await this.webdavClient.mkcol(fullPath); - await this.fileTree.load(); - showNotification(`Created folder ${foldername}`, 'success'); - } + await this.showInputDialog('Enter folder name:', 'new-folder', async (foldername) => { + if (foldername) { + const fullPath = `${path}/${foldername}`.replace(/\/+/g, '/'); + await this.webdavClient.mkcol(fullPath); + await this.fileTree.load(); + showNotification(`Created folder ${foldername}`, 'success'); + } + }); }, rename: async function(path, isDir) { const oldName = path.split('/').pop(); - const newName = await this.showInputDialog('Rename to:', oldName); - - if (newName && newName !== oldName) { - const parentPath = path.substring(0, path.lastIndexOf('/')); + await this.showInputDialog('Rename to:', oldName, async (newName) => { + if (newName && newName !== oldName) { + const parentPath = path.substring(0, path.lastIndexOf('/')); const newPath = parentPath ? `${parentPath}/${newName}` : newName; - await this.webdavClient.move(path, newPath); - await this.fileTree.load(); - showNotification('Renamed', 'success'); - } + await this.webdavClient.move(path, newPath); + await this.fileTree.load(); + showNotification('Renamed', 'success'); + } + }); }, copy: async function(path, isDir) { @@ -143,34 +146,47 @@ class FileTreeActions { }; // Modern dialog implementations - async showInputDialog(title, placeholder = '') { + async showInputDialog(title, placeholder = '', onConfirm) { return new Promise((resolve) => { const dialog = this.createInputDialog(title, placeholder); const input = dialog.querySelector('input'); const confirmBtn = dialog.querySelector('.btn-primary'); const cancelBtn = dialog.querySelector('.btn-secondary'); - + const closeBtn = dialog.querySelector('.btn-close'); + const cleanup = () => { dialog.remove(); - document.querySelector('.modal-backdrop').remove(); + const backdrop = document.querySelector('.modal-backdrop'); + if (backdrop) { + backdrop.remove(); + } document.body.classList.remove('modal-open'); + resolve(); }; - - confirmBtn.onclick = () => { - resolve(input.value.trim()); + + confirmBtn.onclick = async () => { + await onConfirm(input.value.trim()); cleanup(); }; - + cancelBtn.onclick = () => { - resolve(null); cleanup(); }; - - input.onkeypress = (e) => { - if (e.key === 'Enter') confirmBtn.click(); - if (e.key === 'Escape') cancelBtn.click(); + + closeBtn.onclick = () => { + cleanup(); }; - + + input.onkeypress = (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + confirmBtn.click(); + } + if (e.key === 'Escape') { + cancelBtn.click(); + } + }; + document.body.appendChild(dialog); document.body.classList.add('modal-open'); input.focus(); @@ -183,6 +199,7 @@ class FileTreeActions { const dialog = this.createConfirmDialog(title, message); const confirmBtn = dialog.querySelector('.btn-danger'); const cancelBtn = dialog.querySelector('.btn-secondary'); + const closeBtn = dialog.querySelector('.btn-close'); const cleanup = () => { dialog.remove(); @@ -199,6 +216,11 @@ class FileTreeActions { resolve(false); cleanup(); }; + + closeBtn.onclick = () => { + resolve(false); + cleanup(); + }; document.body.appendChild(dialog); document.body.classList.add('modal-open');