2023-03-24 10:57:32 +01:00
import BasicWidget from "../basic_widget.js" ;
2023-03-30 23:48:26 +02:00
import server from "../../services/server.js" ;
2023-04-01 13:58:53 +02:00
import dialogService from "../../services/dialog.js" ;
2023-04-01 23:55:04 +02:00
import toastService from "../../services/toast.js" ;
import ws from "../../services/ws.js" ;
import appContext from "../../components/app_context.js" ;
2023-05-03 10:23:20 +02:00
import openService from "../../services/open.js" ;
2023-03-24 10:57:32 +01:00
const TPL = `
< div class = "dropdown attachment-actions" >
< style >
. attachment - actions {
width : 35 px ;
height : 35 px ;
}
. attachment - actions . dropdown - menu {
2023-04-01 23:55:04 +02:00
width : 20 em ;
2023-03-24 10:57:32 +01:00
}
. attachment - actions . dropdown - item [ disabled ] , . attachment - actions . dropdown - item [ disabled ] : hover {
color : var ( -- muted - text - color ) ! important ;
background - color : transparent ! important ;
pointer - events : none ; /* makes it unclickable */
}
< / s t y l e >
< button type = "button" data - toggle = "dropdown" aria - haspopup = "true"
aria - expanded = "false" class = "icon-action icon-action-always-border bx bx-dots-vertical-rounded" > < / b u t t o n >
< div class = "dropdown-menu dropdown-menu-right" >
2023-05-07 10:43:51 +02:00
< a data - trigger - command = "openAttachment" class = "dropdown-item"
title = "File will be open in an external application and watched for changes. You'll then be able to upload the modified version back to Trilium." > Open externally < / a >
2023-05-03 10:23:20 +02:00
< a data - trigger - command = "downloadAttachment" class = "dropdown-item" > Download < / a >
< a data - trigger - command = "uploadNewAttachmentRevision" class = "dropdown-item" > Upload new revision < / a >
< a data - trigger - command = "copyAttachmentReferenceToClipboard" class = "dropdown-item" > Copy reference to clipboard < / a >
2023-04-01 23:55:04 +02:00
< a data - trigger - command = "convertAttachmentIntoNote" class = "dropdown-item" > Convert attachment into note < / a >
2023-05-03 10:23:20 +02:00
< a data - trigger - command = "deleteAttachment" class = "dropdown-item" > Delete attachment < / a >
2023-03-24 10:57:32 +01:00
< / d i v >
2023-05-03 22:49:24 +02:00
< input type = "file" class = "attachment-upload-new-revision-input" style = "display: none" >
2023-03-24 10:57:32 +01:00
< / d i v > ` ;
export default class AttachmentActionsWidget extends BasicWidget {
2023-05-07 10:43:51 +02:00
constructor ( attachment , isFullDetail ) {
2023-03-24 10:57:32 +01:00
super ( ) ;
this . attachment = attachment ;
2023-05-07 10:43:51 +02:00
this . isFullDetail = isFullDetail ;
2023-03-24 10:57:32 +01:00
}
2023-05-03 10:23:20 +02:00
get attachmentId ( ) {
return this . attachment . attachmentId ;
}
2023-03-24 10:57:32 +01:00
doRender ( ) {
this . $widget = $ ( TPL ) ;
2023-04-01 13:58:53 +02:00
this . $widget . on ( 'click' , '.dropdown-item' , ( ) => this . $widget . find ( "[data-toggle='dropdown']" ) . dropdown ( 'toggle' ) ) ;
2023-05-03 10:23:20 +02:00
this . $widget . find ( "[data-trigger-command='copyAttachmentReferenceToClipboard']" ) . toggle ( this . attachment . role === 'image' ) ;
2023-05-03 22:49:24 +02:00
this . $uploadNewRevisionInput = this . $widget . find ( ".attachment-upload-new-revision-input" ) ;
this . $uploadNewRevisionInput . on ( 'change' , async ( ) => {
const fileToUpload = this . $uploadNewRevisionInput [ 0 ] . files [ 0 ] ; // copy to allow reset below
this . $uploadNewRevisionInput . val ( '' ) ;
const formData = new FormData ( ) ;
formData . append ( 'upload' , fileToUpload ) ;
const result = await $ . ajax ( {
url : ` ${ window . glob . baseApiUrl } attachments/ ${ this . attachmentId } /file ` ,
headers : await server . getHeaders ( ) ,
data : formData ,
type : 'PUT' ,
timeout : 60 * 60 * 1000 ,
contentType : false , // NEEDED, DON'T REMOVE THIS
processData : false , // NEEDED, DON'T REMOVE THIS
} ) ;
if ( result . uploaded ) {
toastService . showMessage ( "New attachment revision has been uploaded." ) ;
} else {
toastService . showError ( "Upload of a new attachment revision failed." ) ;
}
} ) ;
2023-05-07 10:43:51 +02:00
if ( ! this . isFullDetail ) {
// we deactivate this button because the WatchedFileUpdateStatusWidget assumes only one visible attachment
// in a note context, so it doesn't work in a list
const $openAttachmentButton = this . $widget . find ( "[data-trigger-command='openAttachment']" ) ;
$openAttachmentButton
. addClass ( "disabled" )
. append ( $ ( '<span class="disabled-tooltip"> (?)</span>' )
. attr ( "title" , "Opening attachment externally is available only from the detail page, please first click on the attachment detail first and repeat the action." )
) ;
}
2023-05-03 10:23:20 +02:00
}
async openAttachmentCommand ( ) {
await openService . openAttachmentExternally ( this . attachmentId , this . attachment . mime ) ;
}
async downloadAttachmentCommand ( ) {
await openService . downloadAttachment ( this . attachmentId ) ;
}
2023-05-03 22:49:24 +02:00
async uploadNewAttachmentRevisionCommand ( ) {
this . $uploadNewRevisionInput . trigger ( 'click' ) ;
}
2023-05-03 10:23:20 +02:00
async copyAttachmentReferenceToClipboardCommand ( ) {
this . parent . copyAttachmentReferenceToClipboard ( ) ;
}
2023-03-30 23:48:26 +02:00
async deleteAttachmentCommand ( ) {
2023-05-02 22:46:39 +02:00
if ( ! await dialogService . confirm ( ` Are you sure you want to delete attachment ' ${ this . attachment . title } '? ` ) ) {
return ;
2023-04-01 23:55:04 +02:00
}
2023-05-02 22:46:39 +02:00
2023-05-03 10:23:20 +02:00
await server . remove ( ` attachments/ ${ this . attachmentId } ` ) ;
2023-05-02 22:46:39 +02:00
toastService . showMessage ( ` Attachment ' ${ this . attachment . title } ' has been deleted. ` ) ;
2023-04-01 23:55:04 +02:00
}
async convertAttachmentIntoNoteCommand ( ) {
2023-05-02 22:46:39 +02:00
if ( ! await dialogService . confirm ( ` Are you sure you want to convert attachment ' ${ this . attachment . title } ' into a separate note? ` ) ) {
return ;
2023-04-01 13:58:53 +02:00
}
2023-05-02 22:46:39 +02:00
2023-05-03 10:23:20 +02:00
const { note : newNote } = await server . post ( ` attachments/ ${ this . attachmentId } /convert-to-note ` )
2023-05-02 22:46:39 +02:00
toastService . showMessage ( ` Attachment ' ${ this . attachment . title } ' has been converted to note. ` ) ;
await ws . waitForMaxKnownEntityChangeId ( ) ;
await appContext . tabManager . getActiveContext ( ) . setNote ( newNote . noteId ) ;
2023-03-24 10:57:32 +01:00
}
}