From 09596c3c5a6a2a44675f170106bb38746229e02a Mon Sep 17 00:00:00 2001 From: Georgios Andreadis Date: Sat, 23 Sep 2017 09:48:38 +0200 Subject: Remove old frontend --- LICENSE.md | 21 - README.md | 91 - bower.json | 17 - gulpfile.js | 252 --- images/opendc-frontend-component-diagram.png | Bin 100492 -> 0 bytes .../opendc-frontend-interaction-state-diagram.png | Bin 41421 -> 0 bytes package.json | 43 - src/404.html | 29 - src/app.html | 456 ----- src/favicon.ico | Bin 99678 -> 0 bytes src/humans.txt | 27 - src/img/app/coolingitem.png | Bin 2853 -> 0 bytes src/img/app/loading.gif | Bin 36550 -> 0 bytes src/img/app/node-cpu.png | Bin 4062 -> 0 bytes src/img/app/node-gpu.png | Bin 2227 -> 0 bytes src/img/app/node-memory.png | Bin 1980 -> 0 bytes src/img/app/node-network.png | Bin 3058 -> 0 bytes src/img/app/node-storage.png | Bin 4038 -> 0 bytes src/img/app/psu.png | Bin 1523 -> 0 bytes src/img/app/rack-energy.png | Bin 893 -> 0 bytes src/img/app/rack-space.png | Bin 957 -> 0 bytes src/img/datacenter-drawing.png | Bin 219576 -> 0 bytes src/img/email-icon.png | Bin 14761 -> 0 bytes src/img/favicon.png | Bin 2788 -> 0 bytes src/img/github-icon.png | Bin 6441 -> 0 bytes src/img/logo.png | Bin 2825 -> 0 bytes src/img/opendc-splash.png | Bin 304805 -> 0 bytes src/img/portraits/aiosup.png | Bin 111629 -> 0 bytes src/img/portraits/gandreadis.png | Bin 118477 -> 0 bytes src/img/portraits/loverweel.png | Bin 107768 -> 0 bytes src/img/portraits/mbijman.png | Bin 111670 -> 0 bytes src/img/stakeholders/Developer.png | Bin 11411 -> 0 bytes src/img/stakeholders/Manager.png | Bin 9946 -> 0 bytes src/img/stakeholders/Researcher.png | Bin 10984 -> 0 bytes src/img/stakeholders/Sales.png | Bin 10074 -> 0 bytes src/img/stakeholders/Student.png | Bin 12960 -> 0 bytes src/img/technologies/arrow.png | Bin 2153 -> 0 bytes src/img/technologies/cogs-icon.png | Bin 11500 -> 0 bytes src/img/technologies/database-icon.png | Bin 7848 -> 0 bytes src/img/technologies/webserver-icon.png | Bin 5762 -> 0 bytes src/img/technologies/www-icon.png | Bin 11205 -> 0 bytes src/img/tudelfticon.png | Bin 4387 -> 0 bytes src/index.html | 413 ----- src/navbar.html | 18 - src/profile.html | 62 - src/projects.html | 93 -- src/robots.txt | 4 - src/scripts/colors.ts | 43 - src/scripts/controllers/connection/api.ts | 1738 -------------------- src/scripts/controllers/connection/cache.ts | 85 - src/scripts/controllers/connection/socket.ts | 76 - src/scripts/controllers/mapcontroller.ts | 520 ------ src/scripts/controllers/modes/building.ts | 113 -- src/scripts/controllers/modes/node.ts | 297 ---- src/scripts/controllers/modes/object.ts | 296 ---- src/scripts/controllers/modes/room.ts | 382 ----- src/scripts/controllers/scaleindicator.ts | 45 - src/scripts/controllers/simulation/chart.ts | 241 --- src/scripts/controllers/simulation/statecache.ts | 321 ---- src/scripts/controllers/simulation/taskview.ts | 64 - src/scripts/controllers/simulation/timeline.ts | 161 -- src/scripts/controllers/simulationcontroller.ts | 586 ------- src/scripts/definitions.ts | 318 ---- src/scripts/error404.entry.ts | 26 - src/scripts/main.entry.ts | 69 - src/scripts/profile.entry.ts | 40 - src/scripts/projects.entry.ts | 651 -------- src/scripts/serverconnection.ts | 59 - src/scripts/splash.entry.ts | 157 -- src/scripts/tests/util.spec.ts | 326 ---- src/scripts/user-authentication.ts | 65 - src/scripts/util.ts | 613 ------- src/scripts/views/layers/dcobject.ts | 250 --- src/scripts/views/layers/dcprogressbar.ts | 99 -- src/scripts/views/layers/gray.ts | 145 -- src/scripts/views/layers/grid.ts | 59 - src/scripts/views/layers/hover.ts | 129 -- src/scripts/views/layers/layer.ts | 8 - src/scripts/views/layers/room.ts | 177 -- src/scripts/views/layers/roomtext.ts | 68 - src/scripts/views/layers/wall.ts | 62 - src/scripts/views/mapview.ts | 373 ----- src/styles/404.less | 147 -- src/styles/main.less | 1196 -------------- src/styles/navbar.less | 158 -- src/styles/profile.less | 22 - src/styles/projects.less | 391 ----- src/styles/splash.less | 440 ----- src/unit-tests.html | 15 - tsconfig.json | 45 - tslint.json | 75 - typings.json | 16 - 92 files changed, 12693 deletions(-) delete mode 100644 LICENSE.md delete mode 100644 README.md delete mode 100644 bower.json delete mode 100644 gulpfile.js delete mode 100644 images/opendc-frontend-component-diagram.png delete mode 100644 images/opendc-frontend-interaction-state-diagram.png delete mode 100644 package.json delete mode 100644 src/404.html delete mode 100644 src/app.html delete mode 100644 src/favicon.ico delete mode 100644 src/humans.txt delete mode 100644 src/img/app/coolingitem.png delete mode 100644 src/img/app/loading.gif delete mode 100644 src/img/app/node-cpu.png delete mode 100644 src/img/app/node-gpu.png delete mode 100644 src/img/app/node-memory.png delete mode 100644 src/img/app/node-network.png delete mode 100644 src/img/app/node-storage.png delete mode 100644 src/img/app/psu.png delete mode 100644 src/img/app/rack-energy.png delete mode 100644 src/img/app/rack-space.png delete mode 100644 src/img/datacenter-drawing.png delete mode 100644 src/img/email-icon.png delete mode 100644 src/img/favicon.png delete mode 100644 src/img/github-icon.png delete mode 100644 src/img/logo.png delete mode 100644 src/img/opendc-splash.png delete mode 100644 src/img/portraits/aiosup.png delete mode 100644 src/img/portraits/gandreadis.png delete mode 100644 src/img/portraits/loverweel.png delete mode 100644 src/img/portraits/mbijman.png delete mode 100644 src/img/stakeholders/Developer.png delete mode 100644 src/img/stakeholders/Manager.png delete mode 100644 src/img/stakeholders/Researcher.png delete mode 100644 src/img/stakeholders/Sales.png delete mode 100644 src/img/stakeholders/Student.png delete mode 100644 src/img/technologies/arrow.png delete mode 100644 src/img/technologies/cogs-icon.png delete mode 100644 src/img/technologies/database-icon.png delete mode 100644 src/img/technologies/webserver-icon.png delete mode 100644 src/img/technologies/www-icon.png delete mode 100644 src/img/tudelfticon.png delete mode 100644 src/index.html delete mode 100644 src/navbar.html delete mode 100644 src/profile.html delete mode 100644 src/projects.html delete mode 100644 src/robots.txt delete mode 100644 src/scripts/colors.ts delete mode 100644 src/scripts/controllers/connection/api.ts delete mode 100644 src/scripts/controllers/connection/cache.ts delete mode 100644 src/scripts/controllers/connection/socket.ts delete mode 100644 src/scripts/controllers/mapcontroller.ts delete mode 100644 src/scripts/controllers/modes/building.ts delete mode 100644 src/scripts/controllers/modes/node.ts delete mode 100644 src/scripts/controllers/modes/object.ts delete mode 100644 src/scripts/controllers/modes/room.ts delete mode 100644 src/scripts/controllers/scaleindicator.ts delete mode 100644 src/scripts/controllers/simulation/chart.ts delete mode 100644 src/scripts/controllers/simulation/statecache.ts delete mode 100644 src/scripts/controllers/simulation/taskview.ts delete mode 100644 src/scripts/controllers/simulation/timeline.ts delete mode 100644 src/scripts/controllers/simulationcontroller.ts delete mode 100644 src/scripts/definitions.ts delete mode 100644 src/scripts/error404.entry.ts delete mode 100644 src/scripts/main.entry.ts delete mode 100644 src/scripts/profile.entry.ts delete mode 100644 src/scripts/projects.entry.ts delete mode 100644 src/scripts/serverconnection.ts delete mode 100644 src/scripts/splash.entry.ts delete mode 100644 src/scripts/tests/util.spec.ts delete mode 100644 src/scripts/user-authentication.ts delete mode 100644 src/scripts/util.ts delete mode 100644 src/scripts/views/layers/dcobject.ts delete mode 100644 src/scripts/views/layers/dcprogressbar.ts delete mode 100644 src/scripts/views/layers/gray.ts delete mode 100644 src/scripts/views/layers/grid.ts delete mode 100644 src/scripts/views/layers/hover.ts delete mode 100644 src/scripts/views/layers/layer.ts delete mode 100644 src/scripts/views/layers/room.ts delete mode 100644 src/scripts/views/layers/roomtext.ts delete mode 100644 src/scripts/views/layers/wall.ts delete mode 100644 src/scripts/views/mapview.ts delete mode 100644 src/styles/404.less delete mode 100644 src/styles/main.less delete mode 100644 src/styles/navbar.less delete mode 100644 src/styles/profile.less delete mode 100644 src/styles/projects.less delete mode 100644 src/styles/splash.less delete mode 100644 src/unit-tests.html delete mode 100644 tsconfig.json delete mode 100644 tslint.json delete mode 100644 typings.json diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index 6fa9989a..00000000 --- a/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 tudelft-atlarge - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index 8d28e84a..00000000 --- a/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# OpenDC Frontend - -The OpenDC frontend is the user-facing component of the OpenDC stack, allowing users to build and interact with their own (virtual) datacenters. It is built in TypeScript, using CreateJS for canvas interactions and Gulp for build-automation. - -This document gives a high-level view of the frontend architecture ([jump](#architecture)), and describes how to set it up for local development ([jump](#setup-for-local-development)). - -## Architecture - -### Application Interaction Model -Let's first take a look at how the user interacts with the frontend. - -#### Pages -The user starts at the splashpage (`index.html`) where he/she gets a first impression of OpenDC, including screenshots and features. After signing in with Google Authentication, the user is redirected to the page listing all projects (`projects.html`) shared or owned by that user. Here the user also has the possibility to open a particular project, redirecting to the main application page (`app.html`). - -#### Main Application -The main application allows the user to construct and simulate a datacenter. To understand how the user can do this, have a look at the state diagram below. It visualizes the main interactions a user can make with the application, as well as under which conditions those can happen. - -![OpenDC Frontend Interaction State Diagram](https://raw.githubusercontent.com/atlarge-research/opendc-frontend/master/images/opendc-frontend-interaction-state-diagram.png) - -### Components -Under the hood, this looks as follows: - -![OpenDC Frontend Component Diagram](https://raw.githubusercontent.com/atlarge-research/opendc-frontend/master/images/opendc-frontend-component-diagram.png) - -*Squared-off colored boxes indicate packages (colors become more saturated as packages are nested); rounded-off boxes indicate individual components; dotted lines indicate control flow; and solid lines indicate data flow.* - -#### Entry Scripts -The entry scripts are the first entities triggered on page load of the respective pages. They are responsible for instantiating the corresponding view and controller. - -#### Controllers -In the main web-application, the controllers handle user input and state. They also initiate re-renders of views when a part of their managed state changes. There are different classes of controllers; some concerning themselves with the API connection, others with the different modes of interaction, and others with simulation-specific actions. This all is orchestrated by a central class called the `MapController`. - -#### Views -The views are responsible for drawing content to the canvas. They are split up into different layers, corresponding to the way they are rendered. - -## Setup for Local Development - -### Initial setup - -#### Setting up the server -To be able to see the frontend run in your browser, first set up the web server. The steps needed for this are listed on [the `opendc-web-server` repo](https://github.com/atlarge-research/opendc-web-server). - -Once the web-server is set up, clone [this frontend-repo](https://github.com/atlarge-research/opendc-frontend.git) into the same base-directory as the repos you cloned during server setup: - -```bash -git clone https://github.com/atlarge-research/opendc-frontend.git -``` - -Change directory to that new directory, and you're ready to continue to the frontend setup steps below. - -#### Resolving dependencies -We use the NPM package repository to manage our third-party dependencies on the frontend. To fetch and install these dependencies, you'll need to have the [Node.js](https://nodejs.org/en/) environment installed. - -For easier fetching, we recommend the [Yarn Package Manager](https://yarnpkg.com), but the standard NPM tool will suffice, too. You can get your build setup installed by executing the following two commands: - -```bash -npm install -g yarn -npm install -g gulp -``` - -You may need to prepend these commands with `sudo`, if you are on a Debian-based Linux machine. If you're having trouble giving NPM the necessary permissions on such a machine, have a look at [this NPM documentation page](https://docs.npmjs.com/getting-started/fixing-npm-permissions). - -### Building the project -First, create a configuration file called `config.json` in the root of the `opendc-frontend` directory, with the following template: - -```json -{ - "OAUTH_CLIENT_ID": "the-google-oauth-client-id", - "SERVER_BASE_URL": "http://localhost:8081" -} -``` - -Be sure to replace `the-google-oauth-client-id` with your actual OAuth client ID. - -Finally, run the following commands from this directory to fetch dependencies and compile the code of the frontend side: - -```bash -yarn -gulp -``` - -*Note: If you wish to use a configuration file from a different location, pass a `--config=...` parameter to the `gulp` command, providing the relative path to the file to be used.* - -### Automatically triggered builds -To make development easier, we've set up a `watch` task. With this task, you can quickly see what effects a certain change has on the program. It runs in the background, automatically triggering a rebuild of relevant files on file-change. - -Start it by executing: - -```bash -gulp watch -``` diff --git a/bower.json b/bower.json deleted file mode 100644 index 1dcf5964..00000000 --- a/bower.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "opendc", - "description": "Datacenter simulator", - "authors": [ - "Georgios Andreadis " - ], - "license": "MIT", - "homepage": "http://opendc.org", - "private": true, - "dependencies": { - "EaselJS": "^0.8.2", - "PreloadJS": "^0.6.2", - "TweenJS": "^0.6.2", - "bootstrap": "^3.3.6", - "c3": "^0.4.11" - } -} diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index f674055e..00000000 --- a/gulpfile.js +++ /dev/null @@ -1,252 +0,0 @@ -/** - * Build file for the frontend codebase of OpenDC. - * - * Usage: - * $ gulp --config=config.json # for a single build - * $ gulp watch --config=config.json # to run once, watch for changes, and rebuild when something changed - * - * If the `config` argument is omitted, the config file is assumed to be named `config.json` and present in this - * directory. - */ - -'use strict'; - -const argv = require('yargs').argv; - -const gulp = require('gulp'); -const notify = require('gulp-notify'); -const gulpUtil = require('gulp-util'); -const rename = require('gulp-rename'); -const replace = require('gulp-replace'); -const del = require('del'); -const fs = require('fs'); -const runSequence = require('run-sequence'); -const source = require('vinyl-source-stream'); -const es = require('event-stream'); -const less = require('gulp-less'); -const browserify = require('browserify'); -const watchify = require('watchify'); -const tsify = require('tsify'); -const gulpTypings = require("gulp-typings"); -const processHTML = require('gulp-processhtml'); -const bower = require('gulp-bower'); - - -/** - * Checks whether the configuration file is specified and reads its contents. - * - * @throws an Exception if the config file could not be found or read (logs appropriately to the console) - * @returns {Object} the config file contents. - */ -function getConfigFile() { - let configInput = argv.config; - - if (configInput === undefined) { - if (!fs.existsSync("./config.json")) { - gulpUtil.log(gulpUtil.colors.red('Config file argument missing\n'), 'Usage:\n' + - ' $ gulp --config=config.json'); - throw new Exception(); - } else { - gulpUtil.log(gulpUtil.colors.magenta('No config file argument, assuming `config.json`.')); - configInput = "config.json"; - } - } - - try { - let configFilePath; - if (configInput.indexOf('/') === -1) { - configFilePath = './' + configInput; - } else { - configFilePath = configInput; - } - - return require(configFilePath); - } catch (error) { - gulpUtil.log(gulpUtil.colors.red('Config file could not be read'), error); - throw new Exception(); - } -} - - -/** - * Stylesheet task. - */ -const stylesRootDir = './src/styles/'; -const stylesDestDir = './build/styles/'; - -const styleFileNames = ['main', 'splash', 'projects', 'profile', 'navbar', '404']; -const styleFilePaths = styleFileNames.map(function (fileName) { - return stylesRootDir + fileName + '.less'; -}); - -gulp.task('styles', function () { - return gulp.src(styleFilePaths) - .pipe(less()) - .pipe(gulp.dest(stylesDestDir)) - .pipe(notify({message: 'Styles task complete', onLast: true})); -}); - - -/** - * Script task. - */ -const scriptsRootDir = './src/scripts/'; -const scriptsDestDir = './build/scripts/'; - -const postfix = '.entry'; -const scriptsFileNames = ['splash', 'main', 'projects', 'profile', 'error404']; -const scriptsFilePaths = scriptsFileNames.map(function (fileName) { - return scriptsRootDir + fileName + postfix + '.ts'; -}); - -gulp.task('scripts', function () { - const configFile = getConfigFile(); - - const tasks = scriptsFilePaths.map(function (entry, index) { - return browserify({ - entries: [entry], - debug: false, - insertGlobals: true, - cache: {}, - packageCache: {} - }) - .plugin(tsify) - .bundle() - .pipe(source(scriptsFileNames[index] + postfix + '.js')) - .pipe(replace('SERVER_BASE_URL', configFile.SERVER_BASE_URL)) - .pipe(gulp.dest(scriptsDestDir)); - }); - return es.merge.apply(null, tasks) - .pipe(notify({message: 'Scripts task complete', onLast: true})); -}); - -function getWatchifyHandler(bundler, fileName) { - const configFile = getConfigFile(); - - return () => { - gulpUtil.log('Beginning build for ' + fileName); - return bundler - .bundle() - .pipe(source(fileName + postfix + '.js')) - .pipe(replace('SERVER_BASE_URL', configFile.SERVER_BASE_URL)) - .pipe(gulp.dest(scriptsDestDir)); - }; -} - -gulp.task('watch-scripts', function () { - const tasks = scriptsFilePaths.map(function (entry, index) { - const watchedBrowserify = watchify(browserify({ - entries: [entry], - debug: false, - cache: {}, - packageCache: {}, - insertGlobals: true, - poll: 100 - }).plugin(tsify)); - const watchFunction = getWatchifyHandler(watchedBrowserify, scriptsFileNames[index]); - - watchedBrowserify.on('update', watchFunction); - watchedBrowserify.on('log', gulpUtil.log); - return watchFunction(); - }); - - return es.merge.apply(null, tasks) - .pipe(notify({message: 'Scripts watch task complete', onLast: true})); -}); - - -/** - * TypeScript definitions task. - */ -gulp.task("typings", function () { - return gulp.src("./typings.json") - .pipe(gulpTypings()) - .pipe(notify({message: 'Typings task complete'})); -}); - - -/** - * HTML task. - */ -const htmlRootDir = './src/'; -const htmlDestDir = './build/'; - -const htmlFileNames = ['index', 'app', 'projects', 'profile', '404']; -const htmlFilePaths = htmlFileNames.map(function (fileName) { - return htmlRootDir + fileName + '.html'; -}); - -gulp.task('html', function () { - const configFile = getConfigFile(); - - return gulp.src(htmlFilePaths) - .pipe(replace('OAUTH_CLIENT_ID', configFile.OAUTH_CLIENT_ID)) - .pipe(replace('SERVER_BASE_URL', configFile.SERVER_BASE_URL)) - .pipe(processHTML()) - .pipe(gulp.dest(htmlDestDir)) - .pipe(notify({message: 'HTML task complete', onLast: true})); -}); - - -/** - * Images task. - */ -const imagesRootDir = './src/img/'; -const imagesDestDir = './build/img/'; - -const imagesFilePaths = [imagesRootDir + '**/*.png', imagesRootDir + '**/*.gif']; - -gulp.task('images', function () { - return gulp.src(imagesFilePaths) - .pipe(gulp.dest(imagesDestDir)) - .pipe(notify({message: 'Images task complete', onLast: true})); -}); - - -/** - * Clean task. - */ -gulp.task('clean', function () { - return del(['./build']); -}); - - -/** - * Bower task. - */ -gulp.task('bower', function () { - return bower({cmd: 'install'}, ['--allow-root']) - .pipe(notify({message: 'Bower task complete', onLast: true})); -}); - - -/** - * Default build task. - */ -gulp.task('default', function () { - try { - getConfigFile(); - } catch (error) { - return; - } - runSequence('clean', 'typings', 'styles', 'bower', 'scripts', 'html', 'images'); -}); - - -/** - * Watch task. - */ -gulp.task('watch', function () { - try { - getConfigFile(); - } catch (error) { - return; - } - - runSequence('default', () => { - gulp.watch(stylesRootDir + '**/*.less', ['styles']); - gulp.start('watch-scripts'); - gulp.watch(htmlRootDir + '**/*.html', ['html']); - gulp.watch(imagesRootDir + '**/*.png', ['images']); - }); -}); diff --git a/images/opendc-frontend-component-diagram.png b/images/opendc-frontend-component-diagram.png deleted file mode 100644 index 5d6c4704..00000000 Binary files a/images/opendc-frontend-component-diagram.png and /dev/null differ diff --git a/images/opendc-frontend-interaction-state-diagram.png b/images/opendc-frontend-interaction-state-diagram.png deleted file mode 100644 index 7c93358a..00000000 Binary files a/images/opendc-frontend-interaction-state-diagram.png and /dev/null differ diff --git a/package.json b/package.json deleted file mode 100644 index c4f24dd3..00000000 --- a/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "opendc", - "version": "0.0.1", - "description": "Datacenter simulator", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/tudelft-atlarge/opendc" - }, - "dependencies": { - "bower": "^1.7.9", - "browserify": "^13.1.1", - "c3": "^0.4.11", - "del": "^2.2.2", - "event-stream": "^3.3.4", - "file-loader": "^0.9.0", - "gulp": "^3.9.1", - "gulp-bower": "^0.0.13", - "gulp-less": "^3.3.0", - "gulp-notify": "^2.2.0", - "gulp-processhtml": "^1.1.0", - "gulp-rename": "^1.2.2", - "gulp-replace": "^0.5.4", - "gulp-typings": "^2.0.4", - "gulp-util": "^3.0.8", - "jquery": "^3.1.0", - "jquery-mousewheel": "^3.1.13", - "jquery.easing": "^1.4.1", - "less": "^2.7.1", - "run-sequence": "^1.2.2", - "socket.io-client": "^1.4.8", - "tsify": "^2.0.2", - "tslint": "^3.10.2", - "typescript": "^2.1.4", - "typings": "^1.3.2", - "vinyl-source-stream": "^1.1.0", - "watchify": "^3.9.0", - "yargs": "^6.6.0" - }, - "devDependencies": { - "jasmine-core": "^2.4.1" - } -} diff --git a/src/404.html b/src/404.html deleted file mode 100644 index 10f79525..00000000 --- a/src/404.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - 404 Error | OpenDC - - - - - - - -
-
Terminal -- bash
-
-
$ status
- opendc[4264]: segfault at 0000051497be459d1 err 12 in libopendc.9.0.4
- opendc[4269]: segfault at 000004234855fc2db err 3 in libopendc.9.0.4
- opendc[4270]: STDERR Page does not exist -
-
-
Got lost?_
- GET ME BACK TO OPENDC -
-
- - - - diff --git a/src/app.html b/src/app.html deleted file mode 100644 index 5b669910..00000000 --- a/src/app.html +++ /dev/null @@ -1,456 +0,0 @@ - - - - - - - OpenDC - - - - - - - - - - - - -
- - - Sorry, but it seems your browser does not support the HTML5 canvas. - - -
- -
- -
- - - - - - -
- -
-
-
Construction
-
Simulation
-
-
Save version
- - -
- -
- - - -
- - -
-
- 0.5m -
- -
- - -
- -
- - -
- Test Info -
- - -
-
- -
-

