File Control Panel
This commit is contained in:
parent
191afa06fb
commit
bf4301f4be
@ -215,7 +215,7 @@ namespace Api\File {
|
||||
foreach ($files as &$dir) {
|
||||
if ($dir["isDirectory"]) {
|
||||
$target =& $this->findDirectory($dir["items"], $id);
|
||||
if ($target !== $dir) {
|
||||
if ($target !== $dir["items"]) {
|
||||
return $target;
|
||||
}
|
||||
}
|
||||
@ -476,6 +476,7 @@ namespace Api\File {
|
||||
$sha1Hash = @hash_file('sha1', $tmpPath);
|
||||
$filePath = $uploadDir . "/" . $md5Hash . $sha1Hash;
|
||||
if (move_uploaded_file($tmpPath, $filePath)) {
|
||||
|
||||
$res = $sql->insert("UserFile", array("name", "directory", "path", "user_id", "parent_id"))
|
||||
->addRow($fileName, false, $filePath, $userId, $parentId)
|
||||
->returning("uid")
|
||||
@ -582,6 +583,7 @@ namespace Api\File {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
|
239
fileControlPanel/package-lock.json
generated
239
fileControlPanel/package-lock.json
generated
@ -1642,177 +1642,178 @@
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
|
||||
"integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
|
||||
"integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/helper-module-context": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/wast-parser": "1.9.0"
|
||||
"@webassemblyjs/helper-module-context": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/wast-parser": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/floating-point-hex-parser": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz",
|
||||
"integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz",
|
||||
"integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-api-error": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz",
|
||||
"integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz",
|
||||
"integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-buffer": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz",
|
||||
"integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz",
|
||||
"integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-code-frame": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz",
|
||||
"integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz",
|
||||
"integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/wast-printer": "1.9.0"
|
||||
"@webassemblyjs/wast-printer": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/helper-fsm": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz",
|
||||
"integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz",
|
||||
"integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-module-context": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz",
|
||||
"integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz",
|
||||
"integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.9.0"
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"mamacro": "^0.0.3"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/helper-wasm-bytecode": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz",
|
||||
"integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz",
|
||||
"integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/helper-wasm-section": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz",
|
||||
"integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz",
|
||||
"integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-buffer": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/wasm-gen": "1.9.0"
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-buffer": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/wasm-gen": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/ieee754": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz",
|
||||
"integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz",
|
||||
"integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@xtuc/ieee754": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/leb128": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz",
|
||||
"integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz",
|
||||
"integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/utf8": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz",
|
||||
"integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz",
|
||||
"integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/wasm-edit": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz",
|
||||
"integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz",
|
||||
"integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-buffer": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-section": "1.9.0",
|
||||
"@webassemblyjs/wasm-gen": "1.9.0",
|
||||
"@webassemblyjs/wasm-opt": "1.9.0",
|
||||
"@webassemblyjs/wasm-parser": "1.9.0",
|
||||
"@webassemblyjs/wast-printer": "1.9.0"
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-buffer": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-section": "1.8.5",
|
||||
"@webassemblyjs/wasm-gen": "1.8.5",
|
||||
"@webassemblyjs/wasm-opt": "1.8.5",
|
||||
"@webassemblyjs/wasm-parser": "1.8.5",
|
||||
"@webassemblyjs/wast-printer": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-gen": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz",
|
||||
"integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz",
|
||||
"integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/ieee754": "1.9.0",
|
||||
"@webassemblyjs/leb128": "1.9.0",
|
||||
"@webassemblyjs/utf8": "1.9.0"
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/ieee754": "1.8.5",
|
||||
"@webassemblyjs/leb128": "1.8.5",
|
||||
"@webassemblyjs/utf8": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-opt": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz",
|
||||
"integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz",
|
||||
"integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-buffer": "1.9.0",
|
||||
"@webassemblyjs/wasm-gen": "1.9.0",
|
||||
"@webassemblyjs/wasm-parser": "1.9.0"
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-buffer": "1.8.5",
|
||||
"@webassemblyjs/wasm-gen": "1.8.5",
|
||||
"@webassemblyjs/wasm-parser": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wasm-parser": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz",
|
||||
"integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz",
|
||||
"integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-api-error": "1.9.0",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.9.0",
|
||||
"@webassemblyjs/ieee754": "1.9.0",
|
||||
"@webassemblyjs/leb128": "1.9.0",
|
||||
"@webassemblyjs/utf8": "1.9.0"
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-api-error": "1.8.5",
|
||||
"@webassemblyjs/helper-wasm-bytecode": "1.8.5",
|
||||
"@webassemblyjs/ieee754": "1.8.5",
|
||||
"@webassemblyjs/leb128": "1.8.5",
|
||||
"@webassemblyjs/utf8": "1.8.5"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wast-parser": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz",
|
||||
"integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz",
|
||||
"integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/floating-point-hex-parser": "1.9.0",
|
||||
"@webassemblyjs/helper-api-error": "1.9.0",
|
||||
"@webassemblyjs/helper-code-frame": "1.9.0",
|
||||
"@webassemblyjs/helper-fsm": "1.9.0",
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/floating-point-hex-parser": "1.8.5",
|
||||
"@webassemblyjs/helper-api-error": "1.8.5",
|
||||
"@webassemblyjs/helper-code-frame": "1.8.5",
|
||||
"@webassemblyjs/helper-fsm": "1.8.5",
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
"@webassemblyjs/wast-printer": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz",
|
||||
"integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==",
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz",
|
||||
"integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/wast-parser": "1.9.0",
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/wast-parser": "1.8.5",
|
||||
"@xtuc/long": "4.2.2"
|
||||
}
|
||||
},
|
||||
@ -2194,6 +2195,11 @@
|
||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
|
||||
},
|
||||
"attr-accept": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz",
|
||||
"integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg=="
|
||||
},
|
||||
"autoprefixer": {
|
||||
"version": "9.8.6",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz",
|
||||
@ -5617,6 +5623,21 @@
|
||||
"schema-utils": "^2.5.0"
|
||||
}
|
||||
},
|
||||
"file-selector": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.2.4.tgz",
|
||||
"integrity": "sha512-ZDsQNbrv6qRi1YTDOEWzf5J2KjZ9KMI1Q2SGeTkCJmNNW25Jg4TW4UMcmoqcg4WrAyKRcpBXdbWRxkfrOzVRbA==",
|
||||
"requires": {
|
||||
"tslib": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
|
||||
"integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"filesize": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.0.1.tgz",
|
||||
@ -10589,6 +10610,16 @@
|
||||
"prop-types": "^15.7.2"
|
||||
}
|
||||
},
|
||||
"react-dropzone": {
|
||||
"version": "11.2.4",
|
||||
"resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-11.2.4.tgz",
|
||||
"integrity": "sha512-EGSvK2CxFTuc28WxwuJCICyuYFX8b+sRumwU6Bs6sTbElV2HtQkT0d6C+HEee6XfbjiLIZ+Th9uji27rvo2wGw==",
|
||||
"requires": {
|
||||
"attr-accept": "^2.2.1",
|
||||
"file-selector": "^0.2.2",
|
||||
"prop-types": "^15.7.2"
|
||||
}
|
||||
},
|
||||
"react-error-overlay": {
|
||||
"version": "6.0.8",
|
||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.8.tgz",
|
||||
@ -13442,33 +13473,33 @@
|
||||
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
|
||||
},
|
||||
"webpack": {
|
||||
"version": "4.45.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.45.0.tgz",
|
||||
"integrity": "sha512-JhDaVi4CbRcwLLAoqC7eugMSMJnZbIfE2AyjaZ19pnOIh/R2O/lXOiXA2tQFN0iXEcxgpPJsPJHW2wOWqiTLcw==",
|
||||
"version": "4.42.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz",
|
||||
"integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-module-context": "1.9.0",
|
||||
"@webassemblyjs/wasm-edit": "1.9.0",
|
||||
"@webassemblyjs/wasm-parser": "1.9.0",
|
||||
"acorn": "^6.4.1",
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
"@webassemblyjs/helper-module-context": "1.8.5",
|
||||
"@webassemblyjs/wasm-edit": "1.8.5",
|
||||
"@webassemblyjs/wasm-parser": "1.8.5",
|
||||
"acorn": "^6.2.1",
|
||||
"ajv": "^6.10.2",
|
||||
"ajv-keywords": "^3.4.1",
|
||||
"chrome-trace-event": "^1.0.2",
|
||||
"enhanced-resolve": "^4.3.0",
|
||||
"enhanced-resolve": "^4.1.0",
|
||||
"eslint-scope": "^4.0.3",
|
||||
"json-parse-better-errors": "^1.0.2",
|
||||
"loader-runner": "^2.4.0",
|
||||
"loader-utils": "^1.2.3",
|
||||
"memory-fs": "^0.4.1",
|
||||
"micromatch": "^3.1.10",
|
||||
"mkdirp": "^0.5.3",
|
||||
"mkdirp": "^0.5.1",
|
||||
"neo-async": "^2.6.1",
|
||||
"node-libs-browser": "^2.2.1",
|
||||
"schema-utils": "^1.0.0",
|
||||
"tapable": "^1.1.3",
|
||||
"terser-webpack-plugin": "^1.4.3",
|
||||
"watchpack": "^1.7.4",
|
||||
"watchpack": "^1.6.0",
|
||||
"webpack-sources": "^1.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -8,6 +8,7 @@
|
||||
"react-collapse": "^5.0.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-draft-wysiwyg": "^1.14.5",
|
||||
"react-dropzone": "^11.2.4",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scripts": "^3.4.4"
|
||||
},
|
||||
|
@ -48,4 +48,8 @@ export default class API {
|
||||
listTokens() {
|
||||
return this.apiCall("file/listTokens");
|
||||
}
|
||||
|
||||
delete(id) {
|
||||
return this.apiCall("file/delete", { id: id })
|
||||
}
|
||||
};
|
53
fileControlPanel/src/elements/file-browser.css
Normal file
53
fileControlPanel/src/elements/file-browser.css
Normal file
@ -0,0 +1,53 @@
|
||||
.file-row td {
|
||||
padding: 0;
|
||||
border: none;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.file-control-buttons {
|
||||
display: grid;
|
||||
grid-template-rows: auto auto;
|
||||
grid-template-columns: auto auto;
|
||||
}
|
||||
|
||||
.file-control-buttons > button {
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
.file-upload-container {
|
||||
border: dotted;
|
||||
margin: 18px;
|
||||
padding: 15px;
|
||||
min-height: 150px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.file-upload-container > div > div {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto auto;
|
||||
}
|
||||
|
||||
.uploaded-file {
|
||||
max-width: 120px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.uploaded-file > img {
|
||||
width: 50px;
|
||||
height: 56px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.uploaded-file > span {
|
||||
display: block;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.uploaded-file > i {
|
||||
color: red;
|
||||
position: absolute;
|
||||
top: -9px;
|
||||
right: 25px;
|
||||
cursor: pointer;
|
||||
}
|
@ -1,4 +1,7 @@
|
||||
import * as React from "react";
|
||||
import "./file-browser.css";
|
||||
import Dropzone from "react-dropzone";
|
||||
import Icon from "./icon";
|
||||
|
||||
export class FileBrowser extends React.Component {
|
||||
|
||||
@ -6,10 +9,41 @@ export class FileBrowser extends React.Component {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
api: props.api,
|
||||
files: props.files,
|
||||
token: props.token,
|
||||
filesToUpload: [],
|
||||
}
|
||||
}
|
||||
|
||||
svgMiddle(indentation, size=64) {
|
||||
let style = (indentation > 1 ? { marginLeft: ((indentation-1)*size) + "px" } : {});
|
||||
return <svg width={size} height={size} xmlns="http://www.w3.org/2000/svg" style={style}>
|
||||
<g>
|
||||
<line strokeLinecap="undefined" strokeLinejoin="undefined" y2="0" x2={size/2}
|
||||
y1={size} x1={size/2} strokeWidth="1.5" stroke="#000" fill="none"/>
|
||||
<line strokeLinecap="undefined" strokeLinejoin="undefined" y2={size/2} x2={size}
|
||||
y1={size/2} x1={size/2} fillOpacity="null" strokeOpacity="null" strokeWidth="1.5"
|
||||
stroke="#000" fill="none"/>
|
||||
</g>
|
||||
</svg>;
|
||||
}
|
||||
|
||||
svgEnd(indentation, size=64) {
|
||||
let style = (indentation > 1 ? { marginLeft: ((indentation-1)*size) + "px" } : {});
|
||||
return <svg width={size} height={size} xmlns="http://www.w3.org/2000/svg" style={style}>
|
||||
<g>
|
||||
{ /* vertical line */}
|
||||
<line strokeLinecap="undefined" strokeLinejoin="undefined" y2="0" x2={size/2}
|
||||
y1={size/2} x1={size/2} strokeWidth="1.5" stroke="#000" fill="none"/>
|
||||
{ /* horizontal line */}
|
||||
<line strokeLinecap="undefined" strokeLinejoin="undefined" y2={size/2} x2={size}
|
||||
y1={size/2} x1={size/2} fillOpacity="null" strokeOpacity="null" strokeWidth="1.5"
|
||||
stroke="#000" fill="none"/>
|
||||
</g>
|
||||
</svg>;
|
||||
}
|
||||
|
||||
formatSize(size) {
|
||||
const suffixes = ["B","KiB","MiB","GiB","TiB"];
|
||||
let i = 0;
|
||||
@ -20,24 +54,161 @@ export class FileBrowser extends React.Component {
|
||||
return size.toFixed(1) + " " + suffixes[i];
|
||||
}
|
||||
|
||||
render() {
|
||||
canUpload() {
|
||||
return this.state.api.loggedIn || (this.state.token.valid && this.state.token.type === "upload");
|
||||
}
|
||||
|
||||
onAddUploadFiles(acceptedFiles) {
|
||||
let files = this.state.filesToUpload.slice();
|
||||
files.push(...acceptedFiles);
|
||||
this.setState({ ...this.state, filesToUpload: files });
|
||||
}
|
||||
|
||||
getSelectedIds(items = null, recursive = true) {
|
||||
let ids = [];
|
||||
items = items || this.state.files;
|
||||
for (const fileItem of Object.values(items)) {
|
||||
if (fileItem.selected) {
|
||||
ids.push(fileItem.uid);
|
||||
}
|
||||
if (recursive && fileItem.isDirectory) {
|
||||
ids.push(...this.getSelectedIds(fileItem.items));
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
onSelectAll(selected, items) {
|
||||
for (const fileElement of Object.values(items)) {
|
||||
fileElement.selected = selected;
|
||||
if (fileElement.isDirectory) {
|
||||
this.onSelectAll(selected, fileElement.items);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onSelectFile(e, uid, items=null) {
|
||||
|
||||
let found = false;
|
||||
let updatedFiles = (items === null) ? {...this.state.files} : items;
|
||||
if (updatedFiles.hasOwnProperty(uid)) {
|
||||
let fileElement = updatedFiles[uid];
|
||||
found = true;
|
||||
fileElement.selected = e.target.checked;
|
||||
if (fileElement.isDirectory) {
|
||||
this.onSelectAll(fileElement.selected, fileElement.items);
|
||||
}
|
||||
} else {
|
||||
for (const fileElement of Object.values(updatedFiles)) {
|
||||
if (fileElement.isDirectory) {
|
||||
if (this.onSelectFile(e, uid, fileElement.items)) {
|
||||
if (!e.target.checked) {
|
||||
fileElement.selected = false;
|
||||
} else if (this.getSelectedIds(fileElement.items, false).length === Object.values(fileElement.items).length) {
|
||||
fileElement.selected = true;
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (items === null) {
|
||||
this.setState({
|
||||
...this.state,
|
||||
files: updatedFiles
|
||||
});
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
createFileList(elements, indentation=0) {
|
||||
let rows = [];
|
||||
for (const [uid, fileElement] of Object.entries(this.state.files)) {
|
||||
let i = 0;
|
||||
const values = Object.values(elements);
|
||||
for (const fileElement of values) {
|
||||
let name = fileElement.name;
|
||||
let type = (fileElement.directory ? "Directory" : fileElement.mimeType);
|
||||
let size = (fileElement.directory ? "" : fileElement.size)
|
||||
let uid = fileElement.uid;
|
||||
let type = (fileElement.isDirectory ? "Directory" : fileElement.mimeType);
|
||||
let size = (fileElement.isDirectory ? "" : this.formatSize(fileElement.size));
|
||||
// let iconUrl = (fileElement.directory ? "/img/icon/")
|
||||
let iconUrl = "";
|
||||
let token = (this.state.token && this.state.token.valid ? "&token=" + this.token.state.value : "");
|
||||
let svg = <></>;
|
||||
if (indentation > 0) {
|
||||
if (i === values.length - 1) {
|
||||
svg = this.svgEnd(indentation, 48);
|
||||
} else {
|
||||
svg = this.svgMiddle(indentation, 48);
|
||||
}
|
||||
}
|
||||
|
||||
rows.push(
|
||||
<tr key={"file-" + uid}>
|
||||
<td><img src={iconUrl} alt={"[Icon]"} /></td>
|
||||
<td>{name}</td>
|
||||
<tr key={"file-" + uid} data-id={uid} className={"file-row"}>
|
||||
<td>
|
||||
{ svg }
|
||||
<img src={iconUrl} alt={"[Icon]"} />
|
||||
</td>
|
||||
<td>
|
||||
{fileElement.isDirectory ? name :
|
||||
<a href={"/api/file/download?id=" + uid + token} download={true}>{name}</a>
|
||||
}
|
||||
</td>
|
||||
<td>{type}</td>
|
||||
<td>{this.formatSize(size)}</td>
|
||||
<td>{size}</td>
|
||||
<td>
|
||||
<input type={"checkbox"} checked={!!fileElement.selected}
|
||||
onChange={(e) => this.onSelectFile(e, uid)}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
if (fileElement.isDirectory) {
|
||||
rows.push(...this.createFileList(fileElement.items, indentation + 1));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
let rows = this.createFileList(this.state.files);
|
||||
let selectedIds = this.getSelectedIds();
|
||||
let selectedCount = selectedIds.length;
|
||||
let uploadZone = <></>;
|
||||
let writePermissions = this.canUpload();
|
||||
let uploadedFiles = [];
|
||||
|
||||
if (writePermissions) {
|
||||
|
||||
for(let i = 0; i < this.state.filesToUpload.length; i++) {
|
||||
const file = this.state.filesToUpload[i];
|
||||
uploadedFiles.push(
|
||||
<span className={"uploaded-file"} key={i}>
|
||||
<img />
|
||||
<span>{file.name}</span>
|
||||
<Icon icon={"times"} onClick={(e) => this.onRemoveUploadedFile(e, i)}/>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
uploadZone = <><Dropzone onDrop={this.onAddUploadFiles.bind(this)}>
|
||||
{({getRootProps, getInputProps}) => (
|
||||
<section className={"file-upload-container"}>
|
||||
<div {...getRootProps()}>
|
||||
<input {...getInputProps()} />
|
||||
<p>Drag 'n' drop some files here, or click to select files</p>
|
||||
{ uploadedFiles.length === 0 ? <Icon className={"mx-auto fa-3x text-black-50"} icon={"upload"}/> : <div>{uploadedFiles}</div> }
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</Dropzone>
|
||||
</>;
|
||||
}
|
||||
|
||||
return <>
|
||||
@ -49,12 +220,57 @@ export class FileBrowser extends React.Component {
|
||||
<th>Name</th>
|
||||
<th>Type</th>
|
||||
<th>Size</th>
|
||||
<th/>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{ rows }
|
||||
</tbody>
|
||||
</table>
|
||||
<div className={"file-control-buttons"}>
|
||||
<button type={"button"} className={"btn btn-success"} disabled={selectedCount === 0}>
|
||||
<Icon icon={"download"} className={"mr-1"}/>
|
||||
Download Selected Files ({selectedCount})
|
||||
</button>
|
||||
{ this.state.api.loggedIn ?
|
||||
<button type={"button"} className={"btn btn-info"}>
|
||||
<Icon icon={"plus"} className={"mr-1"}/>
|
||||
Create Directory
|
||||
</button> :
|
||||
<></>
|
||||
}
|
||||
{
|
||||
writePermissions ?
|
||||
<>
|
||||
<button type={"button"} className={"btn btn-primary"} disabled={uploadedFiles.length === 0}>
|
||||
<Icon icon={"upload"} className={"mr-1"}/>
|
||||
Upload
|
||||
</button>
|
||||
<button type={"button"} className={"btn btn-danger"} disabled={selectedCount === 0} onClick={(e) => this.deleteFiles(selectedIds)}>
|
||||
<Icon icon={"trash"} className={"mr-1"}/>
|
||||
Delete Selected Files ({selectedCount})
|
||||
</button>
|
||||
</>
|
||||
: <></>
|
||||
}
|
||||
</div>
|
||||
|
||||
{ uploadZone }
|
||||
</>;
|
||||
}
|
||||
|
||||
onRemoveUploadedFile(e, i) {
|
||||
e.stopPropagation();
|
||||
let files = this.state.filesToUpload.slice();
|
||||
files.splice(i, 1);
|
||||
this.setState({ ...this.state, filesToUpload: files });
|
||||
}
|
||||
|
||||
deleteFiles(selectedIds) {
|
||||
// TODO: delete files
|
||||
this.state.api.delete(selectedIds).then((res) => {
|
||||
if (res.success) {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import * as React from "react";
|
||||
import Icon from "./icon";
|
||||
|
||||
export class TokenList extends React.Component {
|
||||
|
||||
@ -25,6 +26,7 @@ export class TokenList extends React.Component {
|
||||
<td>{token.token}</td>
|
||||
<td>{token.type}</td>
|
||||
<td>{token.valid_until}</td>
|
||||
<td><Icon icon={"times"} className={"text-danger"}/></td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
@ -38,12 +40,19 @@ export class TokenList extends React.Component {
|
||||
<th>Token</th>
|
||||
<th>Type</th>
|
||||
<th>Valid Until</th>
|
||||
<th/>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{ rows }
|
||||
</tbody>
|
||||
</table>
|
||||
<div>
|
||||
<button type={"button"} className={"btn btn-success m-2"}>
|
||||
<Icon icon={"plus"} className={"mr-1"}/>
|
||||
Create Token
|
||||
</button>
|
||||
</div>
|
||||
</>;
|
||||
}
|
||||
}
|
@ -49,10 +49,8 @@ class FileControlPanel extends React.Component {
|
||||
|
||||
if (!this.state.loaded) {
|
||||
this.api.fetchUser().then((isLoggedIn) => {
|
||||
console.log(`api.fetchUser => ${isLoggedIn}`);
|
||||
if (isLoggedIn) {
|
||||
this.api.listFiles().then((res) => {
|
||||
console.log(`api.listFiles => ${res.success}`);
|
||||
this.setState({ ...this.state, loaded: true, user: this.api.user, files: res.files });
|
||||
});
|
||||
} else {
|
||||
@ -63,7 +61,7 @@ class FileControlPanel extends React.Component {
|
||||
} else if (this.api.loggedIn || this.state.token.valid) {
|
||||
let tokenList = (this.api.loggedIn) ?
|
||||
<div className={"row"}>
|
||||
<div className={"col-lg-6 col-md-8 col-sm-10 col-xs-12 mx-auto"}>
|
||||
<div className={"col-lg-8 col-md-10 col-sm-12 mx-auto"}>
|
||||
<TokenList api={this.api} />
|
||||
</div>
|
||||
</div> :
|
||||
@ -71,9 +69,9 @@ class FileControlPanel extends React.Component {
|
||||
|
||||
return <div className={"container mt-4"}>
|
||||
<div className={"row"}>
|
||||
<div className={"col-lg-6 col-md-8 col-sm-10 col-xs-12 mx-auto"}>
|
||||
<div className={"col-lg-8 col-md-10 col-sm-12 mx-auto"}>
|
||||
<h2>File Control Panel</h2>
|
||||
<FileBrowser files={this.state.files}/>
|
||||
<FileBrowser files={this.state.files} token={this.state.token} api={this.api} />
|
||||
</div>
|
||||
</div>
|
||||
{ tokenList }
|
||||
@ -81,7 +79,7 @@ class FileControlPanel extends React.Component {
|
||||
} else {
|
||||
return <div className={"container mt-4"}>
|
||||
<div className={"row"}>
|
||||
<div className={"col-lg-6 col-md-8 col-sm-10 col-xs-12 mx-auto"}>
|
||||
<div className={"col-lg-8 col-md-10 col-sm-12 mx-auto"}>
|
||||
<h2>File Control Panel</h2>
|
||||
<form onSubmit={(e) => e.preventDefault()}>
|
||||
<label htmlFor={"token"}>Enter a file token to download or upload files</label>
|
||||
|
10
js/files.min.js
vendored
10
js/files.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user