diff --git a/frontend/js/apicalls.js b/frontend/js/apicalls.js index 86af4d20e6d8132e92cc60dd783ba9a6476a9946..bd9c42b867b059d12d894b3409ab366a9d0e1bcf 100644 --- a/frontend/js/apicalls.js +++ b/frontend/js/apicalls.js @@ -1,54 +1,45 @@ -// This file will contain the api calls, as well as transform the data into html-text (via a template) - -var apiUrl = "http://zam024.fritz.box/api/"; - -// get variable map from url -function getUrlVars() -{ - var vars = [], hash; - var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); - for(var i = 0; i < hashes.length; i++) - { - hash = hashes[i].split('='); - vars.push(hash[0]); - vars[hash[0]] = hash[1]; - } - return vars; -} +// This file contains the api calls, as well as transform the data into html-text -// return the storage type -function getType() { - var type = getUrlVars()["type"]; - console.log("Type: " + type); - return type; -} +var apiUrl = "http://zam024.fritz.box/api/"; // TODO switch out with real url, ideally during deployment +var allowedTypesList = []; // return the dataset id function getId() { - var id = getUrlVars()["id"]; + var id = getUrlVars()["oid"]; console.log("ID: " + id); return id; } -// set the text of the typetext element -function setTypeText() { - $('#typetext').text(getType()); -} - -// get option-html string from typename and url suffix +// get option-html string from typename suffix function getTypeHTMLString(name) { return '<li><a class="dropdown-item" href="?type=' + name + '">' + name + '</a></li>'; } +// get tableentry-html for a dataset +function getDatasetHTMLString(dataset) { + return '<tr><th scope="row">'+ dataset[0] + '</th><td><a href="?type=' + getType() + "&oid=" + dataset[1] + '">' + dataset[1] + '</a></td></tr>' +} + +/* +get html for table entry with a proeprty +The value field is editable, but the edit is blocked by default +authenticated users should be able to edit and submit +*/ +function getPropertyHTMLString(property, value) { + return '<tr><th scope="row">' + property + '</th><td><input class="form-control" type="text" value="' + value + '" readonly></td></tr>'; +} + // XMLHttpRequest EVENTLISTENER: if a dropdown-menu (a <ul> element) with the dropdownOptions id is present, update it with the available types function setTypeData() { console.log("GET " + this.responseUrl + ": " + this.responseText); var types = JSON.parse(this.responseText); + allowedTypesList = []; // types is now a list of {name : url} elements, where url starts with a slash, and is relative to the root var keyName = ""; types.forEach(element => { keyName = Object.keys(element)[0]; console.log("Detected location type: " + keyName); + allowedTypesList.push(keyName); $('#dropdownOptions').append(getTypeHTMLString(keyName)); }); } @@ -57,17 +48,42 @@ function setTypeData() { function setDatasetList() { console.log("GET " + this.responseUrl + ": " + this.responseText); var datasets = JSON.parse(this.responseText); - + datasets.forEach(element => { + console.log("Found Dataset: " + element) + $('#datasetTableBody').append(getDatasetHTMLString(element)); + }); } -// XMLHttpRequest EVENTLISTENER: show single datset -function setDatasetList() { +// XMLHttpRequest EVENTLISTENER: show dataset in table +function setDatasetView() { console.log("GET " + this.responseUrl + ": " + this.responseText); - var datasets = JSON.parse(this.responseText); - + var dataset = JSON.parse(this.responseText); + if (this.status >= 300) { + alert(getId() + " does not exists for this storage type!"); + window.location.href = "?type=" + getType(); + return; + } + // dataset has a name and url attribute, as well as a map as metadata attribute + // first, hide the list table and make the element viewer visible + $('#datasetListTable').hide(); + $('#storageTypeChooser').hide(); + $('#datasetViewTable').show(); + + // now append name and url to the view + $('#datasetViewTableBody').append(getPropertyHTMLString('Name', dataset.name)); + $('#datasetViewTableBody').append(getPropertyHTMLString('OID', getId())); + $('#datasetViewTableBody').append(getPropertyHTMLString('URL', dataset.url)); + + // insert a linebreak that announces other metadata + $('#datasetViewTableBody').append('<tr><th class="info" scope="row" colspan="2">Other Metadata</th></tr>'); + + // iterate over metadata map and add additional properties + for (const [key, val] of Object.entries(dataset.metadata)) { + $('#datasetViewTableBody').append(getPropertyHTMLString(key, val)); + } } -// get available types from api, put them in the relevant dropdown +// get available types from api, put them in the relevant dropdown (via listener) function getTypes() { var xmlhttp = new XMLHttpRequest(); xmlhttp.addEventListener("loadend", setTypeData); @@ -75,7 +91,7 @@ function getTypes() { xmlhttp.send(); } -// get listing of datasets of the given type, put them in the list element +// get listing of datasets of the given type, put them in the list element (via listener) function listDatasets(datatype) { var fullUrl = apiUrl + datatype; console.log("Full url for listing request is " + fullUrl) @@ -85,7 +101,7 @@ function listDatasets(datatype) { xmlhttp.send(); } -// get details about given dataset, put them in the view element§ +// get details about given dataset, put them in the view element (via listener) function showDataset(datatype, dataset_id) { var fullUrl = apiUrl + datatype + "/" + dataset_id; console.log("Full url for showing request is " + fullUrl) @@ -100,9 +116,22 @@ function showDataset(datatype, dataset_id) { //either enable the dataset listing or enable the single dataset view -function showListingOrSingleDataset() { - // compare getType with allowed types - // if none or illegal type: show first allowed one - // then check if dataset id is present, if yes, show that dataset - // if no id, or non-existent id, list all sets of type -} \ No newline at end of file +async function showListingOrSingleDataset() { + while (allowedTypesList.length == 0) { + await new Promise(resolve => setTimeout(resolve, 10)); + } + if (!getType() ||!allowedTypesList.includes(getType())) { + // no type or invalid type: reload page with first allowed type TODO add some alert? + window.location.href = "?type=" + allowedTypesList[0]; + } + if (!getId()) { // no id given, so list all elements + listDatasets(getType()); + } else { // an id is given, show the dataset, error message if invalid + showDataset(getType(), getId()); + } +} + + +// TODO function(s) to POST new Dataset (get bearer token from auth.js) +// TODO function(s) to PUT existing Dataset (get bearer token from auth.js) +// TODO function(s) to DELETE existing Dataset (get bearer token from auth.js) \ No newline at end of file diff --git a/frontend/js/auth.js b/frontend/js/auth.js index 48f89d356329ce4b6a180693b89401a1d3cac51d..80ba2332348b60d5c00fb9a19e35103c1bcd2196 100644 --- a/frontend/js/auth.js +++ b/frontend/js/auth.js @@ -1 +1,16 @@ // This file will contain functions to manage authentication (including the token storage and access) + +// TODO function to rewrite Login as logout +// TODO function to add "ME" option to navbar (maybe add both and hide as needed) + +// TODO function(s) to post to receive and store bearer token + +/* +makes a post call for the token and stores it in localstorage +*/ +function login(isername, password) { + +} + +// TODO funciton to call /me +// TODO function to get bearer token (for external use) \ No newline at end of file diff --git a/frontend/js/choose_storage.js b/frontend/js/choose_storage.js index 8b71c9a3dc3be275c9439a365ea5cfef9f120ba3..07784301ed19e18257147ac846556794616a9e15 100644 --- a/frontend/js/choose_storage.js +++ b/frontend/js/choose_storage.js @@ -22,6 +22,4 @@ function getType() { // set the text of the typetext element function setTypeText() { $('#typetext').text(getType()) -} - -setTypeText() \ No newline at end of file +} \ No newline at end of file diff --git a/frontend/templates/impressum_content.html.jinja b/frontend/templates/impressum_content.html.jinja index a0a1793bfbcb6ac9787017346322deb5092d8651..6af8ed39dfb4d51ebd71be6c6877fed6cde4d226 100644 --- a/frontend/templates/impressum_content.html.jinja +++ b/frontend/templates/impressum_content.html.jinja @@ -2,7 +2,15 @@ {% block title %}Impressum{% endblock %} {% block content %} -<p>INSERT IMPRESSUM HERE!!</p> +<div class="container"> + <div class="row"> + <div class="col-sm-8"> + <p>INSERT IMPRESSUM HERE!!</p> + + <hr class="hidden-sm hidden-md hidden-lg"> + </div> + </div> +</div> {% endblock %} {% block scripts %} diff --git a/frontend/templates/login_content.html.jinja b/frontend/templates/login_content.html.jinja index 1d044e9b051842ad459992aecd5f78b1776dbc22..466f063cbab050b2df59a099b0634d6ca7bc6c60 100644 --- a/frontend/templates/login_content.html.jinja +++ b/frontend/templates/login_content.html.jinja @@ -1,9 +1,52 @@ {% extends "base.html.jinja"%} {% block title %}Login{% endblock %} +{% block extraheader %} +<link rel="stylesheet" href="css/loginform.css"> +{% endblock %} {% block content %} -<p>INSERT Login Stuff HERE!!</p> + +<div class="container"> + <div class="row"> + <div class="col-sm-8"> + <div id="loginForm"> + <!-- Tabs Titles --> + + <!-- Icon --> + <!-- + <div class="fadeIn first"> + <img src="http://danielzawadzki.com/codepen/01/icon.svg" id="icon" alt="User Icon" /> + </div> + --> + + <!-- Login Form --> + <form> + <input type="text" id="login" class="fadeIn second" name="login" placeholder="username" required='required'> + <input type="password" id="password" class="fadeIn third" name="login" placeholder="password" required='required'> + <button type="submit" class="fadeIn fourth" value="Log In">Log In</button> + </form> + + <!-- Remind Passowrd --> + <!-- + <div id="formFooter"> + <a class="underlineHover" href="#">Forgot Password?</a> + </div> + --> + </div> + + <hr class="hidden-sm hidden-md hidden-lg"> + </div> + </div> +</div> {% endblock %} {% block scripts %} +<script> +$("form").on('submit',function(e){ + e.preventDefault(); + //call actual submission here + // TODO + alert("Tried to Log in, but the function is not yet implemented!"); +}); +</script> {% endblock %} \ No newline at end of file diff --git a/frontend/templates/storage_content.html.jinja b/frontend/templates/storage_content.html.jinja index e5aebece1e41c6132ebd3eecc46ae11af45885ec..3914af26bac6b329640ee8ffbccddf5781e25f47 100644 --- a/frontend/templates/storage_content.html.jinja +++ b/frontend/templates/storage_content.html.jinja @@ -5,18 +5,36 @@ <div class="container"> <div class="row"> <div class="col-sm-8"> - <div class="dropdown"> - <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuType" data-bs-toggle="dropdown" aria-expanded="false"> + <div class="dropdown" id="storageTypeChooser"> + <button class="btn btn-primary dropdown-toggle" type="button" id="dropdownType" data-toggle="dropdown" aria-expanded="false"> Select Storage Type </button> <label id="typetext">TYPENAME</label> - <ul class="dropdown-menu" aria-labelledby="dropdownMenuType"> - <li><a class="dropdown-item" href="?type=dataset">Dataset</a></li> - <li><a class="dropdown-item" href="?type=storagetarget">Storage Target</a></li> + <ul class="dropdown-menu" aria-labelledby="dropdownType" id="dropdownOptions"> </ul> </div> - <h2>Basic information about this service</h2> - <h5>Documentation of the data format</h5> - <div class="fakeimg">Maybe the Logo again</div> + + <table class="table table-hover" id="datasetListTable"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">OID</th> + </tr> + </thead> + <tbody id="datasetTableBody"> + </tbody> + </table> + + <table class="table table-hover" id="datasetViewTable"> + <thead> + <tr> + <th scope="col">Property</th> + <th scope="col">Value</th> + </tr> + </thead> + <tbody id="datasetViewTableBody"> + </tbody> + </table> + <hr class="hidden-sm hidden-md hidden-lg"> </div> </div> @@ -25,4 +43,11 @@ {% block scripts %} <script src="js/choose_storage.js"></script> + <script> + setTypeText(); + getTypes(); + $('#datasetViewTable').hide(); + $('#submitButton').hide(); + showListingOrSingleDataset(); + </script> {% endblock %} \ No newline at end of file