Loading your project...

-

Fetching the DC

-
-
-
-
- - - -
-
-
-
-
Experiments
-
-
- - - - -
-
- - - - -
Save & Launch
-
-
- Previous Experiments -
-
-
Name
-
Path
-
Trace
-
Scheduler
-
-
-
-
-
-
- - No experiments here yet... Add some with the form above! -
- -
-
-
- - - - - - - - - - - - - - - diff --git a/src/favicon.ico b/src/favicon.ico deleted file mode 100644 index c2f40a0d..00000000 Binary files a/src/favicon.ico and /dev/null differ diff --git a/src/humans.txt b/src/humans.txt deleted file mode 100644 index 652f9cd2..00000000 --- a/src/humans.txt +++ /dev/null @@ -1,27 +0,0 @@ -/* TEAM */ -Benevolent Dictator for Life: Alexandru Iosup. -Site: http://www.ds.ewi.tudelft.nl/~iosup/ -Twitter: aiosup. -Location: Delft, Netherlands. - -Backend Engineer: Leon Overweel. -Site: http://leonoverweel.com/ -Twitter: layon_overwhale. -Location: Delft, Netherlands. - -Frontend Engineer: Georgios Andreadis. -Site: https://github.com/gandreadis -Location: Delft, Netherlands. - -Simulation Engineer: Matthijs Bijman. -Site: https://github.com/MDBijman -Location: Delft, Netherlands. - -/* THANKS */ -Executive Producer: Vincent van Beek. -Executive Producer: Tim Hegeman. - -/* SITE */ -Standards: HTML5, CSS3, ES5 -Components: jQuery, Bootstrap, CreateJS, c3.js -Software: WebStorm, Vim, Visual Studio \ No newline at end of file diff --git a/src/img/app/coolingitem.png b/src/img/app/coolingitem.png deleted file mode 100644 index 16c18be0..00000000 Binary files a/src/img/app/coolingitem.png and /dev/null differ diff --git a/src/img/app/loading.gif b/src/img/app/loading.gif deleted file mode 100644 index c6394822..00000000 Binary files a/src/img/app/loading.gif and /dev/null differ diff --git a/src/img/app/node-cpu.png b/src/img/app/node-cpu.png deleted file mode 100644 index 07cfbd31..00000000 Binary files a/src/img/app/node-cpu.png and /dev/null differ diff --git a/src/img/app/node-gpu.png b/src/img/app/node-gpu.png deleted file mode 100644 index 55d4fb05..00000000 Binary files a/src/img/app/node-gpu.png and /dev/null differ diff --git a/src/img/app/node-memory.png b/src/img/app/node-memory.png deleted file mode 100644 index 36e8a44e..00000000 Binary files a/src/img/app/node-memory.png and /dev/null differ diff --git a/src/img/app/node-network.png b/src/img/app/node-network.png deleted file mode 100644 index 795e173b..00000000 Binary files a/src/img/app/node-network.png and /dev/null differ diff --git a/src/img/app/node-storage.png b/src/img/app/node-storage.png deleted file mode 100644 index 7a39cb6f..00000000 Binary files a/src/img/app/node-storage.png and /dev/null differ diff --git a/src/img/app/psu.png b/src/img/app/psu.png deleted file mode 100644 index 471af6ee..00000000 Binary files a/src/img/app/psu.png and /dev/null differ diff --git a/src/img/app/rack-energy.png b/src/img/app/rack-energy.png deleted file mode 100644 index 1088c61b..00000000 Binary files a/src/img/app/rack-energy.png and /dev/null differ diff --git a/src/img/app/rack-space.png b/src/img/app/rack-space.png deleted file mode 100644 index 387d7ea6..00000000 Binary files a/src/img/app/rack-space.png and /dev/null differ diff --git a/src/img/datacenter-drawing.png b/src/img/datacenter-drawing.png deleted file mode 100644 index 401168e3..00000000 Binary files a/src/img/datacenter-drawing.png and /dev/null differ diff --git a/src/img/email-icon.png b/src/img/email-icon.png deleted file mode 100644 index ced9e175..00000000 Binary files a/src/img/email-icon.png and /dev/null differ diff --git a/src/img/favicon.png b/src/img/favicon.png deleted file mode 100644 index 85d74964..00000000 Binary files a/src/img/favicon.png and /dev/null differ diff --git a/src/img/github-icon.png b/src/img/github-icon.png deleted file mode 100644 index 1e221600..00000000 Binary files a/src/img/github-icon.png and /dev/null differ diff --git a/src/img/logo.png b/src/img/logo.png deleted file mode 100644 index d743038b..00000000 Binary files a/src/img/logo.png and /dev/null differ diff --git a/src/img/opendc-splash.png b/src/img/opendc-splash.png deleted file mode 100644 index 99fd8658..00000000 Binary files a/src/img/opendc-splash.png and /dev/null differ diff --git a/src/img/portraits/aiosup.png b/src/img/portraits/aiosup.png deleted file mode 100644 index 30de349c..00000000 Binary files a/src/img/portraits/aiosup.png and /dev/null differ diff --git a/src/img/portraits/gandreadis.png b/src/img/portraits/gandreadis.png deleted file mode 100644 index 403870fa..00000000 Binary files a/src/img/portraits/gandreadis.png and /dev/null differ diff --git a/src/img/portraits/loverweel.png b/src/img/portraits/loverweel.png deleted file mode 100644 index d12a9e86..00000000 Binary files a/src/img/portraits/loverweel.png and /dev/null differ diff --git a/src/img/portraits/mbijman.png b/src/img/portraits/mbijman.png deleted file mode 100644 index decf9fdd..00000000 Binary files a/src/img/portraits/mbijman.png and /dev/null differ diff --git a/src/img/stakeholders/Developer.png b/src/img/stakeholders/Developer.png deleted file mode 100644 index d2638e6c..00000000 Binary files a/src/img/stakeholders/Developer.png and /dev/null differ diff --git a/src/img/stakeholders/Manager.png b/src/img/stakeholders/Manager.png deleted file mode 100644 index 92db7459..00000000 Binary files a/src/img/stakeholders/Manager.png and /dev/null differ diff --git a/src/img/stakeholders/Researcher.png b/src/img/stakeholders/Researcher.png deleted file mode 100644 index d87edd39..00000000 Binary files a/src/img/stakeholders/Researcher.png and /dev/null differ diff --git a/src/img/stakeholders/Sales.png b/src/img/stakeholders/Sales.png deleted file mode 100644 index 5b7c3a72..00000000 Binary files a/src/img/stakeholders/Sales.png and /dev/null differ diff --git a/src/img/stakeholders/Student.png b/src/img/stakeholders/Student.png deleted file mode 100644 index a4900303..00000000 Binary files a/src/img/stakeholders/Student.png and /dev/null differ diff --git a/src/img/technologies/arrow.png b/src/img/technologies/arrow.png deleted file mode 100644 index 374f78bf..00000000 Binary files a/src/img/technologies/arrow.png and /dev/null differ diff --git a/src/img/technologies/cogs-icon.png b/src/img/technologies/cogs-icon.png deleted file mode 100644 index d19e1c20..00000000 Binary files a/src/img/technologies/cogs-icon.png and /dev/null differ diff --git a/src/img/technologies/database-icon.png b/src/img/technologies/database-icon.png deleted file mode 100644 index 26738e76..00000000 Binary files a/src/img/technologies/database-icon.png and /dev/null differ diff --git a/src/img/technologies/webserver-icon.png b/src/img/technologies/webserver-icon.png deleted file mode 100644 index c627106e..00000000 Binary files a/src/img/technologies/webserver-icon.png and /dev/null differ diff --git a/src/img/technologies/www-icon.png b/src/img/technologies/www-icon.png deleted file mode 100644 index e69a54f2..00000000 Binary files a/src/img/technologies/www-icon.png and /dev/null differ diff --git a/src/img/tudelfticon.png b/src/img/tudelfticon.png deleted file mode 100644 index a7a2d56a..00000000 Binary files a/src/img/tudelfticon.png and /dev/null differ diff --git a/src/index.html b/src/index.html deleted file mode 100644 index c3df0c02..00000000 --- a/src/index.html +++ /dev/null @@ -1,413 +0,0 @@ - - - - - OpenDC - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
-
-

