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($("