diff options
| author | Georgios Andreadis <G.Andreadis@student.tudelft.nl> | 2017-01-27 10:26:54 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-01-27 10:26:54 +0100 |
| commit | 50fcb0634c9ebe894988103184d50d372bc76907 (patch) | |
| tree | 5af172c03599f7c680cd32205eab5329b841c85c | |
| parent | 3ad08353d289720cf8f43e1dba078da43c35e97d (diff) | |
| parent | b462c9183ec7c2e41f14daad49f03d8afaa4ec59 (diff) | |
Merge pull request #4 from tudelft-atlarge/states-batch-fetch
Fetch experiment states in one batch
29 files changed, 520 insertions, 358 deletions
diff --git a/gulpfile.js b/gulpfile.js index 941b1119..e57c31d6 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -21,6 +21,7 @@ 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'); @@ -91,8 +92,14 @@ const scriptsFilePaths = scriptsFileNames.map(function (fileName) { gulp.task('scripts', function () { const tasks = scriptsFilePaths.map(function (entry, index) { - return browserify({entries: [entry]}) - .plugin(tsify, {insertGlobals: true}) + return browserify({ + entries: [entry], + debug: false, + insertGlobals: true, + cache: {}, + packageCache: {} + }) + .plugin(tsify) .bundle() .pipe(source(scriptsFileNames[index] + postfix + '.js')) .pipe(gulp.dest(scriptsDestDir)); @@ -101,9 +108,40 @@ gulp.task('scripts', function () { .pipe(notify({message: 'Scripts task complete', onLast: true})); }); +function getWatchifyHandler(bundler, fileName) { + return () => { + gulpUtil.log("Beginning build for " + fileName); + return bundler + .bundle() + .pipe(source(fileName + postfix + '.js')) + .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. + * TypeScript definitions task. */ gulp.task("typings", function () { return gulp.src("./typings.json") @@ -189,10 +227,10 @@ gulp.task('watch', function () { return; } - runSequence('default'); - - gulp.watch(stylesRootDir + '**/*.less', ['styles']); - gulp.watch(scriptsRootDir + '**/*.ts', ['scripts']); - gulp.watch(htmlRootDir + '**/*.html', ['html']); - gulp.watch(imagesRootDir + '**/*.png', ['images']); + runSequence('default', () => { + gulp.watch(stylesRootDir + '**/*.less', ['styles']); + gulp.start('watch-scripts'); + gulp.watch(htmlRootDir + '**/*.html', ['html']); + gulp.watch(imagesRootDir + '**/*.png', ['images']); + }); }); diff --git a/package.json b/package.json index f0ab12b6..c4f24dd3 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { - "name": "open-dc", + "name": "opendc", "version": "0.0.1", "description": "Datacenter simulator", - "license": "UNLICENSED", + "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/leonoverweel/open-dc.git" + "url": "https://github.com/tudelft-atlarge/opendc" }, "dependencies": { "bower": "^1.7.9", @@ -34,6 +34,7 @@ "typescript": "^2.1.4", "typings": "^1.3.2", "vinyl-source-stream": "^1.1.0", + "watchify": "^3.9.0", "yargs": "^6.6.0" }, "devDependencies": { diff --git a/src/scripts/controllers/connection/api.ts b/src/scripts/controllers/connection/api.ts index 067e3ca0..d3278561 100644 --- a/src/scripts/controllers/connection/api.ts +++ b/src/scripts/controllers/connection/api.ts @@ -121,7 +121,7 @@ export class APIController { authorizations = data; return this.getUser(userId); }).then((userData: any) => { - let promises = []; + const promises = []; authorizations.forEach((authorization: IAuthorization) => { authorization.user = userData; promises.push(this.getSimulation(authorization.simulationId).then((simulationData: any) => { @@ -234,7 +234,7 @@ export class APIController { authorizations = data; return this.getSimulation(simulationId); }).then((simulationData: any) => { - let promises = []; + const promises = []; authorizations.forEach((authorization: IAuthorization) => { authorization.simulation = simulationData; promises.push(this.getUser(authorization.userId).then((userData: any) => { @@ -362,7 +362,7 @@ export class APIController { }).then((data: any) => { rooms = data; - let promises = []; + const promises = []; rooms.forEach((room: IRoom) => { promises.push(this.loadRoomTiles(simulationId, datacenterId, room)); }); @@ -412,7 +412,7 @@ export class APIController { query: {} } }).then((data: any) => { - let result = []; + const result = []; data.forEach((roomType: any) => { result.push(roomType.name); }); @@ -519,7 +519,7 @@ export class APIController { query: {} } }).then((data: any) => { - let promises = data.map((item) => { + const promises = data.map((item) => { return this.loadTileObject(simulationId, datacenterId, roomId, item); }); @@ -740,7 +740,7 @@ export class APIController { rack = data; return this.getMachinesByRack(simulationId, datacenterId, roomId, tileId); }).then((machines: any) => { - let promises = machines.map((machine) => { + const promises = machines.map((machine) => { return this.loadMachineUnits(machine); }); @@ -857,7 +857,7 @@ export class APIController { query: {} } }).then((data: any) => { - let promises = data.map((machine) => { + const promises = data.map((machine) => { return this.loadMachineUnits(machine); }); @@ -959,7 +959,7 @@ export class APIController { query: {} } }).then((data: any) => { - let promises = data.map((item: any) => { + const promises = data.map((item: any) => { return this.getTrace(item.traceId).then((traceData: any) => { item.trace = traceData; }); @@ -1067,8 +1067,15 @@ export class APIController { /// // METHOD: GET - public getMachineStatesByTick(simulationId: number, experimentId: number, tick: number, - machines: {[keys: number]: IMachine}): Promise<IMachineState[]> { + public getMachineStates(simulationId: number, experimentId: number, machines: {[keys: number]: IMachine}, + tick?: number): Promise<IMachineState[]> { + let query; + if (tick !== undefined) { + query = {tick}; + } else { + query = {}; + } + return ServerConnection.send({ path: "/simulations/{simulationId}/experiments/{experimentId}/machine-states", method: "GET", @@ -1078,9 +1085,7 @@ export class APIController { simulationId, experimentId }, - query: { - tick - } + query } }).then((data: any) => { data.forEach((item: any) => { @@ -1096,8 +1101,15 @@ export class APIController { /// // METHOD: GET - public getRackStatesByTick(simulationId: number, experimentId: number, tick: number, - racks: {[keys: number]: IRack}): Promise<IRackState[]> { + public getRackStates(simulationId: number, experimentId: number, racks: {[keys: number]: IRack}, + tick?: number): Promise<IRackState[]> { + let query; + if (tick !== undefined) { + query = {tick}; + } else { + query = {}; + } + return ServerConnection.send({ path: "/simulations/{simulationId}/experiments/{experimentId}/rack-states", method: "GET", @@ -1107,18 +1119,14 @@ export class APIController { simulationId, experimentId }, - query: { - tick - } + query: query } }).then((data: any) => { - let promises = data.map((item: any) => { + data.forEach((item: any) => { item.rack = racks[item.rackId]; }); - return Promise.all(promises).then(() => { - return data; - }); + return data; }); } @@ -1127,8 +1135,15 @@ export class APIController { /// // METHOD: GET - public getRoomStatesByTick(simulationId: number, experimentId: number, tick: number, - rooms: {[keys: number]: IRoom}): Promise<IRoomState[]> { + public getRoomStates(simulationId: number, experimentId: number, rooms: {[keys: number]: IRoom}, + tick?: number): Promise<IRoomState[]> { + let query; + if (tick !== undefined) { + query = {tick}; + } else { + query = {}; + } + return ServerConnection.send({ path: "/simulations/{simulationId}/experiments/{experimentId}/room-states", method: "GET", @@ -1138,18 +1153,14 @@ export class APIController { simulationId, experimentId }, - query: { - tick - } + query } }).then((data: any) => { - let promises = data.map((item: any) => { + data.forEach((item: any) => { item.room = rooms[item.roomId]; }); - return Promise.all(promises).then(() => { - return data; - }); + return data; }); } @@ -1158,8 +1169,15 @@ export class APIController { /// // METHOD: GET - public getTaskStatesByTick(simulationId: number, experimentId: number, tick: number, - tasks: {[keys: number]: ITask}): Promise<ITaskState[]> { + public getTaskStates(simulationId: number, experimentId: number, tasks: {[keys: number]: ITask}, + tick?: number): Promise<ITaskState[]> { + let query; + if (tick === undefined) { + query = {tick}; + } else { + query = {}; + } + return ServerConnection.send({ path: "/simulations/{simulationId}/experiments/{experimentId}/task-states", method: "GET", @@ -1169,18 +1187,14 @@ export class APIController { simulationId, experimentId }, - query: { - tick - } + query } }).then((data: any) => { - let promises = data.map((item: any) => { + data.forEach((item: any) => { item.task = tasks[item.taskId]; }); - return Promise.all(promises).then(() => { - return data; - }); + return data; }); } @@ -1201,7 +1215,7 @@ export class APIController { query: {} } }).then((data: any) => { - let promises = data.map((item: any) => { + const promises = data.map((item: any) => { return this.getSectionsByPath(simulationId, item.id).then((sectionsData: any) => { item.sections = sectionsData; }); @@ -1255,7 +1269,7 @@ export class APIController { query: {} } }).then((data: any) => { - let promises = data.map((item: any) => { + const promises = data.map((item: any) => { return this.getSectionsByPath(simulationId, item.id).then((sectionsData: any) => { item.sections = sectionsData; }); @@ -1309,7 +1323,7 @@ export class APIController { query: {} } }).then((data: any) => { - let promises = data.map((path: ISection) => { + const promises = data.map((path: ISection) => { return this.getDatacenter(simulationId, path.datacenterId).then((datacenter: any) => { path.datacenter = datacenter; }); @@ -1364,7 +1378,7 @@ export class APIController { }).then((data: any) => { psus = data; - let promises = []; + const promises = []; data.forEach((psu: IPSU) => { promises.push(this.getFailureModel(psu.failureModelId)); }); @@ -1420,7 +1434,7 @@ export class APIController { }).then((data: any) => { coolingItems = data; - let promises = []; + const promises = []; data.forEach((item: ICoolingItem) => { promises.push(this.getFailureModel(item.failureModelId)); }); @@ -1591,7 +1605,7 @@ export class APIController { }).then((data: any) => { specs = data; - let promises = []; + const promises = []; data.forEach((unit: INodeUnit) => { promises.push(this.getFailureModel(unit.failureModelId)); }); @@ -1685,7 +1699,7 @@ export class APIController { private loadUnitsOfType(idListName: string, objectListName: string, machine: IMachine): Promise<IMachine> { machine[objectListName] = []; - let promises = machine[idListName].map((item) => { + const promises = machine[idListName].map((item) => { return this.getSpecificationOfType(objectListName, item).then((data) => { machine[objectListName].push(data); }); @@ -1697,7 +1711,7 @@ export class APIController { } private loadMachineUnits(machine: IMachine): Promise<IMachine> { - let listNames = [ + const listNames = [ { idListName: "cpuIds", objectListName: "cpus" @@ -1713,7 +1727,7 @@ export class APIController { } ]; - let promises = listNames.map((item: any) => { + const promises = listNames.map((item: any) => { return this.loadUnitsOfType(item.idListName, item.objectListName, machine); }); @@ -1721,4 +1735,4 @@ export class APIController { return machine; }); } -}
\ No newline at end of file +} diff --git a/src/scripts/controllers/connection/cache.ts b/src/scripts/controllers/connection/cache.ts index 15517519..c1c47c2d 100644 --- a/src/scripts/controllers/connection/cache.ts +++ b/src/scripts/controllers/connection/cache.ts @@ -62,7 +62,7 @@ export class CacheController { } public onFetch(request: IRequest, response: IResponse): any { - let pathWithoutVersion = request.path.replace(/\/v\d+/, ""); + 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; diff --git a/src/scripts/controllers/connection/socket.ts b/src/scripts/controllers/connection/socket.ts index b38c303f..c23495f1 100644 --- a/src/scripts/controllers/connection/socket.ts +++ b/src/scripts/controllers/connection/socket.ts @@ -19,7 +19,7 @@ export class SocketController { this._socket.on('connect', onConnect); this._socket.on('response', (jsonResponse: string) => { - let response: IResponse = JSON.parse(jsonResponse); + const response: IResponse = JSON.parse(jsonResponse); console.log("Response, ID:", response.id, response); this.callbacks[response.id](response); delete this.callbacks[response.id]; @@ -34,7 +34,7 @@ export class SocketController { */ public sendRequest(request: IRequest, callback: (response: IResponse) => any): void { // Check local cache, in case request is for cachable GET route - let cacheStatus = this._cacheController.checkCache(request); + const cacheStatus = this._cacheController.checkCache(request); if (cacheStatus === CacheStatus.HIT) { callback({ @@ -73,4 +73,4 @@ export class SocketController { SocketController.id++; } } -}
\ No newline at end of file +} diff --git a/src/scripts/controllers/mapcontroller.ts b/src/scripts/controllers/mapcontroller.ts index d7458852..4ad1b20b 100644 --- a/src/scripts/controllers/mapcontroller.ts +++ b/src/scripts/controllers/mapcontroller.ts @@ -12,7 +12,7 @@ import {ObjectModeController} from "./modes/object"; import {NodeModeController} from "./modes/node"; import {ScaleIndicatorController} from "./scaleindicator"; -export var CELL_SIZE = 50; +export const CELL_SIZE = 50; export enum AppMode { @@ -178,7 +178,7 @@ export class MapController { * Does not change the x and y coordinates, only returns. */ public checkCanvasMovement(x: number, y: number, scale: number): IGridPosition { - let result: IGridPosition = {x: x, y: y}; + 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; @@ -211,10 +211,10 @@ export class MapController { } public static showConfirmDeleteDialog(itemType: string, onConfirm: () => void): void { - let modalDialog = <any>$("#confirm-delete"); + const modalDialog = <any>$("#confirm-delete"); modalDialog.find(".modal-body").text("Are you sure you want to delete this " + itemType + "?"); - let callback = () => { + const callback = () => { onConfirm(); modalDialog.modal("hide"); modalDialog.find("button.confirm").first().off("click"); @@ -241,16 +241,16 @@ export class MapController { * @param type The severity of the message; Currently supported: "info" and "warning" */ public showInfoBalloon(message: string, type: string): void { - let balloon = $(".info-balloon"); + const balloon = $(".info-balloon"); balloon.html('<span></span>' + message); - let callback = () => { + const callback = () => { balloon.fadeOut(300); this.infoTimeOut = undefined; }; const DISPLAY_TIME = 3000; - let balloonIcon = balloon.find("span").first(); + const balloonIcon = balloon.find("span").first(); balloonIcon.removeClass(); balloon.css("background", Colors.INFO_BALLOON_MAP[type]); @@ -278,9 +278,9 @@ export class MapController { this.currentStageMouseX = event.stageX; this.currentStageMouseY = event.stageY; - let gridPos = this.convertScreenCoordsToGridCoords([event.stageX, event.stageY]); - let tileX = gridPos.x; - let tileY = gridPos.y; + 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) { @@ -339,7 +339,7 @@ export class MapController { // Relay scroll events to the MapView zoom handler $("#main-canvas").on("mousewheel", (event: JQueryEventObject) => { - let originalEvent = (<any>event.originalEvent); + const originalEvent = (<any>event.originalEvent); this.mapView.zoom([this.currentStageMouseX, this.currentStageMouseY], -0.7 * originalEvent.deltaY); this.scaleIndicatorController.update(); }); @@ -369,7 +369,7 @@ export class MapController { // Menu panels $(".menu-header-bar .menu-collapse").on("click", (event: JQueryEventObject) => { - let container = $(event.target).closest(".menu-container"); + 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) { @@ -380,7 +380,7 @@ export class MapController { // Menu close button $(".menu-header-bar .menu-exit").on("click", (event: JQueryEventObject) => { - let nearestMenuContainer = $(event.target).closest(".menu-container"); + const nearestMenuContainer = $(event.target).closest(".menu-container"); if (nearestMenuContainer.is("#node-menu")) { this.interactionLevel = InteractionLevel.OBJECT; $(".node-element-overlay").addClass("hidden"); @@ -400,10 +400,10 @@ export class MapController { // Handler for the version-save button $("#save-version-btn").on("click", (event: JQueryEventObject) => { - let target = $(event.target); + const target = $(event.target); target.attr("data-saved", "false"); - let lastPath = this.mapView.simulation.paths[this.mapView.simulation.paths.length - 1]; + 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) => { @@ -437,11 +437,11 @@ export class MapController { * @param stageY The y coordinate of the location in pixels on the stage */ private handleCanvasMouseClick(stageX: number, stageY: number): void { - let gridPos = this.convertScreenCoordsToGridCoords([stageX, stageY]); + const gridPos = this.convertScreenCoordsToGridCoords([stageX, stageY]); if (this.interactionLevel === InteractionLevel.BUILDING) { if (this.interactionMode === InteractionMode.DEFAULT) { - let roomIndex = Util.roomCollisionIndexOf(this.mapView.currentDatacenter.rooms, gridPos); + const roomIndex = Util.roomCollisionIndexOf(this.mapView.currentDatacenter.rooms, gridPos); if (roomIndex !== -1) { this.interactionLevel = InteractionLevel.ROOM; @@ -474,7 +474,7 @@ export class MapController { * @returns {Array} The corresponding grid cell coordinates */ private convertScreenCoordsToGridCoords(stagePosition: number[]): IGridPosition { - let result = {x: 0, y: 0}; + 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) / @@ -486,7 +486,7 @@ export class MapController { * Adjusts the canvas size to fit the window perfectly. */ private onWindowResize() { - let parent = this.canvas.parent(".app-content"); + const parent = this.canvas.parent(".app-content"); parent.height($(window).height() - 50); this.canvas.attr("width", parent.width()); this.canvas.attr("height", parent.height()); @@ -505,15 +505,15 @@ export class MapController { } private matchUserAuthLevel() { - let authLevel = localStorage.getItem("simulationAuthLevel"); + const authLevel = localStorage.getItem("simulationAuthLevel"); if (authLevel === "VIEW") { $(".side-menu-container.right-middle-side, .side-menu-container.right-side").hide(); } } private exportCanvasToImage() { - let canvasData = (<HTMLCanvasElement>this.canvas.get(0)).toDataURL("image/png"); - let newWindow = window.open('about:blank', 'OpenDC Canvas Export'); + const canvasData = (<HTMLCanvasElement>this.canvas.get(0)).toDataURL("image/png"); + const newWindow = window.open('about:blank', 'OpenDC Canvas Export'); newWindow.document.write("<img src='" + canvasData + "' alt='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 index 4d82f090..217f5935 100644 --- a/src/scripts/controllers/modes/building.ts +++ b/src/scripts/controllers/modes/building.ts @@ -22,7 +22,7 @@ export class BuildingModeController { * Connects all DOM event listeners to their respective element targets. */ public setupEventListeners() { - let resetConstructionButtons = () => { + const resetConstructionButtons = () => { this.mapController.interactionMode = InteractionMode.DEFAULT; this.mapView.hoverLayer.setHoverTileVisibility(false); $("#room-construction").text("Construct new room"); @@ -79,7 +79,7 @@ export class BuildingModeController { * @param position The new tile position to be added */ public addSelectedTile(position: IGridPosition): void { - let tile = { + const tile = { id: -1, roomId: this.newRoomId, position: {x: position.x, y: position.y} @@ -96,11 +96,10 @@ export class BuildingModeController { * @param position The position of the tile to be removed */ public removeSelectedTile(position: IGridPosition): void { - let tile; let objectIndex = -1; for (let i = 0; i < this.mapView.roomLayer.selectedTileObjects.length; i++) { - tile = this.mapView.roomLayer.selectedTileObjects[i]; + const tile = this.mapView.roomLayer.selectedTileObjects[i]; if (tile.position.x === position.x && tile.position.y === position.y) { objectIndex = i; } @@ -111,4 +110,4 @@ export class BuildingModeController { this.mapView.roomLayer.removeSelectedTile(position, objectIndex); }); } -}
\ No newline at end of file +} diff --git a/src/scripts/controllers/modes/node.ts b/src/scripts/controllers/modes/node.ts index 3b3f8a32..cef61bba 100644 --- a/src/scripts/controllers/modes/node.ts +++ b/src/scripts/controllers/modes/node.ts @@ -53,17 +53,17 @@ export class NodeModeController { * Connects all DOM event listeners to their respective element targets. */ public setupEventListeners(): void { - let nodeMenu = $("#node-menu"); + const nodeMenu = $("#node-menu"); nodeMenu.find(".panel-group").on("click", ".remove-unit", (event: JQueryEventObject) => { MapController.showConfirmDeleteDialog("unit", () => { - let index = $(event.target).closest(".panel").index(); + const index = $(event.target).closest(".panel").index(); if (index === -1) { return; } - let closestTabPane = $(event.target).closest(".panel-group"); + const closestTabPane = $(event.target).closest(".panel-group"); let objectList, idList; if (closestTabPane.is("#cpu-accordion")) { @@ -94,9 +94,9 @@ export class NodeModeController { }); nodeMenu.find(".add-unit").on("click", (event: JQueryEventObject) => { - let dropdown = $(event.target).closest(".input-group-btn").siblings("select").first(); + const dropdown = $(event.target).closest(".input-group-btn").siblings("select").first(); - let closestTabPane = $(event.target).closest(".input-group").siblings(".panel-group").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; @@ -121,7 +121,7 @@ export class NodeModeController { return; } - let id = parseInt(dropdown.val(), 10); + const id = parseInt(dropdown.val()); idList.push(id); this.mapController.api.getSpecificationOfType(typePlural, id).then((spec: INodeUnit) => { objectList.push(spec); @@ -141,10 +141,10 @@ export class NodeModeController { * Populates the "add" dropdowns with all available unit options. */ private loadAddDropdowns(): void { - let unitTypes = [ + const unitTypes = [ "cpus", "gpus", "memories", "storages" ]; - let dropdowns = [ + const dropdowns = [ $("#add-cpu-form").find("select"), $("#add-gpu-form").find("select"), $("#add-memory-form").find("select"), @@ -166,7 +166,7 @@ export class NodeModeController { */ private populateUnitLists(): void { // Contains the skeleton of a unit element and inserts the given data into it - let generatePanel = (type: string, index: number, list: any, specSection: string): string => { + const generatePanel = (type: string, index: number, list: any, specSection: string): string => { return '<div class="panel panel-default">' + ' <div class="panel-heading">' + ' <h4 class="panel-title">' + @@ -188,7 +188,7 @@ export class NodeModeController { }; // Generates the structure of the specification list of a processing unit - let generateProcessingUnitHtml = (element: IProcessingUnit) => { + const generateProcessingUnitHtml = (element: IProcessingUnit) => { return ' <tr>' + ' <td class="glyphicon glyphicon-tasks"></td>' + ' <td>Number of Cores</td>' + @@ -212,7 +212,7 @@ export class NodeModeController { }; // Generates the structure of the spec list of a storage unit - let generateStorageUnitHtml = (element: IStorageUnit) => { + const generateStorageUnitHtml = (element: IStorageUnit) => { return ' <tr>' + ' <td class="glyphicon glyphicon-floppy-disk"></td>' + ' <td>Size (Mb)</td>' + @@ -236,7 +236,7 @@ export class NodeModeController { }; // Inserts a "No units" message into the container of the given unit type - let addNoUnitsMessage = (type: string) => { + const addNoUnitsMessage = (type: string) => { $("#" + type + "-accordion").append("<p>There are currently no units present here. " + "<em>Add some with the dropdown below!</em></p>"); }; @@ -249,8 +249,8 @@ export class NodeModeController { addNoUnitsMessage("cpu"); } else { this.currentMachine.cpus.forEach((element: ICPU, i: number) => { - let specSection = generateProcessingUnitHtml(element); - let content = generatePanel("cpu", i, this.currentMachine.cpus, specSection); + const specSection = generateProcessingUnitHtml(element); + const content = generatePanel("cpu", i, this.currentMachine.cpus, specSection); container.append(content); }); } @@ -262,8 +262,8 @@ export class NodeModeController { addNoUnitsMessage("gpu"); } else { this.currentMachine.gpus.forEach((element: IGPU, i: number) => { - let specSection = generateProcessingUnitHtml(element); - let content = generatePanel("gpu", i, this.currentMachine.gpus, specSection); + const specSection = generateProcessingUnitHtml(element); + const content = generatePanel("gpu", i, this.currentMachine.gpus, specSection); container.append(content); }); } @@ -275,8 +275,8 @@ export class NodeModeController { addNoUnitsMessage("memory"); } else { this.currentMachine.memories.forEach((element: IMemory, i: number) => { - let specSection = generateStorageUnitHtml(element); - let content = generatePanel("memory", i, this.currentMachine.memories, specSection); + const specSection = generateStorageUnitHtml(element); + const content = generatePanel("memory", i, this.currentMachine.memories, specSection); container.append(content); }); } @@ -288,10 +288,10 @@ export class NodeModeController { addNoUnitsMessage("storage"); } else { this.currentMachine.storages.forEach((element: IMemory, i: number) => { - let specSection = generateStorageUnitHtml(element); - let content = generatePanel("storage", i, this.currentMachine.storages, specSection); + const specSection = generateStorageUnitHtml(element); + const content = generatePanel("storage", i, this.currentMachine.storages, specSection); container.append(content); }); } } -}
\ No newline at end of file +} diff --git a/src/scripts/controllers/modes/object.ts b/src/scripts/controllers/modes/object.ts index e922433e..d974df7a 100644 --- a/src/scripts/controllers/modes/object.ts +++ b/src/scripts/controllers/modes/object.ts @@ -97,12 +97,12 @@ export class ObjectModeController { }); }); - let nodeListContainer = $(".node-list-container"); + const nodeListContainer = $(".node-list-container"); // Handler for the 'add' button of each machine slot of the rack nodeListContainer.on("click", ".add-node", (event: JQueryEventObject) => { // Convert the DOM element index to a JS array index - let index = this.currentRack.machines.length - $(event.target).closest(".node-element").index() - 1; + const index = this.currentRack.machines.length - $(event.target).closest(".node-element").index() - 1; // Insert an empty machine at the selected position this.mapController.api.addMachineToRack(this.mapView.simulation.id, @@ -127,10 +127,10 @@ export class ObjectModeController { // Handler for the 'remove' button of each machine slot of the rack nodeListContainer.on("click", ".remove-node", (event: JQueryEventObject) => { - let target = $(event.target); + const target = $(event.target); MapController.showConfirmDeleteDialog("machine", () => { // Convert the DOM element index to a JS array index - let index = this.currentRack.machines.length - target.closest(".node-element").index() - 1; + const index = this.currentRack.machines.length - target.closest(".node-element").index() - 1; this.mapController.api.deleteMachine(this.mapView.simulation.id, this.mapView.currentDatacenter.id, this.mapController.roomModeController.currentRoom.id, @@ -146,9 +146,9 @@ export class ObjectModeController { // Handler for every node element, triggering node mode nodeListContainer.on("click", ".node-element", (event: JQueryEventObject) => { - let domIndex = $(event.target).closest(".node-element").index(); - let index = this.currentRack.machines.length - domIndex - 1; - let machine = this.currentRack.machines[index]; + const domIndex = $(event.target).closest(".node-element").index(); + const index = this.currentRack.machines.length - domIndex - 1; + const machine = this.currentRack.machines[index]; if (machine != null) { this.mapController.interactionLevel = InteractionLevel.NODE; @@ -222,8 +222,8 @@ export class ObjectModeController { continue; } - let container = this.mapController.appMode === AppMode.CONSTRUCTION ? ".construction" : ".simulation"; - let element = $(container + " .node-element").eq(this.currentRack.machines.length - i - 1); + const container = this.mapController.appMode === AppMode.CONSTRUCTION ? ".construction" : ".simulation"; + const element = $(container + " .node-element").eq(this.currentRack.machines.length - i - 1); if (this.currentRack.machines[i].cpus.length !== 0) { element.find(".overlay-cpu").addClass("hidden"); } else { @@ -251,8 +251,7 @@ export class ObjectModeController { * Dynamically generates and inserts HTML code for every node in the current rack. */ private populateNodeList(): void { - let type, content; - let container = $(".node-list-container"); + const container = $(".node-list-container"); // Remove any previously present node elements container.children().remove(".node-element"); @@ -260,8 +259,8 @@ export class ObjectModeController { for (let i = 0; i < this.currentRack.machines.length; i++) { // Depending on whether the current machine slot is filled, allow removing or adding a new machine by adding // the appropriate button next to the machine slot - type = (this.currentRack.machines[i] == null ? "glyphicon-plus add-node" : "glyphicon-remove remove-node"); - content = + const type = (this.currentRack.machines[i] == null ? "glyphicon-plus add-node" : "glyphicon-remove remove-node"); + let content = '<div class="node-element" data-id="' + (this.currentRack.machines[i] === null ? "" : this.currentRack.machines[i].id) + '">' + ' <div class="node-element-overlay hidden"></div>' + @@ -291,7 +290,7 @@ export class ObjectModeController { } private scrollToBottom(): void { - let scrollContainer = $('.node-list-container'); + const scrollContainer = $('.node-list-container'); scrollContainer.scrollTop(scrollContainer[0].scrollHeight); } -}
\ No newline at end of file +} diff --git a/src/scripts/controllers/modes/room.ts b/src/scripts/controllers/modes/room.ts index a858af5a..8a982ef1 100644 --- a/src/scripts/controllers/modes/room.ts +++ b/src/scripts/controllers/modes/room.ts @@ -63,9 +63,9 @@ export class RoomModeController { MapController.hideAndShowMenus("#room-menu"); // Pre-select the type of the current room in the dropdown - let roomTypeDropdown = $("#roomtype-select"); + const roomTypeDropdown = $("#roomtype-select"); roomTypeDropdown.find('option').prop("selected", "false"); - let roomTypeIndex = this.roomTypes.indexOf(this.currentRoom.roomType); + const roomTypeIndex = this.roomTypes.indexOf(this.currentRoom.roomType); if (roomTypeIndex !== -1) { roomTypeDropdown.find('option[value="' + roomTypeIndex + '"]').prop("selected", "true"); } else { @@ -106,11 +106,11 @@ export class RoomModeController { public setupEventListeners(): void { // Component buttons - let addRackBtn = $("#add-rack-btn"); - let addPSUBtn = $("#add-psu-btn"); - let addCoolingItemBtn = $("#add-cooling-item-btn"); + const addRackBtn = $("#add-rack-btn"); + const addPSUBtn = $("#add-psu-btn"); + const addCoolingItemBtn = $("#add-cooling-item-btn"); - let roomTypeDropdown = $("#roomtype-select"); + const roomTypeDropdown = $("#roomtype-select"); addRackBtn.on("click", () => { this.handleItemClick("RACK"); @@ -137,7 +137,7 @@ export class RoomModeController { MapController.showConfirmDeleteDialog("room", () => { this.mapController.api.deleteRoom(this.mapView.simulation.id, this.mapView.currentDatacenter.id, this.currentRoom.id).then(() => { - let roomIndex = this.mapView.currentDatacenter.rooms.indexOf(this.currentRoom); + const roomIndex = this.mapView.currentDatacenter.rooms.indexOf(this.currentRoom); this.mapView.currentDatacenter.rooms.splice(roomIndex, 1); this.mapView.redrawMap(); @@ -148,7 +148,7 @@ export class RoomModeController { // Handler for the room type dropdown component roomTypeDropdown.on("change", () => { - let newRoomType = this.roomTypes[roomTypeDropdown.val()]; + const newRoomType = this.roomTypes[roomTypeDropdown.val()]; if (!this.checkRoomTypeLegality(newRoomType)) { roomTypeDropdown.val(this.roomTypes.indexOf(this.currentRoom.roomType)); this.mapController.showInfoBalloon("Room type couldn't be changed, illegal objects", "warning"); @@ -167,10 +167,10 @@ export class RoomModeController { public handleCanvasMouseClick(gridPos: IGridPosition): void { if (this.roomInteractionMode === RoomInteractionMode.DEFAULT) { - let tileIndex = Util.tileListPositionIndexOf(this.currentRoom.tiles, gridPos); + const tileIndex = Util.tileListPositionIndexOf(this.currentRoom.tiles, gridPos); if (tileIndex !== -1) { - let tile = this.currentRoom.tiles[tileIndex]; + const tile = this.currentRoom.tiles[tileIndex]; if (tile.object !== undefined) { this.mapController.interactionLevel = InteractionLevel.OBJECT; @@ -192,11 +192,11 @@ export class RoomModeController { } private handleItemClick(type: string): void { - let addRackBtn = $("#add-rack-btn"); - let addPSUBtn = $("#add-psu-btn"); - let addCoolingItemBtn = $("#add-cooling-item-btn"); - let allObjectContainers = $(".dc-component-container"); - let objectTypes = [ + const addRackBtn = $("#add-rack-btn"); + const addPSUBtn = $("#add-psu-btn"); + const addCoolingItemBtn = $("#add-cooling-item-btn"); + const allObjectContainers = $(".dc-component-container"); + const objectTypes = [ { type: "RACK", mode: RoomInteractionMode.ADD_RACK, @@ -264,7 +264,7 @@ export class RoomModeController { return; } - let tileList = this.mapView.mapController.roomModeController.currentRoom.tiles; + const tileList = this.mapView.mapController.roomModeController.currentRoom.tiles; for (let i = 0; i < tileList.length; i++) { if (tileList[i].position.x === position.x && tileList[i].position.y === position.y) { @@ -320,7 +320,7 @@ export class RoomModeController { * Populates the room-type dropdown element with all available room types */ private populateRoomTypeDropdown(): void { - let dropdown = $("#roomtype-select"); + const dropdown = $("#roomtype-select"); this.roomTypes.forEach((type: string, index: number) => { dropdown.append($('<option>').text(Util.toSentenceCase(type)).val(index)); @@ -331,9 +331,9 @@ export class RoomModeController { * Loads all object types that are allowed in the current room into the menu. */ private populateAllowedObjectTypes(): void { - let addObjectsLabel = $("#add-objects-label"); - let noObjectsInfo = $("#no-objects-info"); - let allowedObjectTypes = this.roomTypeMap[this.currentRoom.roomType]; + const addObjectsLabel = $("#add-objects-label"); + const noObjectsInfo = $("#no-objects-info"); + const allowedObjectTypes = this.roomTypeMap[this.currentRoom.roomType]; $(".dc-component-container").addClass("hidden"); @@ -379,4 +379,4 @@ export class RoomModeController { return legality; } -}
\ No newline at end of file +} diff --git a/src/scripts/controllers/scaleindicator.ts b/src/scripts/controllers/scaleindicator.ts index 0ff83486..789f2cc7 100644 --- a/src/scripts/controllers/scaleindicator.ts +++ b/src/scripts/controllers/scaleindicator.ts @@ -24,7 +24,7 @@ export class ScaleIndicatorController { } public update(): void { - let currentZoom = this.mapView.mapContainer.scaleX; + const currentZoom = this.mapView.mapContainer.scaleX; let newWidth; do { newWidth = (currentZoom * CELL_SIZE) / this.currentDivisor; diff --git a/src/scripts/controllers/simulation/chart.ts b/src/scripts/controllers/simulation/chart.ts index 84009622..5f94f412 100644 --- a/src/scripts/controllers/simulation/chart.ts +++ b/src/scripts/controllers/simulation/chart.ts @@ -52,7 +52,7 @@ export class ChartController { room.tiles.forEach((tile: ITile) => { if (tile.object !== undefined && tile.objectType === "RACK" && this.rackSeries[tile.objectId] === undefined) { - let objectName = (<IRack>tile.object).name; + const objectName = (<IRack>tile.object).name; this.names["ra" + tile.objectId] = objectName === "" || objectName === undefined ? "Unnamed rack" : objectName; @@ -177,7 +177,7 @@ export class ChartController { machineId = this.mapController.nodeModeController.currentMachine.id; } - let unloads: string[] = []; + const unloads: string[] = []; for (let id in this.names) { if (this.names.hasOwnProperty(id)) { if (machineId === -1) { @@ -211,17 +211,17 @@ export class ChartController { } public tickUpdated(tick: number): void { - let roomStates: IRoomState[] = this.simulationController.stateCache.stateList[tick].roomStates; + const roomStates: IRoomState[] = this.simulationController.stateCache.stateList[tick].roomStates; roomStates.forEach((roomState: IRoomState) => { ChartController.insertAtIndex(this.roomSeries[roomState.roomId].loadFractions, tick + 1, roomState.loadFraction); }); - let rackStates: IRackState[] = this.simulationController.stateCache.stateList[tick].rackStates; + const rackStates: IRackState[] = this.simulationController.stateCache.stateList[tick].rackStates; rackStates.forEach((rackState: IRackState) => { ChartController.insertAtIndex(this.rackSeries[rackState.rackId].loadFractions, tick + 1, rackState.loadFraction); }); - let machineStates: IMachineState[] = this.simulationController.stateCache.stateList[tick].machineStates; + const machineStates: IMachineState[] = this.simulationController.stateCache.stateList[tick].machineStates; machineStates.forEach((machineState: IMachineState) => { ChartController.insertAtIndex(this.machineSeries[machineState.machineId].loadFractions, tick + 1, machineState.loadFraction); }); @@ -238,4 +238,4 @@ export class ChartController { list[index] = data; } -}
\ No newline at end of file +} diff --git a/src/scripts/controllers/simulation/statecache.ts b/src/scripts/controllers/simulation/statecache.ts index 32f8f4e4..092bfe32 100644 --- a/src/scripts/controllers/simulation/statecache.ts +++ b/src/scripts/controllers/simulation/statecache.ts @@ -2,7 +2,7 @@ import {SimulationController} from "../simulationcontroller"; export class StateCache { - public static CACHE_INTERVAL = 3000; + public static CACHE_INTERVAL = 10000; private static PREFERRED_CACHE_ADVANCE = 5; public stateList: {[key: number]: ITickState}; @@ -22,7 +22,7 @@ export class StateCache { constructor(simulationController: SimulationController) { this.stateList = {}; - this.lastCachedTick = -1; + this.lastCachedTick = 0; this.cacheBlock = true; this.simulationController = simulationController; this.caching = false; @@ -73,7 +73,7 @@ export class StateCache { } private cache(): void { - let tick = this.lastCachedTick + 1; + const tick = this.lastCachedTick + 1; this.updateLastTick().then(() => { // Check if end of simulated region has been reached @@ -81,15 +81,23 @@ export class StateCache { return; } - this.fetchAllStatesOfTick(tick).then((data: ITickState) => { - this.stateList[tick] = data; + this.fetchAllAvailableStates().then((data) => { + this.stateList = data; - this.updateTasks(tick); + // Determine last cached tick + const ticks = Object.keys(this.stateList).sort((a, b) => { + return parseInt(a) - parseInt(b); + }); + if (ticks.length > 0) { + this.lastCachedTick = parseInt(ticks[ticks.length - 1]); + } - // Update chart cache - this.simulationController.chartController.tickUpdated(tick); + for (let i = 1; i <= this.lastCachedTick; i++) { + this.updateTasksForNewTick(i); - this.lastCachedTick++; + // Update chart cache + this.simulationController.chartController.tickUpdated(i); + } if (!this.cacheBlock && this.lastCachedTick - this.simulationController.currentTick <= 0) { this.cacheBlock = true; @@ -105,7 +113,7 @@ export class StateCache { }); } - private updateTasks(tick: number): void { + private updateTasksForNewTick(tick: number): void { const taskIDsInTick = []; this.stateList[tick].taskStates.forEach((taskState: ITaskState) => { @@ -160,8 +168,108 @@ export class StateCache { }); } + private fetchAllAvailableStates(): Promise<{[key: number]: ITickState}> { + let machineStates, rackStates, roomStates, taskStates; + const promises = []; + + promises.push( + this.simulationController.mapController.api.getMachineStates( + this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id, + this.machineCache + ).then((states: IMachineState[]) => { + machineStates = states; + }) + ); + + promises.push( + this.simulationController.mapController.api.getRackStates( + this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id, + this.rackCache + ).then((states: IRackState[]) => { + rackStates = states; + }) + ); + + promises.push( + this.simulationController.mapController.api.getRoomStates( + this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id, + this.roomCache + ).then((states: IRoomState[]) => { + roomStates = states; + }) + ); + + promises.push( + this.simulationController.mapController.api.getTaskStates( + this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id, + this.taskCache + ).then((states: ITaskState[]) => { + taskStates = states; + }) + ); + + return Promise.all(promises).then(() => { + const tickStates: {[key: number]: ITickState} = {}; + + machineStates.forEach((machineState: IMachineState) => { + if (tickStates[machineState.tick] === undefined) { + tickStates[machineState.tick] = { + tick: machineState.tick, + machineStates: [machineState], + rackStates: [], + roomStates: [], + taskStates: [] + }; + } else { + tickStates[machineState.tick].machineStates.push(machineState); + } + }); + rackStates.forEach((rackState: IRackState) => { + if (tickStates[rackState.tick] === undefined) { + tickStates[rackState.tick] = { + tick: rackState.tick, + machineStates: [], + rackStates: [rackState], + roomStates: [], + taskStates: [] + }; + } else { + tickStates[rackState.tick].rackStates.push(rackState); + } + }); + roomStates.forEach((roomState: IRoomState) => { + if (tickStates[roomState.tick] === undefined) { + tickStates[roomState.tick] = { + tick: roomState.tick, + machineStates: [], + rackStates: [], + roomStates: [roomState], + taskStates: [] + }; + } else { + tickStates[roomState.tick].roomStates.push(roomState); + } + }); + taskStates.forEach((taskState: ITaskState) => { + if (tickStates[taskState.tick] === undefined) { + tickStates[taskState.tick] = { + tick: taskState.tick, + machineStates: [], + rackStates: [], + roomStates: [], + taskStates: [taskState] + }; + } else { + tickStates[taskState.tick].taskStates.push(taskState); + } + }); + + return tickStates; + }); + } + private fetchAllStatesOfTick(tick: number): Promise<ITickState> { - let tickState: ITickState = { + const tickState: ITickState = { tick, machineStates: [], rackStates: [], @@ -170,33 +278,41 @@ export class StateCache { }; const promises = []; - promises.push(this.simulationController.mapController.api.getMachineStatesByTick( - this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id, - tick, this.machineCache - ).then((states: IMachineState[]) => { - tickState.machineStates = states; - })); - - promises.push(this.simulationController.mapController.api.getRackStatesByTick( - this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id, - tick, this.rackCache - ).then((states: IRackState[]) => { - tickState.rackStates = states; - })); - - promises.push(this.simulationController.mapController.api.getRoomStatesByTick( - this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id, - tick, this.roomCache - ).then((states: IRoomState[]) => { - tickState.roomStates = states; - })); - - promises.push(this.simulationController.mapController.api.getTaskStatesByTick( - this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id, - tick, this.taskCache - ).then((states: ITaskState[]) => { - tickState.taskStates = states; - })); + promises.push( + this.simulationController.mapController.api.getMachineStates( + this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id, + this.machineCache, tick + ).then((states: IMachineState[]) => { + tickState.machineStates = states; + }) + ); + + promises.push( + this.simulationController.mapController.api.getRackStates( + this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id, + this.rackCache, tick + ).then((states: IRackState[]) => { + tickState.rackStates = states; + }) + ); + + promises.push( + this.simulationController.mapController.api.getRoomStates( + this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id, + this.roomCache, tick + ).then((states: IRoomState[]) => { + tickState.roomStates = states; + }) + ); + + promises.push( + this.simulationController.mapController.api.getTaskStates( + this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id, + this.taskCache, tick + ).then((states: ITaskState[]) => { + tickState.taskStates = states; + }) + ); return Promise.all(promises).then(() => { return tickState; diff --git a/src/scripts/controllers/simulation/timeline.ts b/src/scripts/controllers/simulation/timeline.ts index a558afe1..ec3d8cb4 100644 --- a/src/scripts/controllers/simulation/timeline.ts +++ b/src/scripts/controllers/simulation/timeline.ts @@ -45,8 +45,8 @@ export class TimelineController { }); $(".timeline-container .timeline").on("click", (event: JQueryEventObject) => { - let parentOffset = $(event.target).closest(".timeline").offset(); - let clickX = event.pageX - parentOffset.left; + const parentOffset = $(event.target).closest(".timeline").offset(); + const clickX = event.pageX - parentOffset.left; let newTick = Math.round(clickX / (this.timelineWidth * this.timeUnitFraction)); @@ -111,7 +111,7 @@ export class TimelineController { private updateTaskIndicators(): void { $(".task-indicator").remove(); - let tickStateTypes = { + const tickStateTypes = { "queueEntryTick": "task-queued", "startTick": "task-started", "finishedTick": "task-finished" @@ -121,7 +121,7 @@ export class TimelineController { return; } - let indicatorCountList = new Array(this.simulationController.stateCache.lastCachedTick); + const indicatorCountList = new Array(this.simulationController.stateCache.lastCachedTick); let indicator; this.simulationController.currentExperiment.trace.tasks.forEach((task: ITask) => { for (let tickStateType in tickStateTypes) { @@ -153,9 +153,9 @@ export class TimelineController { let correction = 0; if (this.timeUnitFraction * this.timelineWidth > this.timeMarkerWidth) { correction = (this.timeUnitFraction * this.timelineWidth - this.timeMarkerWidth) * - (tick / this.simulationController.lastSimulatedTick); + ((tick - 1) / this.simulationController.lastSimulatedTick); } - return (100 * (this.timeUnitFraction * tick + correction / this.timelineWidth)) + "%"; + return (100 * (this.timeUnitFraction * (tick - 1) + correction / this.timelineWidth)) + "%"; } -}
\ No newline at end of file +} diff --git a/src/scripts/controllers/simulationcontroller.ts b/src/scripts/controllers/simulationcontroller.ts index 8d9553e9..bb46575c 100644 --- a/src/scripts/controllers/simulationcontroller.ts +++ b/src/scripts/controllers/simulationcontroller.ts @@ -72,7 +72,7 @@ export class SimulationController { this.experimentSelectionMode = true; this.sectionIndex = 0; - this.currentTick = 0; + this.currentTick = 1; this.playing = false; this.stateCache = new StateCache(this); this.colorRepresentation = ColorRepresentation.LOAD; @@ -278,15 +278,15 @@ export class SimulationController { return; } - let row = $(event.target).closest(".experiment-row"); + const row = $(event.target).closest(".experiment-row"); this.prepareAndLaunchExperiment(this.experiments[row.index()]); }); $(".experiment-list .list-body").on("click", ".remove-experiment", (event: JQueryEventObject) => { event.stopPropagation(); - let affectedRow = $(event.target).closest(".experiment-row"); - let index = affectedRow.index(); - let affectedExperiment = this.experiments[index]; + const affectedRow = $(event.target).closest(".experiment-row"); + const index = affectedRow.index(); + const affectedExperiment = this.experiments[index]; MapController.showConfirmDeleteDialog("experiment", () => { this.mapController.api.deleteExperiment(affectedExperiment.simulationId, affectedExperiment.id) @@ -298,7 +298,7 @@ export class SimulationController { }); $("#new-experiment-btn").click(() => { - let nameInput = $("#new-experiment-name-input"); + const nameInput = $("#new-experiment-name-input"); if (nameInput.val() === "") { $(".experiment-name-alert").show(); return; @@ -306,7 +306,7 @@ export class SimulationController { $(".experiment-name-alert").hide(); } - let newExperiment: IExperiment = { + const newExperiment: IExperiment = { id: -1, name: nameInput.val(), pathId: parseInt($("#new-experiment-path-select").val()), @@ -340,7 +340,7 @@ export class SimulationController { this.currentPath = this.getPathById(this.currentExperiment.pathId); this.sections = this.currentPath.sections; this.sectionIndex = 0; - this.currentTick = 0; + this.currentTick = 1; this.playing = false; this.stateCache = new StateCache(this); this.colorRepresentation = ColorRepresentation.LOAD; @@ -361,9 +361,9 @@ export class SimulationController { } private populateDropdowns(): void { - let pathDropdown = $("#new-experiment-path-select"); - let traceDropdown = $("#new-experiment-trace-select"); - let schedulerDropdown = $("#new-experiment-scheduler-select"); + const pathDropdown = $("#new-experiment-path-select"); + const traceDropdown = $("#new-experiment-trace-select"); + const schedulerDropdown = $("#new-experiment-scheduler-select"); pathDropdown.empty(); for (let i = 0; i < this.simulation.paths.length; i++) { @@ -394,7 +394,7 @@ export class SimulationController { * Populates the list of experiments. */ private populateExperimentsList(): void { - let table = $(".experiment-list .list-body"); + const table = $(".experiment-list .list-body"); table.empty(); console.log("EXPERIMENT", this.experiments); @@ -504,16 +504,13 @@ export class SimulationController { return; } - console.log(this.stateCache); - - let html; - let container = $(".building-stats-list"); + const container = $(".building-stats-list"); container.children().remove("div"); this.stateCache.stateList[this.currentTick].roomStates.forEach((roomState: IRoomState) => { if (this.colorRepresentation === ColorRepresentation.LOAD && roomState.room !== undefined) { - html = '<div>' + + const html = '<div>' + ' <h4>' + roomState.room.name + '</h4>' + ' <p>Load: ' + Math.round(roomState.loadFraction * 100) + '%</p>' + '</div>'; @@ -534,8 +531,7 @@ export class SimulationController { $("#room-name-field").text(this.mapController.roomModeController.currentRoom.name); $("#room-type-field").text(this.mapController.roomModeController.currentRoom.roomType); - let html; - let container = $(".room-stats-list"); + const container = $(".room-stats-list"); container.children().remove("div"); @@ -544,7 +540,7 @@ export class SimulationController { return; } if (this.colorRepresentation === ColorRepresentation.LOAD) { - html = '<div>' + + const html = '<div>' + ' <h4>' + rackState.rack.name + '</h4>' + ' <p>Load: ' + Math.round(rackState.loadFraction * 100) + '%</p>' + '</div>'; @@ -554,13 +550,13 @@ export class SimulationController { } private setupColorMenu(): void { - let html = + const html = '<select class="form-control" title="Color Representation" id="color-representation-select">' + ' <option value="1" selected>Load</option>' + ' <option value="2">Power use</option>' + '</select>'; - let indicator = $(".color-indicator"); + const indicator = $(".color-indicator"); indicator["popover"]({ animation: true, content: html, @@ -576,7 +572,7 @@ export class SimulationController { } else { indicator["popover"]("show"); - let selectElement = $("#color-representation-select"); + const selectElement = $("#color-representation-select"); selectElement.change(() => { console.log(selectElement.val()); }); diff --git a/src/scripts/error404.entry.ts b/src/scripts/error404.entry.ts index 07dc9ca0..477a46c0 100644 --- a/src/scripts/error404.entry.ts +++ b/src/scripts/error404.entry.ts @@ -3,24 +3,24 @@ import * as $ from "jquery"; $(document).ready(() => { - let text = + const text = " oo oooo oo <br>" + " oo oo oo oo <br>" + " oo oo oo oo <br>" + " oooooo oo oo oooooo <br>" + " oo oo oo oo <br>" + " oo oooo oo <br>"; - let charList = text.split(''); + const charList = text.split(''); - let binary = "01001111011100000110010101101110010001000100001100100001"; - let binaryIndex = 0; + const binaryString = "01001111011100000110010101101110010001000100001100100001"; + let binaryIndex = 0; for (let i = 0; i < charList.length; i++) { if (charList[i] === "o") { - charList[i] = binary[binaryIndex]; + charList[i] = binaryString[binaryIndex]; binaryIndex++; } } $(".code-block").html(charList.join("")); -});
\ No newline at end of file +}); diff --git a/src/scripts/main.entry.ts b/src/scripts/main.entry.ts index c7d6ef90..48ab7f37 100644 --- a/src/scripts/main.entry.ts +++ b/src/scripts/main.entry.ts @@ -27,8 +27,8 @@ class Display { * Adjusts the canvas size to fit the window's initial dimensions (full expansion). */ private static fitCanvasSize() { - let canvas = $("#main-canvas"); - let parent = canvas.parent(); + const canvas = $("#main-canvas"); + const parent = canvas.parent(); parent.height($(window).height() - 50); canvas.attr("width", parent.width()); canvas.attr("height", parent.height()); diff --git a/src/scripts/profile.entry.ts b/src/scripts/profile.entry.ts index 57c6b56c..b194e3a9 100644 --- a/src/scripts/profile.entry.ts +++ b/src/scripts/profile.entry.ts @@ -6,14 +6,14 @@ window["jQuery"] = $; $(document).ready(() => { - let api = new APIController(() => { + const api = new APIController(() => { }); $("#delete-account").on("click", () => { - let modalDialog = <any>$("#confirm-delete-account"); + const modalDialog = <any>$("#confirm-delete-account"); // Function called on delete confirmation - let callback = () => { + const callback = () => { api.deleteUser(parseInt(localStorage.getItem("userId"))).then(() => { removeUserInfo(); gapi.auth2.getAuthInstance().signOut().then(() => { @@ -23,7 +23,7 @@ $(document).ready(() => { modalDialog.find("button.confirm").off(); modalDialog.modal("hide"); - let alert = $(".account-delete-alert"); + const alert = $(".account-delete-alert"); alert.find("code").text(reason.code + ": " + reason.description); alert.slideDown(200); diff --git a/src/scripts/projects.entry.ts b/src/scripts/projects.entry.ts index 1ceb308b..9ae78586 100644 --- a/src/scripts/projects.entry.ts +++ b/src/scripts/projects.entry.ts @@ -12,7 +12,7 @@ $(document).ready(() => { new APIController((apiInstance: APIController) => { api = apiInstance; api.getAuthorizationsByUser(parseInt(localStorage.getItem("userId"))).then((data: any) => { - let projectsController = new ProjectsController(data, api); + const projectsController = new ProjectsController(data, api); new WindowController(projectsController, api); }); }); @@ -54,7 +54,7 @@ class ProjectsController { * @param list The list of authorizations to be displayed */ public static populateList(list: IAuthorization[]): void { - let body = $(".project-list .list-body"); + const body = $(".project-list .list-body"); body.empty(); list.forEach((element: IAuthorization) => { @@ -82,7 +82,7 @@ class ProjectsController { * @returns {IAuthorization[]} A filtered list of authorizations */ public static filterList(list: IAuthorization[], ownedByUser: boolean): IAuthorization[] { - let resultList: IAuthorization[] = []; + const resultList: IAuthorization[] = []; list.forEach((element: IAuthorization) => { if (element.authorizationLevel === "OWN") { @@ -160,12 +160,12 @@ class ProjectsController { * @param target The element that was clicked on to launch this view */ private displayProjectView(target: JQuery): void { - let closestRow = target.closest(".project-row"); - let activeElement = $(".project-row.active"); + const closestRow = target.closest(".project-row"); + const activeElement = $(".project-row.active"); // Disable previously selected row elements and remove any project-views, to have only one view open at a time if (activeElement.length > 0) { - let view = $(".project-view").first(); + const view = $(".project-view").first(); view.slideUp(200, () => { activeElement.removeClass("active"); @@ -177,19 +177,19 @@ class ProjectsController { } } - let simulationId = parseInt(closestRow.attr("data-id"), 10); + const simulationId = parseInt(closestRow.attr("data-id"), 10); // Generate a list of participants of this project this.api.getAuthorizationsBySimulation(simulationId).then((data: any) => { - let simAuthorizations = data; - let participants = []; + const simAuthorizations = data; + const participants = []; Util.sortAuthorizations(simAuthorizations); // For each participant of this simulation, include his/her name along with an icon of their authorization // level in the list simAuthorizations.forEach((authorization: IAuthorization) => { - let authorizationString = ' (<span class="glyphicon ' + + const authorizationString = ' (<span class="glyphicon ' + ProjectsController.authIconMap[authorization.authorizationLevel] + '"></span>)'; if (authorization.userId === this.currentUserId) { participants.push( @@ -203,7 +203,7 @@ class ProjectsController { }); // Generate a project view component with participants and relevant actions - let object = $('<div class="project-view">').append( + const object = $('<div class="project-view">').append( $('<div class="participants">').append( $('<strong>').text("Participants"), $('<div>').html(participants.join(", ")) @@ -217,7 +217,7 @@ class ProjectsController { closestRow.after(object); // Hide the 'edit' button for non-owners and -editors - let currentAuth = this.authorizationsFiltered[closestRow.index(".project-row")]; + const currentAuth = this.authorizationsFiltered[closestRow.index(".project-row")]; if (currentAuth.authorizationLevel !== "OWN") { $(".project-view .inline-btn.edit").hide(); } @@ -380,7 +380,7 @@ class WindowController { $(".project-name-form input").val(authorizations[0].simulation.name); $(".project-name-form .btn").css("display", "inline-block").click(() => { - let nameInput = $(".project-name-form input").val(); + const nameInput = $(".project-name-form input").val(); if (nameInput !== "") { authorizations[0].simulation.name = nameInput; this.api.updateSimulation(authorizations[0].simulation); @@ -528,7 +528,7 @@ class WindowController { * @param name A selector that uniquely identifies the alert body to be shown. */ private showAlert(name): void { - let alert = $(name); + const alert = $(name); alert.slideDown(200); setTimeout(() => { @@ -556,7 +556,7 @@ class WindowController { $(event.target).closest(".participant-level").find("div").removeClass("active"); $(event.target).addClass("active"); - let affectedRow = $(event.target).closest(".participant-row"); + const affectedRow = $(event.target).closest(".participant-row"); for (let level in ProjectsController.authIconMap) { if (!ProjectsController.authIconMap.hasOwnProperty(level)) { @@ -576,7 +576,7 @@ class WindowController { * @param callback The function to be called if the participant could be found and can be added. */ private handleParticipantAdd(callback: (userId: number) => any): void { - let inputForm = $(".participant-add-form input"); + const inputForm = $(".participant-add-form input"); this.api.getUserByEmail(inputForm.val()).then((data: any) => { let insert = true; for (let i = 0; i < this.simAuthorizations.length; i++) { @@ -585,7 +585,7 @@ class WindowController { } } - let simulationId = this.editMode ? this.simulationId : -1; + const simulationId = this.editMode ? this.simulationId : -1; if (data.id !== this.projectsController.currentUserId && insert) { this.simAuthorizations.push({ userId: data.id, @@ -614,9 +614,9 @@ class WindowController { * @param callback The function to be executed on removal of the participant from the internal list */ private handleParticipantDelete(event: JQueryEventObject, callback: (authorization: IAuthorization) => any): void { - let affectedRow = $(event.target).closest(".participant-row"); - let index = affectedRow.index(); - let authorization = this.simAuthorizations[index]; + const affectedRow = $(event.target).closest(".participant-row"); + const index = affectedRow.index(); + const authorization = this.simAuthorizations[index]; this.simAuthorizations.splice(index, 1); this.populateParticipantList(); callback(authorization); diff --git a/src/scripts/serverconnection.ts b/src/scripts/serverconnection.ts index c7f6e598..e5cbf48a 100644 --- a/src/scripts/serverconnection.ts +++ b/src/scripts/serverconnection.ts @@ -11,7 +11,7 @@ export class ServerConnection { public static send(request: IRequest): Promise<any> { return new Promise((resolve, reject) => { - let checkUnimplemented = ServerConnection.interceptUnimplementedEndpoint(request); + const checkUnimplemented = ServerConnection.interceptUnimplementedEndpoint(request); if (checkUnimplemented) { resolve(checkUnimplemented.content); return; @@ -28,7 +28,7 @@ export class ServerConnection { } public static convertFlatToNestedPositionData(responseContent, resolve): void { - let nestPositionCoords = (content: any) => { + const nestPositionCoords = (content: any) => { if (content["positionX"] !== undefined) { content["position"] = { x: content["positionX"], @@ -56,4 +56,4 @@ export class ServerConnection { // Endpoints that are unimplemented can be intercepted here return null; } -}
\ No newline at end of file +} diff --git a/src/scripts/splash.entry.ts b/src/scripts/splash.entry.ts index c1be1c28..700f52bb 100644 --- a/src/scripts/splash.entry.ts +++ b/src/scripts/splash.entry.ts @@ -15,7 +15,7 @@ $(document).ready(() => { * jQuery for page scrolling feature */ $('a.page-scroll').bind('click', function (event) { - let $anchor = $(this); + const $anchor = $(this); $('html, body').stop().animate({ scrollTop: $($anchor.attr('href')).offset().top }, 1000, 'easeInOutExpo', () => { @@ -28,7 +28,7 @@ $(document).ready(() => { event.preventDefault(); }); - let checkScrollState = () => { + const checkScrollState = () => { const startY = 100; if ($(window).scrollTop() > startY || window.innerWidth < 768) { @@ -44,7 +44,7 @@ $(document).ready(() => { checkScrollState(); - let googleSigninBtn = $("#google-signin"); + const googleSigninBtn = $("#google-signin"); googleSigninBtn.click(() => { hasClickedLogin = true; }); @@ -56,7 +56,7 @@ $(document).ready(() => { googleSigninBtn.hide(); $(".navbar .logged-in").css("display", "inline-block"); $(".logged-in .sign-out").click(() => { - let auth2 = gapi.auth2.getAuthInstance(); + const auth2 = gapi.auth2.getAuthInstance(); auth2.signOut().then(() => { // Remove session storage items @@ -72,12 +72,12 @@ $(document).ready(() => { }); // Check whether Google auth. token has expired and signin again if necessary - let currentTime = (new Date()).getTime(); + const currentTime = (new Date()).getTime(); if (parseInt(localStorage.getItem("googleTokenExpiration")) - currentTime <= 0) { gapi.auth2.getAuthInstance().signIn().then(() => { - let authResponse = gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse(); + const authResponse = gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse(); localStorage.setItem("googleToken", authResponse.id_token); - let expirationTime = (new Date()).getTime() / 1000 + parseInt(authResponse.expires_in) - 5; + const expirationTime = (new Date()).getTime() / 1000 + parseInt(authResponse.expires_in) - 5; localStorage.setItem("googleTokenExpiration", expirationTime.toString()); }); } @@ -98,13 +98,10 @@ window["renderButton"] = () => { let api; new APIController((apiInstance: APIController) => { api = apiInstance; - let email = googleUser.getBasicProfile().getEmail(); + const email = googleUser.getBasicProfile().getEmail(); - let getUser = (userId: number) => { - let reload = true; - if (localStorage.getItem("userId") !== null) { - reload = false; - } + const getUser = (userId: number) => { + const reload = localStorage.getItem("userId") === null; localStorage.setItem("userId", userId.toString()); @@ -118,9 +115,9 @@ window["renderButton"] = () => { }; // Send the token to the server - let id_token = googleUser.getAuthResponse().id_token; + const id_token = googleUser.getAuthResponse().id_token; // Calculate token expiration time (in seconds since epoch) - let expirationTime = (new Date()).getTime() / 1000 + googleUser.getAuthResponse().expires_in - 5; + const expirationTime = (new Date()).getTime() / 1000 + googleUser.getAuthResponse().expires_in - 5; $.post('https://opendc.ewi.tudelft.nl/tokensignin', { idtoken: id_token diff --git a/src/scripts/user.ts b/src/scripts/user.ts index dda2dcab..66e44b21 100644 --- a/src/scripts/user.ts +++ b/src/scripts/user.ts @@ -30,13 +30,13 @@ window["___gcfg"] = { }; /** - * Google signin button + * Google signin button. */ window["gapiSigninButton"] = () => { gapi.signin2.render('google-signin', { 'scope': 'profile email', 'onsuccess': (googleUser) => { - let auth2 = gapi.auth2.getAuthInstance(); + const auth2 = gapi.auth2.getAuthInstance(); // Handle signout click $("nav .user .sign-out").click(() => { @@ -47,12 +47,12 @@ window["gapiSigninButton"] = () => { }); // Check if the token has expired - let currentTime = (new Date()).getTime() / 1000; + const currentTime = (new Date()).getTime() / 1000; if (parseInt(localStorage.getItem("googleTokenExpiration")) - currentTime <= 0) { auth2.signIn().then(() => { localStorage.setItem("googleToken", googleUser.getAuthResponse().id_token); - let expirationTime = (new Date()).getTime() / 1000 + parseInt(googleUser.getAuthResponse().expires_in) - 5; + const expirationTime = (new Date()).getTime() / 1000 + parseInt(googleUser.getAuthResponse().expires_in) - 5; localStorage.setItem("googleTokenExpiration", expirationTime.toString()); }); } @@ -65,12 +65,14 @@ window["gapiSigninButton"] = () => { }; +/** + * Removes session storage items. + */ export function removeUserInfo() { - // Remove session storage items localStorage.removeItem("googleToken"); localStorage.removeItem("googleTokenExpiration"); localStorage.removeItem("googleName"); localStorage.removeItem("googleEmail"); localStorage.removeItem("userId"); localStorage.removeItem("simulationId"); -}
\ No newline at end of file +} diff --git a/src/scripts/util.ts b/src/scripts/util.ts index 74bdb710..7aa615ec 100644 --- a/src/scripts/util.ts +++ b/src/scripts/util.ts @@ -22,12 +22,12 @@ export class Util { * Does so by computing an outline around all tiles in the rooms. */ public static deriveWallLocations(rooms: IRoom[]): IRoomWall[] { - let verticalWalls = {}; - let horizontalWalls = {}; + const verticalWalls = {}; + const horizontalWalls = {}; let doInsert; rooms.forEach((room: IRoom) => { room.tiles.forEach((tile: ITile) => { - let x = tile.position.x, y = tile.position.y; + const x = tile.position.x, y = tile.position.y; for (let dX = -1; dX <= 1; dX++) { for (let dY = -1; dY <= 1; dY++) { if (Math.abs(dX) === Math.abs(dY)) { @@ -77,10 +77,10 @@ export class Util { }); }); - let result: IRoomWall[] = []; - let walls = [verticalWalls, horizontalWalls]; + const result: IRoomWall[] = []; + const walls = [verticalWalls, horizontalWalls]; for (let i = 0; i < 2; i++) { - let wallList = walls[i]; + const wallList = walls[i]; for (let a in wallList) { if (!wallList.hasOwnProperty(a)) { return; @@ -91,7 +91,7 @@ export class Util { }); let startPos = wallList[a][0]; - let positionArray = (i === 1 ? <number[]>[startPos, parseInt(a)] : <number[]>[parseInt(a), startPos]); + const positionArray = (i === 1 ? <number[]>[startPos, parseInt(a)] : <number[]>[parseInt(a), startPos]); if (wallList[a].length === 1) { result.push({ @@ -144,11 +144,11 @@ export class Util { * @returns {Array} A 2D list of tile positions that are valid next tile choices. */ public static deriveValidNextTilePositions(rooms: IRoom[], selectedTiles: ITile[]): IGridPosition[] { - let result = [], newPosition = {x: 0, y: 0}; + const result = [], newPosition = {x: 0, y: 0}; let isSurroundingTile; selectedTiles.forEach((tile: ITile) => { - let x = tile.position.x, y = tile.position.y; + const x = tile.position.x, y = tile.position.y; for (let dX = -1; dX <= 1; dX++) { for (let dY = -1; dY <= 1; dY++) { if (Math.abs(dX) === Math.abs(dY)) { @@ -195,10 +195,9 @@ export class Util { */ public static tileListPositionIndexOf(list: ITile[], position: IGridPosition): number { let index = -1; - let element; for (let i = 0; i < list.length; i++) { - element = list[i]; + const element = list[i]; if (position.x === element.position.x && position.y === element.position.y) { index = i; break; @@ -228,10 +227,9 @@ export class Util { */ public static positionListPositionIndexOf(list: IGridPosition[], position: IGridPosition): number { let index = -1; - let element; for (let i = 0; i < list.length; i++) { - element = list[i]; + const element = list[i]; if (position.x === element.x && position.y === element.y) { index = i; break; @@ -252,10 +250,9 @@ export class Util { */ public static roomCollisionIndexOf(rooms: IRoom[], position: IGridPosition): number { let index = -1; - let room; for (let i = 0; i < rooms.length; i++) { - room = rooms[i]; + const room = rooms[i]; if (Util.tileListContainsPosition(room.tiles, position)) { index = i; break; @@ -285,8 +282,8 @@ export class Util { * @returns {IBounds} The coordinates of the minimum, center, and maximum */ public static calculateRoomListBounds(rooms: IRoom[]): IBounds { - let min = [Number.MAX_VALUE, Number.MAX_VALUE]; - let max = [-1, -1]; + const min = [Number.MAX_VALUE, Number.MAX_VALUE]; + const max = [-1, -1]; rooms.forEach((room: IRoom) => { room.tiles.forEach((tile: ITile) => { @@ -309,7 +306,7 @@ export class Util { max[0]++; max[1]++; - let gridCenter = [min[0] + (max[0] - min[0]) / 2.0, min[1] + (max[1] - min[1]) / 2.0]; + const gridCenter = [min[0] + (max[0] - min[0]) / 2.0, min[1] + (max[1] - min[1]) / 2.0]; return { min: min, @@ -329,7 +326,7 @@ export class Util { } public static calculateRoomNamePosition(room: IRoom): IRoomNamePos { - let result: IRoomNamePos = { + const result: IRoomNamePos = { topLeft: {x: 0, y: 0}, length: 0 }; @@ -348,14 +345,14 @@ export class Util { } // Find the left-most tile at the top and the length of its adjacent tiles to the right - let topTilePositions: number[] = []; + const topTilePositions: number[] = []; room.tiles.forEach((tile: ITile) => { if (tile.position.y === topMin) { topTilePositions.push(tile.position.x); } }); topTilePositions.sort(); - let leftMin = topTilePositions[0]; + const leftMin = topTilePositions[0]; let length = 0; while (length < topTilePositions.length && topTilePositions[length] - leftMin === length) { @@ -428,7 +425,7 @@ export class Util { * @returns {IDateTime} A DateTime object with the parsed date and time information as content */ public static parseDateTime(input: string): IDateTime { - let output: IDateTime = { + const output: IDateTime = { year: 0, month: 0, day: 0, @@ -437,13 +434,13 @@ export class Util { second: 0 }; - let dateAndTime = input.split("T"); - let dateComponents = dateAndTime[0].split("-"); + const dateAndTime = input.split("T"); + const dateComponents = dateAndTime[0].split("-"); output.year = parseInt(dateComponents[0], 10); output.month = parseInt(dateComponents[1], 10); output.day = parseInt(dateComponents[2], 10); - let timeComponents = dateAndTime[1].split(":"); + const timeComponents = dateAndTime[1].split(":"); output.hour = parseInt(timeComponents[0], 10); output.minute = parseInt(timeComponents[1], 10); output.second = parseInt(timeComponents[2], 10); @@ -453,7 +450,7 @@ export class Util { public static formatDateTime(input: IDateTime) { let date; - let currentDate = new Date(); + const currentDate = new Date(); date = Util.addPaddingToTwo(input.day) + "/" + Util.addPaddingToTwo(input.month) + "/" + @@ -474,10 +471,10 @@ export class Util { } public static getCurrentDateTime(): string { - let date = new Date(); - return date.getFullYear() + "-" + Util.addPaddingToTwo(date.getMonth() + 1) + "-" + - Util.addPaddingToTwo(date.getDate()) + "T" + Util.addPaddingToTwo(date.getHours()) + ":" + - Util.addPaddingToTwo(date.getMinutes()) + ":" + Util.addPaddingToTwo(date.getSeconds()); + const currentDate = new Date(); + return currentDate.getFullYear() + "-" + Util.addPaddingToTwo(currentDate.getMonth() + 1) + "-" + + Util.addPaddingToTwo(currentDate.getDate()) + "T" + Util.addPaddingToTwo(currentDate.getHours()) + ":" + + Util.addPaddingToTwo(currentDate.getMinutes()) + ":" + Util.addPaddingToTwo(currentDate.getSeconds()); } /** @@ -493,7 +490,7 @@ export class Util { * @returns {any} A copy of the object without any populated properties (of type object). */ public static packageForSending(object: any) { - let result: any = {}; + const result: any = {}; for (let prop in object) { if (object.hasOwnProperty(prop)) { if (typeof object[prop] !== "object") { @@ -529,6 +526,11 @@ export class Util { let hour = Math.floor(seconds / 3600); let minute = Math.floor(seconds / 60) % 60; let second = seconds % 60; + + hour = isNaN(hour) ? 0 : hour; + minute = isNaN(minute) ? 0 : minute; + second = isNaN(second) ? 0 : second; + return this.addPaddingToTwo(hour) + ":" + this.addPaddingToTwo(minute) + ":" + this.addPaddingToTwo(second); diff --git a/src/scripts/views/layers/dcobject.ts b/src/scripts/views/layers/dcobject.ts index 6cec1f7e..f883a218 100644 --- a/src/scripts/views/layers/dcobject.ts +++ b/src/scripts/views/layers/dcobject.ts @@ -31,7 +31,7 @@ export class DCObjectLayer implements Layer { public static drawHoverRack(position: IGridPosition): createjs.Container { - let result = new createjs.Container(); + const result = new createjs.Container(); DCObjectLayer.drawItemRectangle( position, Colors.RACK_BACKGROUND, Colors.RACK_BORDER, result @@ -47,7 +47,7 @@ export class DCObjectLayer implements Layer { } public static drawHoverPSU(position: IGridPosition): createjs.Container { - let result = new createjs.Container(); + const result = new createjs.Container(); DCObjectLayer.drawItemRectangle( position, Colors.PSU_BACKGROUND, Colors.PSU_BORDER, result @@ -57,7 +57,7 @@ export class DCObjectLayer implements Layer { } public static drawHoverCoolingItem(position: IGridPosition): createjs.Container { - let result = new createjs.Container(); + const result = new createjs.Container(); DCObjectLayer.drawItemRectangle( position, Colors.COOLING_ITEM_BACKGROUND, Colors.COOLING_ITEM_BORDER, result @@ -77,7 +77,7 @@ export class DCObjectLayer implements Layer { */ private static drawItemRectangle(position: IGridPosition, color: string, borderColor: string, container: createjs.Container): createjs.Shape { - let shape = new createjs.Shape(); + const shape = new createjs.Shape(); shape.graphics.beginStroke(borderColor); shape.graphics.setStrokeStyle(DCObjectLayer.STROKE_WIDTH); shape.graphics.beginFill(color); @@ -101,7 +101,7 @@ export class DCObjectLayer implements Layer { */ private static drawItemIcon(position: IGridPosition, container: createjs.Container, originBitmap: createjs.Bitmap): createjs.Bitmap { - let bitmap = originBitmap.clone(); + const bitmap = originBitmap.clone(); container.addChild(bitmap); bitmap.x = position.x * CELL_SIZE + DCObjectLayer.ITEM_MARGIN + DCObjectLayer.ITEM_PADDING * 1.5; bitmap.y = position.y * CELL_SIZE + DCObjectLayer.ITEM_MARGIN + DCObjectLayer.ITEM_PADDING * 1.5; @@ -157,7 +157,7 @@ export class DCObjectLayer implements Layer { this.mapView.currentDatacenter.rooms.forEach((room: IRoom) => { room.tiles.forEach((tile: ITile) => { if (tile.object !== undefined) { - let index = tile.position.y * MapView.MAP_SIZE + tile.position.x; + const index = tile.position.y * MapView.MAP_SIZE + tile.position.x; switch (tile.objectType) { case "RACK": @@ -194,15 +194,13 @@ export class DCObjectLayer implements Layer { } public draw(): void { - let currentObject; - this.container.removeAllChildren(); this.container.cursor = "pointer"; for (let property in this.dcObjectMap) { if (this.dcObjectMap.hasOwnProperty(property)) { - currentObject = this.dcObjectMap[property]; + const currentObject = this.dcObjectMap[property]; switch (currentObject.type) { case "RACK": @@ -249,4 +247,4 @@ export class DCObjectLayer implements Layer { this.mapView.updateScene = true; } -}
\ No newline at end of file +} diff --git a/src/scripts/views/layers/dcprogressbar.ts b/src/scripts/views/layers/dcprogressbar.ts index d0ec4397..e518ead4 100644 --- a/src/scripts/views/layers/dcprogressbar.ts +++ b/src/scripts/views/layers/dcprogressbar.ts @@ -30,7 +30,7 @@ export class DCProgressBar { public static drawItemProgressRectangle(position: IGridPosition, color: string, container: createjs.Container, distanceFromBottom: number, fractionFilled: number): createjs.Shape { - let shape = new createjs.Shape(); + const shape = new createjs.Shape(); shape.graphics.beginFill(color); let x = position.x * CELL_SIZE + DCObjectLayer.ITEM_MARGIN + DCObjectLayer.ITEM_PADDING; let y = (position.y + 1) * CELL_SIZE - DCObjectLayer.ITEM_MARGIN - DCObjectLayer.ITEM_PADDING - @@ -67,7 +67,7 @@ export class DCProgressBar { */ public static drawProgressbarIcon(position: IGridPosition, container: createjs.Container, originBitmap: createjs.Bitmap, distanceFromBottom: number): createjs.Bitmap { - let bitmap = originBitmap.clone(); + const bitmap = originBitmap.clone(); container.addChild(bitmap); bitmap.x = (position.x + 0.5) * CELL_SIZE - DCProgressBar.PROGRESS_BAR_WIDTH * 0.5; bitmap.y = (position.y + 1) * CELL_SIZE - DCObjectLayer.ITEM_MARGIN - DCObjectLayer.ITEM_PADDING - @@ -96,4 +96,4 @@ export class DCProgressBar { DCProgressBar.drawProgressbarIcon(this.position, this.container, this.bitmap, this.distanceFromBottom); } -}
\ No newline at end of file +} diff --git a/src/scripts/views/layers/gray.ts b/src/scripts/views/layers/gray.ts index ed3c9429..63911d19 100644 --- a/src/scripts/views/layers/gray.ts +++ b/src/scripts/views/layers/gray.ts @@ -33,9 +33,9 @@ export class GrayLayer implements Layer { this.container.removeAllChildren(); - let roomBounds = Util.calculateRoomBounds(this.currentRoom); + const roomBounds = Util.calculateRoomBounds(this.currentRoom); - let shape = new createjs.Shape(); + const shape = new createjs.Shape(); shape.graphics.beginFill(Colors.GRAYED_OUT_AREA); shape.cursor = "pointer"; @@ -142,4 +142,4 @@ export class GrayLayer implements Layer { public isGrayedOut(): boolean { return this.currentRoom !== undefined; } -}
\ No newline at end of file +} diff --git a/src/scripts/views/layers/room.ts b/src/scripts/views/layers/room.ts index 0e31fee0..c1989206 100644 --- a/src/scripts/views/layers/room.ts +++ b/src/scripts/views/layers/room.ts @@ -65,7 +65,7 @@ export class RoomLayer implements Layer { public addSelectedTile(tile: ITile): void { this.selectedTiles.push(tile); - let tileObject = MapView.drawRectangle(tile.position, Colors.ROOM_SELECTED, this.container); + const tileObject = MapView.drawRectangle(tile.position, Colors.ROOM_SELECTED, this.container); this.selectedTileObjects.push({ position: {x: tile.position.x, y: tile.position.y}, tileObject: tileObject @@ -84,7 +84,7 @@ export class RoomLayer implements Layer { * @param objectIndex The index of the tile in the selectedTileObjects array */ public removeSelectedTile(position: IGridPosition, objectIndex: number): void { - let index = Util.tileListPositionIndexOf(this.selectedTiles, position); + const index = Util.tileListPositionIndexOf(this.selectedTiles, position); // Check whether the given position doesn't belong to an already removed tile if (index === -1) { @@ -174,4 +174,4 @@ export class RoomLayer implements Layer { tileObj.tileObject.cursor = value ? "pointer" : "default"; }); } -}
\ No newline at end of file +} diff --git a/src/scripts/views/layers/roomtext.ts b/src/scripts/views/layers/roomtext.ts index 65ea0735..63fab0ed 100644 --- a/src/scripts/views/layers/roomtext.ts +++ b/src/scripts/views/layers/roomtext.ts @@ -42,15 +42,15 @@ export class RoomTextLayer implements Layer { return; } - let textPos = Util.calculateRoomNamePosition(room); + const textPos = Util.calculateRoomNamePosition(room); - let bottomY = this.renderText(room.name, "12px Arial", textPos, + const bottomY = this.renderText(room.name, "12px Arial", textPos, textPos.topLeft.y * CELL_SIZE + RoomTextLayer.TEXT_PADDING); this.renderText("Type: " + Util.toSentenceCase(room.roomType), "10px Arial", textPos, bottomY + 5); } private renderText(text: string, font: string, textPos: IRoomNamePos, startY: number): number { - let name = new createjs.Text(text, font, Colors.ROOM_NAME_COLOR); + const name = new createjs.Text(text, font, Colors.ROOM_NAME_COLOR); if (name.getMeasuredWidth() > textPos.length * CELL_SIZE - RoomTextLayer.TEXT_PADDING * 2) { name.scaleX = name.scaleY = (textPos.length * CELL_SIZE - RoomTextLayer.TEXT_PADDING * 2) / diff --git a/src/scripts/views/mapview.ts b/src/scripts/views/mapview.ts index ae7fd5cb..50fc2e45 100644 --- a/src/scripts/views/mapview.ts +++ b/src/scripts/views/mapview.ts @@ -70,7 +70,7 @@ export class MapView { */ public static drawLine(x1: number, y1: number, x2: number, y2: number, lineWidth: number, color: string, container: createjs.Container): createjs.Shape { - let line = new createjs.Shape(); + const line = new createjs.Shape(); line.graphics.setStrokeStyle(lineWidth).beginStroke(color); line.graphics.moveTo(x1, y1); line.graphics.lineTo(x2, y2); @@ -89,7 +89,7 @@ export class MapView { */ public static drawRectangle(position: IGridPosition, color: string, container: createjs.Container, sizeX?: number, sizeY?: number): createjs.Shape { - let tile = new createjs.Shape(); + const tile = new createjs.Shape(); tile.graphics.setStrokeStyle(0); tile.graphics.beginFill(color); tile.graphics.drawRect( @@ -125,14 +125,14 @@ export class MapView { constructor(simulation: ISimulation, stage: createjs.Stage) { this.simulation = simulation; - let path = this.simulation.paths[this.simulation.paths.length - 1]; + const path = this.simulation.paths[this.simulation.paths.length - 1]; this.currentDatacenter = path.sections[path.sections.length - 1].datacenter; this.stage = stage; console.log("THE DATA", simulation); - let canvas = $("#main-canvas"); + const canvas = $("#main-canvas"); this.canvasWidth = canvas.width(); this.canvasHeight = canvas.height(); @@ -207,22 +207,22 @@ export class MapView { // Calculate position difference if zoomed, in order to later compensate for this // unwanted movement - let oldPosition = [ + const oldPosition = [ position[0] - this.mapContainer.x, position[1] - this.mapContainer.y ]; - let newPosition = [ + const newPosition = [ (oldPosition[0] / this.mapContainer.scaleX) * newZoom, (oldPosition[1] / this.mapContainer.scaleX) * newZoom ]; - let positionDelta = [ + const positionDelta = [ newPosition[0] - oldPosition[0], newPosition[1] - oldPosition[1] ]; // Apply the transformation operation to keep the selected position static - let newX = this.mapContainer.x - positionDelta[0]; - let newY = this.mapContainer.y - positionDelta[1]; + const newX = this.mapContainer.x - positionDelta[0]; + const newY = this.mapContainer.y - positionDelta[1]; - let finalPos = this.mapController.checkCanvasMovement(newX, newY, newZoom); + const finalPos = this.mapController.checkCanvasMovement(newX, newY, newZoom); if (!this.animating) { this.animate(this.mapContainer, { @@ -270,24 +270,24 @@ export class MapView { * @param rooms The array of rooms to be viewed */ private zoomInOnRooms(rooms: IRoom[]): void { - let bounds = Util.calculateRoomListBounds(rooms); - let newScale = this.calculateNewScale(bounds); + const bounds = Util.calculateRoomListBounds(rooms); + const newScale = this.calculateNewScale(bounds); // Coordinates of the center of the room, relative to the global origin of the map - let roomCenterCoords = [ + const roomCenterCoords = [ bounds.center[0] * CELL_SIZE * newScale, bounds.center[1] * CELL_SIZE * newScale ]; // Coordinates of the center of the stage (the visible part of the canvas), relative to the global map origin - let stageCenterCoords = [ + const stageCenterCoords = [ -this.mapContainer.x + this.canvasWidth / 2, -this.mapContainer.y + this.canvasHeight / 2 ]; - let newX = this.mapContainer.x - roomCenterCoords[0] + stageCenterCoords[0]; - let newY = this.mapContainer.y - roomCenterCoords[1] + stageCenterCoords[1]; + const newX = this.mapContainer.x - roomCenterCoords[0] + stageCenterCoords[0]; + const newY = this.mapContainer.y - roomCenterCoords[1] + stageCenterCoords[1]; - let newPosition = this.mapController.checkCanvasMovement(newX, newY, newScale); + const newPosition = this.mapController.checkCanvasMovement(newX, newY, newScale); this.animate(this.mapContainer, { scaleX: newScale, scaleY: newScale, @@ -299,11 +299,11 @@ export class MapView { const viewPadding = 30; const sideMenuWidth = 350; - let width = bounds.max[0] - bounds.min[0]; - let height = bounds.max[1] - bounds.min[1]; + const width = bounds.max[0] - bounds.min[0]; + const height = bounds.max[1] - bounds.min[1]; - let scaleX = (this.canvasWidth - 2 * sideMenuWidth) / (width * CELL_SIZE + 2 * viewPadding); - let scaleY = this.canvasHeight / (height * CELL_SIZE + 2 * viewPadding); + const scaleX = (this.canvasWidth - 2 * sideMenuWidth) / (width * CELL_SIZE + 2 * viewPadding); + const scaleY = this.canvasHeight / (height * CELL_SIZE + 2 * viewPadding); let newScale = Math.min(scaleX, scaleY); @@ -321,10 +321,10 @@ export class MapView { */ private drawMap(): void { // Create and draw the container for the entire map - let gridPixelSize = CELL_SIZE * MapView.MAP_SIZE; + const gridPixelSize = CELL_SIZE * MapView.MAP_SIZE; // Add a white background to the entire container - let background = new createjs.Shape(); + const background = new createjs.Shape(); background.graphics.beginFill("#fff"); background.graphics.drawRect(0, 0, gridPixelSize, gridPixelSize); @@ -370,4 +370,4 @@ export class MapView { } }); } -}
\ No newline at end of file +} |