OpenDC

-

- Collaborative Datacenter Simulation and Exploration for Everybody -

-
-
-
- -
-
-
-
-
-

The datacenter (DC) industry...

-
    -
  • Is worth over $15 bn, and growing
  • -
  • Has many hard-to-grasp concepts
  • -
  • Needs to become accessible to many
  • -
-
- -
-

OpenDC provides...

-
    -
  • Collaborative online DC modeling
  • -
  • Diverse and effective DC simulation
  • -
  • Exploratory DC performance feedback
  • -
-
-
-
-
-
- -
-
-
-
-

Stakeholders

-
-
- Managers -
-

Managers

-

Seeing is deciding

-
-
-
- Sales -
-

Sales

-

Demo concepts

-
-
-
- DevOps -
-

DevOps

-

Develop & tune

-
-
-
- Researchers -
-

Researchers

-

Understand & design

-
-
-
- Students -
-

Students

-

Grasp complex concepts

-
-
-
-
-
-
-
- -
-
-
-
-

Datacenter Modeling

-
-
- Collaboratively... -
    -
  • Model DC layout, and room locations and types
  • -
  • Place racks in rooms and nodes in racks
  • -
  • Add real-world CPU, GPU, memory, storage and network units to each node
  • -
  • Select from diverse scheduling policies
  • -
-
- - -
- Mockup of the datacenter construction interface -
- Mockup of the datacenter construction interface -
-
-
-
-
-
-
- -
-
-
-
-

Datacenter Simulation

-
-
- Working with OpenDC: -
    -
  • Seamlessly switch between construction and simulation modes -
  • Choose one of several predefined workloads (Big Data, Bag of Tasks, - Hadoop, etc.) -
  • Play, pause, and skip around the informative simulation timeline -
  • Visualize and demo live -
-
-
- Mockup of the datacenter simulation interface at room level -
- Mockup of the datacenter simulation interface at room level -
-
-
-
-
- Key features: -
    -
  • Live load or power use metrics on building, room, and rack levels -
  • Diverse scenarios from common operation to model-based failures -
  • Retrospective performance review of datacenter simulations -
  • Compare resource management practices -
-
-
- Mockup of the same simulation at node level -
- Mockup of the same simulation at node level -
-
-
-
-
-
-
- -
-
-
-
-

Technologies

-
-
- Web browser -
-

Browser

-

HTML5 canvas, CreateJS, TypeScript, SocketIO

-
-
-
- Web Server -
-

Web Server

-

Python, Flask, FlaskSocketIO, OpenAPI

-
-
-
- Database -
-

Database

-

SQLite

-
-
-
- Simulator -
-

Simulator

-

C++

-
-
-
-
-
-
-
- -
-
-
-
-

The Team

-
-
- -
-

Prof. dr. ir. Alexandru Iosup

-
- Project Lead -
-
-
-
- -
-

Leon Overweel

-
- Product Lead and Software Engineer responsible for the web server, database, and - API - specification -
-
-
-
- -
-

Georgios Andreadis

-
- Software Engineer responsible for the frontend web application and splash page -
-
-
-
- -
-

Matthijs Bijman

-
- Software Engineer responsible for the datacenter simulator -
-
-
-
-
-
-
-
- -
-
-
-
-

Contact

-
- TU Delft Logo - -
- -
-
-
-
- - - - - - - - - -
- - - diff --git a/src/navbar.html b/src/navbar.html deleted file mode 100644 index 92c79000..00000000 --- a/src/navbar.html +++ /dev/null @@ -1,18 +0,0 @@ - \ No newline at end of file diff --git a/src/profile.html b/src/profile.html deleted file mode 100644 index 1cdb560b..00000000 --- a/src/profile.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - OpenDC - Profile - - - - - - - - - - - -
-
-

Profile Settings

