Upload documents in Vitro|VIVO (#251)
* feat: introduced file upload * fix: added file upload config settings * fix: reverted auto formatting of upload file helper * fix: replaced missed condition * Improved naming, internationalization, removed file extensions as misleading information * Fixed wrong bytes number representing 10Mb * fix: show no media types allowed if no media types defined in runtime.properties * fix: Add vitro-languages-home-core as installer dependency to have Vitro RDF internationalization files * fix: change vitro-languages-core-home dependency type from tar.gz to pom
This commit is contained in:
parent
eff04e0979
commit
ebc9237cc6
15 changed files with 642 additions and 1 deletions
44
webapp/src/main/webapp/config/listViewConfig-storedFile.xml
Normal file
44
webapp/src/main/webapp/config/listViewConfig-storedFile.xml
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!-- $This file is distributed under the terms of the license in LICENSE$ -->
|
||||
|
||||
<!-- Default list view config file for object properties
|
||||
|
||||
See guidelines at https://wiki.duraspace.org/x/eYXVAw -->
|
||||
|
||||
<list-view-config>
|
||||
<query-select>
|
||||
|
||||
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
||||
PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#>
|
||||
PREFIX vitro-public: <http://vitro.mannlib.cornell.edu/ns/vitro/public#>
|
||||
|
||||
SELECT <collated> ?subclass </collated>
|
||||
?object
|
||||
?filename
|
||||
?publicFilename
|
||||
?localName
|
||||
?url
|
||||
WHERE {
|
||||
?subject ?property ?object .
|
||||
LET (?localName := REPLACE(STR(?object),"^.*(#)(.*)$", "$2"))
|
||||
?object vitro-public:filename ?filename .
|
||||
?object vitro-public:publicFilename ?publicFilename .
|
||||
?object vitro-public:downloadLocation ?url .
|
||||
|
||||
<collated>
|
||||
OPTIONAL {
|
||||
<precise-subquery>?subject ?property ?object .</precise-subquery>
|
||||
?object a ?subclass .
|
||||
# Require the subclasses retrieved to be in a classgroup, since others are not generally
|
||||
# for display. See vivo-dev-all thread titled "Internal Entity and mostSpecificType,"
|
||||
# Aug 9-10, 2011.
|
||||
# ?subclass vitro:inClassGroup ?classgroup
|
||||
}
|
||||
FILTER ( REPLACE(STR(?subclass),"^(.*)(#)(.*)$", "$1$2") != "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#" )
|
||||
</collated>
|
||||
|
||||
} ORDER BY <collated> ?subclass </collated> ASC( ?publicFilename ) ASC( ?localName )
|
||||
</query-select>
|
||||
|
||||
<template>storedFile-default.ftl</template>
|
||||
</list-view-config>
|
61
webapp/src/main/webapp/js/fileUpload/fileUploadUtils.js
Normal file
61
webapp/src/main/webapp/js/fileUpload/fileUploadUtils.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* $This file is distributed under the terms of the license in LICENSE$ */
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
var xpath = "//attribute::href[contains(., '/uploadFile')]";
|
||||
var result = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);
|
||||
var node = null;
|
||||
while (node = result.iterateNext()) {
|
||||
if(isDeleteUploadFile(node)){
|
||||
$(node.ownerElement).click(function(){
|
||||
var answer = confirm(i18n_confirmDeleteUploadedFile);
|
||||
return answer;
|
||||
});
|
||||
} else if (isUploadFile(node)){
|
||||
$(node.ownerElement).click(function(){
|
||||
uploadFileRequest(event.target);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function isDeleteUploadFile(node){
|
||||
var url = node.nodeValue;
|
||||
if (url.match("&action=delete")){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isUploadFile(node){
|
||||
var url = node.nodeValue;
|
||||
if (url.match("&action=upload")){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function uploadFileRequest(node){
|
||||
var aElement = node.parentElement;
|
||||
var form = document.createElement("form");
|
||||
form.setAttribute("method", "post");
|
||||
form.setAttribute("action", aElement.href);
|
||||
form.setAttribute("enctype","multipart/form-data");
|
||||
form.setAttribute("role","form");
|
||||
document.body.insertBefore(form, null);
|
||||
var inputFile = document.createElement("input");
|
||||
inputFile.type = "file";
|
||||
inputFile.name = "datafile";
|
||||
var inputId = "fileUploadInput" + Math.floor(Math.random() * 1000000);
|
||||
inputFile.setAttribute("id", inputId);
|
||||
inputFile.setAttribute("style", "display:none;");
|
||||
form.insertBefore(inputFile, null);
|
||||
inputFile.click();
|
||||
inputFile.addEventListener("change", onFileSelect);
|
||||
}
|
||||
|
||||
function onFileSelect(e) {
|
||||
e.target.parentElement.submit();
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<#-- $This file is distributed under the terms of the license in LICENSE$ -->
|
||||
|
||||
|
||||
${scripts.add('<script type="text/javascript" src="${urls.base}/js/fileUpload/fileUploadUtils.js"></script>')}
|
||||
|
||||
<#assign i18n = i18n() >
|
||||
|
||||
<section id="fileploadContainer" role="region">
|
||||
<h2>${i18n.file_upload_heading}</h2>
|
||||
|
||||
<#if errorMessage??>
|
||||
<section id="error-alert" role="alert"><img src="${urls.images}/iconAlert.png" alt="${i18n.alt_error_alert}" />
|
||||
<p>${errorMessage}</p>
|
||||
</section>
|
||||
</#if>
|
||||
<#if !supportedMediaTypes?has_content>
|
||||
<section id="error-alert" role="alert"><img src="${urls.images}/iconAlert.png" alt="${i18n.alt_error_alert}" />
|
||||
<p>${i18n.file_upload_no_allowed_media}</p>
|
||||
</section>
|
||||
</#if>
|
||||
<#if action?? && action == "upload" >
|
||||
<form id="fileUploadForm" action="${formAction}" enctype="multipart/form-data" method="post" role="form">
|
||||
<#if supportedMediaTypes?has_content>
|
||||
<label>${i18n.file_upload_supported_media}</label>
|
||||
<p>${supportedMediaTypes}</p>
|
||||
</#if>
|
||||
<input id="datafile" type="file" name="datafile" size="30" />
|
||||
<p class="note">${i18n.maximum_file_size(maxFileSize)}</p>
|
||||
<input class="submit" type="submit" value="${i18n.file_upload_submit_label}"/>
|
||||
<span class="or"> ${i18n.or} <a class="cancel" href="${referrer}" title="${i18n.cancel_title}">${i18n.cancel_link}</a></span>
|
||||
</form>
|
||||
</#if>
|
||||
</section>
|
|
@ -106,9 +106,11 @@ ${headScripts.add('<script type="text/javascript" src="${urls.base}/js/jquery_pl
|
|||
'<script type="text/javascript" src="${urls.base}/js/tiny_mce/tiny_mce.js"></script>')}
|
||||
|
||||
${scripts.add('<script type="text/javascript" src="${urls.base}/js/imageUpload/imageUploadUtils.js"></script>',
|
||||
'<script type="text/javascript" src="${urls.base}/js/fileUpload/fileUploadUtils.js"></script>',
|
||||
'<script type="text/javascript" src="${urls.base}/js/individual/moreLessController.js"></script>',
|
||||
'<script type="text/javascript" src="${urls.base}/js/individual/individualUriRdf.js"></script>')}
|
||||
|
||||
<script type="text/javascript">
|
||||
i18n_confirmDelete = "${i18n().confirm_delete?js_string}";
|
||||
i18n_confirmDeleteUploadedFile = "${i18n().file_upload_confirm_delete?js_string}";
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<#-- $This file is distributed under the terms of the license in LICENSE$ -->
|
||||
|
||||
<#-- Default object property statement template.
|
||||
|
||||
This template must be self-contained and not rely on other variables set for the individual page, because it
|
||||
is also used to generate the property statement during a deletion.
|
||||
-->
|
||||
<@showFiles statement individual />
|
||||
|
||||
<#macro showFiles statement individual>
|
||||
<a download="${statement.publicFilename}" title="${i18n().name}" href="${profileUrl(statement.url)}" >${statement.publicFilename}</a>
|
||||
</#macro>
|
Loading…
Add table
Add a link
Reference in a new issue