756 lines
25 KiB
JavaScript
756 lines
25 KiB
JavaScript
var D4S_STORAGE_SCRIPT = document.currentScript
|
|
|
|
/**
|
|
* Base class of <d4s-storage-tree> and <d4s-storage-folder>
|
|
*/
|
|
class D4SStorageHtmlElement extends HTMLElement {
|
|
|
|
#d4smissmsg = 'Required d4s-boot-2 component not found'
|
|
#baseurl = 'https://api.d4science.org/workspace'
|
|
//#baseurl = 'https://workspace-repository.dev.d4science.org/storagehub/workspace'
|
|
#boot = null
|
|
#d4sworkspace = null;
|
|
#showroot = false; // To show WS root folder by default set it to true
|
|
|
|
constructor() {
|
|
super()
|
|
this.#boot = document.querySelector('d4s-boot-2')
|
|
this.#d4sworkspace = new D4SWorkspace(this.#baseurl, this.#boot)
|
|
}
|
|
|
|
get boot() {
|
|
if (this.#boot == null) {
|
|
this.#boot = document.querySelector('d4s-boot-2')
|
|
if (!this.#boot) {
|
|
throw this.#d4smissmsg
|
|
}
|
|
}
|
|
return this.#boot
|
|
}
|
|
|
|
appendStylesheets(root) {
|
|
const linkElem1 = document.createElement('link')
|
|
linkElem1.setAttribute('rel', 'stylesheet')
|
|
linkElem1.setAttribute('href', 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css')
|
|
root.appendChild(linkElem1)
|
|
}
|
|
|
|
buildListUrl(id) {
|
|
return this.#baseurl + '/items/' + id + '/children'
|
|
}
|
|
|
|
get baseUrl() {
|
|
return this.#baseurl
|
|
}
|
|
|
|
set baseUrl(url) {
|
|
this.#baseurl = url
|
|
this.setAttribute("baseurl", url)
|
|
this.#d4sworkspace = new D4SWorkspace(this.#baseurl, this.#boot)
|
|
}
|
|
|
|
get d4sWorkspace() {
|
|
return this.#d4sworkspace;
|
|
}
|
|
|
|
get showRoot() {
|
|
return this.#showroot;
|
|
}
|
|
|
|
set showRoot(show) {
|
|
this.#showroot = show;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* Builds storagehub VREFolder tree
|
|
* <d4s-storage-tree
|
|
* /@filelist-id: identifier of d4s-storage-folder component
|
|
* /@base-url: the base endpoint url [defaults to: https://api.d4science.org/workspace]
|
|
* /@show-root: false (or omitted) to show the VRE folder (default), true to show the root folder of the WS
|
|
*/
|
|
window.customElements.define('d4s-storage-tree', class extends D4SStorageHtmlElement {
|
|
|
|
#storageFilelistId = null
|
|
|
|
#loadedClass = 'loaded'
|
|
#selectedClass = 'selected'
|
|
#selectedbgcolor = 'lightgray'
|
|
#shadowRoot
|
|
|
|
constructor() {
|
|
super()
|
|
this.#shadowRoot = this.attachShadow({mode: 'open'})
|
|
}
|
|
|
|
/*
|
|
Notes:
|
|
API docs: https://gcube.wiki.gcube-system.org/gcube/StorageHub_REST_API
|
|
Preprod: https://accounts.pre.d4science.org
|
|
Sample context: %2Fpred4s%2Fpreprod%2FpreVRE
|
|
User workspace: https://storagehub.pre.d4science.net/storagehub/workspace
|
|
vrefolder: https://storagehub.pre.d4science.net/storagehub/workspace/vrefolder
|
|
-> and if "id": "e0cd15d2-0071-43ca-bc42-aef8d80660fe",
|
|
the tree dir of vrefolder: https://storagehub.pre.d4science.net/storagehub/workspace/items/e0cd15d2-0071-43ca-bc42-aef8d80660fe/children
|
|
download of a file (domenica.jpg): https://storagehub.pre.d4science.net/storagehub/workspace/items/a5086811-59d1-4230-99fa-98431e820cf1/download
|
|
*/
|
|
connectedCallback() {
|
|
this.appendStylesheets(this.#shadowRoot)
|
|
|
|
var div = document.createElement('div')
|
|
const style = `
|
|
<style>
|
|
.selected > *:first-child {
|
|
background-color: ${this.#selectedbgcolor};
|
|
}
|
|
ul, li {
|
|
list-style-type: none;
|
|
}
|
|
li {
|
|
cursor: pointer;
|
|
}
|
|
</style>
|
|
`
|
|
div.innerHTML = style
|
|
|
|
const initalFolderFunction = (cond) => {if (cond) return this.d4sWorkspace.getWorkspace(); else return this.d4sWorkspace.getVREFolder();}
|
|
initalFolderFunction(this.showRoot).then(data => {
|
|
this.parseResponse(div, data);
|
|
this.#shadowRoot.appendChild(div);
|
|
}).catch(err => console.error(err))
|
|
}
|
|
|
|
parseResponse(parentElement, data) {
|
|
parentElement.classList.add(this.#loadedClass);
|
|
var ul = document.createElement('ul');
|
|
ul.classList.add('nested');
|
|
if (Array.isArray(data)) {
|
|
data
|
|
.filter(item => item['@class'].includes('FolderItem'))
|
|
.forEach(item => {
|
|
const itemName = item.name;
|
|
const itemId = item.id;
|
|
const path = this.buildListUrl(itemId);
|
|
ul.appendChild(this.createListItem(itemName, itemId));
|
|
})
|
|
parentElement.appendChild(ul);
|
|
} else {
|
|
const itemName = data.displayName ? data.displayName : data.name;
|
|
const itemId = data.id;
|
|
const path = this.buildListUrl(itemId);
|
|
ul.appendChild(this.createListItem(itemName, itemId));
|
|
parentElement.appendChild(ul);
|
|
}
|
|
}
|
|
|
|
createListItem(label, id) {
|
|
var li = document.createElement('li')
|
|
li.setAttribute('data-id', id)
|
|
var child = document.createElement('span')
|
|
child.innerHTML = label
|
|
li.appendChild(child)
|
|
|
|
li.addEventListener('click', (ev) => {
|
|
ev.stopPropagation()
|
|
this.select(ev.currentTarget.getAttribute('data-id'))
|
|
})
|
|
return li
|
|
}
|
|
|
|
select(id) {
|
|
var li = this.shadowRoot.querySelector(`*[data-id='${id}']`)
|
|
this.displayPath(li)
|
|
|
|
// if it was already selected then do nothing
|
|
if (li.classList.contains(this.#selectedClass)) {
|
|
this.toggleULDisplay(li)
|
|
return
|
|
}
|
|
// switch selected and lists folder contents
|
|
if (!li.classList.contains(this.#selectedClass)) {
|
|
const selected = this.shadowRoot.querySelector('.' + this.#selectedClass)
|
|
if (selected) {
|
|
selected.classList.remove(this.#selectedClass)
|
|
}
|
|
li.classList.add(this.#selectedClass)
|
|
if (this.#storageFilelistId) {
|
|
var folder = document.getElementById(this.#storageFilelistId)
|
|
folder.join(this)
|
|
folder.list(id)
|
|
}
|
|
}
|
|
if (li.classList.contains(this.#loadedClass)) {
|
|
return
|
|
}
|
|
|
|
this.d4sWorkspace.listFolder(id).then(data => {
|
|
this.parseResponse(li, data)
|
|
}).catch(err => console.error(err))
|
|
}
|
|
|
|
displayPath(li) {
|
|
var curr = li
|
|
while (curr.parentElement != null) {
|
|
if (curr.parentElement.tagName == 'UL') {
|
|
curr.parentElement.style.display = 'block'
|
|
}
|
|
curr = curr.parentElement
|
|
}
|
|
}
|
|
|
|
toggleULDisplay(li) {
|
|
const ul = li.querySelector('ul')
|
|
if (ul) {
|
|
ul.style.display = (ul.style.display === 'none') ? 'block' : 'none'
|
|
}
|
|
}
|
|
|
|
static get observedAttributes() {
|
|
return ["base-url", "filelist-id", "show-root"]
|
|
}
|
|
|
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
if (oldValue !== newValue) {
|
|
switch (name) {
|
|
case "filelist-id":
|
|
this.#storageFilelistId = newValue
|
|
break
|
|
case "base-url":
|
|
this.baseUrl = newValue
|
|
break
|
|
case "show-root":
|
|
this.showRoot = newValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
get filelistId() {
|
|
return this.#storageFilelistId
|
|
}
|
|
|
|
set filelistId(id) {
|
|
this.#storageFilelistId = id
|
|
this.setAttribute("filelist-id", id)
|
|
}
|
|
})
|
|
|
|
/**
|
|
* Lists elements in selected folder
|
|
*
|
|
* <d4s-storage-folder
|
|
* /@id: specify the id to join this component with storage tree component
|
|
* /@base-url: the base endpoint url [defaults to: https://api.d4science.org/workspace]
|
|
*/
|
|
window.customElements.define('d4s-storage-folder', class extends D4SStorageHtmlElement {
|
|
|
|
#d4sstorageTree = null
|
|
#selectedbgcolor = 'lightgray'
|
|
#srcbaseurl = null
|
|
|
|
constructor() {
|
|
super()
|
|
if (D4S_STORAGE_SCRIPT) {
|
|
const d4ssrc = D4S_STORAGE_SCRIPT.src
|
|
this.#srcbaseurl = (d4ssrc) ? d4ssrc.substring(0, d4ssrc.lastIndexOf('/')) : ""
|
|
}
|
|
}
|
|
|
|
connectedCallback() {
|
|
const shadowRoot = this.attachShadow({mode: 'open'})
|
|
this.appendStylesheets(shadowRoot)
|
|
const style = document.createElement('style')
|
|
style.innerHTML = `
|
|
span {
|
|
cursor: pointer;
|
|
user-select: none;
|
|
-moz-user-select: none;
|
|
-webkit-user-select: none;
|
|
-ms-user-select: none;
|
|
}
|
|
`
|
|
shadowRoot.appendChild(style)
|
|
this.createContainer()
|
|
}
|
|
|
|
createContainer() {
|
|
var div = document.createElement('div')
|
|
div.classList.add('d4s-folder')
|
|
var child = this.shadowRoot.querySelector('.d4s-folder')
|
|
if (child) {
|
|
this.shadowRoot.removeChild(child)
|
|
}
|
|
this.shadowRoot.appendChild(div)
|
|
return div
|
|
}
|
|
|
|
join(tree) {
|
|
if (this.#d4sstorageTree == null) {
|
|
this.#d4sstorageTree = tree
|
|
}
|
|
}
|
|
|
|
list(folderId) {
|
|
this.d4sWorkspace.listFolder(folderId).then(data => {
|
|
this.parseResponse(data);
|
|
}).catch(err => console.error(err));
|
|
}
|
|
|
|
parseResponse(data) {
|
|
const root = this.createContainer();
|
|
if (Array.isArray(data)) {
|
|
data.forEach(item => root.appendChild(this.createFileRow(item)));
|
|
} else {
|
|
console.error("Returned data is not an array: " + data);
|
|
}
|
|
}
|
|
|
|
createFileRow(item) {
|
|
var div = document.createElement('div')
|
|
div.classList.add('row')
|
|
var filename = document.createElement('div')
|
|
filename.classList.add('col')
|
|
var name = `<span>${item.name}</span>`
|
|
filename.innerHTML = this.iconTag(item) + name
|
|
const isFolder = item['@class'].includes('FolderItem')
|
|
filename.addEventListener('click', (ev) => {
|
|
ev.stopPropagation()
|
|
if (isFolder) {
|
|
const span = ev.currentTarget.querySelector(':nth-child(2)')
|
|
if (span) {
|
|
span.style = 'background-color: ' + this.#selectedbgcolor
|
|
}
|
|
if (this.#d4sstorageTree != null) {
|
|
this.#d4sstorageTree.select(item.id)
|
|
}
|
|
} else {
|
|
console.info("Download of " + item.id)
|
|
this.d4sWorkspace.download(item.id, item.name).catch(err => {alert(err)});
|
|
}
|
|
})
|
|
|
|
div.appendChild(filename)
|
|
return div
|
|
}
|
|
|
|
iconTag(item) {
|
|
var i = `<img src="${this.#srcbaseurl}/img/file-earmark.svg"></img>`
|
|
if (item['@class'].includes('FolderItem')) {
|
|
i = `<img src="${this.#srcbaseurl}/img/folder.svg"></img>`
|
|
} else if (item['@class'].includes('ImageFile')) {
|
|
i = `<img src="${this.#srcbaseurl}/img/image.svg"></img>`
|
|
} else if (item['@class'].includes('PDFFileItem')) {
|
|
i = `<img src="${this.#srcbaseurl}/img/filetype-pdf.svg"></img>`
|
|
}
|
|
return '<span class="px-2">' + i + '</span>'
|
|
}
|
|
|
|
// buildDownloadUrl(id) {
|
|
// return this.baseUrl+ '/items/' + id + '/download'
|
|
// }
|
|
|
|
// download(url, name) {
|
|
// this.d4sWorkspace.download(url).then(reply => {
|
|
// if (reply.status !== 200) {
|
|
// throw "Unable to download"
|
|
// }
|
|
// return reply.blob()
|
|
|
|
// }).then(blob => {
|
|
// const objectURL = URL.createObjectURL(blob)
|
|
// var tmplnk = document.createElement("a")
|
|
// tmplnk.download = name
|
|
// tmplnk.href = objectURL
|
|
// //tmplnk.target="_blank"
|
|
// document.body.appendChild(tmplnk)
|
|
// tmplnk.click()
|
|
// document.body.removeChild(tmplnk)
|
|
|
|
// }).catch(err => console.error(err))
|
|
// }
|
|
|
|
static get observedAttributes() {
|
|
return ["base-url"];
|
|
}
|
|
|
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
if (oldValue !== newValue) {
|
|
switch (name) {
|
|
case "base-url":
|
|
this.baseUrl = newValue
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
})
|
|
|
|
/**
|
|
* Class that helps the interaction with the D4Science's Workspace via API and user's token as bearer authentication
|
|
*/
|
|
class D4SWorkspace {
|
|
|
|
#d4sboot = null;
|
|
#workspaceURL = null;
|
|
|
|
/**
|
|
* Creates the new D4SWorkspace object, the d4sboot parameter can be null, in this case it is searched in the DOM document via <code>querySelector()</code> method
|
|
* @param {string} workspaceURL the WS API base URL
|
|
* @param {d4s-boot-2} d4sboot the d4s-boot-2 instance
|
|
*/
|
|
constructor(workspaceURL, d4sboot) {
|
|
this.setWorkspaceURL(workspaceURL)
|
|
if (d4sboot) {
|
|
this.setD4SBoot(d4sboot)
|
|
} else {
|
|
this.setD4SBoot(document.querySelector("d4s-boot-2"));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the Workspace API base URL
|
|
* @param {string} workspaceURL the WS API base URL
|
|
*/
|
|
setWorkspaceURL(workspaceURL) {
|
|
this.#workspaceURL = workspaceURL;
|
|
}
|
|
|
|
/**
|
|
* Sets the d4s-boot-2 instance to be used to perform the OIDC/UMA autenticated secure fetches
|
|
* @param {string} d4sboot the d4s-boot-2 instance
|
|
*/
|
|
setD4SBoot(d4sboot) {
|
|
this.#d4sboot = d4sboot;
|
|
}
|
|
|
|
/**
|
|
* Calls with a secure fetch the workspace with provided data.
|
|
* To upload data by using a <code>FormData</code> object you have to leave the <code>mime</code> attribute as <code>null</code>.
|
|
* @param {*} method the method to use for the call, default to <code>GET</code>
|
|
* @param {*} uri the uri to invoke, relative to <code>workspaceURL</code> provided in the object's constructor
|
|
* @param {*} body the payload to send
|
|
* @param {*} mime the mime type of the payload
|
|
* @param {*} extraHeaders extra HTTP headers to send
|
|
* @returns the reponse payload as a promise, JSON data promise if the returned data is "application/json", a String data promise if "text/*" or a blob data promise in other cases
|
|
* @throws the error as string, if occurred
|
|
*/
|
|
#callWorkspace(method, uri, body, mime, extraHeaders) {
|
|
let req = { };
|
|
if (method) {
|
|
req.method = method;
|
|
}
|
|
if (body) {
|
|
req.body = body;
|
|
}
|
|
if (extraHeaders) {
|
|
req.headers = extraHeaders;
|
|
}
|
|
if (mime) {
|
|
if (req.headers) {
|
|
req.headers["Content-Type"] = mime;
|
|
} else {
|
|
req.headers = { "Content-Type" : mime };
|
|
}
|
|
}
|
|
let url = this.#workspaceURL;
|
|
if (uri) {
|
|
url += uri.startsWith('/') ? uri : '/' + uri;
|
|
}
|
|
console.log("Invoking WS API with: " + url);
|
|
return this.#d4sboot.secureFetch(url, req)
|
|
.then(resp => {
|
|
if (resp.ok) {
|
|
const contentType = resp.headers.get("content-type");
|
|
if (contentType && contentType.indexOf("application/json") !== -1) {
|
|
return resp.json();
|
|
} else if (contentType && contentType.indexOf("text/") !== -1) {
|
|
return resp.text();
|
|
} else {
|
|
return resp.blob();
|
|
}
|
|
} else {
|
|
throw "Cannot invoke workspace via secure fetch for URL: " + url;
|
|
}
|
|
}).catch(err => {
|
|
console.error(err);
|
|
throw err;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Gets the user's Workspace root folder JSON item
|
|
* @param {map} extraHeaders extra HTTP headers to be used for the request
|
|
* @returns the WS root folder JSON item object
|
|
* @throws the error as string, if occurred
|
|
*/
|
|
getWorkspace(extraHeaders) {
|
|
return this.#callWorkspace("GET", null, null, null, extraHeaders)
|
|
.then(json => {
|
|
return json.item;
|
|
}).catch(err => {
|
|
const msg = "Cannot get workspace root ID. Error message: " + err;
|
|
console.error(msg);
|
|
throw msg;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Gets the user's Workspace root folder id (as string)
|
|
* @param {map} extraHeaders extra HTTP headers to be used for the request
|
|
* @returns the id of the WS root folder
|
|
* @throws the error as string, if occurred
|
|
*/
|
|
getWorkspaceId(extraHeaders) {
|
|
return this.getWorkspace(extraHeaders)
|
|
.then(json => {
|
|
return json.item.id;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Gets the contents of a folder, all sub-folders and files.
|
|
* @param {string} folderId the WS folder id to list
|
|
* @param {map} extraHeaders extra HTTP headers to be used for the request
|
|
* @returns the contents of the WS folder as json objects
|
|
* @throws the error as string, if occurred
|
|
*/
|
|
listFolder(folderId, extraHeaders) {
|
|
const uri = "/items/" + folderId + "/children";
|
|
return this.#callWorkspace("GET", uri, null, null, extraHeaders)
|
|
.then(json => {
|
|
return json.itemlist;
|
|
}).catch(err => {
|
|
const msg = "Cannot get folder's content list. Error message: " + err;
|
|
console.error(msg);
|
|
throw msg;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Gets the VRE folder JSON item that belongs to the context where the access token has been issued.
|
|
* @param {map} extraHeaders extra HTTP headers to be used for the request
|
|
* @returns the id of the WS VRE folder
|
|
* @throws the error as string, if occurred
|
|
*/
|
|
getVREFolder(extraHeaders) {
|
|
return this.#callWorkspace("GET", "/vrefolder", null, null, extraHeaders)
|
|
.then(json => {
|
|
return json.item;
|
|
}).catch(err => {
|
|
const msg = "Cannot get VRE folder ID. Error message: " + err;
|
|
console.error(msg);
|
|
throw msg;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Gets the VRE folder id (as string) that belongs to the context where the access token has been issued.
|
|
* @param {map} extraHeaders extra HTTP headers to be used for the request
|
|
* @returns the id of the WS VRE folder
|
|
* @throws the error as string, if occurred
|
|
*/
|
|
getVREFolderId(extraHeaders) {
|
|
return this.getVREFolder(extraHeaders)
|
|
.then(item => {
|
|
return item.id;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @deprecated please use getOrCreateFolder() function instead
|
|
* @param {string} parentFolderId the id of the parent folder where search fo the folder
|
|
* @param {string} name the name of the folder (characters not allowed: ":", [others still to be found])
|
|
* @param {string} description the description of the folder if it should be creaded
|
|
* @param {map} extraHeaders extra HTTP headers to be used for the request
|
|
* @returns the id of the folder, if it exists or it has been just created
|
|
* @throws the error as string, if occurred
|
|
*/
|
|
checkOrCreateFolder(parentFolderId, name, description, extraHeaders) {
|
|
return this.getOrCreateFolder(parentFolderId, name, description, extraHeaders);
|
|
}
|
|
|
|
/**
|
|
* Gets the id of the folder represented by the name parameter if exists, a new folder is created if it doesn't not exist
|
|
* @param {string} parentFolderId the id of the parent folder where search fo the folder
|
|
* @param {string} name the name of the folder (characters not allowed: ":", [others still to be found])
|
|
* @param {string} description the description of the folder if it should be creaded
|
|
* @param {map} extraHeaders extra HTTP headers to be used for the request
|
|
* @returns the id of the folder, if it exists or it has been just created
|
|
* @throws the error as string, if occurred
|
|
*/
|
|
getOrCreateFolder(parentFolderId, name, description, extraHeaders) {
|
|
const baseURI = "/items/" + parentFolderId;
|
|
console.log("Checking existance of folder: " + name);
|
|
let uri = baseURI + "/items/" + name;
|
|
return this.#callWorkspace("GET", uri, null, null, extraHeaders)
|
|
.then(json => {
|
|
if (json.itemlist[0]) {
|
|
const id = json.itemlist[0].id;
|
|
console.log("'" + name + "' folder exists with and has id: " + id);
|
|
return id;
|
|
} else {
|
|
console.info("'" + name + "' folder doesn't exist, creating it: " + name);
|
|
uri = baseURI + "/create/FOLDER";
|
|
const params = new URLSearchParams({ name : name, description : description, hidden : false });
|
|
return this.#callWorkspace("POST", uri, params.toString(), "application/x-www-form-urlencoded", extraHeaders).then(id => {
|
|
console.log("New '" + name + "' folder successfully created with id: " + id);
|
|
return id
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Deletes a Workspace item (folder or file) represented by its id.
|
|
* @param {string} itemId the id of the item do delete
|
|
* @param {map} extraHeaders extra HTTP headers to be used for the request
|
|
* @returns <code>true</code> if the file has been correctly created, <code>false<c/ode> otherwise
|
|
*/
|
|
deleteItem(itemId, extraHeaders) {
|
|
return this.#callWorkspace("DELETE", "/workspace/items/" + itemId, null, null, extraHeaders)
|
|
.then(results => {
|
|
return true;
|
|
}).catch(err => {
|
|
console.error("Cannot DELETE workspace item with ID: " + itemId + ". Error message: " + err);
|
|
return false;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Downloads a Workspace item (folder or file) represented by its id.
|
|
* @param {string} itemId the WS item to download
|
|
* @param {string} name the name of the file to use for the download, if null the id is used
|
|
* @param {boolean} skipLocalDownload if provided and <code>true</code> returns the data to function caller, otherwise it also downloads it locally.
|
|
* @param {map} extraHeaders extra HTTP headers to be used for the request
|
|
* @returns the file's content if item is a file or a ZIP compressed archive if the item represents a folder
|
|
* @throws the error as string, if occurred
|
|
*/
|
|
download(itemId, name, skipLocalDownload, extraHeaders) {
|
|
return this.#callWorkspace("GET", "/items/" + itemId + "/download", null, null, extraHeaders)
|
|
.then(data => {
|
|
if (!skipLocalDownload) {
|
|
console.log("Donwloads item also locally to browser");
|
|
const objectURL = URL.createObjectURL(data);
|
|
var tmplnk = document.createElement("a");
|
|
tmplnk.download = name ? name : itemId;
|
|
tmplnk.href = objectURL;
|
|
//tmplnk.target="_blank";
|
|
document.body.appendChild(tmplnk);
|
|
tmplnk.click();
|
|
document.body.removeChild(tmplnk);
|
|
} else {
|
|
console.log("Skipping local download");
|
|
}
|
|
return data;
|
|
}).catch(err => {
|
|
const msg = "Cannot download item with ID: " + itemId + ". Error message: " + err;
|
|
console.error(msg);
|
|
throw msg;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Uploads a new file into the folder represented by its id
|
|
* @param {string} folderId the folder where to create the new file
|
|
* @param {string} name the name of the file to crete (characters not allowed: ":", [others still to be found])
|
|
* @param {object} data the archive data
|
|
* @param {string} contentType the content type of the file
|
|
* @param {map} extraHeaders extra HTTP headers to be used for the request
|
|
* @returns <code>true</code> if the file has been correctly created, <code>false<c/ode> otherwise
|
|
*/
|
|
uploadFile(folderId, name, description, data, contentType, extraHeaders) {
|
|
const uri = "/items/" + folderId + "/create/FILE";
|
|
const request = new FormData();
|
|
request.append("name", name);
|
|
request.append("description", description);
|
|
request.append(
|
|
"file",
|
|
new Blob([data], {
|
|
type: contentType
|
|
})
|
|
);
|
|
return this.#callWorkspace("POST", uri, request, null, extraHeaders)
|
|
.then(item => {
|
|
const id = item.id;
|
|
console.info("File '" + name + "' successfully uploaded and its id is: " + id);
|
|
return true;
|
|
}).catch(err => {
|
|
console.error("Cannot upload file '" + name + "'. Error: " + err);
|
|
return false;
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Uploads a new archive and stores its content into the folder represented by its id
|
|
* @param {string} folderId the folder where to create the new file
|
|
* @param {string} parentFolderName the name of the folder to create (characters not allowed: ":", [others still to be found])
|
|
* @param {object} data the file's contents
|
|
* @param {map} extraHeaders extra HTTP headers to be used for the request
|
|
* @returns <code>true</code> if the file has been correctly created, <code>false<c/ode> otherwise
|
|
*/
|
|
uploadArchive(folderId, parentFolderName, description, data, extraHeaders) {
|
|
const uri = "/items/" + folderId + "/create/ARCHIVE";
|
|
const request = new FormData();
|
|
request.append("parentFolderName", parentFolderName);
|
|
request.append(
|
|
"file",
|
|
new Blob([data], {
|
|
type: "application/octet-stream"
|
|
})
|
|
);
|
|
return this.#callWorkspace("POST", uri, request, null, extraHeaders)
|
|
.then(item => {
|
|
const id = item.id;
|
|
console.info("Archive file successfully uploaded and extracted into the '" + parentFolderName + "' folder, its id is: " + id);
|
|
return true;
|
|
}).catch(err => {
|
|
console.error("Cannot upload archive file. Error: " + err);
|
|
return false;
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Returns the public URL of a file
|
|
* @param {string} itemId the id of the item
|
|
* @param {int} version the optional file version
|
|
* @param {map} extraHeaders extra HTTP headers to be used for the request
|
|
* @returns the public URL of the item
|
|
* @throws the error as string, if occurred
|
|
*/
|
|
getPublicURL(itemId, version, extraHeaders) {
|
|
let uri = "/workspace/items/" + itemId + "/publiclink";
|
|
if (version) {
|
|
uri += "version=" + version;
|
|
}
|
|
return this.#callWorkspace("GET", uri, null, null, extraHeaders)
|
|
.then(publicURL => {
|
|
return publicURL;
|
|
}).catch(err => {
|
|
const message = "Cannot retrieve the item's public URL. Error message: " + err;
|
|
console.error(message);
|
|
throw message;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Finds into a folder all the file files having the name than matches a specific pattern.
|
|
* Wildcard (*) can be used at the start or the end of the pattern (eg. starts with *{name}, ends with = {name}*)
|
|
* @param {string} folderId the WS folder id where to search
|
|
* @param {string} pattern the pattern to use for the search. Wildcard '*' can be used at the start or the end of the pattern (eg. starts with *{name}, ends with = {name}*)
|
|
* @param {map} extraHeaders extra HTTP headers to be used for the request
|
|
* @returns the contents of the WS folder as json objects
|
|
* @throws the error as string, if occurred
|
|
*/
|
|
findByName(folderId, pattern, extraHeaders) {
|
|
const uri = "/items/" + folderId + "/items/" + pattern;
|
|
return this.#callWorkspace("GET", uri, null, null, extraHeaders)
|
|
.then(json => {
|
|
return json.itemlist;
|
|
}).catch(err => {
|
|
const msg = "Cannot get folder's content list. Error message: " + err;
|
|
console.error(msg);
|
|
throw msg;
|
|
});
|
|
}
|
|
} |