From f7e352f5412563ad5572f4c7aec0e4b37272fd0d Mon Sep 17 00:00:00 2001 From: nathan Date: Thu, 4 Apr 2024 15:38:55 -0600 Subject: [PATCH] Add entries to Link To paste dialog --- .../etemplate/Et2Link/Et2LinkPasteDialog.ts | 49 ++++++---- api/js/etemplate/Et2Link/Et2LinkTo.ts | 93 ++++++++++++++----- 2 files changed, 100 insertions(+), 42 deletions(-) diff --git a/api/js/etemplate/Et2Link/Et2LinkPasteDialog.ts b/api/js/etemplate/Et2Link/Et2LinkPasteDialog.ts index 70f6707cbd..bd7aa1fa55 100644 --- a/api/js/etemplate/Et2Link/Et2LinkPasteDialog.ts +++ b/api/js/etemplate/Et2Link/Et2LinkPasteDialog.ts @@ -40,9 +40,9 @@ export class Et2LinkPasteDialog extends Et2VfsSelectDialog this.handleFileClick(event); } - protected localSearch(search : string, searchOptions : object, localOptions : DataType[] = []) : Promise + protected async localSearch(search : string, searchOptions : object, localOptions : DataType[] = []) : Promise { - const files = getClipboardFiles(); + const files = await getClipboardFiles(); // We don't care if they're directories, treat them all as files (no double click, all selectable) files.forEach(f => f.isDir = false); @@ -66,7 +66,7 @@ export class Et2LinkPasteDialog extends Et2VfsSelectDialog * * @return {string[]} Paths */ -export function getClipboardFiles() +export async function getClipboardFiles() { let clipboard_files = []; if(typeof window.egw.getSessionItem('phpgwapi', 'egw_clipboard') != 'undefined') @@ -75,23 +75,36 @@ export function getClipboardFiles() type: [], selected: [] }; - if(clipboard.type.indexOf('file') >= 0) + for(let i = 0; i < clipboard.selected.length; i++) { - for(let i = 0; i < clipboard.selected.length; i++) + let split = clipboard.selected[i].id.split('::'); + const app = split.shift(); + if(app == 'filemanager') { - let split = clipboard.selected[i].id.split('::'); - if(split.shift() == 'filemanager') - { - const data = clipboard.selected[i].data ?? {}; - clipboard_files.push({ - value: split.join("::"), - name: data.name ?? clipboard.selected[i].id, - mime: data.mime, - isDir: data.is_dir ?? false, - path: data.path ?? split.join("::"), - downloadUrl: data.download_url - }); - } + const data = clipboard.selected[i].data ?? {}; + clipboard_files.push({ + value: clipboard.selected[i].id, + app: app, + id: split.join("::"), + name: data.name ?? clipboard.selected[i].id, + mime: data.mime, + isDir: data.is_dir ?? false, + path: data.path ?? split.join("::"), + downloadUrl: data.download_url + }); + } + else + { + clipboard_files.push({ + value: clipboard.selected[i].id, + app: app, + id: split.join("::"), + path: clipboard.selected[i].id, + name: await window.egw().link_title(app, split.join("::"), true), + mime: `egroupware/${app}`, + icon: window.egw().image("navbar", app), + symlink: true + }); } } } diff --git a/api/js/etemplate/Et2Link/Et2LinkTo.ts b/api/js/etemplate/Et2Link/Et2LinkTo.ts index c4a3b4b3c6..188636bb98 100644 --- a/api/js/etemplate/Et2Link/Et2LinkTo.ts +++ b/api/js/etemplate/Et2Link/Et2LinkTo.ts @@ -25,6 +25,7 @@ import {ManualMessage} from "../Validators/ManualMessage"; import {Et2Tabs} from "../Layout/Et2Tabs/Et2Tabs"; import {Et2VfsSelectButton} from "../Et2Vfs/Et2VfsSelectButton"; import {Et2LinkPasteDialog, getClipboardFiles} from "./Et2LinkPasteDialog"; +import {waitForEvent} from "../Et2Widget/event"; /** * Choose an existing entry, VFS file or local file, and link it to the current entry. @@ -102,6 +103,10 @@ export class Et2LinkTo extends Et2InputWidget(ScopedElementsMixin(FormControlMix }; } + private get pasteButton() { return this.shadowRoot?.querySelector("#paste"); } + + private get pasteDialog() { return this.pasteButton?.querySelector("et2-link-paste-dialog"); } + constructor() { super(); @@ -168,32 +173,39 @@ export class Et2LinkTo extends Et2InputWidget(ScopedElementsMixin(FormControlMix - + { // Pre-select all files let files = []; - getClipboardFiles().forEach(f => files.push(f.value)); + let cbFiles = await getClipboardFiles(); + cbFiles.forEach(f => files.push(f.path)); e.target.firstElementChild.value = files; e.target.firstElementChild.requestUpdate(); + + waitForEvent(e.target._dialog, "sl-after-show").then(async() => + { + this.handleVfsSelected(await this.pasteButton._dialog.getComplete()); + }); }} - .onchange=${this.handleVfsSelected} > @@ -496,29 +508,62 @@ export class Et2LinkTo extends Et2InputWidget(ScopedElementsMixin(FormControlMix this._link_result(values); } - handleVfsSelected(event, select : Et2VfsSelectButton) + handleVfsSelected([button, selected]) { + if(!button || !selected?.length) + { + return; + } let values = true; // If entry not yet saved, store for linking on server if(!this.value.to_id || typeof this.value.to_id == 'object') { values = this.value.to_id || {}; - const files = select.value; - if(typeof files !== 'undefined') + for(let i = 0; i < selected.length; i++) { - for(var i = 0; i < files.length; i++) - { - values['link:' + files[i]] = { - app: 'link', - id: files[i], - type: 'unknown', - icon: 'link', - remark: '', - title: files[i] - }; - } + const info = this.pasteDialog.fileInfo(selected[i]); + values['link:' + selected[i]] = { + app: info?.app == "filemanager" ? "link" : info?.app, + id: info?.app == "filemanager" ? selected[i] : info?.id, + type: 'unknown', + icon: 'link', + remark: '', + title: selected[i] + }; } } + else + { + // Send to server to link + const files = []; + const links = []; + selected.forEach(id => + { + const info = this.pasteDialog.fileInfo(id); + switch(info?.app) + { + case "filemanager": + files.push(id); + break; + default: + links.push({app: info.app, id: info.id}); + } + }); + if(files.length > 0) + { + const file_method = 'EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link_existing'; + const methodId = this.value.to_app + ':' + this.value.to_id; + this.egw().request( + file_method, + [methodId, files, button] + ); + } + if(links.length > 0) + { + this.createLink(links); + } + } + this.pasteButton.value = []; this._link_result(values); }