2021-01-10 01:08:03 +01:00
|
|
|
import * as React from "react";
|
2021-01-10 23:41:00 +01:00
|
|
|
import "./file-browser.css";
|
|
|
|
import Dropzone from "react-dropzone";
|
|
|
|
import Icon from "./icon";
|
2021-01-14 18:32:29 +01:00
|
|
|
import Alert from "./alert";
|
|
|
|
import {Popup} from "./popup";
|
|
|
|
import {useState} from "react";
|
2021-01-10 01:08:03 +01:00
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
export function FileBrowser(props) {
|
2021-01-10 01:08:03 +01:00
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
let files = props.files || { };
|
|
|
|
let api = props.api;
|
|
|
|
let tokenObj = props.token || { valid: false };
|
|
|
|
let onSelectFile = props.onSelectFile || function() { };
|
|
|
|
let onFetchFiles = props.onFetchFiles || function() { };
|
2021-03-30 23:12:10 +02:00
|
|
|
let directories = props.directories || {};
|
|
|
|
let restrictions = props.restrictions || { maxFiles: 0, maxSize: 0, extensions: "" };
|
2021-01-10 01:08:03 +01:00
|
|
|
|
2021-01-14 21:45:58 +01:00
|
|
|
let [popup, setPopup] = useState({ visible: false, directoryName: "", directory: 0, type: "upload" });
|
2021-01-14 18:32:29 +01:00
|
|
|
let [alerts, setAlerts] = useState( []);
|
|
|
|
let [filesToUpload, setFilesToUpload] = useState([]);
|
2021-01-10 01:08:03 +01:00
|
|
|
|
2021-01-14 21:45:58 +01:00
|
|
|
function svgMiddle(scale=1.0) {
|
2021-01-12 15:49:41 +01:00
|
|
|
let width = 48 * scale;
|
|
|
|
let height = 64 * scale;
|
|
|
|
|
2021-01-14 21:45:58 +01:00
|
|
|
return <svg width={width} height={height} xmlns="http://www.w3.org/2000/svg">
|
2021-01-10 23:41:00 +01:00
|
|
|
<g>
|
2021-01-14 21:45:58 +01:00
|
|
|
<line y2="0" x2={width/2} y1={height} x1={width/2} strokeWidth="1.5" stroke="#000" fill="none"/>
|
|
|
|
<line y2={height/2} x2={width} y1={height/2} x1={width/2} strokeWidth="1.5" stroke="#000" fill="none"/>
|
2021-01-10 23:41:00 +01:00
|
|
|
</g>
|
|
|
|
</svg>;
|
|
|
|
}
|
|
|
|
|
2021-01-14 21:45:58 +01:00
|
|
|
function svgEnd(scale=1.0) {
|
2021-01-12 15:49:41 +01:00
|
|
|
let width = 48 * scale;
|
|
|
|
let height = 64 * scale;
|
|
|
|
|
2021-01-14 21:45:58 +01:00
|
|
|
return <svg width={width} height={height} xmlns="http://www.w3.org/2000/svg">
|
2021-01-10 23:41:00 +01:00
|
|
|
<g>
|
|
|
|
{ /* vertical line */}
|
2021-01-14 21:45:58 +01:00
|
|
|
<line y2="0" x2={width/2} y1={height/2} x1={width/2} strokeWidth="1.5" stroke="#000" fill="none"/>
|
2021-01-10 23:41:00 +01:00
|
|
|
{ /* horizontal line */}
|
2021-01-14 21:45:58 +01:00
|
|
|
<line y2={height/2} x2={width} y1={height/2} x1={width/2} strokeWidth="1.5" stroke="#000" fill="none"/>
|
|
|
|
</g>
|
|
|
|
</svg>;
|
|
|
|
}
|
|
|
|
|
|
|
|
function svgLeft(scale=1.0) {
|
|
|
|
let width = 48 * scale;
|
|
|
|
let height = 64 * scale;
|
|
|
|
return <svg width={width} height={height} xmlns="http://www.w3.org/2000/svg" style={{}}>
|
|
|
|
<g>
|
|
|
|
{ /* vertical line */}
|
|
|
|
<line y2="0" x2={width/2} y1={height} x1={width/2} strokeWidth="1.5" stroke="#000" fill="none"/>
|
2021-01-10 23:41:00 +01:00
|
|
|
</g>
|
|
|
|
</svg>;
|
|
|
|
}
|
|
|
|
|
2021-03-30 23:00:34 +02:00
|
|
|
function createFileIcon(mimeType, size="2x") {
|
2021-01-12 15:49:41 +01:00
|
|
|
let icon = "";
|
|
|
|
if (mimeType !== null) {
|
|
|
|
mimeType = mimeType.toLowerCase().trim();
|
|
|
|
let types = ["image", "text", "audio", "video"];
|
|
|
|
let languages = ["php", "java", "python", "cpp"];
|
|
|
|
let archives = ["zip", "tar", "archive"];
|
|
|
|
let [mainType, subType] = mimeType.split("/");
|
|
|
|
if (mainType === "text" && languages.find(a => subType.includes(a))) {
|
|
|
|
icon = "code";
|
|
|
|
} else if (mainType === "application" && archives.find(a => subType.includes(a))) {
|
|
|
|
icon = "archive";
|
|
|
|
} else if (mainType === "application" && subType === "pdf") {
|
|
|
|
icon = "pdf";
|
|
|
|
} else if (mainType === "application" && (subType.indexOf("powerpoint") > -1 || subType.indexOf("presentation") > -1)) {
|
|
|
|
icon = "powerpoint";
|
|
|
|
} else if (mainType === "application" && (subType.indexOf("word") > -1 || subType.indexOf("opendocument") > -1)) {
|
|
|
|
icon = "word";
|
|
|
|
} else if (mainType === "application" && (subType.indexOf("excel") > -1 || subType.indexOf("sheet") > -1)) {
|
|
|
|
icon = "excel";
|
|
|
|
} else if (mainType === "application" && subType.indexOf("directory") > -1) {
|
|
|
|
icon = "folder";
|
|
|
|
} else if (types.indexOf(mainType) > -1) {
|
|
|
|
if (mainType === "text") {
|
|
|
|
icon = "alt";
|
|
|
|
} else {
|
|
|
|
icon = mainType;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (icon !== "folder") {
|
|
|
|
icon = "file" + (icon ? ("-" + icon) : icon);
|
|
|
|
}
|
|
|
|
|
2021-03-30 23:00:34 +02:00
|
|
|
return <Icon icon={icon} type={"far"} className={"p-1 align-middle fa-" + size} />
|
2021-01-12 15:49:41 +01:00
|
|
|
}
|
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
function formatSize(size) {
|
2021-01-10 01:08:03 +01:00
|
|
|
const suffixes = ["B","KiB","MiB","GiB","TiB"];
|
|
|
|
let i = 0;
|
|
|
|
for (; i < suffixes.length && size >= 1024; i++) {
|
|
|
|
size /= 1024.0;
|
|
|
|
}
|
|
|
|
|
2021-01-13 15:26:30 +01:00
|
|
|
if (i === 0 || Math.round(size) === size) {
|
|
|
|
return size + " " + suffixes[i];
|
|
|
|
} else {
|
|
|
|
return size.toFixed(1) + " " + suffixes[i];
|
|
|
|
}
|
2021-01-10 01:08:03 +01:00
|
|
|
}
|
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
function canUpload() {
|
|
|
|
return api.loggedIn || (tokenObj.valid && tokenObj.type === "upload");
|
2021-01-10 23:41:00 +01:00
|
|
|
}
|
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
function onAddUploadFiles(acceptedFiles) {
|
|
|
|
let files = filesToUpload.slice();
|
2021-01-10 23:41:00 +01:00
|
|
|
files.push(...acceptedFiles);
|
2021-01-14 18:32:29 +01:00
|
|
|
setFilesToUpload(files);
|
2021-01-10 23:41:00 +01:00
|
|
|
}
|
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
function getSelectedIds(items = null, recursive = true) {
|
2021-01-10 23:41:00 +01:00
|
|
|
let ids = [];
|
2021-01-14 18:32:29 +01:00
|
|
|
items = items || files;
|
2021-01-10 23:41:00 +01:00
|
|
|
for (const fileItem of Object.values(items)) {
|
|
|
|
if (fileItem.selected) {
|
|
|
|
ids.push(fileItem.uid);
|
|
|
|
}
|
|
|
|
if (recursive && fileItem.isDirectory) {
|
2021-01-14 18:32:29 +01:00
|
|
|
ids.push(...getSelectedIds(fileItem.items));
|
2021-01-10 23:41:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ids;
|
|
|
|
}
|
|
|
|
|
2021-03-30 23:00:34 +02:00
|
|
|
// TODO: add more mime type names or use an directory here?
|
|
|
|
function getTypeName(type) {
|
|
|
|
if (type.toLowerCase() === "directory") {
|
|
|
|
return "Directory";
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (type.toLowerCase()) {
|
|
|
|
case "image/jpeg":
|
|
|
|
return "JPEG-Image";
|
|
|
|
case "image/png":
|
|
|
|
return "PNG-Image";
|
|
|
|
case "application/pdf":
|
|
|
|
return "PDF-Document";
|
|
|
|
case "text/plain":
|
|
|
|
return "Text-Document"
|
|
|
|
case "application/x-dosexec":
|
|
|
|
return "Windows Executable";
|
|
|
|
case "application/vnd.oasis.opendocument.text":
|
|
|
|
return "OpenOffice-Document";
|
|
|
|
default:
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
function createFileList(elements, indentation=0) {
|
2021-01-10 01:08:03 +01:00
|
|
|
let rows = [];
|
2021-01-10 23:41:00 +01:00
|
|
|
let i = 0;
|
2021-03-30 23:00:34 +02:00
|
|
|
|
|
|
|
const scale = 0.45;
|
|
|
|
const iconSize = "lg";
|
|
|
|
|
2021-01-10 23:41:00 +01:00
|
|
|
const values = Object.values(elements);
|
|
|
|
for (const fileElement of values) {
|
2021-01-10 01:08:03 +01:00
|
|
|
let name = fileElement.name;
|
2021-01-10 23:41:00 +01:00
|
|
|
let uid = fileElement.uid;
|
|
|
|
let type = (fileElement.isDirectory ? "Directory" : fileElement.mimeType);
|
2021-01-14 18:32:29 +01:00
|
|
|
let size = (fileElement.isDirectory ? "" : formatSize(fileElement.size));
|
2021-01-12 15:49:41 +01:00
|
|
|
let mimeType = (fileElement.isDirectory ? "application/x-directory" : fileElement.mimeType);
|
2021-01-14 18:32:29 +01:00
|
|
|
let token = (tokenObj && tokenObj.valid ? "&token=" + tokenObj.value : "");
|
2021-01-14 21:45:58 +01:00
|
|
|
let svg = [];
|
2021-01-10 23:41:00 +01:00
|
|
|
if (indentation > 0) {
|
2021-01-14 21:45:58 +01:00
|
|
|
for (let i = 0; i < indentation - 1; i++) {
|
2021-03-30 23:00:34 +02:00
|
|
|
svg.push(svgLeft(scale));
|
2021-01-14 21:45:58 +01:00
|
|
|
}
|
|
|
|
|
2021-01-10 23:41:00 +01:00
|
|
|
if (i === values.length - 1) {
|
2021-03-30 23:00:34 +02:00
|
|
|
svg.push(svgEnd(scale));
|
2021-01-10 23:41:00 +01:00
|
|
|
} else {
|
2021-03-30 23:00:34 +02:00
|
|
|
svg.push(svgMiddle(scale));
|
2021-01-10 23:41:00 +01:00
|
|
|
}
|
|
|
|
}
|
2021-01-10 01:08:03 +01:00
|
|
|
|
|
|
|
rows.push(
|
2021-01-10 23:41:00 +01:00
|
|
|
<tr key={"file-" + uid} data-id={uid} className={"file-row"}>
|
|
|
|
<td>
|
|
|
|
{ svg }
|
2021-03-30 23:00:34 +02:00
|
|
|
{ createFileIcon(mimeType, iconSize) }
|
2021-01-10 23:41:00 +01:00
|
|
|
</td>
|
|
|
|
<td>
|
|
|
|
{fileElement.isDirectory ? name :
|
|
|
|
<a href={"/api/file/download?id=" + uid + token} download={true}>{name}</a>
|
|
|
|
}
|
|
|
|
</td>
|
2021-03-30 23:00:34 +02:00
|
|
|
<td>{getTypeName(type)}</td>
|
2021-01-10 23:41:00 +01:00
|
|
|
<td>{size}</td>
|
|
|
|
<td>
|
|
|
|
<input type={"checkbox"} checked={!!fileElement.selected}
|
2021-01-14 18:32:29 +01:00
|
|
|
onChange={(e) => onSelectFile(e, uid)}
|
2021-01-10 23:41:00 +01:00
|
|
|
/>
|
|
|
|
</td>
|
2021-01-10 01:08:03 +01:00
|
|
|
</tr>
|
|
|
|
);
|
2021-01-10 23:41:00 +01:00
|
|
|
|
|
|
|
if (fileElement.isDirectory) {
|
2021-01-14 18:32:29 +01:00
|
|
|
rows.push(...createFileList(fileElement.items, indentation + 1));
|
2021-01-10 23:41:00 +01:00
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return rows;
|
|
|
|
}
|
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
let rows = createFileList(files);
|
|
|
|
let selectedIds = getSelectedIds();
|
2021-01-10 23:41:00 +01:00
|
|
|
let selectedCount = selectedIds.length;
|
|
|
|
let uploadZone = <></>;
|
2021-01-14 18:32:29 +01:00
|
|
|
let writePermissions = canUpload();
|
2021-01-10 23:41:00 +01:00
|
|
|
let uploadedFiles = [];
|
2021-01-14 18:32:29 +01:00
|
|
|
let alertElements = [];
|
2021-01-12 15:49:41 +01:00
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
for (let i = 0; i < alerts.length; i++) {
|
|
|
|
const alert = alerts[i];
|
|
|
|
alertElements.push(
|
|
|
|
<Alert key={"alert-" + i} {...alert} onClose={() => removeAlert(i)} />
|
2021-01-12 15:49:41 +01:00
|
|
|
);
|
|
|
|
}
|
2021-01-10 23:41:00 +01:00
|
|
|
|
2021-01-14 21:45:58 +01:00
|
|
|
let options = [];
|
|
|
|
for (const [uid, dir] of Object.entries(directories)) {
|
|
|
|
options.push(
|
|
|
|
<option key={"option-" + dir} value={uid}>{dir}</option>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-01-10 23:41:00 +01:00
|
|
|
if (writePermissions) {
|
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
for(let i = 0; i < filesToUpload.length; i++) {
|
|
|
|
const file = filesToUpload[i];
|
2021-01-10 23:41:00 +01:00
|
|
|
uploadedFiles.push(
|
|
|
|
<span className={"uploaded-file"} key={i}>
|
2021-03-30 23:00:34 +02:00
|
|
|
{ createFileIcon(file.type, "3x") }
|
2021-01-10 23:41:00 +01:00
|
|
|
<span>{file.name}</span>
|
2021-01-14 18:32:29 +01:00
|
|
|
<Icon icon={"times"} onClick={(e) => onRemoveUploadedFile(e, i)}/>
|
2021-01-10 23:41:00 +01:00
|
|
|
</span>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
uploadZone = <><Dropzone onDrop={onAddUploadFiles}>
|
2021-01-10 23:41:00 +01:00
|
|
|
{({getRootProps, getInputProps}) => (
|
|
|
|
<section className={"file-upload-container"}>
|
|
|
|
<div {...getRootProps()}>
|
|
|
|
<input {...getInputProps()} />
|
|
|
|
<p>Drag 'n' drop some files here, or click to select files</p>
|
2021-01-12 15:49:41 +01:00
|
|
|
{ uploadedFiles.length === 0 ?
|
|
|
|
<Icon className={"mx-auto fa-3x text-black-50"} icon={"upload"}/> :
|
|
|
|
<div>{uploadedFiles}</div>
|
|
|
|
}
|
2021-01-10 23:41:00 +01:00
|
|
|
</div>
|
|
|
|
</section>
|
|
|
|
)}
|
|
|
|
</Dropzone>
|
|
|
|
</>;
|
2021-01-10 01:08:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return <>
|
2021-01-14 18:32:29 +01:00
|
|
|
<h4>
|
|
|
|
<Icon icon={"sync"} className={"mx-3 clickable small"} onClick={fetchFiles}/>
|
|
|
|
File Browser
|
|
|
|
</h4>
|
2021-01-12 15:49:41 +01:00
|
|
|
<table className={"table data-table file-table"}>
|
2021-01-10 01:08:03 +01:00
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th/>
|
|
|
|
<th>Name</th>
|
|
|
|
<th>Type</th>
|
|
|
|
<th>Size</th>
|
2021-01-10 23:41:00 +01:00
|
|
|
<th/>
|
2021-01-10 01:08:03 +01:00
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
2021-01-14 18:32:29 +01:00
|
|
|
{ rows.length > 0 ? rows :
|
|
|
|
<tr>
|
|
|
|
<td colSpan={4} className={"text-center text-black-50"}>
|
|
|
|
No files uploaded yet
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
}
|
2021-01-10 01:08:03 +01:00
|
|
|
</tbody>
|
|
|
|
</table>
|
2021-01-10 23:41:00 +01:00
|
|
|
<div className={"file-control-buttons"}>
|
2021-01-13 01:36:04 +01:00
|
|
|
<button type={"button"} className={"btn btn-success"} disabled={selectedCount === 0}
|
2021-01-14 18:32:29 +01:00
|
|
|
onClick={() => onDownload(selectedIds)}>
|
2021-01-10 23:41:00 +01:00
|
|
|
<Icon icon={"download"} className={"mr-1"}/>
|
|
|
|
Download Selected Files ({selectedCount})
|
|
|
|
</button>
|
2021-01-14 18:32:29 +01:00
|
|
|
{ api.loggedIn ?
|
2021-01-14 21:45:58 +01:00
|
|
|
<button type={"button"} className={"btn btn-info"} onClick={(e) => onPopupOpen("createDirectory")}>
|
2021-01-10 23:41:00 +01:00
|
|
|
<Icon icon={"plus"} className={"mr-1"}/>
|
|
|
|
Create Directory
|
|
|
|
</button> :
|
|
|
|
<></>
|
|
|
|
}
|
|
|
|
{
|
|
|
|
writePermissions ?
|
|
|
|
<>
|
2021-01-12 15:49:41 +01:00
|
|
|
<button type={"button"} className={"btn btn-primary"} disabled={uploadedFiles.length === 0}
|
2021-01-14 21:45:58 +01:00
|
|
|
onClick={(e) => api.loggedIn ? onPopupOpen("upload") : onUpload()}>
|
2021-01-10 23:41:00 +01:00
|
|
|
<Icon icon={"upload"} className={"mr-1"}/>
|
|
|
|
Upload
|
|
|
|
</button>
|
2021-01-12 15:49:41 +01:00
|
|
|
<button type={"button"} className={"btn btn-danger"} disabled={selectedCount === 0}
|
2021-01-14 18:32:29 +01:00
|
|
|
onClick={() => deleteFiles(selectedIds)}>
|
2021-01-10 23:41:00 +01:00
|
|
|
<Icon icon={"trash"} className={"mr-1"}/>
|
|
|
|
Delete Selected Files ({selectedCount})
|
|
|
|
</button>
|
|
|
|
</>
|
|
|
|
: <></>
|
|
|
|
}
|
|
|
|
</div>
|
|
|
|
{ uploadZone }
|
2021-03-30 23:12:10 +02:00
|
|
|
<div className={"file-browser-restrictions px-4 mb-4"}>
|
|
|
|
<b>Restrictions:</b>
|
|
|
|
<span>Max. Files: { restrictions.maxFiles }</span>
|
|
|
|
<span>Max. Filesize: { formatSize(restrictions.maxSize) }</span>
|
|
|
|
<span>{ restrictions.extensions ? "Allowed extensions: " + restrictions.extensions : "All extensions allowed" }</span>
|
|
|
|
</div>
|
2021-01-12 15:49:41 +01:00
|
|
|
<div>
|
2021-01-14 18:32:29 +01:00
|
|
|
{ alertElements }
|
2021-01-12 15:49:41 +01:00
|
|
|
</div>
|
2021-01-14 18:32:29 +01:00
|
|
|
<Popup title={"Create Directory"} visible={popup.visible} buttons={["Ok","Cancel"]} onClose={onPopupClose} onClick={onPopupButton}>
|
|
|
|
<div className={"form-group"}>
|
2021-01-14 21:45:58 +01:00
|
|
|
<label>Destination Directory:</label>
|
|
|
|
<select value={popup.directory} className={"form-control"}
|
|
|
|
onChange={(e) => onPopupChange(e, "directory")}>
|
|
|
|
{ options }
|
|
|
|
</select>
|
2021-01-14 18:32:29 +01:00
|
|
|
</div>
|
2021-01-14 21:45:58 +01:00
|
|
|
{ popup.type !== "upload" ?
|
|
|
|
<div className={"form-group"}>
|
|
|
|
<label>Directory Name</label>
|
|
|
|
<input type={"text"} className={"form-control"} value={popup.directoryName} maxLength={32} placeholder={"Enter name…"}
|
|
|
|
onChange={(e) => onPopupChange(e, "directoryName")}/>
|
|
|
|
</div> : <></>
|
|
|
|
}
|
2021-01-14 18:32:29 +01:00
|
|
|
</Popup>
|
2021-01-10 01:08:03 +01:00
|
|
|
</>;
|
2021-01-14 18:32:29 +01:00
|
|
|
|
2021-01-14 21:45:58 +01:00
|
|
|
function onPopupOpen(type) {
|
|
|
|
setPopup({ ...popup, visible: true, type: type });
|
2021-01-14 18:32:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function onPopupClose() {
|
|
|
|
setPopup({ ...popup, visible: false });
|
|
|
|
}
|
|
|
|
|
|
|
|
function onPopupChange(e, key) {
|
|
|
|
setPopup({ ...popup, [key]: e.target.value });
|
2021-01-10 01:08:03 +01:00
|
|
|
}
|
2021-01-10 23:41:00 +01:00
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
function onPopupButton(btn) {
|
|
|
|
|
|
|
|
if (btn === "Ok") {
|
2021-01-14 21:45:58 +01:00
|
|
|
let parentId = popup.directory === 0 ? null : popup.directory;
|
|
|
|
if (popup.type === "createDirectory") {
|
|
|
|
api.createDirectory(popup.directoryName, parentId).then((res) => {
|
|
|
|
if (!res.success) {
|
|
|
|
pushAlert(res, "Error creating directory");
|
|
|
|
} else {
|
|
|
|
fetchFiles();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else if (popup.type === "upload") {
|
|
|
|
onUpload();
|
|
|
|
}
|
2021-01-14 18:32:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
onPopupClose();
|
|
|
|
}
|
|
|
|
|
|
|
|
function fetchFiles() {
|
|
|
|
if (tokenObj.valid) {
|
|
|
|
api.validateToken(tokenObj.value).then((res) => {
|
2021-01-12 15:49:41 +01:00
|
|
|
if (res) {
|
2021-01-14 18:32:29 +01:00
|
|
|
onFetchFiles(res.files);
|
2021-01-12 15:49:41 +01:00
|
|
|
} else {
|
2021-01-14 18:32:29 +01:00
|
|
|
pushAlert(res);
|
2021-01-12 15:49:41 +01:00
|
|
|
}
|
|
|
|
});
|
2021-01-14 18:32:29 +01:00
|
|
|
} else if (api.loggedIn) {
|
|
|
|
api.listFiles().then((res) => {
|
2021-01-12 15:49:41 +01:00
|
|
|
if (res) {
|
2021-01-14 18:32:29 +01:00
|
|
|
onFetchFiles(res.files);
|
2021-01-12 15:49:41 +01:00
|
|
|
} else {
|
2021-01-14 18:32:29 +01:00
|
|
|
pushAlert(res);
|
2021-01-12 15:49:41 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
function onRemoveUploadedFile(e, i) {
|
2021-01-10 23:41:00 +01:00
|
|
|
e.stopPropagation();
|
2021-01-14 18:32:29 +01:00
|
|
|
let files = filesToUpload.slice();
|
2021-01-10 23:41:00 +01:00
|
|
|
files.splice(i, 1);
|
2021-01-14 18:32:29 +01:00
|
|
|
setFilesToUpload(files);
|
2021-01-10 23:41:00 +01:00
|
|
|
}
|
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
function pushAlert(res, title) {
|
|
|
|
let newAlerts = alerts.slice();
|
|
|
|
newAlerts.push({ type: "danger", message: res.msg, title: title });
|
|
|
|
setAlerts(newAlerts);
|
|
|
|
}
|
|
|
|
|
|
|
|
function removeAlert(i) {
|
|
|
|
if (i >= 0 && i < alerts.length) {
|
|
|
|
let newAlerts = alerts.slice();
|
|
|
|
newAlerts.splice(i, 1);
|
|
|
|
setAlerts(newAlerts);
|
|
|
|
}
|
2021-01-12 15:49:41 +01:00
|
|
|
}
|
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
function deleteFiles(selectedIds) {
|
2021-01-13 01:36:04 +01:00
|
|
|
if (selectedIds && selectedIds.length > 0) {
|
2021-01-14 18:32:29 +01:00
|
|
|
let token = (api.loggedIn ? null : tokenObj.value);
|
|
|
|
api.delete(selectedIds, token).then((res) => {
|
2021-01-13 01:36:04 +01:00
|
|
|
if (res.success) {
|
2021-01-14 18:32:29 +01:00
|
|
|
fetchFiles();
|
2021-01-13 01:36:04 +01:00
|
|
|
} else {
|
2021-01-14 18:32:29 +01:00
|
|
|
pushAlert(res);
|
2021-01-13 01:36:04 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2021-01-10 23:41:00 +01:00
|
|
|
}
|
2021-01-12 15:49:41 +01:00
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
function onUpload() {
|
|
|
|
let token = (api.loggedIn ? null : tokenObj.value);
|
2021-01-14 21:45:58 +01:00
|
|
|
let parentId = ((!api.loggedIn || popup.directory === 0) ? null : popup.directory);
|
|
|
|
api.upload(filesToUpload, token, parentId).then((res) => {
|
2021-01-12 15:49:41 +01:00
|
|
|
if (res.success) {
|
2021-01-14 18:32:29 +01:00
|
|
|
setFilesToUpload([]);
|
|
|
|
fetchFiles();
|
2021-01-12 15:49:41 +01:00
|
|
|
} else {
|
2021-01-14 18:32:29 +01:00
|
|
|
pushAlert(res);
|
2021-01-12 15:49:41 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2021-01-13 01:36:04 +01:00
|
|
|
|
2021-01-14 18:32:29 +01:00
|
|
|
function onDownload(selectedIds) {
|
2021-01-13 01:36:04 +01:00
|
|
|
if (selectedIds && selectedIds.length > 0) {
|
2021-01-14 18:32:29 +01:00
|
|
|
let token = (api.loggedIn ? "" : "&token=" + tokenObj.value);
|
2021-01-13 01:36:04 +01:00
|
|
|
let ids = selectedIds.map(id => "id[]=" + id).join("&");
|
|
|
|
let downloadUrl = "/api/file/download?" + ids + token;
|
|
|
|
fetch(downloadUrl)
|
|
|
|
.then(response => {
|
|
|
|
let header = response.headers.get("Content-Disposition") || "";
|
|
|
|
let fileNameFields = header.split(";").filter(c => c.trim().toLowerCase().startsWith("filename="));
|
|
|
|
let fileName = null;
|
|
|
|
if (fileNameFields.length > 0) {
|
|
|
|
fileName = fileNameFields[0].trim().substr("filename=".length);
|
|
|
|
} else {
|
|
|
|
fileName = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
response.blob().then(blob => {
|
|
|
|
let url = window.URL.createObjectURL(blob);
|
|
|
|
let a = document.createElement('a');
|
|
|
|
a.href = url;
|
|
|
|
if (fileName !== null) a.download = fileName;
|
|
|
|
a.click();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2021-01-10 01:08:03 +01:00
|
|
|
}
|