-
Delete my account on OpenDC
-
This does not delete your Google account, it simply disconnects it from the OpenDC app - and deletes any datacenter info that is associated with you (simulation projects you own, and any - authorizations you may have on other projects). -
- -
-
- - - - - - - - - - - - - diff --git a/src/projects.html b/src/projects.html deleted file mode 100644 index 6c5effb7..00000000 --- a/src/projects.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - OpenDC - Projects - - - - - - - - - - - - - -
-
-
-
-
All Projects
-
My Projects
-
Projects shared with me
-
-
-
- - No projects here yet... Add some with the 'New Project' button! -
-
-
-
Project name
-
Last edited
-
Access rights
-
-
-
-
-
New Project
-
-
- -
-
-
-
-
Edit project
-
-
- - -
Save
-
-
- Participants -
-
-
-
- - -
Add
-
-
- - -
- -
-
- - - - - - - - diff --git a/src/robots.txt b/src/robots.txt deleted file mode 100644 index 2329e38e..00000000 --- a/src/robots.txt +++ /dev/null @@ -1,4 +0,0 @@ -User-agent: * -Disallow: /app.html -Disallow: /profile.html -Disallow: /projects.html \ No newline at end of file diff --git a/src/scripts/colors.ts b/src/scripts/colors.ts deleted file mode 100644 index 559b7ee3..00000000 --- a/src/scripts/colors.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Class serving as a color palette for the application. - */ -export class Colors { - public static GRID_COLOR = "rgba(0, 0, 0, 0.5)"; - - public static WALL_COLOR = "rgba(0, 0, 0, 1)"; - - public static ROOM_DEFAULT = "rgba(150, 150, 150, 1)"; - public static ROOM_SELECTED = "rgba(51, 153, 255, 1)"; - public static ROOM_HOVER_VALID = "rgba(51, 153, 255, 0.5)"; - public static ROOM_HOVER_INVALID = "rgba(255, 102, 0, 0.5)"; - public static ROOM_NAME_COLOR = "rgba(245, 245, 245, 1)"; - public static ROOM_TYPE_COLOR = "rgba(245, 245, 245, 1)"; - - public static RACK_BACKGROUND = "rgba(170, 170, 170, 1)"; - public static RACK_BORDER = "rgba(0, 0, 0, 1)"; - public static RACK_SPACE_BAR_BACKGROUND = "rgba(222, 235, 247, 1)"; - public static RACK_SPACE_BAR_FILL = "rgba(91, 155, 213, 1)"; - public static RACK_ENERGY_BAR_BACKGROUND = "rgba(255, 242, 204, 1)"; - public static RACK_ENERGY_BAR_FILL = "rgba(255, 192, 0, 1)"; - - public static COOLING_ITEM_BACKGROUND = "rgba(40, 50, 230, 1)"; - public static COOLING_ITEM_BORDER = "rgba(0, 0, 0, 1)"; - - public static PSU_BACKGROUND = "rgba(230, 50, 60, 1)"; - public static PSU_BORDER = "rgba(0, 0, 0, 1)"; - - public static GRAYED_OUT_AREA = "rgba(0, 0, 0, 0.6)"; - - public static INFO_BALLOON_INFO = "rgba(40, 50, 230, 1)"; - public static INFO_BALLOON_WARNING = "rgba(230, 60, 70, 1)"; - - public static INFO_BALLOON_MAP = { - "info": Colors.INFO_BALLOON_INFO, - "warning": Colors.INFO_BALLOON_WARNING - }; - - public static SIM_LOW = "rgba(197, 224, 180, 1)"; - public static SIM_MID_LOW = "rgba(255, 230, 153, 1)"; - public static SIM_MID_HIGH = "rgba(248, 203, 173, 1)"; - public static SIM_HIGH = "rgba(249, 165, 165, 1)"; -} diff --git a/src/scripts/controllers/connection/api.ts b/src/scripts/controllers/connection/api.ts deleted file mode 100644 index 1a1c122f..00000000 --- a/src/scripts/controllers/connection/api.ts +++ /dev/null @@ -1,1738 +0,0 @@ -/// -/// -import {Util} from "../../util"; -import {ServerConnection} from "../../serverconnection"; - - -export class APIController { - constructor(onConnect: (api: APIController) => any) { - ServerConnection.connect(() => { - onConnect(this); - }); - } - - - /// - // PATH: /users - /// - - // METHOD: GET - public getUserByEmail(email: string): Promise { - return ServerConnection.send({ - path: "/users", - method: "GET", - parameters: { - body: {}, - path: {}, - query: { - email - } - } - }); - } - - // METHOD: POST - public addUser(user: IUser): Promise { - return ServerConnection.send({ - path: "/users", - method: "POST", - parameters: { - body: { - user: user - }, - path: {}, - query: {} - } - }); - } - - /// - // PATH: /users/{id} - /// - - // METHOD: GET - public getUser(userId: number): Promise { - return ServerConnection.send({ - path: "/users/{userId}", - method: "GET", - parameters: { - body: {}, - path: { - userId - }, - query: {} - } - }); - } - - // METHOD: PUT - public updateUser(userId: number, user: IUser): Promise { - return ServerConnection.send({ - path: "/users/{userId}", - method: "PUT", - parameters: { - body: { - user: { - givenName: user.givenName, - familyName: user.familyName - } - }, - path: { - userId - }, - query: {} - } - }); - } - - // METHOD: DELETE - public deleteUser(userId: number): Promise { - return ServerConnection.send({ - path: "/users/{userId}", - method: "DELETE", - parameters: { - body: {}, - path: { - userId - }, - query: {} - } - }); - } - - /// - // PATH: /users/{userId}/authorizations - /// - - // METHOD: GET - public getAuthorizationsByUser(userId: number): Promise { - let authorizations = []; - return ServerConnection.send({ - path: "/users/{userId}/authorizations", - method: "GET", - parameters: { - body: {}, - path: { - userId - }, - query: {} - } - }).then((data: any) => { - authorizations = data; - return this.getUser(userId); - }).then((userData: any) => { - const promises = []; - authorizations.forEach((authorization: IAuthorization) => { - authorization.user = userData; - promises.push(this.getSimulation(authorization.simulationId).then((simulationData: any) => { - authorization.simulation = simulationData; - })); - }); - return Promise.all(promises); - }).then((data: any) => { - return authorizations; - }); - } - - /// - // PATH: /simulations - /// - - // METHOD: POST - public addSimulation(simulation: ISimulation): Promise { - return ServerConnection.send({ - path: "/simulations", - method: "POST", - parameters: { - body: { - simulation: Util.packageForSending(simulation) - }, - path: {}, - query: {} - } - }).then((data: any) => { - this.parseSimulationTimestamps(data); - return data; - }); - } - - /// - // PATH: /simulations/{simulationId} - /// - - // METHOD: GET - public getSimulation(simulationId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}", - method: "GET", - parameters: { - body: {}, - path: { - simulationId - }, - query: {} - } - }).then((data: any) => { - this.parseSimulationTimestamps(data); - return data; - }); - } - - // METHOD: PUT - public updateSimulation(simulation: ISimulation): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}", - method: "PUT", - parameters: { - body: { - simulation: Util.packageForSending(simulation) - }, - path: { - simulationId: simulation.id - }, - query: {} - } - }).then((data: any) => { - this.parseSimulationTimestamps(data); - return data; - }); - } - - // METHOD: DELETE - public deleteSimulation(simulationId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}", - method: "DELETE", - parameters: { - body: {}, - path: { - simulationId - }, - query: {} - } - }); - } - - /// - // PATH: /simulations/{simulationId}/authorizations - /// - - // METHOD: GET - public getAuthorizationsBySimulation(simulationId: number): Promise { - let authorizations = []; - return ServerConnection.send({ - path: "/simulations/{simulationId}/authorizations", - method: "GET", - parameters: { - body: {}, - path: { - simulationId - }, - query: {} - } - }).then((data: any) => { - authorizations = data; - return this.getSimulation(simulationId); - }).then((simulationData: any) => { - const promises = []; - authorizations.forEach((authorization: IAuthorization) => { - authorization.simulation = simulationData; - promises.push(this.getUser(authorization.userId).then((userData: any) => { - authorization.user = userData; - })); - }); - return Promise.all(promises); - }).then((data: any) => { - return authorizations; - }); - } - - /// - // PATH: /simulations/{simulationId}/authorizations/{userId} - /// - - // METHOD: GET - // Not needed - - // METHOD: POST - public addAuthorization(authorization: IAuthorization): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/authorizations/{userId}", - method: "POST", - parameters: { - body: { - authorization: { - authorizationLevel: authorization.authorizationLevel - } - }, - path: { - simulationId: authorization.simulationId, - userId: authorization.userId - }, - query: {} - } - }); - } - - // METHOD: PUT - public updateAuthorization(authorization: IAuthorization): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/authorizations/{userId}", - method: "PUT", - parameters: { - body: { - authorization: { - authorizationLevel: authorization.authorizationLevel - } - }, - path: { - simulationId: authorization.simulationId, - userId: authorization.userId - }, - query: {} - } - }); - } - - // METHOD: DELETE - public deleteAuthorization(authorization: IAuthorization): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/authorizations/{userId}", - method: "DELETE", - parameters: { - body: {}, - path: { - simulationId: authorization.simulationId, - userId: authorization.userId - }, - query: {} - } - }); - } - - /// - // PATH: /simulations/{simulationId}/datacenters/{datacenterId} - /// - - // METHOD: GET - public getDatacenter(simulationId: number, datacenterId: number): Promise { - let datacenter; - - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - datacenterId - }, - query: {} - } - }).then((data: any) => { - datacenter = data; - - return this.getRoomsByDatacenter(simulationId, datacenterId); - }).then((data: any) => { - datacenter.rooms = data; - return datacenter; - }); - } - - - /// - // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms - /// - - // METHOD: GET - public getRoomsByDatacenter(simulationId: number, datacenterId: number): Promise { - let rooms; - - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - datacenterId - }, - query: {} - } - }).then((data: any) => { - rooms = data; - - const promises = []; - rooms.forEach((room: IRoom) => { - promises.push(this.loadRoomTiles(simulationId, datacenterId, room)); - }); - return Promise.all(promises).then((data: any) => { - return rooms; - }); - }); - } - - // METHOD: POST - public addRoomToDatacenter(simulationId: number, datacenterId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms", - method: "POST", - parameters: { - body: { - room: { - id: -1, - datacenterId, - roomType: "SERVER" - } - }, - path: { - simulationId, - datacenterId - }, - query: {} - } - }).then((data: any) => { - data.tiles = []; - return data; - }); - } - - /// - // PATH: /room-types - /// - - // METHOD: GET - public getAllRoomTypes(): Promise { - return ServerConnection.send({ - path: "/room-types", - method: "GET", - parameters: { - body: {}, - path: {}, - query: {} - } - }).then((data: any) => { - const result = []; - data.forEach((roomType: any) => { - result.push(roomType.name); - }); - return result; - }); - } - - /// - // PATH: /room-types/{name}/allowed-objects - /// - - // METHOD: GET - public getAllowedObjectsByRoomType(name: string): Promise { - return ServerConnection.send({ - path: "/room-types/{name}/allowed-objects", - method: "GET", - parameters: { - body: {}, - path: { - name - }, - query: {} - } - }); - } - - /// - // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId} - /// - - // METHOD: GET - public getRoom(simulationId: number, datacenterId: number, roomId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - datacenterId, - roomId - }, - query: {} - } - }).then((data: any) => { - return this.loadRoomTiles(simulationId, datacenterId, data); - }); - } - - // METHOD: PUT - public updateRoom(simulationId: number, datacenterId: number, room: IRoom): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}", - method: "PUT", - parameters: { - body: { - room: Util.packageForSending(room) - }, - path: { - simulationId, - datacenterId, - roomId: room.id - }, - query: {} - } - }).then((data: any) => { - return this.loadRoomTiles(simulationId, datacenterId, data); - }); - } - - // METHOD: DELETE - public deleteRoom(simulationId: number, datacenterId: number, roomId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}", - method: "DELETE", - parameters: { - body: {}, - path: { - simulationId, - datacenterId, - roomId - }, - query: {} - } - }); - } - - /// - // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles - /// - - // METHOD: GET - public getTilesByRoom(simulationId: number, datacenterId: number, roomId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - datacenterId, - roomId - }, - query: {} - } - }).then((data: any) => { - const promises = data.map((item) => { - return this.loadTileObject(simulationId, datacenterId, roomId, item); - }); - - return Promise.all(promises).then(() => { - return data; - }) - }); - } - - // METHOD: POST - public addTileToRoom(simulationId: number, datacenterId: number, roomId: number, tile: ITile): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles", - method: "POST", - parameters: { - body: { - tile: Util.packageForSending(tile) - }, - path: { - simulationId, - datacenterId, - roomId - }, - query: {} - } - }).then((data: any) => { - return this.loadTileObject(simulationId, datacenterId, roomId, data); - }); - } - - /// - // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId} - /// - - // METHOD: GET - // Not needed (yet) - - // METHOD: DELETE - public deleteTile(simulationId: number, datacenterId: number, roomId: number, tileId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}", - method: "DELETE", - parameters: { - body: {}, - path: { - simulationId, - datacenterId, - roomId, - tileId - }, - query: {} - } - }); - } - - /// - // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/cooling-item - /// - - // METHOD: GET - public getCoolingItem(simulationId: number, datacenterId: number, roomId: number, - tileId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/cooling-item", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - datacenterId, - roomId, - tileId - }, - query: {} - } - }).then((data: any) => { - return this.loadFailureModel(data); - }); - } - - // METHOD: POST - public addCoolingItem(simulationId: number, datacenterId: number, roomId: number, tileId: number, - coolingItem: ICoolingItem): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/cooling-item", - method: "POST", - parameters: { - body: { - coolingItem: Util.packageForSending(coolingItem) - }, - path: { - simulationId, - datacenterId, - roomId, - tileId - }, - query: {} - } - }).then((data: any) => { - return this.loadFailureModel(data); - }); - } - - // METHOD: PUT - // Not needed (yet) - - // METHOD: DELETE - public deleteCoolingItem(simulationId: number, datacenterId: number, roomId: number, - tileId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/cooling-item", - method: "DELETE", - parameters: { - body: {}, - path: { - simulationId, - datacenterId, - roomId, - tileId - }, - query: {} - } - }); - } - - /// - // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/psu - /// - - // METHOD: GET - public getPSU(simulationId: number, datacenterId: number, roomId: number, tileId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/psu", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - datacenterId, - roomId, - tileId - }, - query: {} - } - }).then((data: any) => { - return this.loadFailureModel(data); - }); - } - - // METHOD: POST - public addPSU(simulationId: number, datacenterId: number, roomId: number, tileId: number, - psu: IPSU): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/psu", - method: "POST", - parameters: { - body: { - psu: Util.packageForSending(psu) - }, - path: { - simulationId, - datacenterId, - roomId, - tileId - }, - query: {} - } - }).then((data: any) => { - return this.loadFailureModel(data); - }); - } - - // METHOD: PUT - // Not needed (yet) - - // METHOD: DELETE - public deletePSU(simulationId: number, datacenterId: number, roomId: number, - tileId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/psu", - method: "DELETE", - parameters: { - body: {}, - path: { - simulationId, - datacenterId, - roomId, - tileId - }, - query: {} - } - }); - } - - /// - // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack - /// - - // METHOD: GET - public getRack(simulationId: number, datacenterId: number, roomId: number, - tileId: number): Promise { - let rack = {}; - - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - datacenterId, - roomId, - tileId - }, - query: {} - } - }).then((data: any) => { - rack = data; - return this.getMachinesByRack(simulationId, datacenterId, roomId, tileId); - }).then((machines: any) => { - const promises = machines.map((machine) => { - return this.loadMachineUnits(machine); - }); - - - return Promise.all(promises).then(() => { - rack["machines"] = []; - - machines.forEach((machine: IMachine) => { - rack["machines"][machine.position] = machine; - }); - - for (let i = 0; i < rack["capacity"]; i++) { - if (rack["machines"][i] === undefined) { - rack["machines"][i] = null; - } - } - - return rack; - }); - }); - } - - // METHOD: POST - public addRack(simulationId: number, datacenterId: number, roomId: number, - tileId: number, rack: IRack): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack", - method: "POST", - parameters: { - body: { - rack: Util.packageForSending(rack) - }, - path: { - simulationId, - datacenterId, - roomId, - tileId - }, - query: {} - } - }).then((data: any) => { - data.machines = []; - - for (let i = 0; i < data.capacity; i++) { - data.machines.push(null); - } - - return data; - }); - } - - // METHOD: PUT - public updateRack(simulationId: number, datacenterId: number, roomId: number, - tileId: number, rack: IRack): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack", - method: "PUT", - parameters: { - body: { - rack - }, - path: { - simulationId, - datacenterId, - roomId, - tileId - }, - query: {} - } - }).then((data: any) => { - data.machines = rack.machines; - - return data; - }); - } - - // METHOD: DELETE - public deleteRack(simulationId: number, datacenterId: number, roomId: number, - tileId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack", - method: "DELETE", - parameters: { - body: {}, - path: { - simulationId, - datacenterId, - roomId, - tileId - }, - query: {} - } - }); - } - - /// - // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack/machines - /// - - // METHOD: GET - public getMachinesByRack(simulationId: number, datacenterId: number, roomId: number, - tileId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack/machines", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - datacenterId, - roomId, - tileId - }, - query: {} - } - }).then((data: any) => { - const promises = data.map((machine) => { - return this.loadMachineUnits(machine); - }); - - return Promise.all(promises).then(() => { - return data; - }); - }); - } - - // METHOD: POST - public addMachineToRack(simulationId: number, datacenterId: number, roomId: number, - tileId: number, machine: IMachine): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack/machines", - method: "POST", - parameters: { - body: { - machine: Util.packageForSending(machine) - }, - path: { - simulationId, - datacenterId, - roomId, - tileId - }, - query: {} - } - }).then((data: any) => { - return this.loadMachineUnits(data); - }); - } - - /// - // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack/machines/{position} - /// - - // METHOD: GET - // Not needed (yet) - - // METHOD: PUT - public updateMachine(simulationId: number, datacenterId: number, roomId: number, - tileId: number, machine: IMachine): Promise { - machine["tags"] = []; - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack/machines/{position}", - method: "PUT", - parameters: { - body: { - machine: Util.packageForSending(machine) - }, - path: { - simulationId, - datacenterId, - roomId, - tileId, - position: machine.position - }, - query: {} - } - }).then((data: any) => { - return this.loadMachineUnits(data); - }); - } - - // METHOD: DELETE - public deleteMachine(simulationId: number, datacenterId: number, roomId: number, - tileId: number, position: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack/machines/{position}", - method: "DELETE", - parameters: { - body: {}, - path: { - simulationId, - datacenterId, - roomId, - tileId, - position - }, - query: {} - } - }); - } - - /// - // PATH: /simulations/{simulationId}/experiments - /// - - // METHOD: GET - public getExperimentsBySimulation(simulationId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/experiments", - method: "GET", - parameters: { - body: {}, - path: { - simulationId - }, - query: {} - } - }).then((data: any) => { - const promises = data.map((item: any) => { - return this.getTrace(item.traceId).then((traceData: any) => { - item.trace = traceData; - }); - }); - return Promise.all(promises).then(() => { - return data; - }); - }); - } - - // METHOD: POST - public addExperimentToSimulation(simulationId: number, experiment: IExperiment): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/experiments", - method: "POST", - parameters: { - body: { - experiment: Util.packageForSending(experiment) - }, - path: { - simulationId - }, - query: {} - } - }).then((data: any) => { - return this.getTrace(data.traceId).then((traceData: any) => { - data.trace = traceData; - - return data; - }); - }); - } - - /// - // PATH: /simulations/{simulationId}/experiments/{experimentId} - /// - - // METHOD: GET - // Not needed (yet) - - // METHOD: PUT - public updateExperiment(experiment: IExperiment): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/experiments/{experimentId}", - method: "PUT", - parameters: { - body: { - experiment: Util.packageForSending(experiment) - }, - path: { - experimentId: experiment.id, - simulationId: experiment.simulationId - }, - query: {} - } - }).then((data: any) => { - return this.getTrace(data.traceId).then((traceData: any) => { - data.trace = traceData; - - return data; - }); - }); - } - - // METHOD: DELETE - public deleteExperiment(simulationId: number, experimentId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/experiments/{experimentId}", - method: "DELETE", - parameters: { - body: {}, - path: { - experimentId, - simulationId - }, - query: {} - } - }); - } - - /// - // PATH: /simulations/{simulationId}/experiments/{experimentId}/last-simulated-tick - /// - - // METHOD: GET - public getLastSimulatedTickByExperiment(simulationId: number, experimentId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/experiments/{experimentId}/last-simulated-tick", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - experimentId - }, - query: {} - } - }).then((data: any) => { - return data.lastSimulatedTick; - }); - } - - /// - // PATH: /simulations/{simulationId}/experiments/{experimentId}/machine-states - /// - - // METHOD: GET - public getMachineStates(simulationId: number, experimentId: number, machines: {[keys: number]: IMachine}, - tick?: number): Promise { - let query; - if (tick !== undefined) { - query = {tick}; - } else { - query = {}; - } - - return ServerConnection.send({ - path: "/simulations/{simulationId}/experiments/{experimentId}/machine-states", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - experimentId - }, - query - } - }).then((data: any) => { - data.forEach((item: any) => { - item.machine = machines[item.machineId]; - }); - - return data; - }); - } - - /// - // PATH: /simulations/{simulationId}/experiments/{experimentId}/rack-states - /// - - // METHOD: GET - public getRackStates(simulationId: number, experimentId: number, racks: {[keys: number]: IRack}, - tick?: number): Promise { - let query; - if (tick !== undefined) { - query = {tick}; - } else { - query = {}; - } - - return ServerConnection.send({ - path: "/simulations/{simulationId}/experiments/{experimentId}/rack-states", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - experimentId - }, - query: query - } - }).then((data: any) => { - data.forEach((item: any) => { - item.rack = racks[item.rackId]; - }); - - return data; - }); - } - - /// - // PATH: /simulations/{simulationId}/experiments/{experimentId}/room-states - /// - - // METHOD: GET - public getRoomStates(simulationId: number, experimentId: number, rooms: {[keys: number]: IRoom}, - tick?: number): Promise { - let query; - if (tick !== undefined) { - query = {tick}; - } else { - query = {}; - } - - return ServerConnection.send({ - path: "/simulations/{simulationId}/experiments/{experimentId}/room-states", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - experimentId - }, - query - } - }).then((data: any) => { - data.forEach((item: any) => { - item.room = rooms[item.roomId]; - }); - - return data; - }); - } - - /// - // PATH: /simulations/{simulationId}/experiments/{experimentId}/task-states - /// - - // METHOD: GET - public getTaskStates(simulationId: number, experimentId: number, tasks: {[keys: number]: ITask}, - tick?: number): Promise { - let query; - if (tick === undefined) { - query = {tick}; - } else { - query = {}; - } - - return ServerConnection.send({ - path: "/simulations/{simulationId}/experiments/{experimentId}/task-states", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - experimentId - }, - query - } - }).then((data: any) => { - data.forEach((item: any) => { - item.task = tasks[item.taskId]; - }); - - return data; - }); - } - - /// - // PATH: /simulations/{simulationId}/paths - /// - - // METHOD: GET - public getPathsBySimulation(simulationId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/paths", - method: "GET", - parameters: { - body: {}, - path: { - simulationId - }, - query: {} - } - }).then((data: any) => { - const promises = data.map((item: any) => { - return this.getSectionsByPath(simulationId, item.id).then((sectionsData: any) => { - item.sections = sectionsData; - }); - }); - return Promise.all(promises).then(() => { - return data; - }); - }); - } - - /// - // PATH: /simulations/{simulationId}/paths/{pathId} - /// - - // METHOD: GET - public getPath(simulationId: number, pathId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/paths/{pathId}", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - pathId - }, - query: {} - } - }).then((data: any) => { - return this.getSectionsByPath(simulationId, pathId).then((sectionsData: any) => { - data.sections = sectionsData; - return data; - }); - }); - } - - /// - // PATH: /simulations/{simulationId}/paths/{pathId}/branches - /// - - // METHOD: GET - public getBranchesByPath(simulationId: number, pathId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/paths/{pathId}/branches", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - pathId - }, - query: {} - } - }).then((data: any) => { - const promises = data.map((item: any) => { - return this.getSectionsByPath(simulationId, item.id).then((sectionsData: any) => { - item.sections = sectionsData; - }); - }); - return Promise.all(promises).then(() => { - return data; - }); - }); - } - - // METHOD: POST - public branchFromPath(simulationId: number, pathId: number, startTick: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/paths/{pathId}/branches", - method: "POST", - parameters: { - body: { - section: { - startTick - } - }, - path: { - simulationId, - pathId - }, - query: {} - } - }).then((data: any) => { - return this.getSectionsByPath(simulationId, data.id).then((sectionsData: any) => { - data.sections = sectionsData; - return data; - }); - }); - } - - /// - // PATH: /simulations/{simulationId}/paths/{pathId}/sections - /// - - // METHOD: GET - public getSectionsByPath(simulationId: number, pathId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/paths/{pathId}/sections", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - pathId - }, - query: {} - } - }).then((data: any) => { - const promises = data.map((path: ISection) => { - return this.getDatacenter(simulationId, path.datacenterId).then((datacenter: any) => { - path.datacenter = datacenter; - }); - }); - return Promise.all(promises).then(() => { - return data; - }); - }); - } - - /// - // PATH: /simulations/{simulationId}/paths/{pathId}/sections/{sectionId} - /// - - // METHOD: GET - public getSection(simulationId: number, pathId: number, sectionId: number): Promise { - return ServerConnection.send({ - path: "/simulations/{simulationId}/paths/{pathId}/sections/{sectionId}", - method: "GET", - parameters: { - body: {}, - path: { - simulationId, - pathId, - sectionId - }, - query: {} - } - }).then((data: any) => { - return this.getDatacenter(simulationId, data.datacenterId).then((datacenter: any) => { - data.datacenter = datacenter; - return data; - }); - }); - } - - /// - // PATH: /specifications/psus - /// - - // METHOD: GET - public getAllPSUSpecs(): Promise { - let psus; - return ServerConnection.send({ - path: "/specifications/psus", - method: "GET", - parameters: { - body: {}, - path: {}, - query: {} - } - }).then((data: any) => { - psus = data; - - const promises = []; - data.forEach((psu: IPSU) => { - promises.push(this.getFailureModel(psu.failureModelId)); - }); - return Promise.all(promises); - }).then((data: any) => { - return psus; - }); - } - - /// - // PATH: /specifications/psus/{id} - /// - - // METHOD: GET - public getPSUSpec(id: number): Promise { - let psu; - - return ServerConnection.send({ - path: "/specifications/psus/{id}", - method: "GET", - parameters: { - body: {}, - path: { - id - }, - query: {} - } - }).then((data: any) => { - psu = data; - return this.getFailureModel(data.failureModelId); - }).then((data: any) => { - psu.failureModel = data; - return psu; - }); - } - - /// - // PATH: /specifications/cooling-items - /// - - // METHOD: GET - public getAllCoolingItemSpecs(): Promise { - let coolingItems; - - return ServerConnection.send({ - path: "/specifications/cooling-items", - method: "GET", - parameters: { - body: {}, - path: {}, - query: {} - } - }).then((data: any) => { - coolingItems = data; - - const promises = []; - data.forEach((item: ICoolingItem) => { - promises.push(this.getFailureModel(item.failureModelId)); - }); - return Promise.all(promises); - }).then((data: any) => { - return coolingItems; - }); - } - - /// - // PATH: /specifications/cooling-items/{id} - /// - - // METHOD: GET - public getCoolingItemSpec(id: number): Promise { - let coolingItem; - - return ServerConnection.send({ - path: "/specifications/cooling-items/{id}", - method: "GET", - parameters: { - body: {}, - path: { - id - }, - query: {} - } - }).then((data: any) => { - coolingItem = data; - return this.getFailureModel(data.failureModelId); - }).then((data: any) => { - coolingItem.failureModel = data; - return coolingItem; - }); - } - - /// - // PATH: /schedulers - /// - - // METHOD: GET - public getAllSchedulers(): Promise { - return ServerConnection.send({ - path: "/schedulers", - method: "GET", - parameters: { - body: {}, - path: {}, - query: {} - } - }); - } - - /// - // PATH: /traces - /// - - // METHOD: GET - public getAllTraces(): Promise { - return ServerConnection.send({ - path: "/traces", - method: "GET", - parameters: { - body: {}, - path: {}, - query: {} - } - }); - } - - /// - // PATH: /traces/{traceId} - /// - - // METHOD: GET - public getTrace(traceId: number): Promise { - let trace; - - return ServerConnection.send({ - path: "/traces/{traceId}", - method: "GET", - parameters: { - body: {}, - path: { - traceId - }, - query: {} - } - }).then((data: any) => { - trace = data; - return this.getTasksByTrace(traceId); - }).then((data: any) => { - trace.tasks = data; - return trace; - }); - } - - /// - // PATH: /traces/{traceId}/tasks - /// - - // METHOD: GET - public getTasksByTrace(traceId: number): Promise { - return ServerConnection.send({ - path: "/traces/{traceId}/tasks", - method: "GET", - parameters: { - body: {}, - path: { - traceId - }, - query: {} - } - }); - } - - /// - // PATH: /specifications/failure-models - /// - - // METHOD: GET - public getAllFailureModels(): Promise { - return ServerConnection.send({ - path: "/specifications/failure-models", - method: "GET", - parameters: { - body: {}, - path: {}, - query: {} - } - }); - } - - /// - // PATH: /specifications/failure-models/{id} - /// - - // METHOD: GET - public getFailureModel(id: number): Promise { - return ServerConnection.send({ - path: "/specifications/failure-models/{id}", - method: "GET", - parameters: { - body: {}, - path: { - id - }, - query: {} - } - }); - } - - /// - // PATH: /specifications/[units] - /// - - // METHOD: GET - public getAllSpecificationsOfType(typePlural: string): Promise { - let specs: any; - return ServerConnection.send({ - path: "/specifications/" + typePlural, - method: "GET", - parameters: { - body: {}, - path: {}, - query: {} - } - }).then((data: any) => { - specs = data; - - const promises = []; - data.forEach((unit: INodeUnit) => { - promises.push(this.getFailureModel(unit.failureModelId)); - }); - return Promise.all(promises); - }).then((data: any) => { - return specs; - }); - } - - /// - // PATH: /specifications/[units]/{id} - /// - - // METHOD: GET - public getSpecificationOfType(typePlural: string, id: number): Promise { - let spec; - - return ServerConnection.send({ - path: "/specifications/" + typePlural + "/{id}", - method: "GET", - parameters: { - body: {}, - path: { - id - }, - query: {} - } - }).then((data: any) => { - spec = data; - return this.getFailureModel(data.failureModelId); - }).then((data: any) => { - spec.failureModel = data; - return spec; - }); - } - - - /// - // HELPER METHODS - /// - - private loadRoomTiles(simulationId: number, datacenterId: number, room: IRoom): Promise { - return this.getTilesByRoom(simulationId, datacenterId, room.id).then((data: any) => { - room.tiles = data; - return room; - }); - } - - private loadTileObject(simulationId: number, datacenterId: number, roomId: number, tile: ITile): Promise { - let promise; - - switch (tile.objectType) { - case "RACK": - promise = this.getRack(simulationId, datacenterId, roomId, tile.id).then((data: IRack) => { - tile.object = data; - }); - break; - case "PSU": - promise = this.getPSU(simulationId, datacenterId, roomId, tile.id).then((data: IPSU) => { - tile.object = data; - }); - break; - case "COOLING_ITEM": - promise = this.getCoolingItem(simulationId, datacenterId, roomId, tile.id).then((data: ICoolingItem) => { - tile.object = data; - }); - break; - default: - promise = new Promise((resolve, reject) => { - resolve(undefined); - }); - } - - return promise.then(() => { - return tile; - }) - } - - private parseSimulationTimestamps(simulation: ISimulation): void { - simulation.datetimeCreatedParsed = Util.parseDateTime(simulation.datetimeCreated); - simulation.datetimeLastEditedParsed = Util.parseDateTime(simulation.datetimeLastEdited); - } - - private loadFailureModel(data: any): Promise { - return this.getFailureModel(data.failureModelId).then((failureModel: IFailureModel) => { - data.failureModel = failureModel; - return data; - }); - } - - private loadUnitsOfType(idListName: string, objectListName: string, machine: IMachine): Promise { - machine[objectListName] = []; - - const promises = machine[idListName].map((item) => { - return this.getSpecificationOfType(objectListName, item).then((data) => { - machine[objectListName].push(data); - }); - }); - - return Promise.all(promises).then(() => { - return machine; - }) - } - - private loadMachineUnits(machine: IMachine): Promise { - const listNames = [ - { - idListName: "cpuIds", - objectListName: "cpus" - }, { - idListName: "gpuIds", - objectListName: "gpus" - }, { - idListName: "memoryIds", - objectListName: "memories" - }, { - idListName: "storageIds", - objectListName: "storages" - } - ]; - - const promises = listNames.map((item: any) => { - return this.loadUnitsOfType(item.idListName, item.objectListName, machine); - }); - - return Promise.all(promises).then(() => { - return machine; - }); - } -} diff --git a/src/scripts/controllers/connection/cache.ts b/src/scripts/controllers/connection/cache.ts deleted file mode 100644 index c1c47c2d..00000000 --- a/src/scripts/controllers/connection/cache.ts +++ /dev/null @@ -1,85 +0,0 @@ -export enum CacheStatus { - MISS, - FETCHING, - HIT, - NOT_CACHABLE -} - - -interface ICachableObject { - status: CacheStatus; - object: any; - callbacks: any[]; -} - - -export class CacheController { - private static CACHABLE_ROUTES = [ - "/specifications/psus/{id}", - "/specifications/cooling-items/{id}", - "/specifications/cpus/{id}", - "/specifications/gpus/{id}", - "/specifications/memories/{id}", - "/specifications/storages/{id}", - "/specifications/failure-models/{id}", - ]; - - // Maps every route name to a map of IDs => objects - private routeCaches: { [keys: string]: { [keys: number]: ICachableObject } }; - - - constructor() { - this.routeCaches = {}; - - CacheController.CACHABLE_ROUTES.forEach((routeName: string) => { - this.routeCaches[routeName] = {}; - }) - } - - public checkCache(request: IRequest): CacheStatus { - if (request.method === "GET" && CacheController.CACHABLE_ROUTES.indexOf(request.path) !== -1) { - if (this.routeCaches[request.path][request.parameters.path["id"]] === undefined) { - this.routeCaches[request.path][request.parameters.path["id"]] = { - status: CacheStatus.MISS, - object: null, - callbacks: [] - }; - return CacheStatus.MISS; - } else { - return this.routeCaches[request.path][request.parameters.path["id"]].status; - } - } else { - return CacheStatus.NOT_CACHABLE; - } - } - - public fetchFromCache(request: IRequest): any { - return this.routeCaches[request.path][request.parameters.path["id"]].object; - } - - public setToFetching(request: IRequest): void { - this.routeCaches[request.path][request.parameters.path["id"]].status = CacheStatus.FETCHING; - } - - public onFetch(request: IRequest, response: IResponse): any { - const pathWithoutVersion = request.path.replace(/\/v\d+/, ""); - this.routeCaches[pathWithoutVersion][request.parameters.path["id"]].status = CacheStatus.HIT; - this.routeCaches[pathWithoutVersion][request.parameters.path["id"]].object = response.content; - - this.routeCaches[pathWithoutVersion][request.parameters.path["id"]].callbacks.forEach((callback) => { - callback({ - status: { - code: 200 - }, - content: response.content, - id: request.id - }); - }); - - this.routeCaches[pathWithoutVersion][request.parameters.path["id"]].callbacks = []; - } - - public registerCallback(request: IRequest, callback): any { - this.routeCaches[request.path][request.parameters.path["id"]].callbacks.push(callback); - } -} diff --git a/src/scripts/controllers/connection/socket.ts b/src/scripts/controllers/connection/socket.ts deleted file mode 100644 index 91a0f9e4..00000000 --- a/src/scripts/controllers/connection/socket.ts +++ /dev/null @@ -1,76 +0,0 @@ -import {CacheController, CacheStatus} from "./cache"; -import * as io from "socket.io-client"; - - -export class SocketController { - private static id = 1; - private _socket: SocketIOClient.Socket; - private _cacheController: CacheController; - - // Mapping from request IDs to their registered callbacks - private callbacks: { [keys: number]: (response: IResponse) => any }; - - - constructor(onConnect: () => any) { - this.callbacks = {}; - this._cacheController = new CacheController(); - - this._socket = io.connect('SERVER_BASE_URL'); - this._socket.on('connect', onConnect); - - this._socket.on('response', (jsonResponse: string) => { - const response: IResponse = JSON.parse(jsonResponse); - console.log("Response, ID:", response.id, response); - this.callbacks[response.id](response); - delete this.callbacks[response.id]; - }); - } - - /** - * Sends a request to the server socket and registers the callback to be triggered on response. - * - * @param request The request instance to be sent - * @param callback A function to be called with the response object once the socket has received a response - */ - public sendRequest(request: IRequest, callback: (response: IResponse) => any): void { - // Check local cache, in case request is for cachable GET route - const cacheStatus = this._cacheController.checkCache(request); - - if (cacheStatus === CacheStatus.HIT) { - callback({ - status: { - code: 200 - }, - content: this._cacheController.fetchFromCache(request), - id: -1 - }); - } else if (cacheStatus === CacheStatus.FETCHING) { - this._cacheController.registerCallback(request, callback); - } else if (cacheStatus === CacheStatus.MISS || cacheStatus === CacheStatus.NOT_CACHABLE) { - if (!this._socket.connected) { - console.error("Socket not connected, sending request failed"); - } - - if (cacheStatus === CacheStatus.MISS) { - this._cacheController.setToFetching(request); - - this.callbacks[SocketController.id] = (response: IResponse) => { - this._cacheController.onFetch(request, response); - callback(response); - }; - } else { - this.callbacks[SocketController.id] = callback; - } - - // Setup request object - request.id = SocketController.id; - request.token = localStorage.getItem("googleToken"); - request.path = "/v1" + request.path; - - console.log("Request, ID:", request.id, request); - this._socket.emit("request", request); - - SocketController.id++; - } - } -} diff --git a/src/scripts/controllers/mapcontroller.ts b/src/scripts/controllers/mapcontroller.ts deleted file mode 100644 index 4ad1b20b..00000000 --- a/src/scripts/controllers/mapcontroller.ts +++ /dev/null @@ -1,520 +0,0 @@ -/// -/// -import * as $ from "jquery"; -import {Colors} from "../colors"; -import {Util} from "../util"; -import {SimulationController} from "./simulationcontroller"; -import {MapView} from "../views/mapview"; -import {APIController} from "./connection/api"; -import {BuildingModeController} from "./modes/building"; -import {RoomModeController, RoomInteractionMode} from "./modes/room"; -import {ObjectModeController} from "./modes/object"; -import {NodeModeController} from "./modes/node"; -import {ScaleIndicatorController} from "./scaleindicator"; - -export const CELL_SIZE = 50; - - -export enum AppMode { - CONSTRUCTION, - SIMULATION -} - - -/** - * The current level of datacenter hierarchy that is selected - */ -export enum InteractionLevel { - BUILDING, - ROOM, - OBJECT, - NODE -} - - -/** - * Possible states that the application can be in, in terms of interaction - */ -export enum InteractionMode { - DEFAULT, - SELECT_ROOM -} - - -/** - * Class responsible for handling user input in the map. - */ -export class MapController { - public stage: createjs.Stage; - public mapView: MapView; - - public appMode: AppMode; - public interactionLevel: InteractionLevel; - public interactionMode: InteractionMode; - - public buildingModeController: BuildingModeController; - public roomModeController: RoomModeController; - public objectModeController: ObjectModeController; - public nodeModeController: NodeModeController; - - public simulationController: SimulationController; - public api: APIController; - private scaleIndicatorController: ScaleIndicatorController; - - private canvas: JQuery; - private gridDragging: boolean; - - private infoTimeOut: any; - // Current mouse coordinates on the stage canvas (mainly for zooming purposes) - private currentStageMouseX: number; - - private currentStageMouseY: number; - // Keep start coordinates relative to the grid to compute dragging offset later - private gridDragBeginX: number; - - private gridDragBeginY: number; - // Keep start coordinates on stage to compute delta values - private stageDragBeginX: number; - private stageDragBeginY: number; - - private MAX_DELTA = 5; - - - /** - * Hides all side menus except for the active one. - * - * @param activeMenu An identifier (e.g. #room-menu) for the menu container - */ - public static hideAndShowMenus(activeMenu: string): void { - $(".menu-container.level-menu").each((index: number, elem: Element) => { - if ($(elem).is(activeMenu)) { - $(elem).removeClass("hidden"); - } else { - $(elem).addClass("hidden"); - } - }); - } - - constructor(mapView: MapView) { - this.mapView = mapView; - this.stage = this.mapView.stage; - - new APIController((apiInstance: APIController) => { - this.api = apiInstance; - - this.buildingModeController = new BuildingModeController(this); - this.roomModeController = new RoomModeController(this); - this.objectModeController = new ObjectModeController(this); - this.nodeModeController = new NodeModeController(this); - this.simulationController = new SimulationController(this); - - this.scaleIndicatorController = new ScaleIndicatorController(this); - - this.canvas = $("#main-canvas"); - - $(window).on("resize", () => { - this.onWindowResize(); - }); - - this.gridDragging = false; - - this.appMode = AppMode.CONSTRUCTION; - this.interactionLevel = InteractionLevel.BUILDING; - this.interactionMode = InteractionMode.DEFAULT; - - this.setAllMenuModes(); - - this.setupMapInteractionHandlers(); - this.setupEventListeners(); - this.buildingModeController.setupEventListeners(); - this.roomModeController.setupEventListeners(); - this.objectModeController.setupEventListeners(); - this.nodeModeController.setupEventListeners(); - - this.scaleIndicatorController.init($(".scale-indicator")); - this.scaleIndicatorController.update(); - - this.mapView.roomLayer.setClickable(true); - - this.matchUserAuthLevel(); - }); - } - - /** - * Hides and shows the menu bodies corresponding to the current mode (construction or simulation). - */ - public setAllMenuModes(): void { - $(".menu-body" + (this.appMode === AppMode.CONSTRUCTION ? ".construction" : ".simulation")).show(); - $(".menu-body" + (this.appMode === AppMode.CONSTRUCTION ? ".simulation" : ".construction")).hide(); - } - - /** - * Checks whether the mapContainer is still within its legal bounds. - * - * Resets, if necessary, to the most similar still legal position. - */ - public checkAndResetCanvasMovement(): void { - if (this.mapView.mapContainer.x + this.mapView.gridLayer.gridPixelSize * - this.mapView.mapContainer.scaleX < this.mapView.canvasWidth) { - this.mapView.mapContainer.x = this.mapView.canvasWidth - this.mapView.gridLayer.gridPixelSize * - this.mapView.mapContainer.scaleX; - } - if (this.mapView.mapContainer.x > 0) { - this.mapView.mapContainer.x = 0; - } - if (this.mapView.mapContainer.y + this.mapView.gridLayer.gridPixelSize * - this.mapView.mapContainer.scaleX < this.mapView.canvasHeight) { - this.mapView.mapContainer.y = this.mapView.canvasHeight - this.mapView.gridLayer.gridPixelSize * - this.mapView.mapContainer.scaleX; - } - if (this.mapView.mapContainer.y > 0) { - this.mapView.mapContainer.y = 0; - } - } - - /** - * Checks whether the mapContainer is still within its legal bounds and generates corrections if needed. - * - * Does not change the x and y coordinates, only returns. - */ - public checkCanvasMovement(x: number, y: number, scale: number): IGridPosition { - const result: IGridPosition = {x: x, y: y}; - if (x + this.mapView.gridLayer.gridPixelSize * scale < this.mapView.canvasWidth) { - result.x = this.mapView.canvasWidth - this.mapView.gridLayer.gridPixelSize * - this.mapView.mapContainer.scaleX; - } - if (x > 0) { - result.x = 0; - } - if (y + this.mapView.gridLayer.gridPixelSize * scale < this.mapView.canvasHeight) { - result.y = this.mapView.canvasHeight - this.mapView.gridLayer.gridPixelSize * - this.mapView.mapContainer.scaleX; - } - if (y > 0) { - result.y = 0; - } - - return result; - } - - /** - * Checks whether the current interaction mode is a hover mode (meaning that there is a hover item present). - * - * @returns {boolean} Whether it is in hover mode. - */ - public isInHoverMode(): boolean { - return this.roomModeController !== undefined && - (this.interactionMode === InteractionMode.SELECT_ROOM || - this.roomModeController.roomInteractionMode === RoomInteractionMode.ADD_RACK || - this.roomModeController.roomInteractionMode === RoomInteractionMode.ADD_PSU || - this.roomModeController.roomInteractionMode === RoomInteractionMode.ADD_COOLING_ITEM); - } - - public static showConfirmDeleteDialog(itemType: string, onConfirm: () => void): void { - const modalDialog = $("#confirm-delete"); - modalDialog.find(".modal-body").text("Are you sure you want to delete this " + itemType + "?"); - - const callback = () => { - onConfirm(); - modalDialog.modal("hide"); - modalDialog.find("button.confirm").first().off("click"); - $(document).off("keypress"); - }; - - $(document).on("keypress", (event: JQueryEventObject) => { - if (event.which === 13) { - callback(); - } else if (event.which === 27) { - modalDialog.modal("hide"); - $(document).off("keypress"); - modalDialog.find("button.confirm").first().off("click"); - } - }); - modalDialog.find("button.confirm").first().on("click", callback); - modalDialog.modal("show"); - } - - /** - * Shows an informational popup in a corner of the screen, communicating a certain event. - * - * @param message The message to be displayed in the body of the popup - * @param type The severity of the message; Currently supported: "info" and "warning" - */ - public showInfoBalloon(message: string, type: string): void { - const balloon = $(".info-balloon"); - balloon.html('' + message); - const callback = () => { - balloon.fadeOut(300); - - this.infoTimeOut = undefined; - }; - const DISPLAY_TIME = 3000; - - const balloonIcon = balloon.find("span").first(); - balloonIcon.removeClass(); - - balloon.css("background", Colors.INFO_BALLOON_MAP[type]); - balloonIcon.addClass("glyphicon"); - if (type === "info") { - balloonIcon.addClass("glyphicon-info-sign"); - } else if (type === "warning") { - balloonIcon.addClass("glyphicon-exclamation-sign"); - } - - if (this.infoTimeOut === undefined) { - balloon.fadeIn(300); - this.infoTimeOut = setTimeout(callback, DISPLAY_TIME); - } else { - clearTimeout(this.infoTimeOut); - this.infoTimeOut = setTimeout(callback, DISPLAY_TIME); - } - } - - private setupMapInteractionHandlers(): void { - this.stage.enableMouseOver(20); - - // Listen for mouse movement events to update hover positions - this.stage.on("stagemousemove", (event: createjs.MouseEvent) => { - this.currentStageMouseX = event.stageX; - this.currentStageMouseY = event.stageY; - - const gridPos = this.convertScreenCoordsToGridCoords([event.stageX, event.stageY]); - const tileX = gridPos.x; - const tileY = gridPos.y; - - // Check whether the coordinates of the hover location have changed since the last draw - if (this.mapView.hoverLayer.hoverTilePosition.x !== tileX) { - this.mapView.hoverLayer.hoverTilePosition.x = tileX; - this.mapView.updateScene = true; - } - if (this.mapView.hoverLayer.hoverTilePosition.y !== tileY) { - this.mapView.hoverLayer.hoverTilePosition.y = tileY; - this.mapView.updateScene = true; - } - }); - - // Handle mousedown interaction - this.stage.on("mousedown", (e: createjs.MouseEvent) => { - this.stageDragBeginX = e.stageX; - this.stageDragBeginY = e.stageY; - }); - - // Handle map dragging interaction - // Drag begin and progress handlers - this.mapView.mapContainer.on("pressmove", (e: createjs.MouseEvent) => { - if (!this.gridDragging) { - this.gridDragBeginX = e.stageX - this.mapView.mapContainer.x; - this.gridDragBeginY = e.stageY - this.mapView.mapContainer.y; - this.stageDragBeginX = e.stageX; - this.stageDragBeginY = e.stageY; - this.gridDragging = true; - } else { - this.mapView.mapContainer.x = e.stageX - this.gridDragBeginX; - this.mapView.mapContainer.y = e.stageY - this.gridDragBeginY; - - this.checkAndResetCanvasMovement(); - - this.mapView.updateScene = true; - } - }); - - // Drag exit handlers - this.mapView.mapContainer.on("pressup", (e: createjs.MouseEvent) => { - if (this.gridDragging) { - this.gridDragging = false; - } - - if (Math.abs(e.stageX - this.stageDragBeginX) < this.MAX_DELTA && - Math.abs(e.stageY - this.stageDragBeginY) < this.MAX_DELTA) { - this.handleCanvasMouseClick(e.stageX, e.stageY); - } - }); - - // Disable an ongoing drag action if the mouse leaves the canvas - this.mapView.stage.on("mouseleave", () => { - if (this.gridDragging) { - this.gridDragging = false; - } - }); - - // Relay scroll events to the MapView zoom handler - $("#main-canvas").on("mousewheel", (event: JQueryEventObject) => { - const originalEvent = (event.originalEvent); - this.mapView.zoom([this.currentStageMouseX, this.currentStageMouseY], -0.7 * originalEvent.deltaY); - this.scaleIndicatorController.update(); - }); - } - - /** - * Connects clickable UI elements to their respective event listeners. - */ - private setupEventListeners(): void { - // Zooming elements - $("#zoom-plus").on("click", () => { - this.mapView.zoom([ - this.mapView.canvasWidth / 2, - this.mapView.canvasHeight / 2 - ], 20); - }); - $("#zoom-minus").on("click", () => { - this.mapView.zoom([ - this.mapView.canvasWidth / 2, - this.mapView.canvasHeight / 2 - ], -20); - }); - - $(".export-canvas").click(() => { - this.exportCanvasToImage(); - }); - - // Menu panels - $(".menu-header-bar .menu-collapse").on("click", (event: JQueryEventObject) => { - const container = $(event.target).closest(".menu-container"); - if (this.appMode === AppMode.CONSTRUCTION) { - container.children(".menu-body.construction").first().slideToggle(300); - } else if (this.appMode === AppMode.SIMULATION) { - container.children(".menu-body.simulation").first().slideToggle(300); - } - - }); - - // Menu close button - $(".menu-header-bar .menu-exit").on("click", (event: JQueryEventObject) => { - const nearestMenuContainer = $(event.target).closest(".menu-container"); - if (nearestMenuContainer.is("#node-menu")) { - this.interactionLevel = InteractionLevel.OBJECT; - $(".node-element-overlay").addClass("hidden"); - } - nearestMenuContainer.addClass("hidden"); - }); - - // Handler for the construction mode switch - $("#construction-mode-switch").on("click", () => { - this.simulationController.exitMode(); - }); - - // Handler for the simulation mode switch - $("#simulation-mode-switch").on("click", () => { - this.simulationController.enterMode(); - }); - - // Handler for the version-save button - $("#save-version-btn").on("click", (event: JQueryEventObject) => { - const target = $(event.target); - - target.attr("data-saved", "false"); - const lastPath = this.mapView.simulation.paths[this.mapView.simulation.paths.length - 1]; - this.api.branchFromPath( - this.mapView.simulation.id, lastPath.id, lastPath.sections[lastPath.sections.length - 1].startTick + 1 - ).then((data: IPath) => { - this.mapView.simulation.paths.push(data); - this.mapView.currentDatacenter = data.sections[data.sections.length - 1].datacenter; - target.attr("data-saved", "true"); - }); - }); - - $(document).on("keydown", (event: JQueryKeyEventObject) => { - if ($(event.target).is('input')) { - return; - } - - if (event.which === 83) { - this.simulationController.enterMode(); - } else if (event.which === 67) { - this.simulationController.exitMode(); - } else if (event.which == 32) { - if (this.appMode === AppMode.SIMULATION) { - this.simulationController.timelineController.togglePlayback(); - } - } - }); - } - - /** - * Handles a simple mouse click (without drag) on the canvas. - * - * @param stageX The x coordinate of the location in pixels on the stage - * @param stageY The y coordinate of the location in pixels on the stage - */ - private handleCanvasMouseClick(stageX: number, stageY: number): void { - const gridPos = this.convertScreenCoordsToGridCoords([stageX, stageY]); - - if (this.interactionLevel === InteractionLevel.BUILDING) { - if (this.interactionMode === InteractionMode.DEFAULT) { - const roomIndex = Util.roomCollisionIndexOf(this.mapView.currentDatacenter.rooms, gridPos); - - if (roomIndex !== -1) { - this.interactionLevel = InteractionLevel.ROOM; - this.roomModeController.enterMode(this.mapView.currentDatacenter.rooms[roomIndex]); - } - } else if (this.interactionMode === InteractionMode.SELECT_ROOM) { - if (this.mapView.roomLayer.checkHoverTileValidity(gridPos)) { - this.buildingModeController.addSelectedTile(this.mapView.hoverLayer.hoverTilePosition); - } else if (Util.tileListContainsPosition(this.mapView.roomLayer.selectedTiles, gridPos)) { - this.buildingModeController.removeSelectedTile(this.mapView.hoverLayer.hoverTilePosition); - } - } - } else if (this.interactionLevel === InteractionLevel.ROOM) { - this.roomModeController.handleCanvasMouseClick(gridPos); - } else if (this.interactionLevel === InteractionLevel.OBJECT) { - if (gridPos.x !== this.mapView.grayLayer.currentObjectTile.position.x || - gridPos.y !== this.mapView.grayLayer.currentObjectTile.position.y) { - this.objectModeController.goToRoomMode(); - } - } else if (this.interactionLevel === InteractionLevel.NODE) { - this.interactionLevel = InteractionLevel.OBJECT; - this.nodeModeController.goToObjectMode(); - } - } - - /** - * Takes screen (stage) coordinates and returns the grid cell position they belong to. - * - * @param stagePosition The raw x and y coordinates of the wanted position - * @returns {Array} The corresponding grid cell coordinates - */ - private convertScreenCoordsToGridCoords(stagePosition: number[]): IGridPosition { - const result = {x: 0, y: 0}; - result.x = Math.floor((stagePosition[0] - this.mapView.mapContainer.x) / - (this.mapView.mapContainer.scaleX * CELL_SIZE)); - result.y = Math.floor((stagePosition[1] - this.mapView.mapContainer.y) / - (this.mapView.mapContainer.scaleY * CELL_SIZE)); - return result; - } - - /** - * Adjusts the canvas size to fit the window perfectly. - */ - private onWindowResize() { - const parent = this.canvas.parent(".app-content"); - parent.height($(window).height() - 50); - this.canvas.attr("width", parent.width()); - this.canvas.attr("height", parent.height()); - this.mapView.canvasWidth = parent.width(); - this.mapView.canvasHeight = parent.height(); - - if (this.interactionLevel === InteractionLevel.BUILDING) { - this.mapView.zoomOutOnDC(); - } else if (this.interactionLevel === InteractionLevel.ROOM) { - this.mapView.zoomInOnRoom(this.roomModeController.currentRoom); - } else { - this.mapView.zoomInOnRoom(this.roomModeController.currentRoom, true); - } - - this.mapView.updateScene = true; - } - - private matchUserAuthLevel() { - const authLevel = localStorage.getItem("simulationAuthLevel"); - if (authLevel === "VIEW") { - $(".side-menu-container.right-middle-side, .side-menu-container.right-side").hide(); - } - } - - private exportCanvasToImage() { - const canvasData = (this.canvas.get(0)).toDataURL("image/png"); - const newWindow = window.open('about:blank', 'OpenDC Canvas Export'); - newWindow.document.write("Canvas Image Export"); - newWindow.document.title = "OpenDC Canvas Export"; - } -} diff --git a/src/scripts/controllers/modes/building.ts b/src/scripts/controllers/modes/building.ts deleted file mode 100644 index 217f5935..00000000 --- a/src/scripts/controllers/modes/building.ts +++ /dev/null @@ -1,113 +0,0 @@ -import {InteractionMode, MapController} from "../mapcontroller"; -import {MapView} from "../../views/mapview"; -import * as $ from "jquery"; - - -/** - * Class responsible for handling building mode interactions. - */ -export class BuildingModeController { - public newRoomId: number; - - private mapController: MapController; - private mapView: MapView; - - - constructor(mapController: MapController) { - this.mapController = mapController; - this.mapView = this.mapController.mapView; - } - - /** - * Connects all DOM event listeners to their respective element targets. - */ - public setupEventListeners() { - const resetConstructionButtons = () => { - this.mapController.interactionMode = InteractionMode.DEFAULT; - this.mapView.hoverLayer.setHoverTileVisibility(false); - $("#room-construction").text("Construct new room"); - $("#room-construction-cancel").slideToggle(300); - }; - - // Room construction button - $("#room-construction").on("click", (event: JQueryEventObject) => { - if (this.mapController.interactionMode === InteractionMode.DEFAULT) { - this.mapController.interactionMode = InteractionMode.SELECT_ROOM; - this.mapView.hoverLayer.setHoverTileVisibility(true); - this.mapController.api.addRoomToDatacenter(this.mapView.simulation.id, - this.mapView.currentDatacenter.id).then((room: IRoom) => { - this.newRoomId = room.id; - }); - $(event.target).text("Finalize room"); - $("#room-construction-cancel").slideToggle(300); - } else if (this.mapController.interactionMode === InteractionMode.SELECT_ROOM) { - resetConstructionButtons(); - this.finalizeRoom(); - } - }); - - // Cancel button for room construction - $("#room-construction-cancel").on("click", () => { - resetConstructionButtons(); - this.cancelRoomConstruction(); - }); - } - - /** - * Cancels room construction and deletes the temporary room created previously. - */ - public cancelRoomConstruction() { - this.mapController.api.deleteRoom(this.mapView.simulation.id, - this.mapView.currentDatacenter.id, this.newRoomId).then(() => { - this.mapView.roomLayer.cancelRoomConstruction(); - }); - } - - /** - * Finalizes room construction by triggering a redraw of the room layer with the new room added. - */ - public finalizeRoom() { - this.mapController.api.getRoom(this.mapView.simulation.id, - this.mapView.currentDatacenter.id, this.newRoomId).then((room: IRoom) => { - this.mapView.roomLayer.finalizeRoom(room); - }); - } - - /** - * Adds a newly selected tile to the list of selected tiles. - * - * @param position The new tile position to be added - */ - public addSelectedTile(position: IGridPosition): void { - const tile = { - id: -1, - roomId: this.newRoomId, - position: {x: position.x, y: position.y} - }; - this.mapController.api.addTileToRoom(this.mapView.simulation.id, - this.mapView.currentDatacenter.id, this.newRoomId, tile).then((tile: ITile) => { - this.mapView.roomLayer.addSelectedTile(tile); - }); - } - - /** - * Removes a previously selected tile. - * - * @param position The position of the tile to be removed - */ - public removeSelectedTile(position: IGridPosition): void { - let objectIndex = -1; - - for (let i = 0; i < this.mapView.roomLayer.selectedTileObjects.length; i++) { - const tile = this.mapView.roomLayer.selectedTileObjects[i]; - if (tile.position.x === position.x && tile.position.y === position.y) { - objectIndex = i; - } - } - this.mapController.api.deleteTile(this.mapView.simulation.id, - this.mapView.currentDatacenter.id, this.newRoomId, - this.mapView.roomLayer.selectedTileObjects[objectIndex].tileObject.id).then(() => { - this.mapView.roomLayer.removeSelectedTile(position, objectIndex); - }); - } -} diff --git a/src/scripts/controllers/modes/node.ts b/src/scripts/controllers/modes/node.ts deleted file mode 100644 index cef61bba..00000000 --- a/src/scripts/controllers/modes/node.ts +++ /dev/null @@ -1,297 +0,0 @@ -import {MapController, AppMode, InteractionLevel} from "../mapcontroller"; -import {MapView} from "../../views/mapview"; -import * as $ from "jquery"; - - -/** - * Class responsible for rendering node mode and handling UI interactions within it. - */ -export class NodeModeController { - public currentMachine: IMachine; - - private mapController: MapController; - private mapView: MapView; - - - constructor(mapController: MapController) { - this.mapController = mapController; - this.mapView = this.mapController.mapView; - - this.loadAddDropdowns(); - } - - /** - * Moves the UI model into node mode. - * - * @param machine The machine that was selected in rack mode - */ - public enterMode(machine: IMachine): void { - this.currentMachine = machine; - this.populateUnitLists(); - $("#node-menu").removeClass("hidden"); - - if (this.mapController.appMode === AppMode.SIMULATION) { - this.mapController.simulationController.transitionFromRackToNode(); - } - } - - /** - * Performs cleanup and closing actions before allowing transferal to rack mode. - */ - public goToObjectMode(): void { - $("#node-menu").addClass("hidden"); - $(".node-element-overlay").addClass("hidden"); - this.currentMachine = undefined; - this.mapController.interactionLevel = InteractionLevel.OBJECT; - - if (this.mapController.appMode === AppMode.SIMULATION) { - this.mapController.simulationController.transitionFromNodeToRack(); - } - } - - /** - * Connects all DOM event listeners to their respective element targets. - */ - public setupEventListeners(): void { - const nodeMenu = $("#node-menu"); - - nodeMenu.find(".panel-group").on("click", ".remove-unit", (event: JQueryEventObject) => { - MapController.showConfirmDeleteDialog("unit", () => { - const index = $(event.target).closest(".panel").index(); - - if (index === -1) { - return; - } - - const closestTabPane = $(event.target).closest(".panel-group"); - - let objectList, idList; - if (closestTabPane.is("#cpu-accordion")) { - objectList = this.currentMachine.cpus; - idList = this.currentMachine.cpuIds; - } else if (closestTabPane.is("#gpu-accordion")) { - objectList = this.currentMachine.gpus; - idList = this.currentMachine.gpuIds; - } else if (closestTabPane.is("#memory-accordion")) { - objectList = this.currentMachine.memories; - idList = this.currentMachine.memoryIds; - } else if (closestTabPane.is("#storage-accordion")) { - objectList = this.currentMachine.storages; - idList = this.currentMachine.storageIds; - } - - idList.splice(idList.indexOf(objectList[index]).id, 1); - objectList.splice(index, 1); - - this.mapController.api.updateMachine(this.mapView.simulation.id, - this.mapView.currentDatacenter.id, this.mapController.roomModeController.currentRoom.id, - this.mapController.objectModeController.currentObjectTile.id, this.currentMachine).then( - () => { - this.populateUnitLists(); - this.mapController.objectModeController.updateNodeComponentOverlays(); - }); - }); - }); - - nodeMenu.find(".add-unit").on("click", (event: JQueryEventObject) => { - const dropdown = $(event.target).closest(".input-group-btn").siblings("select").first(); - - const closestTabPane = $(event.target).closest(".input-group").siblings(".panel-group").first(); - let objectList, idList, typePlural; - if (closestTabPane.is("#cpu-accordion")) { - objectList = this.currentMachine.cpus; - idList = this.currentMachine.cpuIds; - typePlural = "cpus"; - } else if (closestTabPane.is("#gpu-accordion")) { - objectList = this.currentMachine.gpus; - idList = this.currentMachine.gpuIds; - typePlural = "gpus"; - } else if (closestTabPane.is("#memory-accordion")) { - objectList = this.currentMachine.memories; - idList = this.currentMachine.memoryIds; - typePlural = "memories"; - } else if (closestTabPane.is("#storage-accordion")) { - objectList = this.currentMachine.storages; - idList = this.currentMachine.storageIds; - typePlural = "storages"; - } - - if (idList.length + 1 > 4) { - this.mapController.showInfoBalloon("Machine has only 4 slots", "warning"); - return; - } - - const id = parseInt(dropdown.val()); - idList.push(id); - this.mapController.api.getSpecificationOfType(typePlural, id).then((spec: INodeUnit) => { - objectList.push(spec); - - this.mapController.api.updateMachine(this.mapView.simulation.id, - this.mapView.currentDatacenter.id, this.mapController.roomModeController.currentRoom.id, - this.mapController.objectModeController.currentObjectTile.id, this.currentMachine).then( - () => { - this.populateUnitLists(); - this.mapController.objectModeController.updateNodeComponentOverlays(); - }); - }); - }); - } - - /** - * Populates the "add" dropdowns with all available unit options. - */ - private loadAddDropdowns(): void { - const unitTypes = [ - "cpus", "gpus", "memories", "storages" - ]; - const dropdowns = [ - $("#add-cpu-form").find("select"), - $("#add-gpu-form").find("select"), - $("#add-memory-form").find("select"), - $("#add-storage-form").find("select"), - ]; - - unitTypes.forEach((type: string, index: number) => { - this.mapController.api.getAllSpecificationsOfType(type).then((data: any) => { - data.forEach((option: INodeUnit) => { - dropdowns[index].append($("