Add entries to Link To paste dialog

This commit is contained in:
nathan 2024-04-04 15:38:55 -06:00
parent 99c86d58bd
commit f7e352f541
2 changed files with 100 additions and 42 deletions

View File

@ -40,9 +40,9 @@ export class Et2LinkPasteDialog extends Et2VfsSelectDialog
this.handleFileClick(event); this.handleFileClick(event);
} }
protected localSearch<DataType extends SearchResult>(search : string, searchOptions : object, localOptions : DataType[] = []) : Promise<DataType[]> protected async localSearch<DataType extends SearchResult>(search : string, searchOptions : object, localOptions : DataType[] = []) : Promise<DataType[]>
{ {
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) // We don't care if they're directories, treat them all as files (no double click, all selectable)
files.forEach(f => f.isDir = false); files.forEach(f => f.isDir = false);
@ -66,7 +66,7 @@ export class Et2LinkPasteDialog extends Et2VfsSelectDialog
* *
* @return {string[]} Paths * @return {string[]} Paths
*/ */
export function getClipboardFiles() export async function getClipboardFiles()
{ {
let clipboard_files = []; let clipboard_files = [];
if(typeof window.egw.getSessionItem('phpgwapi', 'egw_clipboard') != 'undefined') if(typeof window.egw.getSessionItem('phpgwapi', 'egw_clipboard') != 'undefined')
@ -75,23 +75,36 @@ export function getClipboardFiles()
type: [], type: [],
selected: [] 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('::'); const data = clipboard.selected[i].data ?? {};
if(split.shift() == 'filemanager') clipboard_files.push({
{ value: clipboard.selected[i].id,
const data = clipboard.selected[i].data ?? {}; app: app,
clipboard_files.push({ id: split.join("::"),
value: split.join("::"), name: data.name ?? clipboard.selected[i].id,
name: data.name ?? clipboard.selected[i].id, mime: data.mime,
mime: data.mime, isDir: data.is_dir ?? false,
isDir: data.is_dir ?? false, path: data.path ?? split.join("::"),
path: data.path ?? split.join("::"), downloadUrl: data.download_url
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
});
} }
} }
} }

View File

@ -25,6 +25,7 @@ import {ManualMessage} from "../Validators/ManualMessage";
import {Et2Tabs} from "../Layout/Et2Tabs/Et2Tabs"; import {Et2Tabs} from "../Layout/Et2Tabs/Et2Tabs";
import {Et2VfsSelectButton} from "../Et2Vfs/Et2VfsSelectButton"; import {Et2VfsSelectButton} from "../Et2Vfs/Et2VfsSelectButton";
import {Et2LinkPasteDialog, getClipboardFiles} from "./Et2LinkPasteDialog"; 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. * 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() constructor()
{ {
super(); super();
@ -168,32 +173,39 @@ export class Et2LinkTo extends Et2InputWidget(ScopedElementsMixin(FormControlMix
<et2-button slot="footer" image="move" id="move" style="order:3" noSubmit="true" <et2-button slot="footer" image="move" id="move" style="order:3" noSubmit="true"
label=${this.egw().lang("move")}></et2-button> label=${this.egw().lang("move")}></et2-button>
</et2-vfs-select> </et2-vfs-select>
<et2-vfs-select image="linkpaste" aria-label=${this.egw().lang("clipboard contents")} noSubmit="true" <et2-vfs-select
title=${this.egw().lang("Clipboard contents")} id="paste"
?readonly=${this.readonly} image="linkpaste" aria-label=${this.egw().lang("clipboard contents")} noSubmit="true"
?disabled=${!pasteEnabled} title=${this.egw().lang("Clipboard contents")}
method=${method || nothing} ?readonly=${this.readonly}
method-id=${method_id || nothing} ?disabled=${!pasteEnabled}
multiple multiple
@click=${(e) => @click=${async(e) =>
{ {
// Pre-select all files // Pre-select all files
let 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.value = files;
e.target.firstElementChild.requestUpdate(); e.target.firstElementChild.requestUpdate();
waitForEvent(e.target._dialog, "sl-after-show").then(async() =>
{
this.handleVfsSelected(await this.pasteButton._dialog.getComplete());
});
}} }}
.onchange=${this.handleVfsSelected}
> >
<et2-link-paste-dialog open <et2-link-paste-dialog open
title=${this.egw().lang("Clipboard contents")} title=${this.egw().lang("Clipboard contents")}
.buttonLabel=${this.egw().lang("link")} .buttonLabel=${this.egw().lang("link")}
> >
<et2-button slot="footer" image="copy" id="copy" style="order:3" noSubmit="true" <et2-button slot="footer" image="copy" id="copy" style="order:3" noSubmit="true"
?disabled=${!this.value?.to_id}
label=${this.egw().lang("copy")} label=${this.egw().lang("copy")}
title=${this.egw().lang("Copy selected files")} title=${this.egw().lang("Copy selected files")}
></et2-button> ></et2-button>
<et2-button slot="footer" image="move" id="move" style="order:3" noSubmit="true" <et2-button slot="footer" image="move" id="move" style="order:3" noSubmit="true"
?disabled=${!this.value?.to_id}
label=${this.egw().lang("move")} label=${this.egw().lang("move")}
title=${this.egw().lang("Move selected files")} title=${this.egw().lang("Move selected files")}
></et2-button> ></et2-button>
@ -496,29 +508,62 @@ export class Et2LinkTo extends Et2InputWidget(ScopedElementsMixin(FormControlMix
this._link_result(values); this._link_result(values);
} }
handleVfsSelected(event, select : Et2VfsSelectButton) handleVfsSelected([button, selected])
{ {
if(!button || !selected?.length)
{
return;
}
let values = true; let values = true;
// If entry not yet saved, store for linking on server // If entry not yet saved, store for linking on server
if(!this.value.to_id || typeof this.value.to_id == 'object') if(!this.value.to_id || typeof this.value.to_id == 'object')
{ {
values = this.value.to_id || {}; values = this.value.to_id || {};
const files = select.value; for(let i = 0; i < selected.length; i++)
if(typeof files !== 'undefined')
{ {
for(var i = 0; i < files.length; i++) const info = this.pasteDialog.fileInfo(selected[i]);
{ values['link:' + selected[i]] = {
values['link:' + files[i]] = { app: info?.app == "filemanager" ? "link" : info?.app,
app: 'link', id: info?.app == "filemanager" ? selected[i] : info?.id,
id: files[i], type: 'unknown',
type: 'unknown', icon: 'link',
icon: 'link', remark: '',
remark: '', title: selected[i]
title: files[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); this._link_result(values);
} }