diff --git a/Frontend/index.html b/Frontend/index.html index 4215efa..9055375 100644 --- a/Frontend/index.html +++ b/Frontend/index.html @@ -24,9 +24,25 @@
-
-
+ +
+
+ +
+
+
+
diff --git a/Frontend/static/css/components.css b/Frontend/static/css/components.css index bd9d43d..9efc636 100644 --- a/Frontend/static/css/components.css +++ b/Frontend/static/css/components.css @@ -15,7 +15,6 @@ body { main { flex: 1 1 auto; - overflow-y: scroll; } footer { @@ -34,18 +33,27 @@ header { background-color: #404040; color: #ffffff; display: grid; - grid-gap: 5%; - grid-template-columns: 25% 40% 25%; + grid-template-columns: auto min-content; height: auto; max-height: 100px; padding: 10px; } .title { + grid-column: 1; margin: 5px; font-size: 2em; } +.logout { + grid-column: 2; + width: 100%; + display: flex; + align-items: center; + justify-content: right; + cursor: pointer; +} + .box { padding: 5px; height: 100%; @@ -55,6 +63,138 @@ button { cursor: pointer; } +.arrow-pointer { + display: inline-block; + height: 2em; + background: #404040; + position: relative; + color: #ffffff; + margin-left: 1em; + margin-bottom: 10px; + cursor: pointer; +} + +.arrow-pointer:first-child { + margin-left: 0; +} + +.arrow-pointer span { + padding-left: 1.5em; + padding-right: 0.5em; + line-height: 2em; +} + +.arrow-pointer:after { + content: ''; + position: absolute; + left: 0; + bottom: 0; + width: 0; + height: 0; + border-left: 1em solid #212121; + border-top: 1em solid #404040; + border-bottom: 1em solid #404040; +} + +.arrow-pointer:before { + content: ''; + position: absolute; + right: -1em; + bottom: 0; + width: 0; + height: 0; + border-left: 1em solid #404040; + border-top: 1em solid #212121; + border-bottom: 1em solid #212121; +} + +#path .arrow-pointer:first-child:after { + border-left: 1em solid #404040; + border-top: 1em solid #404040; + border-bottom: 1em solid #404040; +} + +#path .arrow-pointer:first-child span { + padding-left: 1em; +} + +.modal { + display: none; + position: fixed; + z-index: 100000; + padding-top: 100px; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgba(0,0,0, 0.8); +} + +#content { + background-color: #fefefe; + margin: auto; + padding: 20px; + border: 1px solid #888; + width: 90%; + height: 80%; +} + +.modal-header { + display: grid; + grid-template-columns: 90% 10%; +} + +.modal-header #file_title { + grid-column: 1; + margin: 0; +} + +.modal-header span { + grid-column: 2; + display: flex; + justify-content: flex-end; + align-items: center; +} + +.modal-header span i { + cursor: pointer; +} + +.modal-content { + background-color: #fefefe; + width: 100%; + height: calc(100% - 16px - 2em); +} + +.error { + display: grid; + grid-template-columns: auto min-content; + background: #db2d2d; + border: solid 2px #b61111; + border-radius: 5px; + width: 90%; + height: 3em; + margin-left: auto; + margin-right: auto; + color: #ffffff; +} + +.error .text { + grid-column: 1; + line-height: 3em; + padding-left: 10px; + +} + +.error span:nth-child(2) { + grid-column: 2; + display: flex; + align-items: center; + cursor: pointer; + line-height: 3em; +} + .material-icon { font-family: Material Icons, sans-serif !important; font-weight: 400; diff --git a/Frontend/static/css/index.css b/Frontend/static/css/index.css index 421d122..2ed31df 100644 --- a/Frontend/static/css/index.css +++ b/Frontend/static/css/index.css @@ -1,74 +1,35 @@ #wrapper { color: white; padding: 5px; + width: calc(100% - 10px); + height: 100%; + display: flex; + flex-direction: row; } -#wrapper1 { +#error_wrapper { + padding: 5px; width: 100%; - height: 100%; - display: grid; - grid-template-columns: 30% 70%; } #tree { - grid-column: 1; margin: 5px; + height: 100%; + width: 30%; + max-width: 400px; + border-right: #404040 2px solid; +} + +#files { + margin: 5px; + height: 100%; + width: 70%; } #path { padding-bottom: 10px; } -.arrow-pointer { - display: inline-block; - height: 2em; - background: #404040; - position: relative; - color: #ffffff; - margin-left: 1em; -} - -.arrow-pointer:first-child { - margin-left: 0; -} - -.arrow-pointer span { - padding-left: 1.5em; - padding-right: 0.5em; - padding-top: 0.5em; - -} - -.arrow-pointer:after { - content: ''; - position: absolute; - left: 0; - bottom: 0; - width: 0; - height: 0; - border-left: 1em solid #212121; - border-top: 1em solid #404040; - border-bottom: 1em solid #404040; -} - -.arrow-pointer:before { - content: ''; - position: absolute; - right: -1em; - bottom: 0; - width: 0; - height: 0; - border-left: 1em solid #404040; - border-top: 1em solid #212121; - border-bottom: 1em solid #212121; -} - - -#files { - grid-column: 2; - margin: 5px; -} - table { width: 100%; border-collapse: collapse; @@ -80,9 +41,69 @@ tr { th, td { border-bottom: 1px solid #ccc; + padding: 10px; } thead tr { text-align: left; background: #0062ff; +} + +#tree ul, #tree #tree_ul { + list-style-type: none; + padding-left: 0; +} + +#tree #tree_ul { + margin: 0; + padding: 0; +} + +#tree .folder { + cursor: pointer; + user-select: none; +} + +#tree .folder::before { + font-family: Material Icons, sans-serif !important; + content: "\e2c7"; + display: inline-block; + margin-right: 6px; + font-size: 2em; + vertical-align: -25%; +} + +#tree .folder-open::before { + font-family: Material Icons, sans-serif !important; + content: "\e2c8"; + display: inline-block; + margin-right: 6px; + font-size: 2em; + vertical-align: -25%; +} + +#tree .nested { + display: none; +} + +#tree .active { + display: block; + margin-left: 15px; +} + + +@media (max-width: 700px) { + #wrapper { + flex-direction: column-reverse; + } + + #tree { + width: 100%; + border-top: #404040 2px solid; + border-right: none; + } + + #files { + width: 100%; + } } \ No newline at end of file diff --git a/Frontend/static/css/login.css b/Frontend/static/css/login.css index 14d21da..4f90196 100644 --- a/Frontend/static/css/login.css +++ b/Frontend/static/css/login.css @@ -33,6 +33,6 @@ } #login button { - background-color: #003100; + background-color: #0062ff; color: #ffffff; } \ No newline at end of file diff --git a/Frontend/static/js/index.js b/Frontend/static/js/index.js index e3c98b5..513695c 100644 --- a/Frontend/static/js/index.js +++ b/Frontend/static/js/index.js @@ -1,11 +1,12 @@ -tree = []; +file_path = []; +tree = {}; window.addEventListener('load', function () { - console.log('All assets are loaded'); - if (sessionStorage.getItem("authorization") !== null) { console.log('Logged in'); + create_logout_view(); url_listener(); + create_tree_view_data(''); } else { console.log('Not logged in'); create_login_view(); @@ -20,7 +21,11 @@ function url_listener() { let curr_dir = findGetParameter('path'); if (curr_dir !== null) { - httpGetAsync('http://localhost:8080' + curr_dir, null, show_files); + if(curr_dir.startsWith('/') || curr_dir === '') { + httpGetAsync('http://localhost:8080' + curr_dir, null, show_files); + } else { + create_error_view('directory does not exist'); + } } else { httpGetAsync('http://localhost:8080', null, show_files); } @@ -37,7 +42,9 @@ function login() { console.log(username + ':' + JSON.parse(xmlHttp.responseText)['token']) sessionStorage.setItem("authorization", btoa(username + ':' + JSON.parse(xmlHttp.responseText)['token'])); - httpGetAsync('http://localhost:8080', null, show_files); + create_logout_view(); + + url_listener(); } } } @@ -48,21 +55,22 @@ function login() { } function show_files(response, code) { - document.getElementById("wrapper").innerHTML = ''; if (code === 200) { // OK - console.log(code); - console.log(JSON.parse(response)); create_file_view(JSON.parse(response)); } else if (code === 401) { // Not logged in sessionStorage.removeItem('authorization'); - // location.reload(); + create_login_view(); } else { // Error console.error(code); console.error(JSON.parse(response)); - sessionStorage.removeItem('authorization'); + + response = JSON.parse(response); + create_error_view(response['error']); + + // sessionStorage.removeItem('authorization'); // location.reload(); } } @@ -70,35 +78,21 @@ function show_files(response, code) { function one_dir_back() { let curr_dir = findGetParameter('path'); - let dir = curr_dir.split('/'); - dir = dir.slice(0, dir.length - 1); - curr_dir = dir.join('/'); + if(curr_dir !== null) { + let dir = curr_dir.split('/'); + dir = dir.slice(0, dir.length - 1); + curr_dir = dir.join('/'); - return curr_dir; + return curr_dir; + } + + return ''; } -// function change_dir(name) { -// let curr_dir = findGetParameter('path'); -// -// if(curr_dir === null) { -// curr_dir = ''; -// } -// -// if (name === '..') { -// let dir = curr_dir.split('/'); -// dir = dir.slice(0, dir.length - 1); -// curr_dir = dir.join('/'); -// -// httpGetAsync('http://localhost:8080' + curr_dir, null, show_files); -// window.history.pushState('index', 'Filemanager', 'index.html?path=' + curr_dir); -// } else { -// httpGetAsync('http://localhost:8080' + curr_dir + '/' + name, null, show_files); -// window.history.pushState('index', 'Filemanager', 'index.html?path=' + curr_dir + '/' + name); -// } -// } - -function load_file(name) { +function load_file(name, type) { let curr_dir = findGetParameter('path'); - console.log(curr_dir + '/' + name); + if (curr_dir === null) curr_dir = ''; + + show_file_view(curr_dir + '/' + name, type); } \ No newline at end of file diff --git a/Frontend/static/js/tools.js b/Frontend/static/js/tools.js index de4f73e..475feba 100644 --- a/Frontend/static/js/tools.js +++ b/Frontend/static/js/tools.js @@ -6,7 +6,6 @@ function httpGetAsync(url, data, callback) { // data includes auth } } - console.log(url) xmlHttp.open("GET", url, true); xmlHttp.setRequestHeader('Authorization', 'Basic ' + sessionStorage.getItem('authorization')); xmlHttp.send(null); diff --git a/Frontend/static/js/views.js b/Frontend/static/js/views.js index 2de8329..e6cd93a 100644 --- a/Frontend/static/js/views.js +++ b/Frontend/static/js/views.js @@ -16,101 +16,276 @@ function create_login_view() { `; - document.getElementById("wrapper").appendChild(tmp.firstChild); + document.getElementById("login").appendChild(tmp.firstChild); } -// function create_tree_view(data) { -// let curr_dir = findGetParameter('path'); -// let path = curr_dir.split('/'); -// -// for (let i = 0; i < data.length; i++) { -// if (tree[path[0]] === null) { -// tree[path[0]] = {}; -// } -// -// if (data[i]['Type'] === 'dir') { -// -// } -// } -// console.log(data) -// } +function create_logout_view() { + let logout = document.createElement('div'); + logout.classList.add('logout'); + logout.innerText = 'Logout'; + logout.onclick = function () { + sessionStorage.removeItem('authorization'); + location.reload(); + } + document.getElementsByClassName('app-header')[0].appendChild(logout); +} + +function create_tree_view_data(curr_dir) { + let url = 'http://localhost:8080' + curr_dir; + + const xmlHttp = new XMLHttpRequest(); + xmlHttp.onreadystatechange = function () { + if (this.readyState === 4) { + if (xmlHttp.status === 200) { + let data = JSON.parse(xmlHttp.responseText); + + for (let i = 0; i < data.length; i++) { + if (data[i]['Type'] === 'dir') { + file_path.push(curr_dir + '/' + data[i]['Name']); + create_tree_view_data(curr_dir + '/' + data[i]['Name']); + } + } + + tree = file_path.reduce((arr, path) => addPath(path.split('/'), arr), [])[0]['children']; + create_tree_view(); + } + } + } + + xmlHttp.open("GET", url, true); + xmlHttp.setRequestHeader('Authorization', 'Basic ' + sessionStorage.getItem('authorization')); + xmlHttp.send(null); +} + +function addPath(pathcomponents, arr ){ + let component = pathcomponents.shift() + let comp = arr.find(item => item.text === component) + if (!comp) { + comp = {text: component} + arr.push(comp) + } + if(pathcomponents.length){ + addPath(pathcomponents, comp.children || (comp.children = [])) + } + return arr +} + +function create_tree_view() { + let tree = document.createElement('div'); + tree.innerHTML = ` `; + + document.getElementById("tree").innerHTML = ''; + create_list_view(this.tree, document.getElementById("tree"), ''); + + // Remove nested-class from root element + document.getElementsByTagName('ul')[0].classList.remove('nested') + + let toggler = document.getElementsByClassName("folder"); + for (let i = 0; i < toggler.length; i++) { + toggler[i].addEventListener("click", function () { + if(this.parentElement.querySelector(".nested") !== null) { + this.parentElement.querySelector(".nested").classList.toggle("active"); + } + this.classList.toggle("folder-open"); + }); + } +} + +function tree_onclick(url) { + window.history.pushState('index', 'Filemanager', 'index.html?path=' + url); + url_listener(); +} + +function create_list_view(dataRoot, elementRoot, url) { + if (dataRoot) { + const list = document.createElement('ul'); + list.classList.add('nested'); + elementRoot.appendChild(list); + + Object.keys(dataRoot).forEach(key => { + // // Create a text node and a list element to put it in + const listElement = document.createElement('li'); + listElement.innerHTML = `${dataRoot[key].text}`; + list.appendChild(listElement); + + // Continue recursively down now using the current list element + console.log(url + '/' + dataRoot[key].text) + create_list_view(dataRoot[key]['children'], listElement, url + '/' + dataRoot[key].text); + }); + } +} function create_file_view(data) { let curr_dir = findGetParameter('path'); - let tmp = document.createElement('div'); - tmp.innerHTML = `
-
Div 1
-
-
- - - - - - - - - - - - - - - - - -
IconNameGrößeDatum
..
-
-
`; + let files = document.createElement('div'); + files.innerHTML = `
+ + + + + + + + + + + + + + + +
NameType
..
`; // Folders for (let i = 0; i < data.length; i++) { if (data[i]['Type'] === 'dir') { - let tmp1 = document.createElement('tr'); - tmp1.style = 'cursor: pointer;'; - tmp1.onclick = function () { + let folder = document.createElement('tr'); + folder.style = 'cursor: pointer;'; + folder.onclick = function () { if (curr_dir === null) curr_dir = ''; window.history.pushState('index', 'Filemanager', 'index.html?path=' + curr_dir + '/' + data[i]['Name']); url_listener(); }; - tmp1.innerHTML = `folder + folder.innerHTML = `folder ${data[i]['Name']} - -- - --`; - tmp.getElementsByTagName('tbody')[0].appendChild(tmp1); + directory`; + files.getElementsByTagName('tbody')[0].appendChild(folder); } } // Files for (let i = 0; i < data.length; i++) { if (data[i]['Type'] !== 'dir') { - let tmp1 = document.createElement('tr'); - tmp1.style = 'cursor: pointer;'; - tmp1.onclick = function () { - if (curr_dir === null) curr_dir = ''; - load_file(curr_dir, data[i]['Name']); + let file = document.createElement('tr'); + file.style = 'cursor: pointer;'; + file.onclick = function () { + load_file(data[i]['Name'], data[i]['Type']); }; - tmp1.innerHTML = `description + + let icon = 'article'; + if (data[i]['Type'].indexOf("application") >= 0) { + icon = 'apps'; + } else if (data[i]['Type'].indexOf("audio") >= 0) { + icon = 'music_note'; + } else if (data[i]['Type'].indexOf("drawing") >= 0) { + icon = 'gesture'; + } else if (data[i]['Type'].indexOf("image") >= 0) { + icon = 'image'; + } else if (data[i]['Type'].indexOf("message") >= 0) { + icon = 'mail'; + } else if (data[i]['Type'].indexOf("multipart") >= 0) { + icon = 'note_add'; + } else if (data[i]['Type'].indexOf("text") >= 0) { + icon = 'description'; + } else if (data[i]['Type'].indexOf("video") >= 0) { + icon = 'movie'; + } + + file.innerHTML = `${icon} ${data[i]['Name']} - -- - --`; - tmp.getElementsByTagName('tbody')[0].appendChild(tmp1); + ${data[i]['Type']}`; + files.getElementsByTagName('tbody')[0].appendChild(file); } } // Path - let tmp1 = document.createElement('div'); - let s = `
/
`; + let s = `
/
`; if (curr_dir !== null) { let folders = curr_dir.split('/'); for (let i = 1; i < folders.length; i++) { - s = s.concat(`
${folders[i]}
`); + s = s.concat(`
${folders[i]}
`); } } - tmp1.innerHTML = s; - tmp.getElementsByTagName('div')[3].appendChild(tmp1); + files.getElementsByTagName('div')[0].innerHTML = s; - document.getElementById("wrapper").appendChild(tmp.firstChild); + document.getElementById("files").innerHTML = ''; + document.getElementById("files").appendChild(files); +} + +function create_error_view(text) { + let error = document.createElement('div'); + error.innerHTML = `
+ ${text}. Go back + close +
`; + + document.getElementById('error_wrapper').appendChild(error.firstChild); +} + +function show_file_view(data, type) { + let modal = document.getElementById("file_view"); + let title = document.getElementById("file_title"); + let modal_content = document.getElementsByClassName("modal-content")[0]; + + + if (type.indexOf("application") >= 0) { + modal_content.innerHTML = ``; + } else if (type.indexOf("audio") >= 0) { + httpGetAsync('http://localhost:8080' + data + '?format=base64', null, show_audio_data); + } else if (type.indexOf("drawing") >= 0) { + modal_content.innerHTML = ``; + } else if (type.indexOf("image") >= 0) { + httpGetAsync('http://localhost:8080' + data + '?format=base64', null, show_image_data); + } else if (type.indexOf("message") >= 0) { + modal_content.innerHTML = ``; + } else if (type.indexOf("multipart") >= 0) { + modal_content.innerHTML = ``; + } else if (type.indexOf("text") >= 0) { + httpGetAsync('http://localhost:8080' + data, null, show_text_data); + } else if (type.indexOf("video") >= 0) { + httpGetAsync('http://localhost:8080' + data + '?format=base64', null, show_video_data); + } else if (type.indexOf("workbook") >= 0) { + modal_content.innerHTML = ``; + } else if (type.indexOf("x-world") >= 0) { + modal_content.innerHTML = ``; + } else { + modal_content.innerHTML = ``; + } + + title.innerText = `File: ${data}`; + + modal.style.display = "block"; +} + +function show_image_data(response, code) { + if (code === 200) { + document.getElementsByClassName("modal-content")[0].innerHTML = `Image`; + } else { + console.log(code + " " + response); + } +} + +function show_text_data(response, code) { + if (code === 200) { + document.getElementsByClassName("modal-content")[0].innerHTML = ` + + + `; + } else { + console.log(code + " " + response); + } +} + +function show_audio_data(response, code) { + if (code === 200) { + document.getElementsByClassName("modal-content")[0].innerHTML = ``; + } else { + console.log(code + " " + response); + } +} + +function show_video_data(response, code) { + if (code === 200) { + document.getElementsByClassName("modal-content")[0].innerHTML = ``; + } else { + console.log(code + " " + response); + } } \ No newline at end of file