Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • maspect/amiv-admintool
  • emustafa/amiv-admintool
  • dvruette/amiv-admintool
  • amiv/amiv-admintool
4 results
Show changes
Commits on Source (484)
Showing with 18383 additions and 2839 deletions
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-dockerfile
{
"name": "amiv-admintool",
"image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:14",
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [9000],
// Uncomment the next line to run commands after the container is created.
"postCreateCommand": "npm install"
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root.
//"remoteUser": "node"
}
......@@ -7,9 +7,18 @@ module.exports = {
"browser": true,
},
"rules": {
"no-console": 0,
"no-console": 1,
"class-methods-use-this": 0,
"prefer-destructuring": 1,
"no-underscore-dangle": 0,
"linebreak-style": 0,
"import/no-unresolved": [ "error", { "ignore": [ 'networkConfig' ] } ], // hack until resolving import properly
"object-curly-newline": [ "error", {
ObjectExpression: { multiline: true, consistent: true },
ObjectPattern: { multiline: true, consistent: true },
ImportDeclaration: { minProperties: 7, consistent: true },
ExportDeclaration: { minProperties: 7, consistent: true },
}],
"max-len": [ "error", { "code": 100, ignorePattern: ".*<svg.+>" }],
}
};
.ftpconfig
node_modules/
.idea/
dist/
.DS_Store
stages:
- test
- build
- deploy
dev_deploy:
stage: deploy
image: alpine:latest
when: manual
eslint:
stage: test
image: node:latest
before_script:
- npm install
script:
- npm run lint
build_master:
stage: build
image: docker:stable
services:
- docker:dind
before_script:
- 'which ssh-agent || ( apk update -y && apk add openssh-client -y )'
- mkdir -p ~/.ssh
- eval $(ssh-agent -s)
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
- echo "$DEPLOY_PRIVATE_KEY" | ssh-add -
- echo "$CI_DOCKER_REGISTRY_TOKEN" | docker login -u "$CI_DOCKER_REGISTRY_USER" --password-stdin
script:
- ssh -p22 amivadmin@amiv-zoidberg.ethz.ch "docker build -t admintools ./amiv-containers/admintools/"
- ssh -p22 amivadmin@amiv-zoidberg.ethz.ch "cd ./amiv-containers/ && docker-compose up -d"
- docker build --build-arg NPM_BUILD_COMMAND=build --pull -t "$CI_REGISTRY_IMAGE:prod" ./
- docker build --build-arg NPM_BUILD_COMMAND=build-staging --pull -t "$CI_REGISTRY_IMAGE:staging" ./
- docker build --build-arg NPM_BUILD_COMMAND=build-local --pull -t "$CI_REGISTRY_IMAGE:local" ./
- docker push "$CI_REGISTRY_IMAGE:prod"
- docker push "$CI_REGISTRY_IMAGE:staging"
- docker push "$CI_REGISTRY_IMAGE:local"
environment:
name: production
url: https://admin.amiv.ethz.ch
only:
- master
build_dev:
stage: build
image: docker:stable
services:
- docker:dind
before_script:
- echo "$CI_DOCKER_REGISTRY_TOKEN_DEV" | docker login -u "$CI_DOCKER_REGISTRY_USER_DEV" --password-stdin
script:
- docker build --build-arg NPM_BUILD_COMMAND=build-dev --pull -t "$CI_REGISTRY_IMAGE_DEV" ./
- docker push "$CI_REGISTRY_IMAGE_DEV"
environment:
name: development
url: https://amiv-admin.amiv.ethz.ch
url: https://admin-dev.amiv.ethz.ch
deploy:
stage: deploy
image: amiveth/ansible-ci-helper
script:
- python /main.py
File moved
# Summary
> Hi! Thanks for contributing to the admintools by reporting a new Bug!
> In order to fix the bug soon, please help us to figure out what causes the
> malfunction!
> describe the issue here
# Steps to Reproduce
> What is the main menu point (left menu bar) where this issue occurs?
> Copy and Paste the url from the window where the issue occured
> Describe in your own words what steps you did before the issue occured
# Additional Debug Information
> Please add information on what browser and operating system you are using
> If possible, can you make a screenshot of the bug?
> Please open the "developer tools" of your browser and copy and paste any
> printouts in the "console"
/label ~bug
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/src/relationlistcontroller.js"
}
]
}
\ No newline at end of file
# First stage: Build project
FROM node:14 as build
ARG NPM_BUILD_COMMAND=build
# Copy files and install dependencies
COPY ./ /
RUN npm install
# Build project
RUN npm run $NPM_BUILD_COMMAND
# Second stage: Server to deliver files
FROM nginx:1.15-alpine
# Copy files from first stage
COPY --from=build /index.html /var/www/
COPY --from=build /dist /var/www/dist
# Copy nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Admintool
### Software:
* ```ubuntu /14.04.1```
* ```nginx /1.4.6```
### Dependecies:
* ```jQuery /2.2.2```
* ```bootstrap /3.3.6```
# Developer Installation
## w/ Docker
Start the dev Container in VS Code
run ```npm run start``` inside the container.
The development server is available under localhost:9000. It refreshes automatically as soon as you save changes in any `.js` file.
## w/o Docker
```
npm install
......@@ -16,17 +17,30 @@ npm install
And now, start developing:
```
npm start
npm run start
```
*Warning*: For installation on Ubuntu 16.04 (and possibly similar), you need to install nodejs from the repos source.
1. Remove nodejs if you already have it (ONLY IF YOU REALLY WANT!):
```
sudo apt remove nodejs
```
2. Add nodejs10 from repo (download): `curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -`
3. Install: `sudo apt install -y nodejs`
4. Clean-up and install the packages for amiv-admintools
```
rm -rf node_modules/
npm install
npm run start
```
This will open up a local server outputting the current version of the admintools. It refreshes automatically as soon as you save changes in any `.js` file.
### File Structure:
* admin (Admintool)
* res (Resources)
* bg (big pictures and backgrounds)
* favicon
* fonts
* logo
* bootstrap
* js
* src
* public (Website)
* res (Resources)
- favicon
- logo
* src
- views (reusable view components, etc for Tables and selection lists)
- `index.js` main file
- `*Tool.js` main file per API resource, e.g. for all user-related UIs.
......@@ -20,8 +20,19 @@
<link rel="icon" type="image/png" sizes="96x96" href="res/favicon/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="res/favicon/favicon-16x16.png">
<link href="res/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="lib/cust/main.css" rel="stylesheet">
<!--link href="lib/cust/main.css" rel="stylesheet"-->
<style>
@keyframes spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
@keyframes popup {
from { opacity: 0; }
90% { opacity: 0; }
to { opacity: 100%; }
}
} </style>
</head>
<body>
......
(function(window) {
'use strict';
// Library NameSpace
var lns = 'amivcore'
function libgen() {
// Lib to returned
var lib = {};
// Core
var core = {
// Important vars n' stuff
lib: {
api_url: api_url_config,
spec_url: spec_url_config,
authenticated: false,
ready: false,
req_time_out: 5000,
on_interval: 100,
auth_interval: 5000,
auth_allowed_fails: 5,
auth_fails: 0,
show_errors: false,
},
// Header Setup
header: {
req: {
'get': ['Content-Type', 'Authorization'],
'post': ['Content-Type', 'Authorization'],
'patch': ['Content-Type', 'Authorization', 'If-Match'],
'delete': ['Content-Type', 'Authorization', 'If-Match'],
},
make: {
'Content-Type': function() {
return 'application/json'
},
'Authorization': function() {
var token = get('cur_token');
if (token != null)
return token;
return '';
},
'If-Match': function() {
return null;
}
}
},
adapter: {
'none': function(ret) {
return ret;
},
'string': function(strg) {
return String(strg);
},
'integer': function(int) {
return parseInt(int);
},
'boolean': function(bool) {
return (String(bool).trim().toLowerCase() == 'true' || bool === true || bool === 1)
},
'datetime': function(dt) {
var tmp = new Date(dt);
// send an iso string without the milis, thats what the api expects
return new Date(dt).toISOString().split('.')[0]+"Z";
}
}
}
/**
* Utility empty function for no callback
* @constructor
*/
function dummy() {};
/**
* Save and get into localStorage
* @constructor
* @param {string} cname
* @param {string} cvalue
*/
function set(cname, cvalue) {
if (lib.shortSession) {
window.sessionStorage.setItem('glob-' + cname, cvalue);
}
else
window.localStorage.setItem('glob-' + cname, cvalue);
}
/**
* Get from LocalStorage
* @constructor
* @param {string} cname
*/
function get(cname) {
if (lib.shortSession)
return window.sessionStorage.getItem('glob-' + cname);
else
return window.localStorage.getItem('glob-' + cname);
}
/**
* Remove variable in localStorage
* @param {string} cname
*/
function remove(cname) {
if (lib.shortSession) {
if (window.sessionStorage.getItem('glob-' + cname) !== null)
window.sessionStorage.removeItem('glob-' + cname);
}
else {
if (window.localStorage.getItem('glob-' + cname) !== null)
window.localStorage.removeItem('glob-' + cname);
}
}
/**
* Make JSON request with all request parameters in attr
* @constructor
* @param {} attr - all request parameters (attr.path, attr.data, attr.method ...)
* @param {} callback
*/
function req(attr, callback) {
callback = callback || function(msg) {
console.log(msg);
};
$.ajax({
url: core.lib.api_url + attr.path,
data: JSON.stringify(attr.data),
method: attr.method,
dataType: "json",
timeout: core.lib.req_time_out,
headers: attr.headers,
error: function(res) {
if (core.lib.show_errors) console.log(res);
callback(res);
},
}).done(function(res) {
callback(res);
});
}
/**
* Make FormData request with all request parameters in attr
* @constructor
* @param {} attr - all request parameters (attr.path, attr.data, attr.method ...)
* @param {} callback
*/
function reqFormData(attr, callback) {
callback = callback || function(msg) {
console.log(msg);
};
// put the json object into form-data
var form = new FormData();
for (var key in attr['data'])
form.append(key, attr['data'][key]);
$.ajax({
url: core.lib.api_url + attr.path,
data: form,
method: attr.method,
dataType: "json",
contentType: false,
processData: false,
timeout: core.lib.req_time_out,
headers: attr.headers,
error: function(res) {
if (core.lib.show_errors) console.log(res);
callback(res);
},
}).done(function(res) {
callback(res);
});
}
/**
* Make Function
* @constructor
* @param {string} domain
* @param {string} m - method
*/
function makeFunc(domain, m) {
return function(attr, callback) {
attr = attr || {}; // if attr does not exist use empty object
var curLib = {}
for (var curAttr in attr['data']) {
var curAttrType = lib.getParamType(domain, curAttr);
if (core.adapter.hasOwnProperty(curAttrType))
curLib[curAttr] = core.adapter[lib.getParamType(domain, curAttr)](attr['data'][curAttr]);
else
curLib[curAttr] = attr['data'][curAttr];
}
//curLib[curAttr] = attr['data'][curAttr];
var hdr = {};
for (var curHdr in attr['header'])
hdr[curHdr] = attr['header'][curHdr];
var curPath = '/' + domain;
var curLink = curPath;
if (attr['id'] != undefined) {
curPath += '/' + attr['id'];
curLink += '/{_id}';
}
// handle where, sort, projection, embedded
var urlParams = "";
var urlTypes = ['where', 'sort', 'projection', 'embedded'];
if (m === 'GET') {
for (var curUrlType of urlTypes) {
if (attr[curUrlType] != undefined) {
urlParams += ((urlParams != "") ? "&" + curUrlType + "=": curUrlType + "=");
if (typeof attr[curUrlType] === 'object')
urlParams += JSON.stringify(attr[curUrlType]);
else
urlParams += attr[curUrlType];
}
}
}
// append urlParams
curPath += "?" + urlParams;
if (get('cur_token') != null)
hdr['Authorization'] = 'Basic ' + btoa(get('cur_token') + ':');
if (m != 'GET') {
if (m == 'POST' || m == 'PUT')
for (var param in lib[domain]['methods'][m][curLink]['params'])
if (lib[domain]['methods'][m][curLink]['params'][param]['required'] == true)
if (curLib[lib[domain]['methods'][m][curLink]['params'][param]['name']] == undefined)
return 'Error: Missing ' + lib[domain]['methods'][m][curLink]['params'][param]['name'];
// hdr['Content-Type'] = 'application/json';
// curLib = JSON.stringify(curLib);
}
if (m != 'POST' && m != 'PATCH') {
req({
path: curPath,
method: m,
data: curLib,
headers: hdr,
}, callback);
}
else {
reqFormData({
path: curPath,
method: m,
data: curLib,
headers: hdr,
}, callback);
}
return true;
};
}
/**
* Read spec.json and set all needed parameters
* @constructor
*/
$.ajax({
url: core.lib.spec_url,
dataType: 'json',
timeout: core.lib.req_time_out,
success: function(d) {
var data = d['domains'];
for (var domain in data) {
lib[domain] = {};
lib[domain].methods = [];
for (var p in data[domain]['paths']) {
for (var m in data[domain]['paths'][p]) {
if (lib[domain].methods[m] == undefined) lib[domain].methods[m] = {};
lib[domain].methods[m][p] = data[domain]['paths'][p][m];
}
}
for (var m in lib[domain]['methods']) {
lib[domain][m] = makeFunc(domain, m);
}
}
checkAuth();
},
error: function(d) {
console.log('Cannot reach initialization spec: ' + core.lib.spec_url);
console.error(d);
}
});
/**
* Check Authentication
* @constructor
* @param {} exec_once
*/
function checkAuth(exec_once) {
exec_once = exec_once || false;
if (get('cur_token') != null) {
lib.sessions.GET({
data: {
where: 'token==["' + get('cur_token') + '"]'
}
}, function(res) {
if (res !== undefined && res.hasOwnProperty('_items') && res['_items'].length > 0) {
core.lib.authenticated = true;
core.lib.auth_fails = 0;
} else {
core.lib.auth_allowed_fails++;
if (core.lib.auth_fails > core.lib.auth_allowed_fails)
core.lib.authenticated = false;
}
core.lib.ready = true;
if (!exec_once)
setTimeout(checkAuth, core.lib.auth_interval);
});
} else {
core.lib.authenticated = false;
core.lib.ready = true;
if (!exec_once)
setTimeout(checkAuth, core.lib.auth_interval);
}
}
/**
* Get parameter type
* @constructor
* @param {string} dom
* @param {string} param
* @example
* // returns type of field "_id" of resource "users"
* amivcore.getParamType("users", "_id")
*/
lib.getParamType = function(dom, param) {
var tmp = 'none';
try {
if (Array.isArray(lib[dom].methods.POST['/' + dom].params))
lib[dom].methods.POST['/' + dom].params.forEach(function(cur) {
if (cur.name == param) {
tmp = cur.type;
}
});
} catch (e) {}
return tmp;
}
/**
* Get the time converted to the format the api understands
* @param {Date} d - date. If none is given then the NOW is used
* @example
* amivcore.getTime() // "2016-12-20T14:12:55Z"
* amivcore.getTime(new Date(2011, 0, 1, 2, 3, 4, 567)) // "2011-01-01T01:03:04Z"
*/
lib.getTime = function(d) {
d = d || new Date();
return core.adapter['datetime'](d.toISOString());
}
/**
* Get the etag
* @constructor
* @param {} curDomain
* @param {} curId
* @param {} callback
* @example
* amivcore.getEtag("users", amivcore.cur_user, function(res) {
* console.log(res);
* });
*/
lib.getEtag = function(curDomain, curId, callback) {
return lib[curDomain].GET({
id: curId
}, function(res) {
callback(res['_etag']);
});
}
/**
* Returns whether user is logged in
* @constructor
*/
lib.authenticated = function() {
return core.lib.authenticated;
}
/**
* Login function
* @constructor
* @param {String} curUser
* @param {String} curPass
* @param {function} callback
* @param {boolean} shortSession - if user is on a public computer
*/
lib.login = function(curUser, curPass, callback, shortSession = false) {
lib.shortSession = shortSession || false;
callback = callback || dummy;
req({
path: '/sessions/',
method: 'POST',
data: {
username: curUser.toLowerCase(),
password: curPass
},
headers: {
'Content-Type': 'application/json',
},
}, function(msg) {
var reqVar = ['token', 'user', '_id'];
for (var i in reqVar) {
lib['cur_' + reqVar[i]] = msg[reqVar[i]];
}
if (msg['_status'] == 'OK') {
set('cur_token_id', msg['_id']);
set('cur_token', msg['token']);
set('cur_user_id', msg['user']);
set('cur_session_etag', msg['_etag']);
callback(true);
} else {
remove('cur_token_id');
remove('cur_token');
remove('cur_user_id');
remove('cur_session_etag');
callback(false);
}
});
}
/**
* Logout
* @constructor
*/
lib.logout = function() {
// Deleting token from api and unsetting the vars
lib.sessions.DELETE({
id: get('cur_token_id'),
header: {"if-match": get('cur_session_etag')}
}, function(res) {
remove('cur_token');
remove('cur_token_id');
remove('cur_user_id');
remove('cur_session_etag');
});
}
/**
* Get info about the current user
* @constructor
* @param {} attr
* @param {} callback
*/
lib.user = function(attr, callback) {
callback = callback || dummy;
lib.users.GET({
id: get('cur_user_id')
}, function(res) {
if (typeof attr === 'object') {
var ret = {};
for (var key in attr)
ret[attr[key]] = res[attr[key]];
callback(ret);
} else {
callback(res[attr]);
}
});
}
/**
* Get the necessary field for specific requests
* @constructor
* @param {} domain - resource eg. "/users"
* @param {} type - HTTP request type eg. "PATCH"
* @param {boolean} wId - with id eg. "/users/$id"
* @example
* amivcore.getRequiredFields("users", "POST", false)
*/
lib.getRequiredFields = function(domain, type, wId) {
var curTree;
var resAttr = {};
if (wId)
curTree = lib[domain]['methods'][type]['/' + domain + '/{_id}']['params'];
else
curTree = lib[domain]['methods'][type]['/' + domain]['params'];
if (curTree.length == 0) return false;
else {
for (var i = 0; i < curTree.length; i++)
if (curTree[i].required == true)
resAttr[curTree[i].name] = curTree[i];
}
return resAttr;
}
/**
* On function
* @constructor
* @param {} trigger
* @param {} callback
*/
lib.on = function(trigger, callback) {
if (callback) {
lib.on_mem[trigger].callback = callback;
lib.on_mem[trigger].func();
}
}
lib.on_mem = {
ready: {
func: function() {
if (core.lib.ready)
lib.on_mem.ready.callback();
else setTimeout(function() {
lib.on_mem.ready.func();
}, core.lib.on_interval);
}
},
login: {
func: function() {
if (core.lib.authenticated && !lib.on_mem.login.prev)
lib.on_mem.login.callback();
lib.on_mem.login.prev = core.lib.authenticated;
setTimeout(lib.on_mem.login.func, core.lib.on_interval);
},
prev: false,
},
logout: {
func: function() {
if (!core.lib.authenticated && lib.on_mem.logout.prev)
lib.on_mem.logout.callback();
lib.on_mem.logout.prev = core.lib.authenticated;
setTimeout(lib.on_mem.logout.func, core.lib.on_interval);
},
prev: false,
},
}
return lib;
}
if (typeof(window[lns]) === 'undefined') {
window[lns] = libgen();
} else {
console.log(lns + ' already defined, please solve conflict');
}
})(window);
This diff is collapsed.
/*
IMPORTS
*/
@font-face {
font-family: DINPro;
font-weight: normal;
src: url(../../res/fonts/DINPro-Light.ttf);
}
@font-face {
font-family: DINPro;
font-weight: bold;
src: url(../../res/fonts/DINPro-Bold.ttf);
}
/*
GENERAL SETUP
*/
* {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
body {
font-family: DINPro;
overflow: hidden;
}
/*
UTILITY CLASSES
*/
.smooth {
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
transition: all 0.5s ease;
}
[contenteditable=true]:empty:before {
content: attr(placeholder);
display: block; /* For Firefox */
}
/*
LOGIN PANEL
*/
.loginPanel {
width: 100%;
height: 100%;
top: 0%;
left: 0%;
display: flex;
align-items: center;
justify-content: center;
position: fixed;
z-index: 20;
//background: rgba(30,30,30,.9);
background: rgba(31, 45, 84, 1);
}
.loginPanel>div {
box-shadow: 0 0 2em #000;
}
.loginPanel .login-logo {
width: 70%;
}
/*
MAIN FRAMEWORK
*/
.wrapper-main {
height: 100%;
width: 100%;
top: 0;
left: 0;
}
.wrapper-main.toggled {
padding-left: 250px;
}
.wrapper-sidebar {
z-index: 10;
left: 250px;
width: 0px;
height: 100%;
margin-left: -250px;
overflow-y: auto;
position: fixed;
background: #222;
color: #fff;
box-shadow: 0 0 1em rgba(0, 0, 0, 0.5);
}
.wrapper-main.toggled .wrapper-sidebar {
width: 250px;
}
.nav-sidebar .navbar ul {
float: none;
display: block;
}
.wrapper-sidebar .navbar li {
float: none;
display: block;
}
@media(min-width:768px) {
.wrapper-main {
padding-left: 250px;
}
.wrapper-main.toggled {
padding-left: 0px;
}
.wrapper-sidebar {
width: 250px;
}
.wrapper-main.toggled .wrapper-sidebar {
width: 0px;
}
}
.wrapper-sidebar ul li a {
color: inherit;
}
.wrapper-sidebar ul li a:hover, .wrapper-sidebar ul li a:active, .wrapper-sidebar ul li a:focus {
color: #000;
}
.wrapper-sidebar>div {
padding: 1em;
}
.wrapper-sidebar .sidebar-logo {
width: 100%;
}
.wrapper-content {
margin-top: -20px;
//height: calc(100vh - 51px);
background: #eee;
width: 100%;
overflow: auto;
}
/*
MAIN NAVBAR
*/
.navbar-main .container-fluid>ul>li {
float: left;
}
/*
LOG BAR
*/
.alertCont {
position: fixed;
z-index: 10000;
left: 50%;
top: 10px;
transform: translateX(-50%);
}
'use strict';
// Library for all tool actions
var tools = {
//Log Function & Utility Vars
alertElems: [],
alertNum: 0,
alertType: {
's': 'alert-success',
'i': 'alert-info',
'w': 'alert-warning',
'e': 'alert-danger'
},
log: function(msg, type, timeout) {
timeout = timeout || 5000;
tools.alertNum++;
$('.alertCont').append('<div id="alertBox-' + tools.alertNum + '" class="alert ' + tools.alertType[type] + ' alert-dismissible" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>' + msg + '</div>');
tools.alertElems.push(tools.alertNum);
setTimeout(function() {
$('#alertBox-' + tools.alertElems[0]).alert('close');
tools.alertElems.shift();
}, timeout);
console.log(msg);
},
// Modal function
modalFunc: {
init: 0,
},
modalClose: function() {
$('.modalCont').modal('hide');
},
modal: function(attr) {
attr = attr || {};
if (attr.cancel !== undefined && typeof(attr.cancel) == 'function')
tools.modalFunc.cancel = attr.cancel;
if (!tools.modalFunc.init) {
$('.modalCont').on('hide.bs.modal', tools.modalFunc.cancel);
tools.modalFunc.init = 1;
}
$('.modalCont .modal-title').html(attr.head);
$('.modalCont .modal-body').html(attr.body);
$('.modalCont .modal-footer').html('<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>');
var modalBtnId = 0;
for (var curBtn in attr.button) {
if (attr.button[curBtn].type === undefined || attr.button[curBtn].type == '')
attr.button[curBtn].type = 'primary';
$('.modalCont .modal-footer').append('<button type="button" class="btn btn-' + attr.button[curBtn].type + ' modal-btn-' + modalBtnId + '">' + curBtn + '</button>');
if (attr.button[curBtn].callback !== undefined && typeof(attr.button[curBtn].callback) == 'function')
$('.modal-btn-' + modalBtnId).off('click').on('click', attr.button[curBtn].callback);
if (attr.button[curBtn].close === true)
$('.modal-btn-' + modalBtnId).on('click', tools.modalClose);
modalBtnId++;
}
$('.modalCont').modal('show');
},
// Ajax loading gunction and getting the tools
curTool: '',
getTool: function(tool) {
//Setting home if no other tool is selected
if (window.location.hash == '' || window.location.hash == null)
window.location.hash = 'home';
// If tool is specfied, get it
var nextTool = (tool && typeof tool != 'object') ? tool : window.location.hash.slice(1);
if (tools.curTool == nextTool)
return;
tools.curTool = nextTool;
window.location.hash = tools.curTool;
$('#wheel-logo').css('transform', 'rotate(360deg)');
$('#main-content').fadeOut(100, function() {
// Reset Custom menu
tools.ui.menu();
$.ajax({
url: 'tools/' + tools.curTool + '.tool',
dataType: 'html',
error: function() {
tools.log('Tool not found', 'e');
}
}).done(function(data) {
$('#main-content').html(data);
$('#main-content').fadeIn(250, function() {
$('#wheel-logo').css('transform', 'rotate(0deg)');
});
});
});
},
// UI Stuff
ui: {
//Toggle the sidemenu
toggleSideMenu: function() {
$('.wrapper-main').toggleClass('toggled');
},
login: function() {
$('.loginPanel').css({
'top': '-200%'
});
},
logout: function() {
$('.loginPanel').css({
'top': '0%'
});
},
resizeTool: function() {
$('.wrapper-content').height($(window).height() - $('.navbar-main').height());
},
menuId: 0,
menu: function(attr) {
var custMenu = $('.cust-menu');
custMenu.html('');
for (var cur in attr) {
tools.ui.menuId++;
if (attr[cur].link == '' || attr[cur].link === undefined)
attr[cur].link = 'javascript:void(0);';
custMenu.append('<li><a href="' + attr[cur].link + '" id="cust-menu-link-' + tools.ui.menuId + '">' + cur + '</a></li>');
if (typeof(attr[cur].callback) == 'function')
$('#cust-menu-link-' + tools.ui.menuId).on('click', attr[cur].callback);
}
}
},
// Memory to store stuff
memStore: function(type, name, val) {
window[type].setItem(name, val);
},
memGet: function(type, name) {
return window[type].getItem(name);
},
mem: {
local: {
set: function(name, val) {
tools.memStore('localStorage', tools.curTool + name, val);
},
get: function(name) {
return tools.memGet('localStorage', tools.curTool + name);
},
},
session: {
set: function(name, val) {
tools.memStore('sessionStorage', tools.curTool + name, val);
},
get: function(name) {
return tools.memGet('sessionStorage', tools.curTool + name);
},
}
}
}
/*
Initialization of page
*/
//Turning off cache for ajax on dev stage
$.ajaxSetup({
cache: false
});
//Binding tool change whenever the hash is changed
window.onhashchange = tools.getTool;
//Resizing Body when menu changes size and calling it on ready
window.onresize = tools.ui.resizeTool;
// Login function
function loginFunc() {
$('.loginPanel input').attr('readonly', 1);
amivcore.login($('#loginUsername').val(), $('#loginPassword').val(), function(ret) {
if (ret !== true)
tools.log('Wrong Credentials', 'w');
$('.loginPanel input').removeAttr('readonly');
});
}
// When document loaded
$(document).ready(function() {
// Resizing main wrapper-main
tools.ui.resizeTool();
// Binding the buttons
$('.toggleSidebarBtn').click(tools.ui.toggleSideMenu);
$('.loginAction').click(loginFunc);
$('.logoutAction').click(amivcore.logout);
$('.loginPanel').keypress(function(e) {
if (e.which == 13) {
e.preventDefault();
loginFunc();
}
});
});
amivcore.on('ready', function() {
tools.getTool();
});
amivcore.on('login', function() {
tools.ui.login();
});
amivcore.on('logout', function() {
tools.ui.logout();
});
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /var/www/;
index index.html;
try_files $uri /index.html =404;
}
This diff is collapsed.
......@@ -6,7 +6,10 @@
"scripts": {
"start": "webpack-dev-server --hot --inline",
"build": "webpack -p --config webpack.config.prod.js",
"lint": "eslint src/**"
"build-dev": "webpack -p --config webpack.config.dev.js",
"build-staging": "webpack -p --config webpack.config.staging.js",
"build-local": "webpack -p --config webpack.config.local.js",
"lint": "eslint src/**/*.js src/*.js"
},
"repository": {
"type": "git",
......@@ -14,24 +17,39 @@
},
"author": "Hermann Blum et al",
"dependencies": {
"@material/drawer": "^0.30.0",
"@material/select": "^0.35.1",
"ajv": "^5.5.0",
"amiv-web-ui-components": "git+https://git@gitlab.ethz.ch/amiv/web-ui-components.git#360e65da63f4511db1f6ac56ce103be9254d1d9f",
"axios": "^0.17.1",
"babel": "^6.23.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"compression-webpack-plugin": "^1.0.1",
"file-loader": "^1.1.5",
"mithril": "^1.1.5",
"client-oauth2": "^4.2.0",
"mithril": "^1.1.6",
"mithril-infinite": "^1.2.4",
"polythene-core-css": "^1.2.0",
"polythene-css": "^1.2.0",
"polythene-mithril": "1.2.0",
"querystring": "^0.2.0",
"uglifyjs-webpack-plugin": "^1.0.1",
"webpack": "^3.8.1"
"showdown": "^1.9.0"
},
"devDependencies": {
"eslint": "^4.10.0",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-loader": "^1.9.0",
"eslint-plugin-import": "^2.8.0",
"webpack-dev-server": "^2.9.3"
"@babel/cli": "^7.2.3",
"@babel/core": "^7.2.2",
"@babel/plugin-proposal-object-rest-spread": "^7.2.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/preset-env": "^7.2.3",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.4",
"compression-webpack-plugin": "^2.0.0",
"css-loader": "^2.1.0",
"eslint": "^5.16.0",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-import-resolver-webpack": "^0.10.1",
"eslint-loader": "^3.0.0",
"eslint-plugin-import": "^2.14.0",
"file-loader": "^3.0.1",
"style-loader": "^0.23.1",
"webpack": "^4.28.3",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.14"
}
}
res/bg/beer.jpg

344 KiB

res/bg/cab-1440.jpg

366 KiB